<?xml version="1.0"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->

<document>

 <properties>
  <title>Torque Runtime Reference - Support for new Databases</title>
  <author email="jon@latchkey.com">Jon S. Stevens</author>
  <author email="fischer@seitenbau.de">Thomas Fischer</author>
  <author email="tv@apache.org">Thomas Vandahl</author>
 </properties>

 <body>

  <section name="Introduction">

    <p>
      In the Torque Runtime, all information about a specific Database is
      gathered in a so-called Database adapter class.  So if you want to
      support a new database in the runtime, you need to provide a
      Database Adapter class for this database.
    </p>
    
    <p>
      If you are adding support for a new RDBMS, then you will probably also
      want to support the database in the Torque generator. 
      To do this, you need to create a set of Velocity templates--used 
      by Torque to generate a SQL schema for your RDBMS--in the templates 
      component. The recommend method for doing this is to copy an existing set
      of templates and adapt them to your RDBMS as needed.  This is not
      elaborated further here.
    </p>

  </section>
 
  <section name="Database Adapters">

    <p>
      A database adapter class is a class that implements
      <code>org.apache.torque.adapter.DB</code> and encapsulates access
      to a specific RDBMS implementation. Database adapter classes already
      found in Torque include DBOracle, DBMM, DBSybase, etc. 
      These classes allow Torque to gain access to a wide range of databases
      in a uniform manner. This allows you to easily swap between databases
      without any modification to Torque or the application built
      on top of Torque.
    </p>

    <p>
      Why is this necessary if Java already offers uniform database access
      in the form of JDBC? Unfortunately, underlying databases still
      use different SQL implementations and conventions. For example, the use
      of single and double quotes varies. The use of database adapter classes in
      Torque endeavors to overcome this problem.
    </p>

    <p>
      To add a new database adapter class to Torque you must follow these
      steps:
    </p>

    <p>
      <ul>
        <li>
          Create a new class DB&lt;dbname> that implements
          <code>org.apache.torque.adapter.DB</code> (where dbname is the name of
          the database or database driver you wish to add to Torque). An abstract
          implementation, <code>org.apache.torque.adapter.AbstractDBAdapter</code> is
          provided which sets some defaults so that you only need to implement a 
          number of methods.
        </li>

        <li>
          Implement getStringDelimiter(). This method has to return
          the character that the specific database implementation uses to
          indicate string literals in SQL. This will usually be a single qoute
          (').
        </li>

        <li>
          Implement generateLimits(). This method has to provide the special
          SQL expressions to limit the number of records returned and/or the
          offset into the result set. This is only needed if supportsNativeLimit()
          or supportsNativeOffset() return true.
        </li>

        <li>
          Implement getIdMethodType(). This method should return the method
          the database uses to generates unique Ids.  Valid return values are
          <code>org.apache.torque.adapter.IDMethod.AUTO_INCREMENT</code>,
          <code>org.apache.torque.adapter.IDMethod.SEQUENCE</code>, and
          <code>org.apache.torque.adapter.IDMethod.NO_ID_METHOD</code>.  
        </li>

        <li>
          Implement String getIDMethodSQL(Object obj). Databases that use 
          sequences for Id generation should return the SQL to get the next Id 
          from the sequence, where <code>obj</code> is the name of the sequence.
          Databases that use auto increment fields should return the last
          generated id; <code>obj</code> is the name of the table in this case.
          Databases that do not support this must return null.
        </li>

        <li>
          Implement lockTable(Connection con, String table). This method
          should place a lock on a database table, if this is possible for the 
          database.  This method is not used internally by Torque, and was only
          retained to provide backwards compatibility.
        </li>

        <li>
          Implement unlockTable(Connection con, String table). This method
          should release the table lock acquired by the above-mentioned method,
          if possible.  This method is not used internally by Torque, 
          and was only retained to provide backwards compatibility.
        </li>

        <li>
          Implement ignoreCase(String in). This method should implement
          a mechanism for case insensitive comparisons in the database. 
          Usually this converts the string to Uppercase, for example UPPER 
          (&lt;in&gt;). 
          If such a mechanism does not exist in your database, 
          simply return the in parameter without any modification. 
          DO NOT return in.toUpper().
        </li>

        <li>
          Some databases (for example Interbase) do not support the function
          returned by their implementation of ignoreCase() in the ORDER BY
          clause of SELECT statements. If your database falls into this
          category you should override the default implementation of
          String ignoreCaseInOrderBy(String in). It is NOT required to override
          this method for other databases--the default implementation calls
          ignoreCase() and respectCase().
        </li>
      </ul>
    </p>

  </section>

  <section name="Configuring Torque to use the new adapter">
    <p>
      The adapter you wrote does not need to be compiled into Torque but
      it can be referenced in the configuration. Just use a new short name for 
      the adapter and provide the class name in the configuration file. See the
      following example:
    </p>
    <source>
torque.database.mydatabase.adapter=myadapter
torque.database.mydatabase.adapter.myadapter.className=com.acme.DBMyAdapter
    </source>
  </section>

 </body>
</document>
