woc is not able to rebuild DB schema
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Tue, 3 Feb 2009 15:28:26 +0000 (15:28 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Tue, 3 Feb 2009 15:28:26 +0000 (15:28 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@260 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

14 files changed:
wob/audit.wolf [new file with mode: 0644]
wob/basics.wolf
wob/cart.wolf [new file with mode: 0644]
wob/customer.wolf [new file with mode: 0644]
wob/event.wolf [new file with mode: 0644]
wob/magicsmoke.wolf
wob/order.wolf
woc/phpout.cpp
woc/processor.cpp
woc/processor.h
www/inc/db/db_scheme.php
www/inc/loader.php
www/inc/wbase/autoload.php
www/inc/wbase/schema.php [new file with mode: 0644]

diff --git a/wob/audit.wolf b/wob/audit.wolf
new file mode 100644 (file)
index 0000000..94395a9
--- /dev/null
@@ -0,0 +1,23 @@
+<?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
index f8e0598..60ab614 100644 (file)
@@ -7,10 +7,63 @@
   - 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>
diff --git a/wob/cart.wolf b/wob/cart.wolf
new file mode 100644 (file)
index 0000000..e36da7e
--- /dev/null
@@ -0,0 +1,40 @@
+<?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
diff --git a/wob/customer.wolf b/wob/customer.wolf
new file mode 100644 (file)
index 0000000..05ba216
--- /dev/null
@@ -0,0 +1,24 @@
+<?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
diff --git a/wob/event.wolf b/wob/event.wolf
new file mode 100644 (file)
index 0000000..03fa4d1
--- /dev/null
@@ -0,0 +1,33 @@
+<?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
index f0316be..f53a27b 100644 (file)
@@ -10,7 +10,7 @@
        <!-- 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"/>
@@ -19,8 +19,9 @@
        <!-- 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
index 12bee92..a3449f0 100644 (file)
@@ -7,6 +7,13 @@
   - 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-->
index c8b2150..0a2b8fb 100644 (file)
@@ -50,6 +50,7 @@ WocPHPServerOut::WocPHPServerOut(QString srcDir,QString subDir,QString ext,bool
        }
        m_schema.write(PHPSTART);
        m_schema.write(SCHEMASTART);
+       m_schema.write(("\t$this->sversion=\""+WocProcessor::instance()->dbVersion()+"\";\n").toAscii());
        addLoad("WobSchema","schema");
 }
 
@@ -86,12 +87,45 @@ void WocPHPServerOut::newTable(const WocTable&tbl)
        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());
 }
index c21bbb0..cb44b7f 100644 (file)
@@ -112,6 +112,8 @@ bool WocProcessor::processFile(QString fn)
                                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"));
@@ -207,6 +209,22 @@ void WocProcessor::finalize()
        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()));
@@ -223,12 +241,29 @@ WocClass::WocClass(const QDomElement&cls)
        
 }
 
+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");
@@ -238,8 +273,20 @@ WocTable::WocTable(const QDomElement&tbl)
                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
@@ -247,7 +294,25 @@ WocTable::WocTable(const QDomElement&tbl)
                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");
@@ -283,5 +348,138 @@ WocTable::WocTable(const QDomElement&tbl)
                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;
 }
index 55ca722..e65deac 100644 (file)
@@ -32,18 +32,38 @@ class WocClass
 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;
@@ -81,6 +101,10 @@ class WocProcessor:public QObject
                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&);
@@ -88,7 +112,7 @@ class WocProcessor:public QObject
                
        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;
index c2af52f..416c0b1 100644 (file)
@@ -1,418 +1,3 @@
 <?
-/**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
index f3cfe2a..2e51c6b 100644 (file)
@@ -1,6 +1,9 @@
 <?
 //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');
index ba642c7..7b3d4f6 100644 (file)
@@ -10,6 +10,7 @@
 //
 
 $AUTOCLASS["WobTable"]="inc/wbase/table.php";
+$AUTOCLASS["WobSchemaBase"]="inc/wbase/schema.php";
 
 function __autoload($cname)
 {
diff --git a/www/inc/wbase/schema.php b/www/inc/wbase/schema.php
new file mode 100644 (file)
index 0000000..3903b05
--- /dev/null
@@ -0,0 +1,165 @@
+<?
+/**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