#set ($db = $table.Database)
#if ($db.Package)
    #set ($package = $db.Package)
#else
    #set ($package = $targetPackage)
#end
package ${package};

import java.util.*;
import java.math.*;
import java.sql.*;
import com.workingdogs.village.*;
import org.apache.turbine.om.*;
import org.apache.turbine.om.peer.*;
import org.apache.turbine.util.*;
import org.apache.turbine.util.db.*;
import org.apache.turbine.util.db.map.*;
import org.apache.turbine.util.db.pool.DBConnection;
import org.apache.turbine.services.db.TurbineDB;
import org.apache.turbine.util.TurbineException;

// Local classes
import ${package}.map.*;

/**
#if ($addTimeStamp)
 * This class was autogenerated by Torque on:
 *
 * [$now]
 *
#end
 */
public abstract class $basePrefix${table.JavaName}Peer 
    extends $table.BasePeer
{
#if (!$table.isAlias())

    /** the mapbuilder for this class */
    private static final ${table.JavaName}MapBuilder mapBuilder = 
        (${table.JavaName}MapBuilder)getMapBuilder(${table.JavaName}MapBuilder.CLASS_NAME);

    /** the table name for this class */
    public static final String TABLE_NAME = mapBuilder.getTable();

    /** 
     * @return the map builder for this peer
     */
    public static MapBuilder getMapBuilder()
    {
       return(mapBuilder);
    }

#foreach ($col in $table.Columns)
    #set ( $tfc=$table.JavaName )
    #set ( $cfc=$col.JavaName )
    #set ( $cup=$col.Name.toUpperCase() )
    /** the column name for the $cup field */
    public static final String $cup = mapBuilder.get${tfc}_${cfc}();
#end

#end ## ends if (!$table.isAlias())

    /** number of columns for this peer */
    public static final int numColumns =  $table.NumColumns;

    /** A class that can be returned by this peer. */
    protected static final String CLASSNAME_DEFAULT = 
        "${package}.$table.JavaName";

    /** A class that can be returned by this peer. */
    protected static final Class CLASS_DEFAULT = initClass();

    /** Initialization method for static CLASS_DEFAULT attribute */
    private static Class initClass()
    {
        Class c = null;
        try
        { 
            c = Class.forName(CLASSNAME_DEFAULT);
        }
        catch (Exception e)
        {
            Log.error("A FATAL ERROR has occurred which should not" +
                "have happened under any circumstance.  Please notify" +
                "Turbine and give as many details as possible including the " +
                "error stacktrace.", e);
        }
        return c;
    }

#if (!$table.isAlias())

    /**
     * Get the list of objects for a ResultSet.  Please not that your
     * resultset MUST return columns in the right order.  You can use
     * getFieldNames() in BaseObject to get the correct sequence.
     */
    public static Vector resultSet2Objects (java.sql.ResultSet results) throws Exception
    {
        QueryDataSet qds = null;
        Vector rows = null;
        try
        {
            qds = new QueryDataSet( results );
            rows = getSelectResults( qds );
        }
        finally
        {
            if (qds != null) qds.close();
        }

        return populateObjects (rows);

    }


#if ($table.ChildrenColumn)

    #set ($col = $table.ChildrenColumn)
    #set ( $tfc=$table.JavaName )
    #set ( $cfc=$col.JavaName )
    #set ( $cup=$col.Name.toUpperCase() )

    #if ($col.isEnumeratedClasses())
        ## NOTE: this hack requires a class type definition column to
        ## be a primitive type or a String. Should not be a bad assumption
        #if ($col.isPrimitive())
            #set ($quote = "")
        #else
            #set ($quote = '"')
        #end

        #foreach ($child in $col.Children)
    /** A key representing a particular subclass */
    public static final $col.JavaNative CLASSKEY_$child.Key.toUpperCase() = 
        $quote$child.Key$quote;

    /** A class that can be returned by this peer. */
    public static final String CLASSNAME_$child.Key.toUpperCase() = 
        "${package}.$child.ClassName";

    /** A class that can be returned by this peer. */
    public static final Class CLASS_$child.Key.toUpperCase() = 
        init${child.Key.toUpperCase()}Class();

    /** Initialization method for static CLASS_$child.Key.toUpperCase() attribute */
    private static Class init${child.Key.toUpperCase()}Class()
    {
        Class c = null;
        try
        { 
            c = Class.forName(CLASSNAME_$child.Key.toUpperCase());
        }
        catch (Exception e)
        {
            Log.error("A FATAL ERROR has occurred which should not" +
                "have happened under any circumstance.  Please notify " +
                "Turbine and give as many details as possible including the " +
                "error stacktrace.", e);
        }
        return c;
    }
        #end
    #end
#end

    /** Method to do inserts */
    public static ObjectKey doInsert( Criteria criteria ) throws Exception
    {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
     #end
        return BasePeer.doInsert( criteria );
    }

    /** 
     * Method to do inserts.  This method is to be used during a transaction,
     * otherwise use the doInsert(Criteria) method.  It will take care of 
     * the connection details internally. 
     */
    public static ObjectKey doInsert( Criteria criteria, DBConnection dbCon ) 
        throws Exception
    {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
     #end
        return BasePeer.doInsert( criteria, dbCon );
    }

    /** Add all the columns needed to create a new object */
    public static void addSelectColumns (Criteria criteria) throws Exception
    {
    #foreach ($col in $table.Columns)
        #set ( $cup=$col.Name.toUpperCase() )
        criteria.addSelectColumn( $cup );
    #end
    }


    /** 
     * Create a new object of type cls from a resultset row starting
     * from a specified offset.  This is done so that you can select
     * other rows than just those needed for this object.  You may
     * for example want to create two objects from the same row.
     */
    public static $table.JavaName row2Object (Record row, 
                                              int offset, 
                                              Class cls ) 
        throws Exception
    {
        $table.JavaName obj = ($table.JavaName)cls.newInstance();
        populateObject(row, offset, obj);
        #if ($addSaveMethod)
            obj.setModified(false);
        #end
        obj.setNew(false);

        return obj;
    }

    /** 
     * Populates an object from a resultset row starting
     * from a specified offset.  This is done so that you can select
     * other rows than just those needed for this object.  You may
     * for example want to create two objects from the same row.
     */
    public static void populateObject (Record row, 
                                       int offset, 
                                       $table.JavaName obj ) 
        throws Exception
    {
        #set ( $n=0 )
        #foreach ($col in $table.Columns)
            #if ($col.isBooleanChar())
            obj.set${col.JavaName}
                ("Y".equals(row.getValue(offset+$n).$col.VillageMethod));
            #elseif ($col.isBooleanInt())
            obj.set${col.JavaName}
                (1 == row.getValue(offset+$n).$col.VillageMethod);
            #else
                #if ($col.isPrimaryKey() || $col.isForeignKey() )
            obj.set${col.JavaName}(
                new ${col.JavaNative}(row.getValue(offset+$n).$col.VillageMethod));
                #else
            obj.set${col.JavaName}(row.getValue(offset+$n).$col.VillageMethod);
                #end
            #end
                #set ( $n = $n + 1 )
        #end
    }

    /** Method to do selects */
    public static Vector doSelect( Criteria criteria ) throws Exception
    {
        return populateObjects( doSelectVillageRecords(criteria) ); 
    }


    /** Method to do selects within a transaction */
    public static Vector doSelect( Criteria criteria, 
                                   DBConnection dbCon ) 
        throws Exception
    {
        return populateObjects( doSelectVillageRecords(criteria, dbCon) ); 
    }

    /** 
     * Grabs the raw Village records to be formed into objects.
     * This method handles connections internally.  The Record objects
     * returned by this method should be considered readonly.  Do not
     * alter the data and call save(), your results may vary, but are
     * certainly likely to result in hard to track MT bugs.
     */
    public static Vector doSelectVillageRecords( Criteria criteria ) 
        throws Exception
    {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
        if (criteria.getSelectColumns().size() == 0)
        {
            addSelectColumns ( criteria );
        }

     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
     #end

        // BasePeer returns a Vector of Value (Village) arrays.  The array
        // order follows the order columns were placed in the Select clause.
        return BasePeer.doSelect(criteria);
    }


    /** 
     * Grabs the raw Village records to be formed into objects.
     * This method should be used for transactions 
     */
    public static Vector doSelectVillageRecords( Criteria criteria, 
                                                 DBConnection dbCon ) 
        throws Exception
    {
        if (criteria.getSelectColumns().size() == 0)
        {
            addSelectColumns ( criteria );
        }

     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
     #end

        // BasePeer returns a Vector of Value (Village) arrays.  The array
        // order follows the order columns were placed in the Select clause.
        return BasePeer.doSelect(criteria, dbCon);
    }

    /** 
     * The returned vector will contain objects of the default type or
     * objects that inherit from the default.
     */
    public static Vector populateObjects(Vector records) 
        throws Exception
    {
        Vector results = new Vector(records.size());

        // populate the object(s)
        for ( int i=0; i<records.size(); i++ )
        {
            Record row = (Record)records.elementAt(i);
#if ($table.ChildrenColumn)
            results.add(${table.JavaName}Peer.row2Object(row, 1,
                ${table.JavaName}Peer.getOMClass(row, 1)));
#else
            results.add(${table.JavaName}Peer.row2Object(row, 1,
                ${table.JavaName}Peer.getOMClass()));
#end
        }
        return results;
    }
#end ## ends if(!$table.isAlias())

#if ($table.ChildrenColumn)

    #set ($col = $table.ChildrenColumn)
    /** 
     * The returned Class will contain objects of the default type or
     * objects that inherit from the default.
     */
    public static Class getOMClass(Record record, int offset) 
        throws Exception
    {
    #if ($col.isEnumeratedClasses())
            Class omClass = null;
            $col.JavaNative classKey = 
                record.getValue(offset-1 + $col.Position)
                .$col.VillageMethod;
        #set ($if = "if")
        #foreach ($child in $col.Children)
            #if ($col.isPrimitive())
            $if (classKey == CLASSKEY_$child.Key.toUpperCase())
            #else
            $if (CLASSKEY_${child.Key.toUpperCase()}.equals(classKey))
            #end
            {
                omClass = CLASS_$child.Key.toUpperCase();
            }
            #set ($if = "else if")
        #end
            else
            {
                omClass = getOMClass();
            }
            return omClass;
    #else
            return Class.forName( 
                record.getValue(offset-1 + $col.Position).asString());
    #end
    }
    
#end

    /** 
     * The class that the Peer will make instances of. 
     * If the BO is abstract then you must implement this method
     * in the BO.
     */
    public static Class getOMClass() 
        throws Exception
    {
    #if ($table.isAbstract())
        String error = "You must implement the getOMClass method in your";
               error += " Peer object in order for things to work properly.";
               error += " This method should return the proper Class that";
               error += " represents the Peer's Business Object.";
        throw new TurbineException (error);
    #else
        return CLASS_DEFAULT;
    #end
    }

#if (!$table.isAlias())

    /**
     * Method to do updates. 
     *
     * @param Criteria object containing data that is used to create the UPDATE statement.
     */
    public static void doUpdate(Criteria criteria) throws Exception
    {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
        Criteria selectCriteria = new
            Criteria(mapBuilder.getDatabaseMap().getName(), 2);
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) ) 
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
        }
         #end
         #if($col.isPrimaryKey())
         selectCriteria.put( $cup, criteria.remove($cup) );
         #end
     #end
         BasePeer.doUpdate( selectCriteria, criteria );
    }

    /** 
     * Method to do updates.  This method is to be used during a transaction,
     * otherwise use the doUpdate(Criteria) method.  It will take care of 
     * the connection details internally. 
     *
     * @param Criteria object containing data that is used to create the UPDATE statement.
     */
    public static void doUpdate(Criteria criteria, DBConnection dbCon) throws Exception
    {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
        Criteria selectCriteria = new
            Criteria(mapBuilder.getDatabaseMap().getName(), 2);
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
         #if($col.isPrimaryKey())
         selectCriteria.put( $cup, criteria.remove($cup) );
         #end
     #end
         BasePeer.doUpdate( selectCriteria, criteria, dbCon );
     }

    /** 
     * Method to do deletes.
     *
     * @param Criteria object containing data that is used DELETE from database.
     */
     public static void doDelete(Criteria criteria) throws Exception
     {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
     #end
         BasePeer.doDelete ( criteria );
     }

    /** 
     * Method to do deletes.  This method is to be used during a transaction,
     * otherwise use the doDelete(Criteria) method.  It will take care of 
     * the connection details internally. 
     *
     * @param Criteria object containing data that is used DELETE from database.
     */
     public static void doDelete(Criteria criteria, DBConnection dbCon) throws Exception
     {
    #if ($table.Database.Name != "default")
        criteria.setDbName(mapBuilder.getDatabaseMap().getName());
    #end
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, 1);
                }
                else
                {   
                    criteria.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( criteria.containsKey($cup) )
        {
            Object possibleBoolean = criteria.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    criteria.add($cup, "Y");
                }
                else
                {   
                    criteria.add($cup, "N");
                }
            }                     
         }
         #end
     #end
         BasePeer.doDelete ( criteria, dbCon );
     }

    /** Method to do inserts */
    public static void doInsert( $table.JavaName obj ) throws Exception
    {
        #if ($table.IdMethod.equals("none"))
        doInsert(buildCriteria(obj));
        #else
        obj.setPrimaryKey(doInsert(buildCriteria(obj)));
        #end
        obj.setNew(false);
    }

    /**
     * @param obj the data object to update in the database.
     */
    public static void doUpdate($table.JavaName obj) throws Exception
    {
        doUpdate(buildCriteria(obj));
    }
    /**
     * @param obj the data object to delete in the database.
     */
    public static void doDelete($table.JavaName obj) throws Exception
    {
        doDelete(buildCriteria(obj));
    }

    /** 
     * Method to do inserts.  This method is to be used during a transaction,
     * otherwise use the doInsert($table.JavaName) method.  It will take 
     * care of the connection details internally. 
     *
     * @param obj the data object to insert into the database.
     */
    public static void doInsert( $table.JavaName obj, DBConnection dbCon) throws Exception
    {
        #if ($table.IdMethod.equals("none"))
        doInsert(buildCriteria(obj), dbCon);
        #else
        obj.setPrimaryKey(doInsert(buildCriteria(obj), dbCon));
        #end
        obj.setNew(false);
    }

    /**
     * Method to do update.  This method is to be used during a transaction,
     * otherwise use the doUpdate($table.JavaName) method.  It will take 
     * care of the connection details internally. 
     *
     * @param obj the data object to update in the database.
     */
    public static void doUpdate($table.JavaName obj, DBConnection dbCon) throws Exception
    {
        doUpdate(buildCriteria(obj), dbCon);
    }
    /**
     * Method to delete.  This method is to be used during a transaction,
     * otherwise use the doDelete($table.JavaName) method.  It will take 
     * care of the connection details internally. 
     *
     * @param obj the data object to delete in the database.
     */
    public static void doDelete($table.JavaName obj, DBConnection dbCon) throws Exception
    {
        doDelete(buildCriteria(obj), dbCon);
    }

    /** Build a Criteria object from the data object for this peer */
    public static Criteria buildCriteria( $table.JavaName obj )
    {
        Criteria criteria = new Criteria();
        #foreach ($col in $table.Columns)
            #set ( $cfc=$col.JavaName )
            #set ( $cup=$col.Name.toUpperCase() )
            #if ($col.isPrimaryKey() && !$table.IdMethod.equals("none"))
        if ( !obj.isNew() )
           #end
            criteria.add( $cup, obj.get${cfc}() );
        #end
        return criteria;
    }

    /** 
     * Retrieve a single object by pk
     *
     * @param ObjectKey pk
     */
    public static $table.JavaName retrieveByPK( ObjectKey pk )
        throws Exception
    {
        DBConnection db = null;
        $table.JavaName retVal = null;
       try
        {
           db = TurbineDB.getConnection( mapBuilder.getDatabaseMap().getName() );
           retVal = retrieveByPK( pk, db );
        }
        finally
        {
           if (db != null)
              TurbineDB.releaseConnection(db);
        }
        return(retVal);
    }

    /** 
     * Retrieve a single object by pk
     *
     * @param ObjectKey pk
     * @param DBConnection dbcon
     */
    public static $table.JavaName retrieveByPK( ObjectKey pk, DBConnection dbcon )
        throws Exception
    {

        Criteria criteria = new Criteria();
#if ($table.PrimaryKeys.size() == 1)
            criteria.add( $table.PrimaryKeys.get(0).Name.toUpperCase(), pk );
#else
        SimpleKey[] keys = (SimpleKey[])pk.getValue();
    #set ( $i = 0 )
    #foreach ($col in $table.PrimaryKeys)
        #set ( $cup=$col.Name.toUpperCase() )
            criteria.add( $cup, keys[$i] );
        #set ( $i = $i + 1 )
    #end
#end
        Vector v = doSelect(criteria, dbcon);
        if ( v.size() != 1)
        {
            throw new Exception("Failed to select one and only one row.");
        }
        else
        {
            return ($table.JavaName)v.firstElement();
        }
    }


#if ($table.PrimaryKeys.size() > 1)
#set ( $comma = false )
    /** 
     * retrieve object using using pk values.
     *
#foreach ($col in $table.PrimaryKeys)
    #set ( $clo=$col.Name.toLowerCase() )
    #set ( $cjtype= $col.JavaNative )
     * @param $cjtype $clo
#end
     */
    public static $table.JavaName retrieveByPK(
#foreach ($col in $table.PrimaryKeys)
    #set ( $clo=$col.Name.toLowerCase() )
    #set ( $cjtype = $col.JavaNative )
    #if ($comma),#end $cjtype $clo
        #set ( $comma = true )
#end
        ) throws Exception
    {
        DBConnection db = null;
        $table.JavaName retVal = null;
       try
        {
           db = TurbineDB.getConnection( mapBuilder.getDatabaseMap().getName() );
           retVal = retrieveByPK( 
           #set ( $comma = false )
           #foreach ($col in $table.PrimaryKeys)
         #set ( $clo=$col.Name.toLowerCase() )
         #if ($comma),#end $clo
              #set ( $comma = true )
           #end
               , db);
        }
        finally
        {
           if (db != null)
              TurbineDB.releaseConnection(db);
        }
        return(retVal);
    }   

#set ( $comma = false )
    /** 
     * retrieve object using using pk values.
     *
#foreach ($col in $table.PrimaryKeys)
    #set ( $clo=$col.Name.toLowerCase() )
    #set ( $cjtype= $col.JavaNative )
     * @param $cjtype $clo
#end
     * @param DBConnection dbcon
     */
    public static $table.JavaName retrieveByPK(
#foreach ($col in $table.PrimaryKeys)
    #set ( $clo=$col.Name.toLowerCase() )
    #set ( $cjtype = $col.JavaNative )
    #if ($comma),#end $cjtype $clo
        #set ( $comma = true )
#end
       ,DBConnection dbcon ) throws Exception
    {
    
        Criteria criteria = new Criteria(5);
#foreach ($col in $table.PrimaryKeys)
    #set ( $cup=$col.Name.toUpperCase() )
    #set ( $clo=$col.Name.toLowerCase() )
        criteria.add( $cup, $clo );
#end
        Vector v = doSelect(criteria, dbcon);
        if ( v.size() != 1)
        {
            throw new Exception("Failed to select one and only one row.");
        }
        else
        {
            return ($table.JavaName) v.firstElement();
        }
    }
#end

#end ## ends if (!$table.isAlias())

#if ($complexObjectModel)

 ## 
 ## setup joins
 ##
 #set ( $className = $table.JavaName ) 
 #set ( $countFK = 0 )  
 #foreach ($dummyFK in $table.ForeignKeys)
      #set ( $countFK = $countFK + 1 )
 #end

 #if ($countFK >= 1)
 #foreach ($fk in $table.ForeignKeys)
   ## want to cover this case, but the code is not there yet.
   #if ( !($fk.ForeignTableName.equals($table.Name)) )

     #set ( $partJoinName = "" )
     #foreach ($columnName in $fk.LocalColumns)
        #set ( $column = $table.getColumn($columnName) )
        #if ($column.isMultipleFK())
            #set ( $partJoinName=$strings.concat([$partJoinName,$column.JavaName]) )
        #elseif ( $fk.ForeignTableName.equals($table.Name) )
            #set ( $partJoinName=$strings.concat([$partJoinName,$column.JavaName]) )
        #end
     #end

     #set ( $joinTable = $table.Database.getTable($fk.ForeignTableName) )
     #set ( $joinClassName = $joinTable.JavaName )

     #if ($partJoinName == "")
        #set ( $joinColumnId = $joinClassName )
        #set ( $collThisTable = $strings.concat([$className, "s"]) )
        #set ( $collThisTableMs = $className )
     #else
        #set ( $joinColumnId=$strings.concat([$joinClassName,"RelatedBy",$partJoinName]) )
        #set ( $collThisTable=$strings.concat([$className,"sRelatedBy",$partJoinName]) )
        #set ( $collThisTableMs=$strings.concat([$className,"RelatedBy",$partJoinName]) )
     #end


## ------------------------------------------------------------

   /**
    * selects a collection of $className objects pre-filled with their
    * $joinClassName objects.
    *
    * This method is protected by default in order to keep the public
    * api reasonable.  You can provide public methods for those you
    * actually need in ${table.JavaName}Peer.
    */
    protected static Vector doSelectJoin${joinColumnId}(Criteria c)
        throws Exception
    {
         c.setDbName(mapBuilder.getDatabaseMap().getName());

        ${table.JavaName}Peer.addSelectColumns(c);
        int offset = numColumns + 1;
        ${joinClassName}Peer.addSelectColumns(c);


     #set ( $lfMap = $fk.LocalForeignMapping )
     #foreach ($columnName in $fk.LocalColumns)
        #set ( $column = $table.getColumn($columnName) )
        #set ( $columnFk = $joinTable.getColumn( $lfMap.get($columnName) ) )
        c.addJoin(${table.JavaName}Peer.$column.Name.toUpperCase(),
            ${joinClassName}Peer.$columnFk.Name.toUpperCase());
     #end




     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( c.containsKey($cup) )
        {
            Object possibleBoolean = c.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    c.add($cup, 1);
                }
                else
                {   
                    c.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( c.containsKey($cup) )
        {
            Object possibleBoolean = c.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    c.add($cup, "Y");
                }
                else
                {   
                    c.add($cup, "N");
                }
            }                     
         }
         #end
     #end
        
        Vector rows = BasePeer.doSelect(c);
        Vector results = new Vector();

        for (int i=0; i<rows.size(); i++)
        {
            Record row = (Record)rows.elementAt(i);

#set ($classDecl = "Class")
#if ($table.ChildrenColumn)
            $classDecl omClass = ${table.JavaName}Peer.getOMClass(row, 1);
#else
            $classDecl omClass = ${table.JavaName}Peer.getOMClass();
#end
#set ($classDecl = "")

            $className obj1 = ($className)${table.JavaName}Peer
                .row2Object( row, 1, omClass);


#if ($joinTable.ChildrenColumn)
            $classDecl omClass = ${joinClassName}Peer.getOMClass(row, offset);
#else
            $classDecl omClass = ${joinClassName}Peer.getOMClass();
#end
#set ($classDecl = "")
            $joinClassName obj2 = ($joinClassName)${joinClassName}Peer
                .row2Object(row, offset, omClass);
            
            boolean newObject = true;
            for (int j=0; j<results.size(); j++)
            {
                $className temp_obj1 = ($className)results.elementAt(j);
                $joinClassName temp_obj2 = temp_obj1.get${joinColumnId}();
                if ( temp_obj2.getPrimaryKey().equals(obj2.getPrimaryKey() ) )
                {
                    newObject = false;
                    temp_obj2.add${collThisTableMs}(obj1);
                    break;
                }
            }
            if (newObject)
            {
                obj2.init${collThisTable}();
                obj2.add${collThisTableMs}(obj1);
            }
            results.add(obj1);

        }

        return results;
    }
  #end
 #end 
 #end 

## ===========================================================

  #if ($countFK > 2)

  #foreach ($fk in $table.ForeignKeys)

     #set ( $excludeTable = $table.Database.getTable($fk.ForeignTableName) )
     #set ( $excludeClassName = $excludeTable.JavaName )

     #set ( $relatedByCol = "" )
     #foreach ($columnName in $fk.LocalColumns)
        #set ( $column = $table.getColumn($columnName) )
        #if ($column.isMultipleFK())
            #set ($relatedByCol=$strings.concat([$relatedByCol,$column.JavaName]))
        #end
     #end

     #if ($relatedByCol == "")
        #set ( $excludeString = $excludeClassName )
        #set ( $collThisTable = $strings.concat([$className, "s"]) )
        #set ( $collThisTableMs = $className )
     #else
        #set ( $excludeString=$strings.concat([$excludeClassName,"RelatedBy",$relatedByCol]) )
        #set ( $collThisTable=$strings.concat([$className,"sRelatedBy",$relatedByCol]) )
        #set ( $collThisTableMs=$strings.concat([$className,"RelatedBy",$relatedByCol]) )
     #end



   /**
    * selects a collection of $className objects pre-filled with 
    * all related objects.
    *
    * This method is protected by default in order to keep the public
    * api reasonable.  You can provide public methods for those you
    * actually need in ${table.JavaName}Peer.
    */
    protected static Vector doSelectJoinAllExcept${excludeString}(Criteria c) 
        throws Exception
    {
         c.setDbName(mapBuilder.getDatabaseMap().getName());

        addSelectColumns(c);
        int offset2 = numColumns + 1;
    #set ( $index = 2 )
    #foreach ($fk in $table.ForeignKeys)
      ## want to cover this case, but the code is not there yet.
      #if ( !($fk.ForeignTableName.equals($table.Name)) )
        #set ( $joinTable = $table.Database.getTable($fk.ForeignTableName) )
        #set ( $joinClassName = $joinTable.JavaName )

        #if (!$joinClassName.equals($excludeClassName))
            #set ( $new_index = $index + 1 )
        ${joinClassName}Peer.addSelectColumns(c);
        int offset$new_index = offset$index + ${joinClassName}Peer.numColumns;
            #set ( $index = $new_index )
        #end
      #end
    #end
     #foreach ($col in $table.Columns)
         #set ( $cup=$col.Name.toUpperCase() )
         #if($col.isBooleanInt())
        // check for conversion from boolean to int
        if ( c.containsKey($cup) )
        {
            Object possibleBoolean = c.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    c.add($cup, 1);
                }
                else
                {   
                    c.add($cup, 0);
                }
            }                     
         }
         #elseif ($col.isBooleanChar())
        // check for conversion from boolean to Y/N
        if ( c.containsKey($cup) )
        {
            Object possibleBoolean = c.get($cup);
            if ( possibleBoolean instanceof Boolean )
            {
                if ( ((Boolean)possibleBoolean).booleanValue() )
                {
                    c.add($cup, "Y");
                }
                else
                {   
                    c.add($cup, "N");
                }
            }                     
         }
         #end
     #end

        Vector rows = BasePeer.doSelect(c);
        Vector results = new Vector();

        for (int i=0; i<rows.size(); i++)
        {
            Record row = (Record)rows.elementAt(i);

      #set ($classDecl = "Class")
      #if ($table.ChildrenColumn)
            $classDecl omClass = ${table.JavaName}Peer.getOMClass(row, 1);
      #else
            $classDecl omClass = ${table.JavaName}Peer.getOMClass();
      #end
      #set ($classDecl = "")

            $className obj1 = ($className)${table.JavaName}Peer
                .row2Object( row, 1, omClass);


    #set ( $index = 1 )
    #foreach ($fk in $table.ForeignKeys)
      ## want to cover this case, but the code is not there yet.
      #if ( !($fk.ForeignTableName.equals($table.Name)) )
        #set ( $joinTable = $table.Database.getTable($fk.ForeignTableName) )
        #set ( $joinClassName = $joinTable.JavaName )

        #if (!$joinClassName.equals($excludeClassName))
            #set ( $partJoinName = "" )
            #foreach ($columnName in $fk.LocalColumns)
                #set ( $column = $table.getColumn($columnName) )
                #if ($column.isMultipleFK())
                    #set ( $partJoinName=$strings.concat([$partJoinName,$column.JavaName]) )
                #end
            #end

            #if ($partJoinName == "")
                #set ( $joinString = $joinClassName )
                #set ( $collThisTable = $strings.concat([$className, "s"]) )
                #set ( $collThisTableMs = $className )
            #else
                #set ( $joinString=$strings.concat([$joinClassName,"RelatedBy",$partJoinName]) )
                #set ( $collThisTable=$strings.concat([$className,"sRelatedBy",$partJoinName]) )
                #set ( $collThisTableMs=$strings.concat([$className,"RelatedBy",$partJoinName]) )
            #end

            #set ( $index = $index + 1 )

    #if ($joinTable.ChildrenColumn)
            $classDecl omClass = ${joinClassName}Peer.getOMClass(row, offset$index);
    #else
            $classDecl omClass = ${joinClassName}Peer.getOMClass();
    #end
    #set ($classDecl = "")
            $joinClassName obj$index = ($joinClassName)${joinClassName}Peer
                .row2Object( row, offset$index, omClass);
            
            #if ($index == 2) boolean #end newObject = true;
            for (int j=0; j<results.size(); j++)    
            {
                $className temp_obj1 = ($className)results.elementAt(j);
                $joinClassName temp_obj$index = temp_obj1.get${joinString}();
                if ( temp_obj${index}.getPrimaryKey().equals(obj${index}.getPrimaryKey() ) )
                {
                    newObject = false;
                    temp_obj${index}.add${collThisTableMs}(obj1);
                    break;
                }
            }
            if (newObject)
            {
                obj${index}.init${collThisTable}();
                obj${index}.add${collThisTableMs}(obj1);
            }
      #end
    #end
  #end
            results.add(obj1);

        }

        return results;
    }
 #end
 #end  
#end

## ------------------------------------------------------------


#if (!$table.isAlias())
    /** 
     * Returns the TableMap related to this peer.  This method is not 
     * needed for general use but a specific application could have a
     * need.
     */
    protected static TableMap getTableMap()
    {
        return mapBuilder.getDatabaseMap().getTable(TABLE_NAME);
    }     
#end ## ends if (!$table.isAlias())


}

