add ability to add complex unique constraints
authorKonrad Rosenbaum <konrad@silmor.de>
Fri, 8 Jul 2016 22:38:42 +0000 (00:38 +0200)
committerKonrad Rosenbaum <konrad@silmor.de>
Fri, 8 Jul 2016 22:38:42 +0000 (00:38 +0200)
doc/wolf-db.html
phpbase/db.php
woc/php/phpdb.cpp
woc/proc/proctable.cpp
woc/proc/proctable.h

index b57e84b..ec239a2 100644 (file)
@@ -39,8 +39,22 @@ For each database table woc needs a description of that table:
     &lt;V col="orderid" val="1"/>
   &lt;/Preset>
   &lt;Foreign method="getRabbit" via="rabbit:rabbitid=eventid"/>
+  &lt;Unique>price,status&lt;/Unique>
 &lt;/Table>
-</pre>
+</pre><p>
+
+The XML Tags are:
+<table frame="1" border="1">
+<tr><td><b>Tag</b></td><td><b>Description</b></td></tr>
+<tr><td>Table</td><td>Encompasses the entire table description.</td></tr>
+<tr><td>Column</td><td>Describes a single column.</td></tr>
+<tr><td> &nbsp; Column/Value</td><td>For enum columns: describes the values that the column can take.</td></tr>
+<tr><td>AuditColumn</td><td>Describes a column that exists in the audit-sub-table only.</td></tr>
+<tr><td>Foreign</td><td>Defines a method that returns rows from a sub-ordinate table via the foreign key relation given.</td></tr>
+<tr><td>Preset</td><td>Defines a row that will be inserted into the table at creation time.</td></tr>
+<tr><td> &nbsp; Preset/V</td><td>Defines a column value for a preset row.</td></tr>
+<tr><td>Unique</td><td>Defines a Unique constraint that spans several columns.</td></tr>
+</table><p>
 
 Table attributes:
 <table frame="1" border="1">
@@ -128,4 +142,4 @@ It is then enough to add the <tt>audit="yes"</tt> tag to each table that will ha
 <a href="wolf.html">Previous: Overall Format</a><br>
 <a href="wolf-comm.html">Next: Communication Layer</a>
 
-</html>
\ No newline at end of file
+</html>
index adc9bfa..68747c4 100644 (file)
@@ -177,6 +177,7 @@ abstract class DbEngine
        const COLUMN_CREATE_KEY = 12;
        const COLUMN_CREATE_DEFAULT = 16;
        const COLUMN_CREATE_INDEX = 32;
+       const COLUMN_CREATE_CONSTRAINT = 64;
        const COLUMN_CREATE_ALL = 0xffff;
 
        ///creates SQL92 part of a statement for creating a single column
@@ -186,8 +187,11 @@ abstract class DbEngine
                //check whether this is a special column
                if(substr($columnname,0,1)==":"){
                        if($columnname==":primarykey"){
-                               if($flag & self::COLUMN_CREATE_PKEY)
+                               if($flags & self::COLUMN_CREATE_PKEY)
                                        $ret.=$this->sqlCreateTablePrimaryKey($columndef);
+                       }else if($columnname==":uniqueconstraint"){
+                               if($flags & self::COLUMN_CREATE_CONSTRAINT)
+                                       $ret.=$this->sqlCreateTableUniqueConstraint($columndef);
                        }else die("Unknown special column ".$columnname." while creating table ".$tablename);
                }else{
                        //column name
@@ -219,6 +223,17 @@ abstract class DbEngine
                $ret.=")";
                return $ret;
        }
+
+       ///creates the complex unique constraints; overwrite this to implement DB specific syntax
+       protected function sqlCreateTableUniqueConstraint(array $constraints)
+       {
+               $ret="";
+               for($i=0;$i<count($constraints);$i++){
+                       if($i>0)$ret.=",";
+                       $ret.="UNIQUE (".$constraints[$i].")";
+               }
+               return $ret;
+       }
        
        /**creates a SQL92 statement for selects; overwrite this to implement DB specific syntax; the concrete DB implementation should append "for update" to the select statement if $this->transmode is true and the DB supports it*/
        public function sqlSelect($table,$cols,$where,$orderby)
index 472d928..aac07ff 100644 (file)
@@ -198,6 +198,15 @@ void WocPHPTable::newTable(const WocTable&tbl)
                }
                code+=")";
        }
+       QStringList ucols=tbl.uniqueConstraints();
+       if(ucols.size()>0){
+               code+=",\n\t\t\":uniqueconstraint\"=>array(";
+               for(int i=0;i<ucols.size();i++){
+                       if(i)code+=",";
+                       code+="\""+ucols[i]+"\"";
+               }
+               code+=")";
+       }
        code+="\n\t);\n";
        if(tbl.inBackup()){
                code+="\tself::$backup[]=\""+tbl.name()+"\";\n";
index 1555d5f..ed33dcd 100644 (file)
@@ -121,6 +121,12 @@ WocTable::WocTable(const QDomElement&tbl)
                QString s=nl.at(i).toElement().text().trimmed();
                if(s!="")m_docstrings<<s;
        }
+
+       //Complex Unique cols
+       nl=elementsByTagName(tbl,"Unique");
+       for(int i=0;i<nl.size();i++){
+               m_uniquecols<<nl[i].toElement().text().trimmed();
+       }
        
        //sanity checks
        //check we have any columns at all
@@ -133,6 +139,27 @@ WocTable::WocTable(const QDomElement&tbl)
        if(primaryColumns().size()==0){
                qDebug("Warning: table %s does not have any primary key columns.",m_name.toLatin1().data());
        }
+       //check that unique definitions are valid
+       for(QString uniq:m_uniquecols){
+               if(uniq.isEmpty()){
+                       qDebug("Error: table %s contains an empty Unique declaration.",m_name.toLatin1().data());
+                       m_valid=false;
+                       return;
+               }
+               for(QString col:uniq.split(',')){
+                       bool found=false;
+                       for(auto c:m_columns)
+                               if(c.name==col){
+                                       found=true;
+                                       break;
+                               }
+                       if(!found){
+                               qDebug("Error: table %s has Unique declaration that refers to unknown column %s.",m_name.toLatin1().data(),col.toLatin1().data());
+                               m_valid=false;
+                               return;
+                       }
+               }
+       }
 }
 
 
index b17cc95..2ca846f 100644 (file)
@@ -90,6 +90,9 @@ class WocTable
                WocTable auditTable()const;
                /**returns the names of audit columns (except auditid)*/
                QStringList auditColumns()const;
+
+               ///returns all complex Unique constraints (those not defined for a single column)
+               QStringList uniqueConstraints()const{return m_uniquecols;}
                
                /**returns table documentation*/
                QStringList docStrings()const{return m_docstrings;}
@@ -115,7 +118,7 @@ class WocTable
                QList<QMap<QString,QString> >m_presets;
                int m_backupsize=-1;
                
-               QStringList m_docstrings;
+               QStringList m_docstrings,m_uniquecols;
                QMap<QString,QString>m_fordocs;
                
                //helper method: parses a single column element