<?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 ORM 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.AbstractAdapter</code>
      and encapsulates access to a specific RDBMS implementation.
      Database adapter classes already
      found in Torque include OracleAdapter, MysqlAdapter 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 &lt;dbname&gt;Adapter that implements
          <code>org.apache.torque.adapter.Adapter</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.AbstractAdapter</code>
          is provided which sets some defaults so that you only need
          to implement a few methods.
        </li>

        <li>
          Override getStringDelimiter() if necessary.<br/>
          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 quote
          (').
        </li>

        <li>
          Override generateLimits() if necessary.<br/>
          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().<br/>
          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).<br/>
          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).<br/>
          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).<br/> 
          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).<br/>
          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>
          Override ignoreCaseInOrderBy(String in) if necessary.<br/>
          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().
        </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>
