--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Audit MagicSmoke WOLF
+ - Auditing features
+ -
+ - (c) Konrad Rosenbaum, 2009
+ - this file is protected under the GNU AGPLv3 or at your option any newer
+ - see COPYING.AGPL for details
+ -->
+<Wolf>
+
+ <Table name="moneylog" backup="yes">
+ <Column name="logid" type="seq64" primarykey="yes"/>
+ <Column name="logtime" type="int64" notnull="yes"/>
+ <Column name="uname" type="string:64" foreignkey="users:uname" null="yes"/>
+ <Column name="orderid" type="int32" foreignkey="order:orderid" null="yes"/>
+ <Column name="voucherid" type="string:32" foreignkey="voucher:voucherid" null="yes"/>
+ <Column name="moved" type="int32" notnull='yes'/>
+ <Column name="orderpaid" type="int32" null="yes"/>
+ <Column name="orderdue" type="int32" null="yes"/>
+ <Column name="vouchervalue" type="int32" null="yes"/>
+ <Column name="log" type="string" notnull='yes'/>
+ </Table>
+</Wolf>
\ No newline at end of file
- see COPYING.AGPL for details
-->
<Wolf>
- <Table name="host">
+ <Table name="config" backup="yes">
+ <Column name="ckey" type="string:32" primarykey="yes"/>
+ <Column name="cval" type="string"/>
+
+ <Preset><V col="ckey" val="MagicSmokeVersion"/><V col="cval" code="$this->version()"/></Preset>
+ <Preset><V col="ckey" val="ValidVouchers"/><V col="cval" val="1000 2000 2500 5000"/></Preset>
+ <Preset><V col="ckey" val="OrderStop"/><V col="cval" val="24"/></Preset>
+ <Preset><V col="ckey" val="SaleStop"/><V col="cval" val="0"/></Preset>
+ <Preset><V col="ckey" val="TicketIDChars"/><V col="cval" val="10"/></Preset>
+ <Preset><V col="ckey" val="VoucherIDChars"/><V col="cval" val="10"/></Preset>
+ </Table>
+
+ <!-- // ////////////////////
+ // Machine Interface Stuff
+ -->
+ <Table name="host" backup="yes">
<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" />
+
+ <Preset><V col="hostname" code='translate("SpecialHost","_any")'/></Preset>
+ <Preset><V col="hostname" code='translate("SpecialHost","_anon")'/></Preset>
+ <Preset><V col="hostname" code='translate("SpecialHost","_online")'/></Preset>
+ </Table>
+
+ <Table name="users" backup="yes">
+ <Column name="uname" type="string:64" primarykey="yes"/>
+ <Column name="passwd" type="string" notnull="yes"/>
+ <!-- more detailed data that can be displayed to admins -->
+ <Column name="description" type="text"/>
+ </Table>
+
+ <Table name="userrole" backup="yes">
+ <Column name="uname" type="string:64" notnull="yes" foreignkey="users:uname" index="yes" primarykey="yes"/>
+ <Column name="role" type="string:32" notnull="yes" primarykey="yes"/>
</Table>
+ <Table name="userhosts" backup="yes">
+ <Column name="uname" type="string:64" notnull="yes" foreignkey="users:uname" index="yes" primarykey="yes"/>
+ <Column name="host" type="string:64" notnull="yes" foreignkey="host:hostname" primarykey="yes"/>
+ </Table>
+
+ <Table name="session">
+ <Column name="sessionid" type="string:64" primarykey="yes"/>
+ <!-- if empty: not authenticated -->
+ <Column name="user" type="string:64"/>
+ <!-- used during authentication; emptied after authentication: -->
+ <Column name="hchallenge" type="string:64"/>
+ <Column name="uchallenge" type="string:64"/>
+ <!-- unix timestamp at which to delete this session -->
+ <Column name="timeout" type="int64" notnull="yes"/>
+ </Table>
+
+ <Table name="template" backup="yes">
+ <Column name="filename" type="string" primarykey="yes"/>
+ <Column name="description" type="string"/>
+ <Column name="content" type="blob"/>
+ <Column name="hash" type="string:32" notnull="yes"/> <!--md5-->
+ </Table>
</Wolf>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Cart MagicSmoke WOLF
+ - shopping cart management (web interface)
+ -
+ - (c) Konrad Rosenbaum, 2009
+ - this file is protected under the GNU AGPLv3 or at your option any newer
+ - see COPYING.AGPL for details
+ -->
+<Wolf>
+ <Table name="cart">
+ <!--the cookie for this cart-->
+ <Column name="cartid" type="string:32" primarykey="yes"/>
+ <!--when the cart expires-->
+ <Column name="timeout" type="int64" notnull="yes"/>
+ <!--shipping address during order process-->
+ <Column name="shippingaddress" type="text"/>
+ <!--customer comments during order process-->
+ <Column name="ordercomments" type="text"/>
+ </Table>
+ <Table name="cart_ticket">
+ <Column name="cartid" type="string:32" notnull="yes" foreignkey="cart:cartid" primarykey="yes"/>
+ <!--tickets in the cart-->
+ <Column name="eventid" type="int32" notnull="yes" foreignkey="event:eventid" primarykey="yes"/>
+ <Column name="amount" type="int32" notnull="yes"/>
+ </Table>
+ <Table name="cart_voucher">
+ <Column name="cvid" type="seq64" primarykey="yes"/>
+ <Column name="cartid" type="string:32" notnull="yes" foreignkey="cart:cartid"/>
+ <!--voucher value-->
+ <Column name="value" type="int32" notnull="yes"/>
+ </Table>
+
+ <Table name="websession">
+ <Column name="sessionid" type="string:64" primarykey="yes"/>
+ <!--/customer-->
+ <Column name="customerid" type="int32" notnull="yes" foreignkey="customer:customerid"/>
+ <!--unix timestamp at which to delete this session-->
+ <Column name="timeout" type="int64" notnull="yes"/>
+ </Table>
+</Wolf>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Customer MagicSmoke WOLF
+ - customer management
+ -
+ - (c) Konrad Rosenbaum, 2009
+ - this file is protected under the GNU AGPLv3 or at your option any newer
+ - see COPYING.AGPL for details
+ -->
+<Wolf>
+ <Table name="customer" backup="yes">
+ <Column name="customerid" type="seq32" primarykey="yes"/>
+ //contact data
+ <Column name="name" type="string" notnull="yes"/>
+ <Column name="address" type="text"/>
+ <Column name="contact" type="string"/> <!-- //phone or something -->
+ <Column name="comments" type="text"/>
+ </Table>
+ <Table name="webuser" backup="yes">
+ //online login data
+ <Column name="email" type="string" primarykey="yes"/>
+ <Column name="customerid" type="int32" unique="yes" notnull="yes" foreignkey="customer:customerid"/>
+ <Column name="passwd" type="string:64"/> <!-- salted SHA-1 hash of passwd -->
+ </Table>
+</Wolf>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Event Definition MagicSmoke WOLF
+ - declares everything needed to define events
+ -
+ - (c) Konrad Rosenbaum, 2009
+ - this file is protected under the GNU AGPLv3 or at your option any newer
+ - see COPYING.AGPL for details
+ -->
+<Wolf>
+ <Table name="room" backup="yes">
+ <Column name="roomid" type="string:64" primarykey="yes"/>
+ <Column name="capacity" type="int32" notnull="yes"/>
+ <Column name="description" type="text"/>
+ </Table>
+
+ <Table name="event" backup="yes">
+ <Column name="eventid" type="seq32" primarykey="yes"/>
+ <!--display data-->
+ <Column name="title" type="string" notnull="yes"/>
+ <Column name="artist" type="string" notnull="yes"/>
+ <Column name="description" type="text"/>
+ <!--timing and location-->
+ <Column name="starttime" type="int64" notnull="yes"/>
+ <Column name="endtime" type="int64" notnull="yes"/>
+ <Column name="roomid" type="string:64" foreignkey="room:roomid"/>
+ <!--initially a copy from room, can be adjusted-->
+ <Column name="capacity" type="int32" notnull="yes"/>
+ <!--default pricing in cents-->
+ <Column name="defaultprice" type="int32" notnull="yes"/>
+ <!--if not null/empty: event has been cancelled-->
+ <Column name="cancelreason" type="string"/>
+ </Table>
+</Wolf>
\ No newline at end of file
<!-- generic settings -->
<Project baseDir=".." wobDir="wob"/>
<Version comm="0100" needcomm="0100" humanReadable="1.1 alpha" svnTarget="."/>
- <DataBase instance="db" scheme="dbScheme"/>
+ <DataBase instance="db" scheme="dbScheme" version="00.03"/>
<!-- configure output -->
<QtClientOutput sourceDir="src" subDir="wob" priInclude="wob.pri"/>
<!-- 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="customer.wolf"/>
+ <Include file="event.wolf"/>
<Include file="order.wolf"/>
+ <Include file="cart.wolf"/>
+ <Include file="audit.wolf"/>
</Wolf>
\ No newline at end of file
- see COPYING.AGPL for details
-->
<Wolf>
+ <Table name="shipping" backup="yes">
+ <Column name="shipid" type="seq32" primarykey="yes"/>
+ <Column name="cost" type="int32" notnull="yes"/> <!--default cost of this shipping type-->
+ <Column name="canuseweb" type="bool" default="false"/> <!--is offered on web interface-->
+ <Column name="canallusers" type="bool" default="true"/> <!--all GUI users may select it-->
+ <Column name="description" type="string"/> <!--description for the shipping type-->
+ </Table>
<Table name="order" backup="yes">
<Column name="orderid" type="seq32" primarykey="yes"/>
<!--customer-->
}
m_schema.write(PHPSTART);
m_schema.write(SCHEMASTART);
+ m_schema.write(("\t$this->sversion=\""+WocProcessor::instance()->dbVersion()+"\";\n").toAscii());
addLoad("WobSchema","schema");
}
code+="public static function getFromDB(...){global $db...;}\n";
//automatic resolution of internal foreign keys
//reverse resolution of configured foreign keys
+ //create enum constants
//write table class
code+="};\n";
tf.write(code.toAscii());
tf.write(PHPEND);
tf.close();
+
//extend schema file
+ //column definitions
+ QStringList cols=tbl.columns();
+ QStringList pcols=tbl.primaryColumns();
+ code="\t$this->scheme[\""+tbl.name()+"\"]=array(";
+ for(int i=0;i<cols.size();i++){
+ if(i)code+=",";
+ code+="\n\t\t\""+cols[i]+"\"=>array(\"";
+ code+=tbl.columnType(cols[i])+"\"";
+ if(!tbl.columnIsNull(cols[i]))code+=",\"notnull\"";
+ if(tbl.columnIsForeign(cols[i]))code+=",\"foreignkey:"+tbl.columnForeign(cols[i])+"\"";
+ if(pcols.size()<2 && tbl.columnIsPrimary(cols[i]))code+=",\"primarykey\"";
+ if(tbl.columnHasDefault(cols[i]))code+=",\"default:"+tbl.columnDefault(cols[i])+"\"";
+ if(tbl.columnIsIndexed(cols[i]))code+=",\"index\"";
+ if(tbl.columnIsUnique(cols[i]))code+=",\"unique\"";
+ code+=")";
+ }
+ if(pcols.size()>=2){
+ code+=",\n\t\t\":primarykey\"=>array(";
+ for(int i=0;i<pcols.size();i++){
+ if(i)code+=",";
+ code+="\""+pcols[i]+"\"";
+ }
+ code+=")";
+ }
+ code+="\n\t);\n";
+ if(tbl.inBackup())code+="\t$this->backup[]=\""+tbl.name()+"\";\n";
+ //write presets
+
+ //write
+ m_schema.write(code.toAscii());
+
//create autoloading
addLoad("WT"+tbl.name(),"wt_"+tbl.name());
}
m_dbInst=el.attribute("instance");
if(el.hasAttribute("scheme"))
m_dbScheme=el.attribute("scheme");
+ if(el.hasAttribute("version"))
+ m_dbVer=el.attribute("version");
}else
if(tn=="QtClientOutput"){
new WocQtClientOut(el.attribute("sourceDir","."), el.attribute("subDir","qtwob"), el.attribute("priInclude","qtwob.pri"));
emit sfinalize();
}
+bool WocProcessor::haveTable(QString n)const
+{
+ for(int i=0;i<m_tables.size();i++)
+ if(m_tables[i].name()==n)return true;
+ return false;
+}
+
+WocTable WocProcessor::table(QString n)const
+{
+ for(int i=0;i<m_tables.size();i++)
+ if(m_tables[i].name()==n)return m_tables[i];
+ return WocTable();
+}
+
+
+
WocOutput::WocOutput()
{
connect(WocProcessor::instance(),SIGNAL(sfinalize()),this,SLOT(finalize()));
}
+WocTable::WocTable()
+{
+ m_backup=m_valid=false;
+}
+
WocTable::WocTable(const QDomElement&tbl)
{
m_valid=true;
//parse XML
m_name=tbl.attribute("name");
- //TODO: check name syntax, check it does not exist yet
+ WocProcessor*woc=WocProcessor::instance();
+ QRegExp good("[a-z][a-z0-9_]*",Qt::CaseInsensitive);
+ //check name syntax, check it does not exist yet
+ if(woc->haveTable(m_name)){
+ qDebug("Error: double definition of table %s.",m_name.toAscii().data());
+ m_valid=false;
+ return;
+ }
+ if(!good.exactMatch(m_name)){
+ qDebug("Error: table %s does not have a regular name.",m_name.toAscii().data());
+ m_valid=false;
+ return;
+ }
m_backup=str2bool(tbl.attribute("backup","0"));
qDebug("Info: parsing table %s",m_name.toAscii().data());
QDomNodeList nl=tbl.elementsByTagName("Column");
if(el.isNull())continue;
s_col cl;
cl.name=el.attribute("name");
- //TODO: check name syntax, check it is not doubled
+ //check name syntax, check it is not doubled
+ if(!good.exactMatch(cl.name)){
+ qDebug("Error: table %s column %s does not have a regular name.",m_name.toAscii().data(),cl.name.toAscii().data());
+ m_valid=false;
+ return;
+ }
+ if(haveColumn(cl.name)){
+ qDebug("Error: double definition of column %s in table %s.",cl.name.toAscii().data(),m_name.toAscii().data());
+ m_valid=false;
+ return;
+ }
cl.isprime=str2bool(el.attribute("primarykey","0"));
+ cl.isunique=str2bool(el.attribute("unique","0"));
+ cl.isindex=str2bool(el.attribute("index","0"));
if(el.hasAttribute("null"))
cl.isnull=str2bool(el.attribute("null"));
else
cl.type=el.attribute("type");
//TODO: validate type
cl.foreign=el.attribute("foreignkey");
- //TODO: check foreign key exists
+ //check foreign key exists
+ if(cl.foreign!=""){
+ QStringList fgn=cl.foreign.split(":");
+ if(fgn.size()!=2){
+ qDebug("Error: table %s column %s: foreign key definition must use syntax 'table:column'",m_name.toAscii().data(),cl.name.toAscii().data());
+ m_valid=false;
+ return;
+ }
+ if(!woc->haveTable(fgn[0])){
+ qDebug("Error: table %s column %s: foreign key target table %s does not exist",m_name.toAscii().data(),cl.name.toAscii().data(),fgn[0].toAscii().data());
+ m_valid=false;
+ return;
+ }
+ if(!woc->table(fgn[0]).haveColumn(fgn[1])){
+ qDebug("Error: table %s column %s: foreign key target table/column %s does not exist",m_name.toAscii().data(),cl.name.toAscii().data(),cl.foreign.toAscii().data());
+ m_valid=false;
+ return;
+ }
+ }
cl.defaultval=el.attribute("default");
//TODO: validate default against type
QDomNodeList nl2=el.elementsByTagName("Value");
m_valid=false;
return;
}
- //TODO: check that we have a primary key
+ //check that we have a primary key
+ if(primaryColumns().size()==0){
+ qDebug("Warning: table %s does not have any primary key columns.",m_name.toAscii().data());
+ }
+}
+
+QStringList WocTable::columns()const
+{
+ QStringList r;
+ for(int i=0;i<m_columns.size();i++)
+ r<<m_columns[i].name;
+ return r;
+}
+
+QStringList WocTable::primaryColumns()const
+{
+ QStringList r;
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].isprime)
+ r<<m_columns[i].name;
+ return r;
+}
+
+QString WocTable::columnType(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].type;
+ return "";
+}
+
+bool WocTable::columnIsNull(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].isnull;
+ return false;
+}
+
+bool WocTable::columnIsPrimary(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].isprime;
+ return false;
+}
+
+bool WocTable::columnHasDefault(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].defaultval!="";
+ return false;
+}
+
+QString WocTable::columnDefault(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].defaultval;
+ return "";
+}
+
+bool WocTable::haveColumn(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return true;
+ return false;
+}
+
+
+QList<QPair<QString,int> > WocTable::getEnums()const
+{
+ QList<QPair<QString,int> > r;
+ for(int i=0;i<m_columns.size();i++)
+ for(int j=0;j<m_columns[i].enumvals.size();j++)
+ r.append(m_columns[i].enumvals[j]);
+ return r;
+}
+bool WocTable::columnIsForeign(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].foreign!="";
+ return false;
+}
+
+QString WocTable::columnForeign(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].foreign;
+ return "";
+}
+
+bool WocTable::columnIsIndexed(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].isindex;
+ return false;
+}
+
+bool WocTable::columnIsUnique(QString c)const
+{
+ for(int i=0;i<m_columns.size();i++)
+ if(m_columns[i].name==c)
+ return m_columns[i].isunique;
+ return false;
+}
+
+QStringList WocTable::foreigns()const
+{
+ QStringList r;
+ for(int i=0;i<m_foreign.size();i++)
+ r<<m_foreign[i].first;
+ return r;
+}
+
+QString WocTable::foreignQuery(QString f)const
+{
+ for(int i=0;i<m_foreign.size();i++)
+ if(m_foreign[i].first==f)
+ return m_foreign[i].second;
+ return "";
+}
+
+bool WocTable::haveForeign(QString f)const
+{
+ for(int i=0;i<m_foreign.size();i++)
+ if(m_foreign[i].first==f)
+ return true;
+ return false;
}
class WocTable
{
public:
+ WocTable();
WocTable(const QDomElement&);
bool isValid()const{return m_valid;}
QString name()const{return m_name;}
bool inBackup()const{return m_backup;}
+
+ QStringList columns()const;
+ QStringList primaryColumns()const;
+ QString columnType(QString)const;
+ bool columnIsNull(QString)const;
+ bool columnIsPrimary(QString)const;
+ bool columnHasDefault(QString)const;
+ QString columnDefault(QString)const;
+ bool haveColumn(QString)const;
+ bool columnIsForeign(QString)const;
+ QString columnForeign(QString)const;
+ bool columnIsIndexed(QString)const;
+ bool columnIsUnique(QString)const;
+
+ QList<QPair<QString,int> > getEnums()const;
+
+ QStringList foreigns()const;
+ QString foreignQuery(QString)const;
+ bool haveForeign(QString)const;
private:
bool m_valid,m_backup;
QString m_name;
struct s_col {
QString name,type,foreign,defaultval;
- bool isnull,isprime;
+ bool isnull,isprime,isindex,isunique;
QList<QPair<QString,int> >enumvals;
};
QList<s_col>m_columns;
QString svnRevision()const{return m_svnRev;}
QString dbInst()const{return m_dbInst;}
QString dbScheme()const{return m_dbScheme;}
+ QString dbVersion()const{return m_dbVer;}
+
+ bool haveTable(QString)const;
+ WocTable table(QString)const;
signals:
void sfinalize();
void newClass(const WocClass&);
private:
QString m_baseDir,m_wobDir,m_verComm,m_verNeedComm,m_verHR;
- QString m_svnTarget,m_svnRev,m_svnExe,m_dbInst,m_dbScheme;
+ QString m_svnTarget,m_svnRev,m_svnExe,m_dbInst,m_dbScheme,m_dbVer;
QList<WocTable> m_tables;
QList<WocClass> m_classes;
<?
-/**This class contains a high-level description of the database structure*/
-class DbScheme {
- private static $scheme;
- private static $preset;
- private static $sversion;
- private static $backup;
-
- function __construct()
- {
- // ////////////////////
- // version of this scheme
- $this->sversion="00.02";
-
- // ////////////////////
- //configuration
- $this->scheme["config"]=array(
- "ckey"=>array("string:32","primarykey"),
- "cval"=>array("string")
- );
- $this->preset["config"]=array(
- array("ckey"=>"MagicSmokeVersion","cval"=>$this->sversion),
- array("ckey"=>"ValidVouchers","cval"=>"1000 2000 2500 5000"),
- array("ckey"=>"OrderStop","cval"=>"24"),
- array("ckey"=>"SaleStop","cval"=>"0"),
- array("ckey"=>"TicketIDChars","cval"=>"10"),
- array("ckey"=>"VoucherIDChars","cval"=>"10")
- );
- $this->backup[]="config";
-
- // ////////////////////
- // Machine Interface Stuff
-
- //clients
- $this->scheme["host"]=array(
- "hostname"=>array("string:64","primarykey"),
- //if hostkey is NULL it is a special host (_any, _anon, _online)
- "hostkey"=>array("string")
- );
- $this->preset["host"]=array(
- array("hostname"=>translate("SpecialHost","_any")),
- array("hostname"=>translate("SpecialHost","_anon")),
- array("hostname"=>translate("SpecialHost","_online"))
- );
- $this->backup[]="host";
-
- //client users (ticket sellers, admins, etc.; for customers and web logins see below)
- $this->scheme["users"]=array(
- "uname" => array("string:64","primarykey"),
- "passwd" => array("string","notnull"),
- //more detailed data that can be displayed to admins
- "description" => array("text")
- );
- $this->backup[]="users";
- $this->scheme["userrole"]=array(
- "uname" =>array("string:64","notnull","foreignkey:users:uname","index"),
- "role" =>array("string:32","notnull"),
- ":primarykey"=>array("uname","role")
- );
- $this->backup[]="userrole";
- $this->scheme["userhosts"]=array(
- "uname" => array("string:64","notnull","foreignkey:users:uname","index"),
- "host" => array("string:64","notnull","foreignkey:host:hostname"),
- ":primarykey" =>array("uname","host")
- );
- $this->backup[]="userhosts";
- //sessions
- $this->scheme["session"]=array(
- "sessionid" => array("string:64","primarykey"),
- //if empty: not authenticated
- "user"=>array("string:64"),
- //emptied after authentication:
- "hchallenge"=>array("string:64"),
- "uchallenge"=>array("string:64"),
- //unix timestamp at which to delete this session
- // this needs to change to 64-bit int in 2038
- "timeout"=>array("int32","notnull")
- );
- //templates
- $this->scheme["template"]=array(
- "filename" => array("string","primarykey"),
- "description" =>array("string"),
- "content" => array("blob"),
- "hash" => array("string:32","notnull") //md5
- );
- $this->backup[]="template";
-
-
- // //////////////////////
- // Shared Stuff (web & GUI-client)
-
- //rooms
- $this->scheme["room"]=array(
- "roomid" => array("string:64","primarykey"),
- "capacity" => array("int32","notnull"),
- "description" => array("text")
- );
- $this->backup[]="room";
- //event
- $this->scheme["event"]=array(
- "eventid" => array("seq32","primarykey"),
- //display data
- "title" => array("string","notnull"),
- "artist" => array("string","notnull"),
- "description" => array("text"),
- //timing and location (needs to change to 64bit in 2038)
- "starttime" => array("int32","notnull"),
- "endtime" => array("int32","notnull"),
- "roomid" => array("string:64","foreignkey:room:roomid"),
- //initially a copy from room, can be adjusted
- "capacity" => array("int32","notnull"),
- //default pricing in cents
- "defaultprice" => array("int32","notnull"),
- //if not null/empty: event has been cancelled
- "cancelreason" => array("string")
- );
- $this->backup[]="event";
-
- //shopping item type
-// $this->scheme[""]
-
- //customer
- $this->scheme["customer"]=array(
- "customerid" => array("seq32","primarykey"),
- //contact data
- "name" => array("string","notnull"),
- "address" => array("text"),
- "contact" => array("string"),//phone or something
- "comments" => array("text")
- );
- $this->backup[]="customer";
- $this->scheme["webuser"]=array(
- //online login data
- "email" => array("string","primarykey"),
- "customerid" => array("int32","unique","foreignkey:customer:customerid"),
- "passwd" => array("string:64"),//salted SHA-1 hash of passwd
- );
- $this->backup[]="webuser";
-
- //kinds of shipping that are available (templates)
- $this->scheme["shipping"]=array(
- "shipid" => array("seq32","primarykey"),
- "cost" => array("int32","notnull"), //default cost of this shipping type
- "canuseweb" => array("bool","defaultbool:false"), //is offered on web interface
- "canallusers" => array("bool","defaultbool:true"), //all GUI users may select it
- "description" => array("string") //description for the shipping type
- );
- $this->backup[]="shipping";
-
- //orders by customers
- $this->scheme["order"]=array(
- "orderid" => array("seq32","primarykey"),
- //customer
- "customerid" => array("int32","foreignkey:customer:customerid"),
- //seller (_online for web forms)
- "soldby" => array("string:64","foreignkey:users:uname"),
- //if not null/empty: this address for delivery, customer address for invoice
- "deliveryaddress" => array("text"),
- //if not null/empty: lodge/deposit the tickets at a seller with _deposit flag
- "depositat" => array("string:64","foreignkey:users:uname"),
- //status, see ORDER_* constants
- "status" => array("int32","notnull"),
- "ordertime" => array("int32","notnull"),
- "senttime" => array("int32"),
- //comments made on web form (eg. "urgently needed for dads birthday")
- "comments" => array("text"),
- //how much has been paid already (including used vouchers)
- //this is for comparison with the price fields in ticket and voucher tables
- "amountpaid" => array("int32"),
- //shipping price
- "shippingcosts" => array("int32","defaultint:0"),
- //pointer to shipping type (none per default, programmatic default is in config)
- "shippingtype" => array("int32","null","foreignkey:shipping:shipid")
- );
- $this->backup[]="order";
- //tickets
- $this->scheme["ticket"]=array(
- //a 8-32 char code (code39: case-insensitive letters+digits) for the ticket
- "ticketid" => array("string:32","primarykey"),
- "eventid" => array("int32","foreignkey:event:eventid"),
- //initially a copy from event, can be adjusted by seller
- "price" => array("int32","notnull"),
- //status of ticket (see TICKET_* constants)
- "status" => array("int32","notnull"),
- //if status is reserved, this contains the reserving seller
- "reservedby" => array("string:64","foreignkey:users:uname"),
- "reservetimeout" => array("int32"),
- //sold to someone (may be NULL for direct sales or reserves)
- "orderid" => array("int32","foreignkey:order:orderid")
- );
- $this->backup[]="ticket";
- //vouchers and re-imbursments
- $this->scheme["voucher"]=array(
- //a 8-32 char code (code39: case-insensitive letters+digits) for the voucher
- "voucherid" => array("string:32","primarykey"),
- //price of the voucher (0 if cancelled)
- "price" => array("int32","notnull"),
- //order this voucher belongs to
- "orderid" => array("int32","foreignkey:order:orderid"),
- //marker: voucher has been used to pay something
- "isused" => array("bool","defaultbool:false"),
- //remaining value in cents (0 for cancelled)
- "value" => array("int32","notnull")
- );
- $this->backup[]="voucher";
-
- //money transaction log
- $this->scheme["moneylog"]=array(
- "logid" => array("seq64","primarykey"),
- "logtime" => array("int64","notnull"),
- "uname" => array("string:64","foreignkey:users:uname","null"),
- "orderid" => array("int32","foreignkey:order:orderid","null"),
- "voucherid" => array("string:32","foreignkey:voucher:voucherid","null"),
- "moved" => array("int32","notnull"),
- "orderpaid" => array("int32","null"),
- "orderdue" => array("int32","null"),
- "vouchervalue" => array("int32","null"),
- "log" => array("string","notnull")
- );
- $this->backup[]="moneylog";
-
-
- // /////////////////////////
- // Web-Interface Stuff
-
- //shopping cart
- $this->scheme["cart"]=array(
- //the cookie for this cart
- "cartid" => array("string:32","primarykey"),
- //when the cart expires
- "timeout" => array("int32","notnull"),
- //shipping address during order process
- "shippingaddress" => array("text"),
- //customer comments during order process
- "ordercomments" => array("text")
- );
- //buying tickets
- $this->scheme["cart_ticket"]=array(
- "cartid" => array("string:32","notnull","foreignkey:cart:cartid"),
- //tickets in the cart
- "eventid" => array("int32","notnull","foreignkey:event:eventid"),
- "amount" => array("int32","notnull"),
- //primary key definition
- ":primarykey" => array("cartid","eventid")
- );
- //buying vouchers
- $this->scheme["cart_voucher"]=array(
- "cvid" => array("seq64","primarykey"),
- "cartid" => array("string:32","notnull","foreignkey:cart:cartid"),
- //voucher value
- "value" => array("int32","notnull")
- );
-
- //web sessions
- $this->scheme["websession"]=array(
- "sessionid" => array("string:64","primarykey"),
- //customer
- "customerid" => array("int32","notnull","foreignkey:customer:customerid"),
- //unix timestamp at which to delete this session
- // this needs to change to 64-bit int in 2038
- "timeout"=>array("int32","notnull")
- );
- }
-
- /**return the version of this scheme*/
- public function version(){return $this->sversion;}
-
- /**return the tables to be created in order*/
- public function tableNames()
- {
- return array_keys($this->scheme);
- }
-
- /**returns whether a table exists in the schema*/
- public function haveTable($t)
- {
- return in_array($t,array_keys($this->scheme));
- }
-
- /**return the tables that are included in the backup*/
- public function backupTables()
- {
- return $this->backup;
- }
-
- /**return the full definition of a table, or false if it does not exist*/
- public function tableDefinition($tab)
- {
- if(!isset($this->scheme[$tab]))
- return false;
- return $this->scheme[$tab];
- }
-
- /**return the names of all columns of a table, or false if the table does not exist*/
- public function tableColumns($tab)
- {
- if(!isset($this->scheme[$tab]))
- return false;
- $r=array();
- foreach(array_keys($this->scheme[$tab]) as $c)
- if(substr($c,0,1)!=":")
- $r[]=$c;
- return $r;
- }
-
- /**return default lines of the table for the initialization; returns empty array if there are none*/
- public function tableDefaults($tab)
- {
- if(isset($this->preset[$tab]))return $this->preset[$tab];
- else return array();
- }
-
- /**return the type of a column, or false if it does not exist*/
- public function columnType($tab,$col)
- {
- if(!isset($this->scheme[$tab][$col]))
- return false;
- return $this->scheme[$tab][$col][0];
- }
-
- /**return the flags of a column, empty array if no flags are set, or false if the column does not exist*/
- public function columnFlags($tab,$col)
- {
- if(!isset($this->scheme[$tab][$col]))
- return false;
- $tmp=$this->scheme[$tab][$col];
- unset($tmp[0]);
- return array_values($tmp);
- }
-
- /**returns true if the given column is of an integer type*/
- public function isIntColumn($tab,$col)
- {
- if(!isset($this->scheme[$tab][$col]))
- return false;
- $tpa=explode(":",$this->scheme[$tab][$col][0]);
- switch($tpa[0]){
- case "int32":case "seq32":case "int64":case "seq64":
- return true;
- default:
- return false;
- }
- }
-
- /**returns the sequence column name if the table has a sequence, false otherwise*/
- public function hasSequence($tab)
- {
- if(!isset($this->scheme[$tab]))
- return false;
- foreach($this->scheme[$tab] as $cl => $def){
- if($def[0] == "seq32" || $def[0] == "seq64")
- return $cl;
- }
- return false;
- }
-
- /**returns true if the given column is of a string type*/
- public function isStringColumn($tab,$col)
- {
- if(!isset($this->scheme[$tab][$col]))
- return false;
- $tpa=explode(":",$this->scheme[$tab][$col][0]);
- switch($tpa[0]){
- case "string":case "text":
- return true;
- default:
- return false;
- }
- }
-
- /**returns true if the given column is of a blob type*/
- public function isBlobColumn($tab,$col)
- {
- if(!isset($this->scheme[$tab][$col]))
- return false;
- $tpa=explode(":",$this->scheme[$tab][$col][0]);
- switch($tpa[0]){
- case "blob":
- return true;
- default:
- return false;
- }
- }
-
- /**returns true if the given column is of a bool type*/
- public function isBoolColumn($tab,$col)
- {
- if(!isset($this->scheme[$tab][$col]))
- return false;
- $tpa=explode(":",$this->scheme[$tab][$col][0]);
- switch($tpa[0]){
- case "bool":
- case "boolean":
- return true;
- default:
- return false;
- }
- }
-
- /**returns the names of all primary key columns of the table*/
- public function primaryKeyColumns($tab)
- {
- $r=array();
- //search for direct mark
- foreach($this->scheme[$tab] as $col=>$def)
- if(in_array("primarykey",$def))
- $r[]=$col;
- //search for special mark
- if(isset($this->scheme[$tab][":primarykey"]))
- foreach($this->scheme[$tab][":primarykey"] as $col)
- if(!in_array($col,$r))
- $r[]=$col;
- //return result
- return $r;
- }
-};
-$dbScheme=new DbScheme;
+$dbScheme=new WobSchema;
?>
\ No newline at end of file
<?
//load the linguist dummies, since we use them quite often
include_once("inc/tr.php");
+//load WOB data
+include('./inc/wbase/autoload.php');
+include('./inc/wob/autoload.php');
//load DB drivers
include('./inc/db/db.php');
include('./inc/db/db_mysql.php');
//
$AUTOCLASS["WobTable"]="inc/wbase/table.php";
+$AUTOCLASS["WobSchemaBase"]="inc/wbase/schema.php";
function __autoload($cname)
{
--- /dev/null
+<?
+/**This class parses the high-level description of the database structure generated by woc; access it via $dbScheme*/
+class WobSchemaBase {
+ protected static $scheme;
+ protected static $preset;
+ protected static $sversion;
+ protected static $backup;
+
+ function __construct()
+ {
+ }
+
+ /**return the version of this scheme*/
+ public function version(){return $this->sversion;}
+
+ /**return the tables to be created in order*/
+ public function tableNames()
+ {
+ return array_keys($this->scheme);
+ }
+
+ /**returns whether a table exists in the schema*/
+ public function haveTable($t)
+ {
+ return in_array($t,array_keys($this->scheme));
+ }
+
+ /**return the tables that are included in the backup*/
+ public function backupTables()
+ {
+ return $this->backup;
+ }
+
+ /**return the full definition of a table, or false if it does not exist*/
+ public function tableDefinition($tab)
+ {
+ if(!isset($this->scheme[$tab]))
+ return false;
+ return $this->scheme[$tab];
+ }
+
+ /**return the names of all columns of a table, or false if the table does not exist*/
+ public function tableColumns($tab)
+ {
+ if(!isset($this->scheme[$tab]))
+ return false;
+ $r=array();
+ foreach(array_keys($this->scheme[$tab]) as $c)
+ if(substr($c,0,1)!=":")
+ $r[]=$c;
+ return $r;
+ }
+
+ /**return default lines of the table for the initialization; returns empty array if there are none*/
+ public function tableDefaults($tab)
+ {
+ if(isset($this->preset[$tab]))return $this->preset[$tab];
+ else return array();
+ }
+
+ /**return the type of a column, or false if it does not exist*/
+ public function columnType($tab,$col)
+ {
+ if(!isset($this->scheme[$tab][$col]))
+ return false;
+ return $this->scheme[$tab][$col][0];
+ }
+
+ /**return the flags of a column, empty array if no flags are set, or false if the column does not exist*/
+ public function columnFlags($tab,$col)
+ {
+ if(!isset($this->scheme[$tab][$col]))
+ return false;
+ $tmp=$this->scheme[$tab][$col];
+ unset($tmp[0]);
+ return array_values($tmp);
+ }
+
+ /**returns true if the given column is of an integer type*/
+ public function isIntColumn($tab,$col)
+ {
+ if(!isset($this->scheme[$tab][$col]))
+ return false;
+ $tpa=explode(":",$this->scheme[$tab][$col][0]);
+ switch($tpa[0]){
+ case "int32":case "seq32":case "int64":case "seq64":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**returns the sequence column name if the table has a sequence, false otherwise*/
+ public function hasSequence($tab)
+ {
+ if(!isset($this->scheme[$tab]))
+ return false;
+ foreach($this->scheme[$tab] as $cl => $def){
+ if($def[0] == "seq32" || $def[0] == "seq64")
+ return $cl;
+ }
+ return false;
+ }
+
+ /**returns true if the given column is of a string type*/
+ public function isStringColumn($tab,$col)
+ {
+ if(!isset($this->scheme[$tab][$col]))
+ return false;
+ $tpa=explode(":",$this->scheme[$tab][$col][0]);
+ switch($tpa[0]){
+ case "string":case "text":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**returns true if the given column is of a blob type*/
+ public function isBlobColumn($tab,$col)
+ {
+ if(!isset($this->scheme[$tab][$col]))
+ return false;
+ $tpa=explode(":",$this->scheme[$tab][$col][0]);
+ switch($tpa[0]){
+ case "blob":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**returns true if the given column is of a bool type*/
+ public function isBoolColumn($tab,$col)
+ {
+ if(!isset($this->scheme[$tab][$col]))
+ return false;
+ $tpa=explode(":",$this->scheme[$tab][$col][0]);
+ switch($tpa[0]){
+ case "bool":
+ case "boolean":
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**returns the names of all primary key columns of the table*/
+ public function primaryKeyColumns($tab)
+ {
+ $r=array();
+ //search for direct mark
+ foreach($this->scheme[$tab] as $col=>$def)
+ if(in_array("primarykey",$def))
+ $r[]=$col;
+ //search for special mark
+ if(isset($this->scheme[$tab][":primarykey"]))
+ foreach($this->scheme[$tab][":primarykey"] as $col)
+ if(!in_array($col,$r))
+ $r[]=$col;
+ //return result
+ return $r;
+ }
+};
+?>
\ No newline at end of file