one step closer to woc
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 8 Feb 2009 15:31:04 +0000 (15:31 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 8 Feb 2009 15:31:04 +0000 (15:31 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@265 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

woc/phpout.cpp
woc/phpout.h
woc/processor.cpp
woc/processor.h
woc/qtout.cpp
woc/qtout.h

index c0677c6..a9662cb 100644 (file)
@@ -67,8 +67,6 @@ void WocPHPServerOut::finalize()
        }
 }
 
-void WocPHPServerOut::newClass(const WocClass&){}
-
 void WocPHPServerOut::newTable(const WocTable&tbl)
 {
        if(!m_loader.isOpen())return;
@@ -213,3 +211,40 @@ void WocPHPServerOut::addLoad(QString cn,QString fn)
        QString ld="$AUTOCLASS[\""+cn+"\"]=\""+m_subdir+"/"+fn+m_fileext+"\";\n";
        m_loader.write(ld.toAscii());
 }
+
+void WocPHPServerOut::newClass(const WocClass&cls)
+{
+       //cover basics
+       QString cn="WO"+cls.name();
+       QString cna=cn;
+       if(cls.isAbstract())cna+="Abstract";
+       QString fn="wo_"+cls.name();
+       addLoad(cna,fn);
+       fn=m_subdir+"/"+fn+m_fileext;
+       QFile tf(m_basedir+"/"+fn);
+       if(!tf.open(QIODevice::ReadWrite|QIODevice::Truncate)){
+               qDebug("Error: cannot create PHP object file %s.",fn.toAscii().data());
+               return;
+       }
+       tf.write(PHPSTART);
+       //generate code
+       QString code="class "+cna+" extends "+cls.baseClass()+"{\n";
+       //implement enums
+       //implement properties
+       
+       //implement mappings
+       
+       //implement serializers
+       
+       //implement de-serializer
+       
+       code+="};\n";
+       //write & close
+       tf.write(code.toAscii());
+       tf.write(PHPEND);
+       tf.close();
+}
+
+void WocPHPServerOut::newTransaction(const WocTransaction&)
+{
+}
index ac7e8eb..18da2bd 100644 (file)
@@ -25,6 +25,7 @@ class WocPHPServerOut:public WocOutput
                virtual void finalize();
                virtual void newClass(const WocClass&);
                virtual void newTable(const WocTable&);
+               virtual void newTransaction(const WocTransaction&);
        private:
                QString m_basedir,m_subdir,m_fileext;
                QFile m_loader,m_schema;
index 2b2de15..17832ee 100644 (file)
@@ -97,6 +97,14 @@ bool WocProcessor::processFile(QString fn)
                        }else
                                return false;
                }else
+               if(tn=="Transaction"){
+                       WocTransaction trn(el);
+                       if(trn.isValid()){
+                               m_transactions.append(trn);
+                               emit newTransaction(trn);
+                       }else
+                               return false;
+               }else
                if(tn=="Project"){
                        if(el.hasAttribute("baseDir"))
                                m_baseDir=el.attribute("baseDir");
@@ -109,9 +117,9 @@ bool WocProcessor::processFile(QString fn)
                }else
                if(tn=="DataBase"){
                        if(el.hasAttribute("instance"))
-                               m_dbInst=el.attribute("instance");
+                               m_dbInst=el.attribute("instance","dbInst");
                        if(el.hasAttribute("schema"))
-                               m_dbSchema=el.attribute("schema");
+                               m_dbSchema=el.attribute("schema","dbSchema");
                        if(el.hasAttribute("version"))
                                m_dbVer=el.attribute("version");
                }else
@@ -138,6 +146,10 @@ bool WocProcessor::processFile(QString fn)
                        qDebug("Warning: file %s has unknown element '%s' at line %i column %i", fn.toLocal8Bit().data(), tn.toLocal8Bit().data(), el.lineNumber(), el.columnNumber());
                }
        }
+       //TODO: verify classes
+       //TODO: verify transactions
+       
+       //return success
        return true;
 }
 
@@ -209,7 +221,7 @@ void WocProcessor::finalize()
        emit sfinalize();
 }
 
-bool WocProcessor::haveTable(QString n)const
+bool WocProcessor::hasTable(QString n)const
 {
        for(int i=0;i<m_tables.size();i++)
                if(m_tables[i].name()==n)return true;
@@ -223,24 +235,172 @@ WocTable WocProcessor::table(QString n)const
        return WocTable();
 }
 
+bool WocProcessor::hasClass(QString n)const
+{
+       for(int i=0;i<m_classes.size();i++)
+               if(m_classes[i].name()==n)return true;
+       return false;
+}
+
 
+/******************************************************************************
+ * WocOutput
+ ******************************************************************************/
 
 WocOutput::WocOutput()
 {
        connect(WocProcessor::instance(),SIGNAL(sfinalize()),this,SLOT(finalize()));
        connect(WocProcessor::instance(),SIGNAL(newClass(const WocClass&)),this,SLOT(newClass(const WocClass&)));
        connect(WocProcessor::instance(),SIGNAL(newTable(const WocTable&)),this,SLOT(newTable(const WocTable&)));
+       connect(WocProcessor::instance(),SIGNAL(newTransaction(const WocTransaction&)),this,SLOT(newTransaction(const WocTransaction&)));
 }
 
 WocOutput::~WocOutput(){}
 
+/******************************************************************************
+ * WocClass
+ ******************************************************************************/
+
 WocClass::WocClass(const QDomElement&cls)
 {
+       //scan basics
        m_valid=true;
-       qDebug("not really parsing class %s",cls.attribute("name").toAscii().data());
-       
+       m_abstract=str2bool(cls.attribute("abstract","0"));
+       WocProcessor *woc=WocProcessor::instance();
+       QRegExp symok("[a-z_][a-z0-9_]*",Qt::CaseInsensitive);
+       m_name=cls.attribute("name");
+       if(m_name==""){
+               qDebug("Error: unnamed class at line %i column %i.",cls.lineNumber(),cls.columnNumber());
+               m_valid=false;
+               return;
+       }
+       if(woc->hasClass(m_name)){
+               qDebug("Error: double definition of class %s at line %i column %i.",m_name.toAscii().data(),cls.lineNumber(),cls.columnNumber());
+               m_valid=false;
+               return;
+       }
+       if(!symok.exactMatch(m_name)){
+               qDebug("Error: Illegal class name %s.",m_name.toAscii().data());
+               m_valid=false;
+               return;
+       }
+       qDebug("Info: parsing class %s",m_name.toAscii().data());
+       m_base=cls.attribute("base","WObject");
+       //scan properties
+       QDomNodeList nl=cls.elementsByTagName("Property");
+       for(int i=0;i<nl.size();i++){
+               QDomElement el=nl.at(i).toElement();
+               if(el.isNull())continue;
+               s_prop p;
+               p.name=el.attribute("name");
+               if(!symok.exactMatch(p.name)){
+                       qDebug("Error: Illegal property %s in class %s.",p.name.toAscii().data(),m_name.toAscii().data());
+                       m_valid=false;
+                       return;
+               }
+               if(hasProperty(p.name)){
+                       qDebug("Error: Double definition of property %s in class %s.",p.name.toAscii().data(),m_name.toAscii().data());
+                       m_valid=false;
+                       return;
+               }
+               p.type=el.attribute("type");
+               p.isid=str2bool(el.attribute("id","0"));
+               p.isabstract=str2bool(el.attribute("abstract","0"));
+               m_props.append(p);
+       }
+       //scan enums
+       nl=cls.elementsByTagName("Enum");
+       for(int i=0;i<nl.size();i++){
+               QDomElement el=nl.at(i).toElement();
+               if(el.isNull())continue;
+               QString nm=el.attribute("name");
+               QList<QPair<QString,int> >ev;
+               //check whether there is a reference
+               if(el.hasAttribute("refColumn")){
+                       QStringList ref=el.attribute("refColumn").split(":");
+                       if(ref.size()!=2){
+                               qDebug("Error: illegal enum reference in class %s enum %s.",m_name.toAscii().data(),nm.toAscii().data());
+                               m_valid=false;
+                               return;
+                       }
+                       if(!woc->hasTable(ref[0])){
+                               qDebug("Error: enum reference in class %s enum %s points to non-existant table.",m_name.toAscii().data(),nm.toAscii().data());
+                               m_valid=false;
+                               return;
+                       }
+                       WocTable tab=woc->table(ref[0]);
+                       if(!tab.hasColumn(ref[1])){
+                               qDebug("Error: enum reference in class %s enum %s points to non-existant column.",m_name.toAscii().data(),nm.toAscii().data());
+                               m_valid=false;
+                               return;
+                       }
+                       ev=tab.columnEnums(ref[1]);
+               }
+               //scan values
+               QDomNodeList nl2=el.elementsByTagName("Value");
+               int nxval=0;
+               for(int j=0;j<nl2.size();j++){
+                       QDomElement el2=nl2.at(j).toElement();
+                       if(el2.isNull())continue;
+                       QString n=el2.attribute("name");
+                       if(n==""){
+                               qDebug("Warning: anonymous enum value in class %s enum %s. Ignoring it.",m_name.toAscii().data(),nm.toAscii().data());
+                               continue;
+                       }
+                       nxval=el2.attribute("value",QString::number(nxval)).toInt(0,0);
+                       ev.append(QPair<QString,int>(n,nxval));
+                       nxval++;
+               }
+               m_enumvals.insert(nm,ev);
+       }
+       //scan mappings
+       nl=cls.elementsByTagName("Mapping");
+       for(int i=0;i<nl.size();i++){
+               QDomElement el=nl.at(i).toElement();
+               if(el.isNull())continue;
+               QString name=el.attribute("name");
+               QList<QPair<QString,QString> >map;
+               QDomNodeList nl2=el.elementsByTagName("Map");
+               for(int j=0;j<nl2.size();j++){
+                       QDomElement el2=nl2.at(j).toElement();
+                       if(el2.isNull())continue;
+                       QString col=el2.attribute("column");
+                       QString prp=el2.attribute("property");
+                       if(prp=="")prp=col;
+                       if(col=="")col=prp;
+                       if(col==""){
+                               qDebug("Warning: empty mapping in class %s mapping %s. Ignoring it.",m_name.toAscii().data(),name.toAscii().data());
+                               continue;
+                       }
+                       map.append(QPair<QString,QString>(col,prp));
+               }
+               m_maps.insert(name,map);
+       }
+       //check abstraction
+       if(!m_abstract && isAbstract()){
+               qDebug("Warning: class %s should be declared abstract.",m_name.toAscii().data());
+       }
 }
 
+bool WocClass::hasProperty(QString p)const
+{
+       for(int i=0;i<m_props.size();i++)
+               if(m_props[i].name==p)return true;
+       return false;
+}
+
+bool WocClass::isAbstract()const
+{
+       for(int i=0;i<m_props.size();i++)
+               if(m_props[i].isabstract)return true;
+       return m_abstract;
+}
+
+
+/******************************************************************************
+ * WocTable
+ ******************************************************************************/
+
 WocTable::WocTable()
 {
        m_backup=m_valid=false;
@@ -254,7 +414,7 @@ WocTable::WocTable(const QDomElement&tbl)
        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)){
+       if(woc->hasTable(m_name)){
                qDebug("Error: double definition of table %s.",m_name.toAscii().data());
                m_valid=false;
                return;
@@ -303,7 +463,7 @@ WocTable::WocTable(const QDomElement&tbl)
                                m_valid=false;
                                return;
                        }
-                       if(!woc->haveTable(fgn[0])){
+                       if(!woc->hasTable(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;
index 4d5aff8..fc673b1 100644 (file)
@@ -26,8 +26,24 @@ class WocClass
                WocClass(const QDomElement&);
                
                bool isValid()const{return m_valid;}
+               
+               QString name()const{return m_name;}
+               QString baseClass()const{return m_base;}
+               
+               bool hasProperty(QString)const;
+               
+               bool isAbstract()const;
+               
        private:
-               bool m_valid;
+               bool m_valid,m_abstract;
+               QString m_name,m_base;
+               struct s_prop{
+                       QString name,type;
+                       bool isid,isabstract;
+               };
+               QList<s_prop> m_props;
+               QMap<QString,QList<QPair<QString,QString> > >m_maps;
+               QMap<QString,QList<QPair<QString,int> > >m_enumvals;
 };
 
 class WocTable
@@ -76,6 +92,14 @@ class WocTable
                QList<QMap<QString,QString> >m_presets;
 };
 
+class WocTransaction
+{
+       public:
+               WocTransaction(const QDomElement&){}
+               bool isValid(){return true;}
+               
+};
+
 class WocOutput:public QObject
 {
        Q_OBJECT
@@ -87,6 +111,7 @@ class WocOutput:public QObject
                virtual void finalize()=0;
                virtual void newClass(const WocClass&)=0;
                virtual void newTable(const WocTable&)=0;
+               virtual void newTransaction(const WocTransaction&)=0;
 };
 
 class WocProcessor:public QObject
@@ -109,12 +134,15 @@ class WocProcessor:public QObject
                QString dbSchema()const{return m_dbSchema;}
                QString dbVersion()const{return m_dbVer;}
                
-               bool haveTable(QString)const;
+               bool hasTable(QString)const;
                WocTable table(QString)const;
+               
+               bool hasClass(QString)const;
        signals:
                void sfinalize();
                void newClass(const WocClass&);
                void newTable(const WocTable&);
+               void newTransaction(const WocTransaction&);
                
        private:
                QString m_baseDir,m_wobDir,m_verComm,m_verNeedComm,m_verHR;
@@ -122,6 +150,7 @@ class WocProcessor:public QObject
                
                QList<WocTable> m_tables;
                QList<WocClass> m_classes;
+               QList<WocTransaction> m_transactions;
                
                static WocProcessor*inst;
                
index 31fd52b..9c2c412 100644 (file)
@@ -15,4 +15,5 @@
 WocQtClientOut::WocQtClientOut(QString srcDir,QString subDir,QString prifile){}
 void WocQtClientOut::finalize(){}
 void WocQtClientOut::newClass(const WocClass&){}
-void WocQtClientOut::newTable(const WocTable&){}
\ No newline at end of file
+void WocQtClientOut::newTable(const WocTable&){}
+void WocQtClientOut::newTransaction(const WocTransaction&){}
index 1a50ef4..9c438e7 100644 (file)
@@ -23,6 +23,7 @@ class WocQtClientOut:public WocOutput
                virtual void finalize();
                virtual void newClass(const WocClass&);
                virtual void newTable(const WocTable&);
+               virtual void newTransaction(const WocTransaction&);
 };
 
 #endif