--- /dev/null
+<Wolf>
+ <Table name="host">
+ <Column name="hostname" type="string:64" primarykey="yes"/>
+ <!-- if hostkey is NULL it is a special host (_any, _anon, _online) -->
+ <Column name="hostkey" type="string" />
+ </Table>
+
+</Wolf>
--- /dev/null
+<Wolf>
+ <!-- generic settings -->
+ <Project baseDir=".." wobDir="wob"/>
+ <Version comm="0100" needcomm="0100" humanReadable="1.1 alpha">
+ <Svn target="." cacheFile="svn_*.xml"/>
+ </Version>
+ <DataBase instance="db" scheme="dbScheme"/>
+
+ <!-- configure output -->
+ <QtClientOutput sourceDir="src" subDir="wob" priInclude="wob.pri"/>
+ <PHPServerOutput sourceDir="www" subDir="inc/wob" extension=".php" loader="wobload.php"/>
+ <SOAPOutput sourceDir="soap" schema="magicsmoke.xs" wsdl="magicsmoke.wsdl"/>
+
+ <!-- load and parse class definitions -->
+ <Include file="basics.wolf"/>
+ <Include file="user.wolf"/>
+ <!-- <Include file="customer.wolf"/>
+ <Include file="ticket.wolf"/>
+ <Include file="voucher.wolf"/> -->
+ <Include file="order.wolf"/>
+</Wolf>
\ No newline at end of file
--- /dev/null
+<Wolf>
+ <Table name="order" backup="yes">
+ <Column name="orderid" type="seq32" primarykey="yes"/>
+ <!--customer-->
+ <Column name="customerid" type="int32" foreignkey="customer:customerid"/>
+ <!--seller (_online for web forms)-->
+ <Column name="soldby" type="string:64" foreignkey="users:uname"/>
+ <!--if not null/empty: this address for delivery, customer address for invoice-->
+ <Column name="deliveryaddress" type="text"/>
+ <!--if not null/empty: lodge/deposit the tickets at a seller with _deposit flag-->
+ <Column name="depositat" type="string:64" foreignkey="users:uname"/>
+ <!--status, see ORDER_* constants-->
+ <Column name="status" type="enum32" notnull="yes">
+ <Value name="ORDER_PLACED" value="0"/>
+ <Value name="ORDER_SENT" value="1"/>
+ <Value name="ORDER_SOLD" value="1"/>
+ <Value name="ORDER_CANCELLED" value="2"/>
+ <Value name="ORDER_RESERVED" value="4"/>
+ <Value name="ORDER_CLOSED" value="0x80"/>
+ </Column>
+ <Column name="ordertime" type="int32" notnull="yes"/>
+ <Column name="senttime" type="int32"/>
+ <!--comments made on web form (eg. "urgently needed for dads birthday")-->
+ <Column name="comments" type="text"/>
+ <!--how much has been paid already (including used vouchers)
+ this is for comparison with the price fields in ticket and voucher tables-->
+ <Column name="amountpaid" type="int32"/>
+ <!--shipping price-->
+ <Column name="shippingcosts" type="int32" default="0"/>
+ <!--pointer to shipping type (none per default, programmatic default is in config)-->
+ <Column name="shippingtype" type="int32" null="yes" foreignkey="shipping:shipid"/>
+
+ <Foreign method="getTickets" via="ticket:orderid=orderid"/>
+ <Foreign method="getVouchers" via="voucher:orderid=orderid"/>
+ </Table>
+ <Table name="ticket" backup="yes">
+ <!--a 8-32 char code (code39: case-insensitive letters+digits) for the ticket-->
+ <Column name="ticketid" type="string:32" primarykey="yes"/>
+ <Column name="eventid" type="int32" foreignkey="event:eventid"/>
+ <!--initially a copy from event, can be adjusted by seller-->
+ <Column name="price" type="int32" notnull="yes"/>
+ <!--status of ticket (see TICKET_* constants)-->
+ <Column name="status" type="int32" notnull="yes"/>
+ <Column name="orderid" type="int32" foreignkey="order:orderid" notnull="yes"/>
+ </Table>
+ <Table name="voucher" backup="yes">
+ <!--a 8-32 char code (code39: case-insensitive letters+digits) for the voucher-->
+ <Column name="voucherid" type="string:32" primarykey="yes"/>
+ <!--price of the voucher (0 if cancelled)-->
+ <Column name="price" type="int32" notnull="yes"/>
+ <!--order this voucher belongs to-->
+ <Column name="orderid" type="int32" foreignkey="order:orderid" notnull="yes"/>
+ <!--marker: voucher has been used to pay something-->
+ <Column name="isused" type="bool" default="false"/>
+ <!--remaining value in cents (0 for cancelled)-->
+ <Column name="value" type="int32" notnull="yes"/>
+ </Table>
+
+
+
+ <Class name="CartTicket">
+ <Enum name="TicketValidationState">
+ <Value name="Ok"/>
+ <Value name="TooLate"/>
+ <Value name="Exhausted"/>
+ <Value name="SaleOnly"/>
+ <Value name="OrderOnly"/>
+ </Enum>
+ <Property name="eventid" type="int"/>
+ <Property name="amount" type="int"/>
+ <Property name="price" type="int" optional="1"/>
+ <Property name="status" type="TicketValidationState" optional="1"/>
+ <Property name="maxamount" type="int" optional="1"/>
+ </Class>
+
+
+ <Class name="CartVoucher">
+ <Enum name="ValidationState">
+ <Value name="Ok"/>
+ <Value name="InvalidValue"/>
+ <Value name="InvalidPrice"/>
+ </Enum>
+ <Property name="value" type="int"/>
+ <Property name="price" type="int" optional="1"/>
+ <Property name="status" type="Enum:ValidationState" optional="1"/>
+ </Class>
+
+ <Class name="CartOrder">
+ <Enum name="ValidationState">
+ <Value name="Ok"/>
+ <Value name="SaleOnly"/>
+ <Value name="OrderOnly"/>
+ <Value name="Invalid"/>
+ </Enum>
+ <Property name="status" type="Enum:ValidationState" optional="1"/>
+ <Property name="customerid" type="int"/>
+ <Property name="tickets" type="List:CartTicket"/>
+ <Property name="vouchers" type="List:CartVoucher"/>
+ </Class>
+
+ <Class name="Order">
+ <Enum name="OrderState">
+ <Value name="Placed" dbvalue="0"/>
+ <Value name="Sent" dbvalue="1"/>
+ <Value name="Sold" dbvalue="1"/>
+ <Value name="Cancelled" dbvalue="2"/>
+ <Value name="Reserved" dbvalue="4"/>
+ <Value name="Closed" dbvalue="0x80"/>
+ </Enum>
+
+ <Select name="getAll" table="orders"/>
+ <Select name="getByID" params="int orderid" table="orders" where="orderid=$orderid$"/>
+
+ <Property name="orderid" type="int"/>
+ <Property name="customerid" type="int"/>
+ <Property name="seller" type="astring"/>
+ <Property name="tickets" type="List:Ticket">
+ <Select table="tickets" where="orderid=$orderid$"/>
+ </Property>
+ <Property name="vouchers" type="List:Voucher">
+ <Select table="vouchers" where="orderid=$orderid$"/>
+ </Property>
+ <Property name="amountpaid" type="int"/>
+ <Property name="state" type="Enum:OrderState"/>
+
+ <Virtual name="amountdue" type="int" access="ro"/>
+ <!-- etc.pp. -->
+
+ <ToXml name="Short">orderid customerid seller amountpaid state amountdue</ToXml>
+ <ToXml name="Full">orderid customerid seller amountpaid state amountdue tickets/Full vouchers/Full</ToXml>
+ </Class>
+</Wolf>
\ No newline at end of file
--- /dev/null
+<Wolf>
+ <Class name="User">
+ <Property name="name" column="uname" type="astring"/>
+ <Property name="password" column="passwd" type="string"/>
+ <Property name="description" type="string"/>
+
+ </Class>
+</Wolf>
\ No newline at end of file
--- /dev/null
+//
+// C++ Implementation: phpout
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "phpout.h"
+
+WocPHPServerOut::WocPHPServerOut(QString srcDir,QString subDir,QString ext,QString loader){}
+void WocPHPServerOut::finalize(){}
+void WocPHPServerOut::newClass(const WocClass&){}
--- /dev/null
+//
+// C++ Interface: phpout
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef WOC_PHPOUT_H
+#define WOC_PHPOUT_H
+
+#include "processor.h"
+
+class WocPHPServerOut:public WocOutput
+{
+ public:
+ WocPHPServerOut(QString srcDir,QString subDir,QString ext,QString loader);
+ protected:
+ virtual void finalize();
+ virtual void newClass(const WocClass&);
+};
+
+#endif
--- /dev/null
+//
+// C++ Implementation: processor
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "processor.h"
+
+#include "phpout.h"
+#include "qtout.h"
+
+#include <QDir>
+#include <QDomDocument>
+#include <QDomElement>
+#include <QProcess>
+
+WocProcessor* WocProcessor::inst=0;
+
+WocProcessor::WocProcessor()
+{
+ m_baseDir=QDir(".").absolutePath();
+ m_wobDir=".";
+ m_verComm="0";
+ m_verNeedComm="0";
+ m_verHR="0.0";
+ m_svnTarget=".";
+ m_svnCache=".svn_*.xml";
+ m_svnExe="svn";
+ m_dbInst="dbInst";
+ m_dbScheme="dbScheme";
+
+ inst=this;
+}
+
+bool WocProcessor::processFile(QString fn)
+{
+ //open file
+ QFile fd(fn);
+ if(!fd.open(QIODevice::ReadOnly)){
+ qDebug("Error: cannot read file %s",fn.toLocal8Bit().data());
+ return false;
+ }
+ //get XML content
+ QDomDocument doc;
+ QString err;int eln,ecl;
+ if(!doc.setContent(&fd,&err,&eln,&ecl)){
+ qDebug("Error: XML parser error in file %s line %i column %i: %s",fn.toLocal8Bit().data(),eln,ecl,err.toLocal8Bit().data());
+ fd.close();
+ return false;
+ }
+ fd.close();
+ QDomElement root=doc.documentElement();
+ if(root.isNull() || root.tagName()!="Wolf"){
+ qDebug("Error: XML File %s is not a Wolf.",fn.toLocal8Bit().data());
+ return false;
+ }
+ //go on, process file
+ qDebug("Info: processing file %s...",fn.toLocal8Bit().data());
+ QDomNodeList nl=root.childNodes();
+ for(int i=0;i<nl.size();i++){
+ if(!nl.at(i).isElement())continue;
+ QDomElement el=nl.at(i).toElement();
+ if(el.isNull())continue;
+ QString tn=el.tagName();
+ if(tn=="Class"){
+ WocClass cls(el);
+ if(cls.isValid())
+ emit newClass(cls);
+ else
+ return false;
+ }else
+ if(tn=="Project"){
+ if(el.hasAttribute("baseDir"))
+ m_baseDir=el.attribute("baseDir");
+ if(el.hasAttribute("wobDir"))
+ m_wobDir=el.attribute("wobDir");
+ }else
+ if(tn=="Include"){
+ if(!processFile(m_baseDir+"/"+m_wobDir+"/"+el.attribute("file")))
+ return false;
+ }else
+ if(tn=="DataBase"){
+ if(el.hasAttribute("instance"))
+ m_dbInst=el.attribute("instance");
+ if(el.hasAttribute("scheme"))
+ m_dbScheme=el.attribute("scheme");
+ }else
+ if(tn=="QtClientOutput"){
+ new WocQtClientOut(el.attribute("sourceDir","."), el.attribute("subDir","qtwob"), el.attribute("priInclude","qtwob.pri"));
+ }else
+ if(tn=="PHPServerOutput"){
+ new WocPHPServerOut(el.attribute("sourceDir","."), el.attribute("subDir","phpwob"), el.attribute("extension",".inc"), el.attribute("loader",""));
+ }else
+ if(tn=="Version"){
+ if(el.hasAttribute("comm"))
+ m_verComm=el.attribute("comm");
+ if(el.hasAttribute("needcomm"))
+ m_verNeedComm=el.attribute("needcomm");
+ if(el.hasAttribute("humanReadable"))
+ m_verHR=el.attribute("humanReadable");
+ QDomNodeList nl2=el.elementsByTagName("Svn");
+ for(int j=0;j<nl2.size();j++){
+ QDomElement el2=nl2.at(j).toElement();
+ if(el2.isNull())continue;
+ if(el2.hasAttribute("target"))
+ m_svnTarget=el2.attribute("target");
+ if(el2.hasAttribute("cacheFile"))
+ m_svnCache=el2.attribute("cacheFile");
+ if(el2.hasAttribute("exe"))
+ m_svnExe=el2.attribute("exe");
+ }
+ if(nl2.size()>0)callSvn();
+ }
+ else{
+ qDebug("Warning: file %s has unknown element '%s' at line %i column %i", fn.toLocal8Bit().data(), tn.toLocal8Bit().data(), el.lineNumber(), el.columnNumber());
+ }
+ }
+ return true;
+}
+
+void WocProcessor::callSvn()
+{
+ //svn info
+ QString svntgt=m_baseDir+"/"+m_svnTarget;
+ QProcess svn;
+ svn.setProcessChannelMode(QProcess::MergedChannels);
+ svn.setWorkingDirectory(svntgt);
+ svn.start(m_svnExe,QStringList()<<"info"<<"-R"<<"--xml"<<"--non-interactive"<<".");
+ svn.waitForFinished();
+ if(svn.exitCode()!=0){
+ qDebug("Warning: error while calling svn info.");
+ return;
+ }else{
+ QDomDocument doc;
+ if(!doc.setContent(svn.readAllStandardOutput())){
+ qDebug("Warning: unable to parse output of svn info.");
+ return;
+ }
+ //TODO: parse it.
+ }
+ //svn status
+ svn.start(m_svnExe,QStringList()<<"status"<<"--xml"<<"--non-interactive"<<".");
+ svn.waitForFinished();
+ if(svn.exitCode()!=0)return;
+ QFile stat(m_baseDir+"/"+QString(m_svnCache).replace("*","status"));
+ if(stat.open(QIODevice::WriteOnly|QIODevice::Truncate)){
+ stat.write(svn.readAllStandardOutput());
+ stat.close();
+ qDebug("Info: wrote svn status to %s",stat.fileName().toLocal8Bit().data());
+ }else
+ qDebug("Warning: unable to call svn status");
+}
+
+void WocProcessor::finalize()
+{
+ emit sfinalize();
+}
+
+WocOutput::WocOutput()
+{
+ connect(WocProcessor::instance(),SIGNAL(sfinalize()),this,SLOT(finalize()));
+ connect(WocProcessor::instance(),SIGNAL(newClass(const WocClass&)),this,SLOT(newClass(const WocClass&)));
+}
+
+WocOutput::~WocOutput(){}
+
+WocClass::WocClass(const QDomElement&cls)
+{
+ m_valid=true;
+ qDebug("not really parsing class %s",cls.attribute("name").toAscii().data());
+
+}
--- /dev/null
+//
+// C++ Interface: processor
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef WOC_PROCESSOR_H
+#define WOC_PROCESSOR_H
+
+#include <QObject>
+
+class QDomElement;
+
+class WocClass
+{
+ public:
+ WocClass(const QDomElement&);
+
+ bool isValid()const{return m_valid;}
+ private:
+ bool m_valid;
+};
+
+class WocOutput:public QObject
+{
+ Q_OBJECT
+ public:
+ WocOutput();
+ virtual ~WocOutput();
+
+ protected slots:
+ virtual void finalize()=0;
+ virtual void newClass(const WocClass&)=0;
+};
+
+class WocProcessor:public QObject
+{
+ Q_OBJECT
+ public:
+ WocProcessor();
+
+ bool processFile(QString);
+ void finalize();
+
+ static WocProcessor* instance(){return inst;}
+ QString baseDir()const{return m_baseDir;}
+ QString wobDir()const{return m_wobDir;}
+ QString verComm()const{return m_verComm;}
+ QString verNeedComm()const{return m_verNeedComm;}
+ QString verHR()const{return m_verHR;}
+ QString svnCache()const{return m_svnCache;}
+ QString dbInst()const{return m_dbInst;}
+ QString dbScheme()const{return m_dbScheme;}
+ signals:
+ void sfinalize();
+ void newClass(const WocClass&);
+
+ private:
+ QString m_baseDir,m_wobDir,m_verComm,m_verNeedComm,m_verHR;
+ QString m_svnTarget,m_svnCache,m_svnExe,m_dbInst,m_dbScheme;
+
+ static WocProcessor*inst;
+
+ void callSvn();
+};
+
+
+#endif
--- /dev/null
+//
+// C++ Implementation: qtout
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "qtout.h"
+
+WocQtClientOut::WocQtClientOut(QString srcDir,QString subDir,QString prifile){}
+void WocQtClientOut::finalize(){}
+void WocQtClientOut::newClass(const WocClass&){}
--- /dev/null
+//
+// C++ Interface: qtout
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef WOC_QTOUT_H
+#define WOC_QTOUT_H
+
+#include "processor.h"
+
+class WocQtClientOut:public WocOutput
+{
+ public:
+ WocQtClientOut(QString srcDir,QString subDir,QString prifile);
+ protected:
+ virtual void finalize();
+ virtual void newClass(const WocClass&);
+};
+
+#endif
--- /dev/null
+//
+// C++ Implementation: woc
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include <QCoreApplication>
+#include <QStringList>
+
+#include "processor.h"
+
+int main(int argc,char**argv)
+{
+ QCoreApplication app(argc,argv);
+ //get arguments
+ QStringList args=app.arguments();
+ args.removeFirst();
+ //process files
+ WocProcessor proc;
+ for(int i=0;i<args.size();i++)
+ if(!proc.processFile(args[i])){
+ qDebug("aborting scan.");
+ return 1;
+ }
+ //call finalizer
+ proc.finalize();
+ qDebug("done.");
+ //return success
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+TEMPLATE=app
+TARGET=../woc/woc
+QT-=gui
+QT+=xml
+
+SOURCES+=processor.cpp woc.cpp qtout.cpp phpout.cpp
+HEADERS+=processor.h phpout.h qtout.h
\ No newline at end of file
define("RND_VOUCHER",0x08);
//not used yet:
define("RND_OTHER1",0x10);
-define("RND_OTHER1",0x18);
+define("RND_OTHER2",0x18);
/**return a new Code-39 capable ID; length is the amount of characters*/
function getCode39ID($length,$range=RND_ANYRANGE)
defversion(CURSERVER,0005)
//current human readable version of the server
-defversion(HRSERVER,0.2 beta)
+defversion(HRSERVER,1.1 beta)
//minimum version that the client requires
defversion(MINCLIENT,0000)
defversion(CURCLIENT,0005)
//current human readable version of the client
-defversion(HRCLIENT,0.2 beta)
+defversion(HRCLIENT,1.1 beta)
--- /dev/null
+<?php
+// +----------------------------------------------------------------------
+// | PHP Source
+// +----------------------------------------------------------------------
+// | Copyright (C) 2009 by Konrad Rosenbaum <konrad@silmor.de>
+// +----------------------------------------------------------------------
+// |
+// | Copyright: See COPYING file that comes with this distribution
+// +----------------------------------------------------------------------
+//
+
+$AUTOCLASS["WobTable"]="wbase/table.php";
+
+function __autoload($cname)
+{
+ global $AUTOCLASS;
+ if(isset($AUTOCLASS[$cname]))
+ require_once 'inc/'.$AUTOCLASS[$cname];
+}
+
+?>
--- /dev/null
+<?
+//
+// PHP Implementation: wob table base class
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+class WobTable
+{
+ private $data;
+ private $isfromdb;
+ private $table;
+
+ protected function __construct(array $data,$isfromdb,$table)
+ {
+ $this->data=$data;
+ $this->isfromdb=$isfromdb;
+ $this->table=$table;
+ }
+
+ public function __set($name,$value)
+ {
+ //verify name against scheme
+ //escape value
+ //DB update (if from DB)
+ //if successful: store
+ }
+
+ public function __get($name)
+ {
+ //verify name
+ //return value or false
+ }
+
+ public function __isset($name)
+ {
+ //verify name and return true on existence
+ }
+
+ public function __unset($name)
+ {
+ //ignore those fools!
+ }
+
+ /**insert the object under a new primary key value into the DB (implicitly calls newKey)*/
+ public function insert()
+ {
+ }
+
+ /**generate a new primary key value for insert and marks the object as not yet in the DB; the default sets the primary key to NULL; call the original first if you overwrite it*/
+ public function newKey()
+ {
+ $this->isfromdb=false;
+ //get primary key columns and set them to false
+ }
+};
+
+?>
\ No newline at end of file