You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by jv...@apache.org on 2001/07/31 04:40:00 UTC

cvs commit: jakarta-turbine-torque/xdocs guide-developer.xml guide-user.xml schema-reference.xml

jvanzyl     01/07/30 19:40:00

  Modified:    xdocs    schema-reference.xml
  Added:       xdocs    guide-developer.xml guide-user.xml
  Log:
  - moving torque docs from turbine repo here.
  
  Revision  Changes    Path
  1.2       +0 -2      jakarta-turbine-torque/xdocs/schema-reference.xml
  
  Index: schema-reference.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-torque/xdocs/schema-reference.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- schema-reference.xml	2001/07/19 11:48:02	1.1
  +++ schema-reference.xml	2001/07/31 02:40:00	1.2
  @@ -384,5 +384,3 @@
     </section>
   </body>
   </document>
  -
  -
  
  
  
  1.1                  jakarta-turbine-torque/xdocs/guide-developer.xml
  
  Index: guide-developer.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
  
    <properties>
      <title>Torque User's Guide</title>
      <author email="jvanzyl@apache.org">Jason van Zyl</author>
      <author email="jmcnally@collab.net">John McNally</author>
    </properties>
  
  <body>
  
  <section name="What is Torque?">
  
  <p>
    Torque is a utility packaged with Turbine
    that generates all the database resources required by your web
    application. Torque uses a single XML database schema to generate the SQL for
    your target database and Turbine's Peer-based object relation model representing 
    your XML database schema. Additionally, an HTML document describing the database
    can be generated if you wish to make a browseable version of the database
    schema.
  </p>
  
  <p>
    Torque is currently deployed in two forms: a stand-alone version and a version
    that is bundled with the <a href="tdk-howto.html">Turbine Developer's Kit</a>.
    Both versions are identical in function, but have slightly different 
    configurations. 
  </p>
  
  </section>
  
  <section name="Torque Directory Structure">
  
  <p>
    Here is what the Torque directory structure looks like. There are slight
    differences between the stand-alone and TDK versions but nothing significant:
  </p>
  
  <source><![CDATA[
  torque/
      lib/              <--  Jar files required by Torque (stand-alone version)
      dtd/              <--- DTD for Torque XML database descriptors.
      schema/           <--- Project specific XML database descriptor.
      templates/        <--- Velocity templates used for source generation.
      xsl/              <--- XSLT stylesheets use for HTML generation.
      output/           <--- Target location for output (stand-alone version).
  
      build.xml         <--- Ant build file that controls Torque.
      build.properties  <--- Properties file that controls Torque behaviour.
  ]]></source>
  
  <p>
    A typical user of Torque would really only ever need to edit the
    <em>build.properties</em> file in base directory, and the
    <em>project-schema.xml</em> in the <strong>schema</strong> directory. We'll
    quickly go over each of these files and some of options you have using Torque.
  </p>
  
  </section>
  
  <section name="Quick Start Guide">
  
  <p>
    For those who just want to see Torque go all you have to do is select your
    target database and target package in <em>build.properties</em>, edit the
    <em>project-schema.xml</em> to suit your needs, then <strong>ant</strong>.
    That's it!
  </p>
  
  <p>
    You will probably want to set the <em>project</em> property in the
    <em>build.properties</em> file eventually so that your generated sources have names
    that reflect your project name, but you can do that later :-). You also have to
    remember that if you change the <em>project</em> property that you have to
    change the name of your project XML database schema to match! For example if you
    change the <em>project</em> property from the default value of "project" to
    "killerapp" then you must change the name of the default schema in the
    <strong>schema</strong> directory from <em>project-schema.xml</em> to
    <em>killerapp-schema.xml</em>.
  </p>
  
  </section>
  
  <section name="Configuring Torque">
  
  <strong>build.properties</strong>
  
  <p>
    Here is a list of all the properties currently supported by Torque:
  </p>
  
  <table>
  <tr>
      <td>project</td>
      <td>The name of your Turbine project. The project name is reflected in the
      names used for the generated output. If your project is set to "killerapp"
      then you will get the following files:<br/>
      killerapp-schema.sql<br/>
      killerapp.generation.report<br/>
      Remember when changing this property to change the name
      of your XML database schema to match!
      </td>
  </tr>
  <tr>
      <td>database</td>
      <td>The target database for your Turbine project. This is used in conjuction
      with SQL generation.
      </td>
  </tr>
  <tr>
      <td>extend</td>
      <td>Used in conjuction with the OM generation.</td>
  </tr>
  <tr>
      <td>mapname</td>
      <td>Used in conjuction with the OM generation.</td>
  </tr>
  <tr>
      <td>suffix</td>
      <td>
          Used in conjuction with the OM generation.
      </td>
  </tr>
  <tr>
      <td>targetPackage</td>
      <td>
          Used in conjuction with the OM generation.
      </td>
  </tr>
  <tr>
      <td>databaseUrl</td>
      <td>
          Used by the JDBC -> XML process, and by the SQL Ant Task
          that will initialize your target database with the
          generated SQL.
      </td>
  </tr>
  <tr>
      <td>databaseDriver</td>
      <td>
          Used by the JDBC -> XML process, and by the SQL Ant Task
          that will initialize your target database with the
          generated SQL.
      </td>
  </tr>
  <tr>
      <td>databaseUser</td>
      <td>
          Used by the JDBC -> XML process, and by the SQL Ant Task
          that will initialize your target database with the
          generated SQL.
      </td>
  </tr>
  <tr>
      <td>databasePassword</td>
      <td>
          Used by the JDBC -> XML process, and by the SQL Ant Task
          that will initialize your target database with the
          generated SQL.
      </td>
  </tr>
  <tr>
      <td><strong>You should not have to edit any properties below here!</strong></td>
      <td></td>
  </tr>
  <tr>
      <td>configDir</td>
      <td>The directory Torque looks in for the <em>build.properties</em> file.</td>
  </tr>
  <tr>
      <td>templatePath</td>
      <td>The path to the Velocity templates used for source generation.</td>
  </tr>
  <tr>
      <td>SQLControlTemplate</td>
      <td>Control template used for SQL source generation.</td>
  </tr>
  <tr>
      <td>OMControlTemplate</td>
      <td>Control template used for object model source generation.</td>
  </tr>
  <tr>
      <td>idTableControlTemplate</td>
      <td>Control template used for Id Broker source generation.</td>
  </tr>
  <tr>
      <td>outputDirectory</td>
      <td>Directory where the generated sources are placed.</td>
  </tr>
  <tr>
      <td>schemaDirectory</td>
      <td>Directory where Torque looks for XML database schemas.</td>
  </tr>
  </table>
  
  <strong>project-schema.xml</strong>
  <p>
  This is an example of what the XML database schema might look like. This
  particular example is a snippet of the database used for Turbines role-based
  user system:
  </p>
  
  <source><![CDATA[
  <database>
  
    <table name="ID_TABLE">
      <column name="ID_TABLE_ID" required="true" primaryKey="true" type="INTEGER"/>
      <column name="TABLE_NAME" required="true" size="255" type="VARCHAR"/>
      <column name="NEXT_ID" type="INTEGER"/>
      <column name="QUANTITY" type="INTEGER"/>
  
      <unique>
        <unique-column name="TABLE_NAME"/>
      </unique>
  
    </table>
  
    <table name="TURBINE_PERMISSION" idMethod="idbroker">
      <column name="PERMISSION_ID" required="true" primaryKey="true" type="INTEGER"/>
      <column name="PERMISSION_NAME" required="true" size="99" type="VARCHAR" javaName="Name"/>
    
      <unique>
        <unique-column name="PERMISSION_NAME"/>
      </unique>        
      
    </table>
  
    <table name="TURBINE_ROLE_PERMISSION">
      <column name="ROLE_ID" required="true" primaryKey="true" type="INTEGER"/>
      <column name="PERMISSION_ID" required="true" primaryKey="true" type="INTEGER"/>
      
      <foreign-key foreignTable="TURBINE_ROLE">
        <reference local="ROLE_ID" foreign="ROLE_ID"/>
      </foreign-key>
      
      <foreign-key foreignTable="TURBINE_PERMISSION">
        <reference local="PERMISSION_ID" foreign="PERMISSION_ID"/>
      </foreign-key>
    </table>
  
  </database>
  ]]></source>
  
  <p>
  Please refer to <a href="torque-schema-ref.html">Torque Schema Reference</a> 
  to find out more about the the different elements and attributes.
  </p>
  
  <!--
  
  <p>
  This is what the resultant SQL looks like, in the case the target database is
  <a href="http://www.mysql.com">MySQL</a>:
  </p>
  
  <source><![CDATA[
  drop table if exists ID_TABLE;
  CREATE TABLE ID_TABLE
  (
      ID_TABLE_ID integer NOT NULL,
      TABLE_NAME varchar(255) NOT NULL,
      NEXT_ID integer,
      QUANTITY integer,
      PRIMARY KEY(ID_TABLE_ID),
      UNIQUE(TABLE_NAME)
  );
  
  drop table if exists Jobentry;
  CREATE TABLE Jobentry
  (
      OID integer NOT NULL,
      MINUTE integer default -1 NOT NULL,
      HOUR integer default -1 NOT NULL,
      WEEKDAY integer default -1 NOT NULL,
      DAY_OF_MONTH integer default -1 NOT NULL,
      TASK varchar(99) NOT NULL,
      EMAIL varchar(99),
      PRIMARY KEY(OID)
  );
  ]]></source>
  
  <p>
  This is what the sources look like for the Peer based object model:
  </p>
  
  <p>
  <ul>
      <li>BaseObjects
          <ul>
              <li><a href="resources/IdTable.java">IdTable.java</a></li>
              <li><a href="resources/Jobentry.java">Jobentry.java</a></li>
          </ul>
      </li>
  
      <li>Peers
          <ul>
              <li><a href="resources/IdTablePeer.java">IdTablePeer.java</a></li>
              <li><a href="resources/JobentryPeer.java">JobentryPeer.java</a></li>
          </ul>
      </li>
  
      <li>MapBuilders
          <ul>
              <li><a href="resources/IdTableMapBuilder.java">IdTableMapBuilder.java</a></li>
              <li><a href="resources/JobentryMapBuilder.java">JobentryMapBuilder.java</a></li>
          </ul>
      </li>
  </ul>
  </p>
  
  <p>
  Please refer to <a href="getting-started.html">Getting Started</a> to find out
  more about the Peer based object model.
  </p>
  
  <p>
  This is what the HTML description of the database looks like:
  </p>
  
  <table>
  <tr>
      <td colspan="3">
          <strong>
          <font face="Lucida,Verdana,Helvetica,Arial" color="white">ID_TABLE</font>
          </strong>
      </td>
  </tr>
  <tr>
      <td>Column</td><td>Type</td><td>Size</td>
  </tr>
  <tr>
      <td>ID_TABLE_ID</td><td >INTEGER</td><td>&#160;</td>
  </tr>
  <tr>
      <td>TABLE_NAME</td><td >VARCHAR</td><td >255&#160;</td>
  </tr>
  <tr>
      <td>NEXT_ID</td><td >INTEGER</td><td >&#160;</td>
  </tr>
  <tr>
      <td>QUANTITY</td><td >INTEGER</td><td >&#160;</td>
  </tr>
  
  </table>
  
  <table>
  <tr>
      <td colspan="3">
          <strong>
          <font face="Lucida,Verdana,Helvetica,Arial" color="white">Jobentry</font>
          </strong>
      </td>
  </tr>
  <tr><td>Column</td><td>Type</td><td>Size</td>
  </tr>
  <tr>
      <td>JOBID</td><td >INTEGER</td><td>&#160;</td>
  </tr>
  <tr>
      <td>MINUTE</td><td >INTEGER</td><td>&#160;</td>
  </tr>
  <tr>
      <td>HOUR</td><td >INTEGER</td><td>&#160;</td>
  </tr>
  <tr>
      <td>WEEKDAY</td><td >INTEGER</td><td>&#160;</td>
  </tr>
  <tr>
      <td>DAY_OF_MONTH</td><td >INTEGER</td><td>&#160;</td
  ></tr>
  <tr>
      <td>TASK</td><td >VARCHAR</td><td >99&#160;</td>
  </tr>
  <tr>
      <td>EMAIL</td><td >VARCHAR</td><td >99&#160;</td>
  </tr>
  
  </table>
  -->
  
  </section>
  
  <section name="The Object Relational Map">
  
  <p>
    
    The OM/Peer (Torque) system can map a class hierarchy into a single table.
    This is 1 of 3 methods generally described in object-relational mapping
    designs.  Its benefits include that it does not require joins in order to
    gather the attributes for a single object.  It falls short in modelling a
    class hierarchy where the related classes have a non intersecting collection
    of attributes, as in this case a row in the table will have several null
    columns.
  
  </p>
  
  </section>
  
  <section name="A Class Hierarchy">
  
  <source>
         A     
         |     
       -----  
      |     | 
      B     C  
      |        
      D        
  </source>
  
  <p>
    
    There are two ways that are built into the torque generated Peers in order
    to specify what class a particular row in the table A represents.  A row
    will need to have some information that can distinguish the class.  You
    should specify the column in the table that serves this purpose with the
    attribute "inheritance"
  
  </p>
  
  <source><![CDATA[
  <table name="A"...>
    ...
    <column name="FOO" inheritance="single" type="VARCHAR".../>
  </table>
  ]]></source>
  
  <p>
    In this case you would need to specify the full className in column FOO, so
    the valid values of FOO would be:
  </p>
  
  <source>
  com.mycompany.project.om.A
  com.mycompany.project.om.B
  com.mycompany.project.om.C
  com.mycompany.project.om.D
  </source>
  
  <p>
    This is slightly inefficient in storage and also generates some inefficient
    code in the Peers because the Peer cannot know what classes are available
    until it gets each record and so will call Class.forName(FOO's value) for each
    row.
  </p>
  
  <p>
    The efficiency can be improved in the case where the class hierarchy is
    known, which would be in most circumstances.  So you can specify the
    classes in the xml specification:
  </p>
  
  <source><![CDATA[
  <table name="A"...>
    ...
    <column name="FOO" inheritance="single" type="CHAR" size="1"...>
      <inheritance key="B" class="B" extends="com.mycompany.project.om.A"/>
      <inheritance key="C" class="C" extends="com.mycompany.project.om.A"/>
      <inheritance key="D" class="D" extends="com.mycompany.project.om.B"/>
    </column>
  </table>
  ]]></source>
  
  <p>
    where in the above we are using NULL (or any other value) to stand for class
    "A".  An numeric column could also be used for the key.  Using the above 
    method, torque will cache a copy of each class, so the Class.forName is only
    done during APeer's initial load into memory.
  </p>
  
  </section>
  
  <section name="Overriding the Default Behavior">
  
  <p>
    The following example comes from <a href="http://scarab.tigris.org">Scarab</a>
    (an issue tracking system). In Scarab a class hierarchy definition is 
    described in a few tables, this provides for an evolving hierarchy.  This
    arrangement can be provided for using the following extensions.  In the
    xml specification, the column responsible for determining the class
    is marked using the inheritance="single" attribute.
  </p>
  
  <source><![CDATA[
  <table name="SCARAB_ISSUE_ATTRIBUTE_VALUE" idMethod="none" 
          javaName="AttributeValue">
      <column name="ISSUE_ID" primaryKey="true" required="true" 
              type="INTEGER"/>
      <column name="ATTRIBUTE_ID" primaryKey="true" required="true" 
              type="INTEGER" inheritance="single"/>
      <column name="OPTION_ID" required="false" type="INTEGER"/>
  ...
      <foreign-key foreignTable="SCARAB_ISSUE">
          <reference local="ISSUE_ID" foreign="ISSUE_ID"/>
      </foreign-key>
      <foreign-key foreignTable="SCARAB_ATTRIBUTE">
          <reference local="ATTRIBUTE_ID" foreign="ATTRIBUTE_ID"/>
      </foreign-key>
      <foreign-key foreignTable="SCARAB_ATTRIBUTE_OPTION">
          <reference local="OPTION_ID" foreign="OPTION_ID"/>
      </foreign-key>
  ...
  </table>
  ]]></source>
  
  <p>
    It might be interesting to note that the column responsible for the determining
    the class is also a primary and foreign key.  Marking the column this way
    will cause torque to generate an BaseAttributeValuePeer.getOMClass method.The 
    code in this method will be attempting to create a class from the information
    provided in column which is an integer.  This is obviously wrong, but it
    gives us a method to override to provide the correct information.
  </p>
  
  <p>
    So in AttributeValuePeer, we override the method:
  </p>
  
  <source><![CDATA[
  /** 
   * Get the className appropriate for a row in the 
   * SCARAB_ISSUE_ATTRIBUTE_VALUE table
   */
  public static Class getOMClass(Record record, int offset) 
      throws Exception
  {
      NumberKey attId = new NumberKey(record.getValue(offset-1 + 2)
                                          .asString());
      Attribute attribute = Attribute.getInstance(attId);
      String className = attribute.getAttributeType().getJavaClassName(); 
  
      TurbineGlobalCacheService tgcs = 
          (TurbineGlobalCacheService)TurbineServices
          .getInstance().getService(GlobalCacheService.SERVICE_NAME);
  
      String key = getClassCacheKey(className);
      Class c = null;
      try
      {
          c = (Class)tgcs.getObject(key).getContents();
      }
      catch (ObjectExpiredException oee)
      {
          c = Class.forName(className);
          tgcs.addObject(key, new CachedObject(c));
      }
      return c;
  }
  ]]></source>
  
  <p>  
    where in the above method, we use the foreign key(s) to traverse
    the tables to get the class information.  Then we cache the Class to 
    avoid the inefficiency of Class.forName on each row.  (We also cache
    the contents of the class hierarchy tables, since the dataset is
    quite small and static.)
  </p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-turbine-torque/xdocs/guide-user.xml
  
  Index: guide-user.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
  
    <properties>
      <title>Torque Developer's Guide</title>
      <author email="jvanzyl@apache.org">Jason van Zyl</author>
    </properties>
  
  <body>
  
  <section name="What is Torque?">
  
  <p>
  </p>
  
  </body>
  </document>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-dev-help@jakarta.apache.org