refined wobs & docu
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 8 Feb 2009 15:32:11 +0000 (15:32 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 8 Feb 2009 15:32:11 +0000 (15:32 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@267 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

doc/prog_woc.html
wob/cart.wolf
wob/magicsmoke.wolf
wob/order.wolf

index ca6f426..4400156 100644 (file)
@@ -20,15 +20,128 @@ The Web Object Compiler (woc) helps implementing these three-tier architecture i
 
 <h2>Overall File Format</h2>
 
-Woc translates Web Object Language Files (*.wolf) into PHP or C++/Qt code. The wolf files are simple XML syntax.
+Woc translates Web Object Language Files (*.wolf) into PHP or C++/Qt code. The wolf files are simple XML syntax.<p>
+
+Each wolf file must be enclosed in the &lt;Wolf> and &lt;/Wolf> tags. The first few statements inside must describe the project itself:
+
+<pre>
+&lt;Wolf>
+  &lt;Project baseDir=".." wobDir="wob"/>
+  &lt;Version comm="0100" needcomm="0100" humanReadable="1.1 alpha" svnTarget="."/>
+&lt;/Wolf>
+</pre>
+
+Above the &lt;Project> tag tells woc what the overall project directory is (relative to its current working directory) and where, relative to the baseDir, it will find all wolf files.<p>
+
+The &lt;Version> tag describes the communication protocol:
+
+<table frame="1" border="1">
+<tr><td><b>Attribute</b></td><td><b>Description</b></td></tr>
+<tr><td>comm</td><td>the communication protocol described by this wolf file</td></tr>
+<tr><td>needcomm</td><td>the minimum communication protocol this wolf file is compatible with (attention: the processor uses ASCII string comparison, not int comparison)</td></tr>
+<tr><td>humanReadable</td><td>the version number shown to the user</td></tr>
+<tr><td>svnTarget</td><td>if given: woc will call SVN to find out which repository revision was used</td></tr>
+<tr><td>svnExe</td><td>executable to call for subversion (default: svn)</td></tr>
+</table><p>
+
+The Include tag can be used to include other wolf files in the processing:
+<pre>
+&lt;Include file="user.wolf"/>
+</pre><p>
+
+<h3>Attribute Types</h3>
+
+Boolean attributes in wolf files allow integers (0 is false, non-zere is true) or the explicit strings "yes", "true", "on" for true and "no", "false", "off" for false.<p>
+
+Integers can be entered in C notation - if it starts with 1 through 9 it is decimal, if it starts with 0 it is octal, if it starts with 0x it is hexadecimal. All integers are interpreted by woc - the generated source will always contain decimal numbers.<p>
+
+Woc is case-sensitive.
+
+<h2>Chosing Outputs</h2>
+
+Outputs should be declared after the basics have been declared, but before any tables, classes or transactions are declared.
+
+<pre>
+&lt;QtClientOutput sourceDir="src" subDir="wob" priInclude="wob.pri"/>
+&lt;PHPServerOutput sourceDir="www" subDir="inc/wob" extension=".php" clean="yes"/>
+&lt;HtmlOutput sourceDir="doc" subDir="wob"/>
+</pre>
+
+The attribute "sourceDir" tells woc which directory (above baseDir) is the root source directory for each sub-project, the "subDir" attribute tells it which subdirectory below the sourceDir should be used for woc's generated output. The attribute "clean" tells woc to first delete all files from that sub-directory before starting the generator. Multiple generators of the same type can be used.<p>
+
+The QtClientOutput tag tells woc to create a generator for a Qt based client - the priInclude attribute tells woc which name it should give to the QMake include for its generated output.<p>
+
+The PHPServerOutput tag tells woc to create a generator for a PHP based server. The "extension" attribute tells woc which file extension to use for the generated files (default is .php). Woc will automatically create a "autoload" (plus extension) file that should be included from the main body of the PHP project to load the automatically generated classes.<p>
+
+The HtmlOutput tag tells woc where to generate API documentation.
 
 <h2>Database Abstraction Layer</h2>
 
-The Database Abstraction Layer is the servers lower bound towards the database. It is a simple translation of the database structure into usable PHP objects.
+The Database Abstraction Layer is the servers lower bound towards the database. It is a simple translation of the database structure into usable PHP objects. The woc compiler generates one class per table.<p>
+
+One of the first statements is the manifest for the database schema:
+
+<pre>
+&lt;DataBase instance="dbInst" schema="dbSchema" version="00.01"/>
+</pre>
+
+The attribute "instance" tells woc what variable name it should use for the database connection instance, likewise "schema" tells woc which variable represents the database schema (usually an instance of WobSchema, which is generated by woc). The "version" attribute tells woc which database schema version is described in this wolf file.<p>
+
+For each database table woc needs a description of that table:
+
+<pre>
+&lt;Table name="ticket" backup="yes" base="BarcodeTable">
+  &lt;Column name="ticketid" type="string:32" primarykey="yes"/>
+  &lt;Column name="eventid" type="int32" foreignkey="event:eventid"/>
+  &lt;Column name="price" type="int32" notnull="yes"/>
+  &lt;Column name="status" type="enum32" notnull="yes">
+    &lt;Value name="Reserved" value="0x301"/> &lt;!--dec: 769-->
+    &lt;Value name="Cancelled" value="0x4"/> &lt;!--dec: 4-->
+    &lt;Value name="MaskUsable" value="0x300"/> &lt;!--dec: 768-->
+  &lt;/Column>
+  &lt;Column name="orderid" type="int32" foreignkey="order:orderid" notnull="yes"/>
+&lt;/Table>
+</pre>
+
+Table attributes:
+<table frame="1" border="1">
+<tr><td><b>Attribute</b></td><td><b>Description</b></td></tr>
+<tr><td>name</td><td>the name of the table, the generated class will be <tt>Wt<i>tablename</i></tt></td></tr>
+<tr><td>backup</td><td>bool, contains whether the table is in the backup routine (default: false)</td></tr>
+<tr><td>base</td><td>optional, contains the class that this tables class is derived from, the base class must be derived from WobTable (default is to derive from WobTable directly)</td></tr>
+</table><p>
+
+Column attributes:
+<table frame="1" border="1">
+<tr><td><b>Attribute</b></td><td><b>Description</b></td></tr>
+<tr><td>name</td><td>the name of the column in the database</td></tr>
+<tr><td>type</td><td>the type of the column, this must be a woc type which is then translated into SQL by woc</td></tr>
+<tr><td>notnull, null</td><td>bool, marks the column to (not) allow NULL values, only one of the two attributes is allowed, currently the default is to allow NULL, but this may change in the future</td></tr>
+<tr><td>foreignkey</td><td>declares a reference to a foreign key column, the syntax is "foreigntablename:column" - the table that is referenced must be declared before the current one</td></tr>
+<tr><td>unique</td><td>bool, declares the column UNIQUE</td></tr>
+<tr><td>primarykey</td><td>bool, tells woc that this column is part of the primary key (multiple columns may be part of the primary key)</td></tr>
+<tr><td>default</td><td>declares a default value for the column (currently defaults for enums must be given as integer)</td></tr>
+</table><p>
+
+Column Types:
+<table frame="1" border="1">
+<tr><td><b>Attribute</b></td><td><b>Description</b></td></tr>
+<tr><td>string:<i>int</i>, string</td><td>a string column (SQL: VARCHAR), if the :int is given the column will have that maximum length assigned, if it is not given the database maximum is used; most databases support VARCHARs up to 255 characters</td></tr>
+<tr><td>int32, int64</td><td>a 32-bit/64-bit integer type</td></tr>
+<tr><td>enum, enum32, enum64</td><td>a 32bit/64bit (enum=enum32) integer interpreted as enumeration, the column must contain "Value" tags to declare the valid values</td></tr>
+<tr><td>bool</td><td>a boolean column (the SQL representation may vary per database system)</td></tr>
+<tr><td>seq32, seq64</td><td>a 32bit/64bit integer that counts up automatically (ie. that has a sequence attached to it) - this is usually only used for primary keys</td></tr>
+<tr><td>text</td><td>a large text field</td></tr>
+<tr><td>blob</td><td>binary large object</td></tr>
+</table><p>
+
+All names in table descriptions must follow a very strict syntax in order to be compatible with as many database systems as possible. Woc allows names that start with letters and contain only letters, underscored and digits.<p>
+
+The Value tags for enum types function similar to enums in C++. If a value attribute is given that value is assigned to the enum symbol, if no value is given the previous one is increased by one (the first value is 0).<p>
 
 <h2>Communication Abstraction Layer</h2>
 
-The Communication Abstraction Layer is the servers upper bound towards the client. It hides the complexities of serializing data onto the network transport protocol by providing communication classes that do this automatically.
+The Communication Abstraction Layer is the servers upper bound towards the client. It hides the complexities of serializing data onto the network transport protocol by providing communication classes that do this automatically. The configuration of this layer is split into two major components: communication classes and transactions. While the communication classes describe what data can be transported over the connection, the transactions describe what operations can be performed.
 
 <h2>Business Logic: Mapping - the Trivial Case</h2>
 
index e36da7e..2e2a190 100644 (file)
                <!--unix timestamp at which to delete this session-->
                <Column name="timeout" type="int64" notnull="yes"/>
        </Table>
+       
+       
+       <Class name="CartTicket">
+               <Enum name="TicketValidationState">
+                       <Value name="Ok"/>
+                       <Value name="TooLate"/>
+                       <Value name="Exhausted"/>
+                       <Value name="SaleOnly"/>
+                       <Value name="OrderOnly"/>
+               </Enum>
+               <Property name="eventid" type="int"/>
+               <Property name="amount" type="int"/>
+               <Property name="price" type="int" optional="1"/>
+               <Property name="status" type="TicketValidationState" optional="1"/>
+               <Property name="maxamount" type="int" optional="1"/>
+       </Class>
+       
+       
+       <Class name="CartVoucher">
+               <Enum name="ValidationState">
+                       <Value name="Ok"/>
+                       <Value name="InvalidValue"/>
+                       <Value name="InvalidPrice"/>
+               </Enum>
+               <Property name="value" type="int"/>
+               <Property name="price" type="int" optional="1"/>
+               <Property name="status" type="Enum:ValidationState" optional="1"/>
+       </Class>
+       
+       <Class name="CartOrder">
+               <Enum name="ValidationState">
+                       <Value name="Ok"/>
+                       <Value name="SaleOnly"/>
+                       <Value name="OrderOnly"/>
+                       <Value name="Invalid"/>
+               </Enum>
+               <Property name="status" type="Enum:ValidationState" optional="1"/>
+               <Property name="customerid" type="int"/>
+               <Property name="tickets" type="List:CartTicket"/>
+               <Property name="vouchers" type="List:CartVoucher"/>
+       </Class>
 </Wolf>
\ No newline at end of file
index 4641462..389cf08 100644 (file)
@@ -14,7 +14,8 @@
        
        <!-- configure output -->
        <QtClientOutput sourceDir="src" subDir="wob" priInclude="wob.pri"/>
-       <PHPServerOutput sourceDir="www" subDir="inc/wob" extension=".php" loader="wobload.php" clean="yes"/>
+       <PHPServerOutput sourceDir="www" subDir="inc/wob" extension=".php" clean="yes"/>
+       <HtmlOutput sourceDir="doc" subDir="wob"/>
        
        <!-- load and parse class definitions -->
        <Include file="basics.wolf"/>
index b6a9194..cfed4b6 100644 (file)
                <Column name="depositat" type="string:64" foreignkey="users:uname"/>
                <!--status, see ORDER_* constants-->
                <Column name="status" type="enum32" notnull="yes">
-                       <Value name="ORDER_PLACED" value="0"/>
-                       <Value name="ORDER_SENT" value="1"/>
-                       <Value name="ORDER_SOLD" value="1"/>
-                       <Value name="ORDER_CANCELLED" value="2"/>
-                       <Value name="ORDER_RESERVED" value="4"/>
-                       <Value name="ORDER_CLOSED" value="0x80"/>
+                       <Value name="Placed" value="0"/>
+                       <Value name="Sent" value="1"/>
+                       <Value name="Sold" value="1"/>
+                       <Value name="Cancelled" value="2"/>
+                       <Value name="Reserved" value="4"/>
+                       <Value name="Closed" value="0x80"/>
                </Column>
                <Column name="ordertime" type="int32" notnull="yes"/>
                <Column name="senttime" type="int32"/>
                <!--initially a copy from event, can be adjusted by seller-->
                <Column name="price" type="int32" notnull="yes"/>
                <!--status of ticket (see TICKET_* constants)-->
-               <Column name="status" type="int32" notnull="yes"/>
+               <Column name="status" type="enum32" notnull="yes">
+                       <Value name="Reserved" value="0x301"/> <!--dec: 769-->
+                       <Value name="Bought" value="0x302"/> <!--dec: 770-->
+                       <Value name="Used" value="0x303"/> <!--dec: 771-->
+                       <Value name="Cancelled" value="0x4"/> <!--dec: 4-->
+                       <Value name="Refund" value="0x4"/>
+                       <Value name="MaskBlock" value="0x100"/> <!--dec: 256-->
+                       <Value name="MaskPay" value="0x200"/> <!--dec: 512-->
+                       <Value name="MaskUsable" value="0x300"/> <!--dec: 768-->
+
+               </Column>
                <Column name="orderid" type="int32" foreignkey="order:orderid" notnull="yes"/>
        </Table>
        <Table name="voucher" backup="yes" base="BarcodeTable">
 
        
        
-       <Class name="CartTicket">
-               <Enum name="TicketValidationState">
-                       <Value name="Ok"/>
-                       <Value name="TooLate"/>
-                       <Value name="Exhausted"/>
-                       <Value name="SaleOnly"/>
-                       <Value name="OrderOnly"/>
-               </Enum>
+       <Class name="Ticket">
+               <Enum name="TicketState" refColumn="ticket:status"/>
+               <Property name="ticketid" type="astring" id="yes"/>
                <Property name="eventid" type="int"/>
-               <Property name="amount" type="int"/>
-               <Property name="price" type="int" optional="1"/>
-               <Property name="status" type="TicketValidationState" optional="1"/>
-               <Property name="maxamount" type="int" optional="1"/>
+               <Property name="price" type="int"/>
+               <Property name="status" type="TicketState"/>
+               <Property name="orderid" type="int"/>
+               
+               <ToXml name="inOrder">ticketid eventid price status</ToXml>
+               
+               <Mapping table="ticket">
+                       <Map column="ticketid"/>
+                       <Map column="price"/>
+                       <Map column="eventid"/>
+                       <Map column="status"/>
+                       <Map column="orderid" property="orderid"/>
+               </Mapping>
        </Class>
        
+       <Transaction name="GetTicket">
+               <Input name="ticketid" type="astring"/>
+               <Output type="Ticket"/>
+       </Transaction>
        
-       <Class name="CartVoucher">
-               <Enum name="ValidationState">
+       
+       <Class name="Voucher">
+               <Enum name="VoucherState">
                        <Value name="Ok"/>
                        <Value name="InvalidValue"/>
                        <Value name="InvalidPrice"/>
                </Enum>
+               <Property name="voucherid" type="astring" id="yes"/>
                <Property name="value" type="int"/>
                <Property name="price" type="int" optional="1"/>
                <Property name="status" type="Enum:ValidationState" optional="1"/>
        </Class>
        
-       <Class name="CartOrder">
-               <Enum name="ValidationState">
-                       <Value name="Ok"/>
-                       <Value name="SaleOnly"/>
-                       <Value name="OrderOnly"/>
-                       <Value name="Invalid"/>
-               </Enum>
-               <Property name="status" type="Enum:ValidationState" optional="1"/>
-               <Property name="customerid" type="int"/>
-               <Property name="tickets" type="List:CartTicket"/>
-               <Property name="vouchers" type="List:CartVoucher"/>
-       </Class>
-       
-       <Class name="Order">
-               <Enum name="OrderState">
-                       <Value name="Placed" dbvalue="0"/>
-                       <Value name="Sent" dbvalue="1"/>
-                       <Value name="Sold" dbvalue="1"/>
-                       <Value name="Cancelled" dbvalue="2"/>
-                       <Value name="Reserved" dbvalue="4"/>
-                       <Value name="Closed" dbvalue="0x80"/>
-               </Enum>
-               
-               <Select name="getAll" table="orders"/>
-               <Select name="getByID" params="int orderid" table="orders" where="orderid=$orderid$"/>
+       <Class name="Order" abstract="yes">
+               <Enum name="OrderState" refColumn="order:status" />
                
                <Property name="orderid" type="int"/>
                <Property name="customerid" type="int"/>
                <Property name="seller" type="astring"/>
-               <Property name="tickets" type="List:Ticket">
-                       <Select table="tickets" where="orderid=$orderid$"/>
-               </Property>
-               <Property name="vouchers" type="List:Voucher">
-                       <Select table="vouchers" where="orderid=$orderid$"/>
-               </Property>
+               <Property name="tickets" type="List:Ticket"/>
+               <Property name="vouchers" type="List:Voucher"/>
                <Property name="amountpaid" type="int"/>
                <Property name="state" type="Enum:OrderState"/>
                
-               <Virtual name="amountdue" type="int" access="ro"/>
+               <Property name="amountdue" type="int" abstract="yes"/>
                <!-- etc.pp. -->
                
                <ToXml name="Short">orderid customerid seller amountpaid state amountdue</ToXml>