db-torque-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t.@apache.org
Subject svn commit: r590654 [2/3] - in /db/torque/village/trunk: src/ src/java/ src/java/com/ src/java/com/workingdogs/ src/java/com/workingdogs/village/ src/test/ src/test/com/ src/test/com/workingdogs/ xdocs/
Date Wed, 31 Oct 2007 12:50:47 GMT
Added: db/torque/village/trunk/src/java/com/workingdogs/village/Record.java
URL: http://svn.apache.org/viewvc/db/torque/village/trunk/src/java/com/workingdogs/village/Record.java?rev=590654&view=auto
==============================================================================
--- db/torque/village/trunk/src/java/com/workingdogs/village/Record.java (added)
+++ db/torque/village/trunk/src/java/com/workingdogs/village/Record.java Wed Oct 31 05:50:45 2007
@@ -0,0 +1,1712 @@
+package com.workingdogs.village;
+
+/*
+ * 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.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+import java.math.BigDecimal;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * A Record represents a row in the database. It contains a collection of <a href="Value.html">Values</A> which are the individual
+ * contents of each column in the row.
+ *
+ * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
+ * @version $Revision: 568 $
+ */
+public class Record
+{
+    /** an array of Value objects, this is 1 based */
+    private Value [] values;
+
+    /** a 1 To 1 relationship between Values and whether they are clean or not */
+    private boolean [] isClean;
+
+    /** the parent DataSet for this Record */
+    private DataSet parentDataSet;
+
+    /** number of columns in this Record */
+    private int numberOfColumns;
+
+    /** this is the state of this record */
+    private int saveType = 0;
+
+    /** a saved copy of the schema for this Record */
+    private Schema schema;
+
+    /**
+     * This isn't used and doesn't do anything.
+     */
+    public Record()
+    {
+        // don't do anything
+    }
+
+    /**
+     * Creates a new Record and sets the parent dataset to the passed in value. This method also creates the Value objects which
+     * are associated with this Record.
+     *
+     * @param ds TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    public Record(DataSet ds)
+            throws DataSetException, SQLException
+    {
+        setParentDataSet(ds);
+        initializeRecord();
+        createValues(dataset().resultSet());
+    }
+
+    /**
+     * This is a special case method for Record. This case is really only used when DataSet.addRecord() is called because we may
+     * not have an existing ResultSet so there will not be any values in the Value objects that are created. Passing null to
+     * createValues forces the Value object to be created, but no processing to be done within the Value object constructor.
+     *
+     * <P>
+     * This method is a package method only because it is really not useful outside of the package.
+     * </p>
+     *
+     * @param ds the dataset
+     * @param addRecord whether or not this method is being called from DataSet.addRecord()
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    Record(DataSet ds, boolean addRecord)
+            throws DataSetException, SQLException
+    {
+        setParentDataSet(ds);
+        initializeRecord();
+        createValues(null);
+    }
+
+    /**
+     * Performs initialization for this Record.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    private void initializeRecord()
+            throws DataSetException
+    {
+        this.schema = dataset().schema();
+        this.numberOfColumns = schema.numberOfColumns();
+        this.values = new Value[size() + 1];
+        this.isClean = new boolean[size() + 1];
+        setSaveType(Enums.UNKNOWN);
+
+        for (int i = 1; i <= size(); i++)
+        {
+            markValueClean(i);
+            this.values[i] = null;
+        }
+    }
+
+    /**
+     * Creates the value objects for this Record. It is 1 based
+     *
+     * @param rs TODO: DOCUMENT ME!
+     *
+     * @exception DataSetException
+     * @exception SQLException
+     */
+    private void createValues(ResultSet rs)
+            throws DataSetException, SQLException
+    {
+        for (int i = 1; i <= size(); i++)
+        {
+            Value val = new Value(rs, i, schema().column(i).typeEnum());
+            this.values[i] = val;
+        }
+    }
+
+    /**
+     * Saves the data in this Record to the database. Uses the parent dataset's connection.
+     *
+     * @return 1 if the save completed. 0 otherwise.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    public int save()
+            throws DataSetException, SQLException
+    {
+        return save(dataset().connection());
+    }
+
+    /**
+     * Saves the data in this Record to the database. Uses the connection passed into it.
+     *
+     * @param connection TODO: DOCUMENT ME!
+     *
+     * @return 1 if the save completed. 0 otherwise.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    public int save(Connection connection)
+            throws DataSetException, SQLException
+    {
+        int returnValue = 0;
+
+        if (dataset() instanceof QueryDataSet)
+        {
+            throw new DataSetException("You cannot save a QueryDataSet. Please use a TableDataSet instead.");
+        }
+
+        if (!needsToBeSaved())
+        {
+            return returnValue;
+        }
+
+        if (toBeSavedWithInsert())
+        {
+            returnValue = saveWithInsert(connection);
+        }
+        else if (toBeSavedWithUpdate())
+        {
+            returnValue = saveWithUpdate(connection);
+        }
+        else if (toBeSavedWithDelete())
+        {
+            returnValue = saveWithDelete(connection);
+        }
+
+        return returnValue;
+    }
+
+    /**
+     * Saves the data in this Record to the database with an DELETE statement
+     *
+     * @param connection TODO: DOCUMENT ME!
+     *
+     * @return SQL DELETE statement
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    private int saveWithDelete(Connection connection)
+            throws DataSetException, SQLException
+    {
+        PreparedStatement stmt = null;
+
+        try
+        {
+            stmt = connection.prepareStatement(getSaveString());
+
+            int ps = 1;
+
+            for (int i = 1; i <= dataset().keydef().size(); i++)
+            {
+                Value val = getValue(dataset().keydef().getAttrib(i));
+
+                val.setPreparedStatementValue(stmt, ps++);
+            }
+
+            int ret = stmt.executeUpdate();
+
+            // note that the actual deletion of the Record objects
+            // from the TDS is now in the save() method of the TDS
+            // instead of here. This fixes a bug where multiple
+            // records would not be deleted properly because they
+            // were being removed from here and the Records Vector
+            // was getting out of sync with reality. So, just
+            // mark them as needing to be removed here.
+            setSaveType(Enums.ZOMBIE);
+
+            if (ret > 1)
+            {
+                throw new SQLException("There were " + ret + " rows deleted with this records key value.");
+            }
+
+            return ret;
+        }
+        catch (SQLException e1)
+        {
+            throw e1;
+        }
+        finally
+        {
+            try
+            {
+                if (stmt != null)
+                {
+                    stmt.close();
+                }
+            }
+            catch (SQLException e2)
+            {
+                throw e2;
+            }
+        }
+    }
+
+    /**
+     * Saves the data in this Record to the database with an UPDATE statement
+     *
+     * @param connection TODO: DOCUMENT ME!
+     *
+     * @return SQL UPDATE statement
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    private int saveWithUpdate(Connection connection)
+            throws DataSetException, SQLException
+    {
+        PreparedStatement stmt = null;
+
+        try
+        {
+            stmt = connection.prepareStatement(getSaveString());
+
+            int ps = 1;
+
+            for (int i = 1; i <= size(); i++)
+            {
+                Value val = getValue(i);
+
+                if (!valueIsClean(i) && !schema().column(i).readOnly())
+                {
+                    val.setPreparedStatementValue(stmt, ps++);
+                }
+            }
+
+            for (int i = 1; i <= dataset().keydef().size(); i++)
+            {
+                Value val = getValue(dataset().keydef().getAttrib(i));
+
+                val.setPreparedStatementValue(stmt, ps++);
+            }
+
+            int ret = stmt.executeUpdate();
+
+            if (((TableDataSet) dataset()).refreshOnSave())
+            {
+                refresh(dataset().connection());
+            }
+            else
+            {
+                // Marks all of the values clean since they have now been saved
+                markRecordClean();
+            }
+
+            setSaveType(Enums.AFTERUPDATE);
+
+            if (ret > 1)
+            {
+                throw new SQLException("There were " + ret + " rows updated with this records key value.");
+            }
+
+            return ret;
+        }
+        catch (SQLException e1)
+        {
+            throw e1;
+        }
+        finally
+        {
+            try
+            {
+                if (stmt != null)
+                {
+                    stmt.close();
+                }
+            }
+            catch (SQLException e2)
+            {
+                throw e2;
+            }
+        }
+    }
+
+    /**
+     * Saves the data in this Record to the database with an INSERT statement
+     *
+     * @param connection TODO: DOCUMENT ME!
+     *
+     * @return SQL INSERT statement
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     * @throws SQLException TODO: DOCUMENT ME!
+     */
+    private int saveWithInsert(Connection connection)
+            throws DataSetException, SQLException
+    {
+        PreparedStatement stmt = null;
+
+        try
+        {
+            stmt = connection.prepareStatement(getSaveString());
+
+            int ps = 1;
+
+            for (int i = 1; i <= size(); i++)
+            {
+                Value val = getValue(i);
+
+                if (!valueIsClean(i) && !schema().column(i).readOnly())
+                {
+                    val.setPreparedStatementValue(stmt, ps++);
+                }
+            }
+
+            int ret = stmt.executeUpdate();
+
+            if (((TableDataSet) dataset()).refreshOnSave())
+            {
+                refresh(dataset().connection());
+            }
+            else
+            {
+                // Marks all of the values clean since they have now been saved
+                markRecordClean();
+            }
+
+            setSaveType(Enums.AFTERINSERT);
+
+            if (ret > 1)
+            {
+                throw new SQLException("There were " + ret + " rows inserted with this records key value.");
+            }
+
+            return ret;
+        }
+        catch (SQLException e1)
+        {
+            throw e1;
+        }
+        finally
+        {
+            try
+            {
+                if (stmt != null)
+                {
+                    stmt.close();
+                }
+            }
+            catch (SQLException e2)
+            {
+                throw e2;
+            }
+        }
+    }
+
+    /**
+     * Builds the SQL UPDATE statement for this Record
+     *
+     * @return SQL UPDATE statement
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    private String getUpdateSaveString()
+            throws DataSetException
+    {
+        KeyDef kd = dataset().keydef();
+
+        if ((kd == null) || (kd.size() == 0))
+        {
+            throw new DataSetException(
+                "You must specify KeyDef attributes for this TableDataSet in order to create a Record for update.");
+        }
+        else if (recordIsClean())
+        {
+            throw new DataSetException("You must Record.setValue() on a column before doing an update.");
+        }
+
+        StringBuffer iss1 = new StringBuffer(256);
+        StringBuffer iss2 = new StringBuffer(256);
+        boolean comma = false;
+
+        for (int i = 1; i <= size(); i++)
+        {
+            if (!valueIsClean(i) && !schema().column(i).readOnly())
+            {
+                if (!comma)
+                {
+                    iss1.append(schema().column(i).name());
+                    iss1.append(" = ?");
+                    comma = true;
+                }
+                else
+                {
+                    iss1.append(", ");
+                    iss1.append(schema().column(i).name());
+                    iss1.append(" = ?");
+                }
+            }
+        }
+
+        comma = false;
+
+        for (int i = 1; i <= kd.size(); i++)
+        {
+            String attrib = kd.getAttrib(i);
+
+            if (!valueIsClean(schema().index(attrib)))
+            {
+                throw new DataSetException("The value for column '" + attrib + "' is a key value and cannot be updated.");
+            }
+
+            if (!comma)
+            {
+                iss2.append(attrib);
+                iss2.append(" = ?");
+                comma = true;
+            }
+            else
+            {
+                iss2.append(" AND ");
+                iss2.append(attrib);
+                iss2.append(" = ?");
+            }
+        }
+
+        return "UPDATE " + schema().tableName() + " SET " + iss1.toString() + " WHERE " + iss2.toString();
+    }
+
+    /**
+     * Builds the SQL DELETE statement for this Record
+     *
+     * @return SQL DELETE statement
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    private String getDeleteSaveString()
+            throws DataSetException
+    {
+        KeyDef kd = dataset().keydef();
+
+        if ((kd == null) || (kd.size() == 0))
+        {
+            throw new DataSetException("You must specify KeyDef attributes for this TableDataSet in order to delete a Record.");
+        }
+
+        StringBuffer iss1 = new StringBuffer(256);
+
+        boolean comma = false;
+
+        for (int i = 1; i <= kd.size(); i++)
+        {
+            if (!comma)
+            {
+                iss1.append(kd.getAttrib(i));
+                iss1.append(" = ?");
+                comma = true;
+            }
+            else
+            {
+                iss1.append(" AND ");
+                iss1.append(kd.getAttrib(i));
+                iss1.append(" = ? ");
+            }
+        }
+
+        return "DELETE FROM " + schema().tableName() + " WHERE " + iss1.toString();
+    }
+
+    /**
+     * Builds the SQL INSERT statement for this Record
+     *
+     * @return SQL INSERT statement
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    private String getInsertSaveString()
+            throws DataSetException
+    {
+        StringBuffer iss1 = new StringBuffer(256);
+        StringBuffer iss2 = new StringBuffer(256);
+
+        boolean comma = false;
+
+        for (int i = 1; i <= size(); i++)
+        {
+            if (!valueIsClean(i) && !schema().column(i).readOnly())
+            {
+                if (!comma)
+                {
+                    iss1.append(schema().column(i).name());
+                    iss2.append("?");
+                    comma = true;
+                }
+                else
+                {
+                    iss1.append(", " + schema().column(i).name());
+                    iss2.append(", ?");
+                }
+            }
+        }
+
+        return "INSERT INTO " + schema().tableName() + " ( " + iss1.toString() + " ) VALUES ( " + iss2.toString() + " )";
+    }
+
+    /*
+     *       private Hashtable getAffectedColumns()
+     *         throws DataSetException
+     *       {
+     *               Hashtable affectedColumns = new Hashtable ( size() );
+     *               for ( int i = 1; i <= size(); i++ )
+     *         {
+     *           if ( valueIsClean(i) == false )
+     *             affectedColumns.put ( (Object) new Integer(i) , (Object) schema().getColumns()[i].name() );
+     *         }
+     *               return affectedColumns;
+     *       }
+     */
+
+    /**
+     * Gets the appropriate SQL string for this record.
+     *
+     * @return SQL string
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public String getSaveString()
+            throws DataSetException
+    {
+        if (toBeSavedWithInsert())
+        {
+            return getInsertSaveString();
+        }
+        else if (toBeSavedWithUpdate())
+        {
+            return getUpdateSaveString();
+        }
+        else if (toBeSavedWithDelete())
+        {
+            return getDeleteSaveString();
+        }
+        else
+        {
+            throw new DataSetException("Not able to return save string: " + this.saveType);
+        }
+    }
+
+    /**
+     * gets the value at index i
+     *
+     * @param i TODO: DOCUMENT ME!
+     *
+     * @return the Value object at index i
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Value getValue(int i)
+            throws DataSetException
+    {
+        if (i == 0)
+        {
+            throw new DataSetException("Values are 1 based!");
+        }
+        else if (i > size())
+        {
+            throw new DataSetException("Only " + size() + " columns exist!");
+        }
+        else if (values[i] == null)
+        {
+            throw new DataSetException("No values for the requested column!");
+        }
+
+        return values[i];
+    }
+
+    /**
+     * TODO: DOCUMENT ME!
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Value getValue(String columnName)
+            throws DataSetException
+    {
+        return getValue(schema().index(columnName));
+    }
+
+    /**
+     * the number of columns in this object
+     *
+     * @return the number of columns in this object
+     */
+    public int size()
+    {
+        return numberOfColumns;
+    }
+
+    /**
+     * whether or not this Record is to be saved with an SQL insert statement
+     *
+     * @return true if saved with insert
+     */
+    public boolean toBeSavedWithInsert()
+    {
+        return (this.saveType == Enums.INSERT) ? true : false;
+    }
+
+    /**
+     * whether or not this Record is to be saved with an SQL update statement
+     *
+     * @return true if saved with update
+     */
+    public boolean toBeSavedWithUpdate()
+    {
+        return (this.saveType == Enums.UPDATE) ? true : false;
+    }
+
+    /**
+     * whether or not this Record is to be saved with an SQL delete statement
+     *
+     * @return true if saved with delete
+     */
+    public boolean toBeSavedWithDelete()
+    {
+        return (this.saveType == Enums.DELETE) ? true : false;
+    }
+
+    /**
+     * Marks all the values in this record as clean.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markRecordClean()
+            throws DataSetException
+    {
+        for (int i = 1; i <= size(); i++)
+        {
+            markValueClean(i);
+        }
+    }
+
+    /**
+     * Marks this record to be inserted when a save is executed.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markForInsert()
+            throws DataSetException
+    {
+        if (dataset() instanceof QueryDataSet)
+        {
+            throw new DataSetException("You cannot mark a record in a QueryDataSet for insert");
+        }
+
+        setSaveType(Enums.INSERT);
+    }
+
+    /**
+     * Marks this record to be updated when a save is executed.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markForUpdate()
+            throws DataSetException
+    {
+        if (dataset() instanceof QueryDataSet)
+        {
+            throw new DataSetException("You cannot mark a record in a QueryDataSet for update");
+        }
+
+        setSaveType(Enums.UPDATE);
+    }
+
+    /**
+     * Marks this record to be deleted when a save is executed.
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record markToBeDeleted()
+            throws DataSetException
+    {
+        if (dataset() instanceof QueryDataSet)
+        {
+            throw new DataSetException("You cannot mark a record in a QueryDataSet for deletion");
+        }
+
+        setSaveType(Enums.DELETE);
+
+        return this;
+    }
+
+    /**
+     * Unmarks a record that has been marked for deletion.
+     *
+     * <P>
+     * WARNING: You must reset the save type before trying to save this record again.
+     * </p>
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     *
+     * @see #markForUpdate()
+     * @see #markForInsert()
+     * @see #markToBeDeleted()
+     */
+    public Record unmarkToBeDeleted()
+            throws DataSetException
+    {
+        if (this.saveType == Enums.ZOMBIE)
+        {
+            throw new DataSetException("This record has already been deleted!");
+        }
+
+        setSaveType(Enums.UNKNOWN);
+
+        return this;
+    }
+
+    /**
+     * marks a value at a given position as clean.
+     *
+     * @param pos TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markValueClean(int pos)
+            throws DataSetException
+    {
+        if (pos == 0)
+        {
+            throw new DataSetException("Value position must be greater than 0.");
+        }
+        else if (pos > size())
+        {
+            throw new DataSetException("Value position is greater than number of values.");
+        }
+
+        this.isClean[pos] = true;
+    }
+
+    /**
+     * marks a value with a given column name as clean.
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markValueClean(String columnName)
+            throws DataSetException
+    {
+        markValueClean(schema().index(columnName));
+    }
+
+    /**
+     * marks a value at a given position as dirty.
+     *
+     * @param pos TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markValueDirty(int pos)
+            throws DataSetException
+    {
+        if (pos == 0)
+        {
+            throw new DataSetException("Value position must be greater than 0.");
+        }
+        else if (pos > size())
+        {
+            throw new DataSetException("Value position is greater than number of values.");
+        }
+
+        this.isClean[pos] = false;
+    }
+
+    /**
+     * marks a value with a given column name as dirty.
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void markValueDirty(String columnName)
+            throws DataSetException
+    {
+        markValueDirty(schema().index(columnName));
+    }
+
+    /**
+     * sets the internal save type as one of the defined privates (ie: ZOMBIE)
+     *
+     * @param type TODO: DOCUMENT ME!
+     */
+    void setSaveType(int type)
+    {
+        this.saveType = type;
+    }
+
+    /**
+     * gets the internal save type as one of the defined privates (ie: ZOMBIE)
+     *
+     * @return TODO: DOCUMENT ME!
+     */
+    int getSaveType()
+    {
+        return this.saveType;
+    }
+
+    /**
+     * sets the value at pos with a BigDecimal
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, BigDecimal value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a boolean
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, boolean value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(new Boolean(value));
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a byte[]
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, byte [] value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a java.util.Date
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, java.util.Date value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a java.sql.Date
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, java.sql.Date value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a double
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, double value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(new Double(value));
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a float
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, float value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(new Float(value));
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a int
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, int value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(new Integer(value));
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a long
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, long value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(new Long(value));
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a String
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, String value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a java.sql.Time
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, java.sql.Time value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a java.sql.Timestamp
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, java.sql.Timestamp value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a Value
+     *
+     * @param pos TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(int pos, Value value)
+            throws DataSetException
+    {
+        this.values[pos].setValue(value.getValue());
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a BigDecimal
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, BigDecimal value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a boolean
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, boolean value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a byte[]
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, byte [] value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a java.util.Date
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, java.util.Date value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a java.sql.Date
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, java.sql.Date value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a double
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, double value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a float
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, float value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a int
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, int value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a long
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, long value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a String
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, String value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a java.sql.Time
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, java.sql.Time value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a java.sql.Timestamp
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, java.sql.Timestamp value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a Value
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     * @param value TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValue(String columnName, Value value)
+            throws DataSetException
+    {
+        setValue(schema().index(columnName), value);
+
+        return this;
+    }
+
+    /**
+     * sets the value at pos with a NULL
+     *
+     * @param pos TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValueNull(int pos)
+            throws DataSetException
+    {
+        if (pos == 0)
+        {
+            throw new DataSetException("Value position must be greater than 0.");
+        }
+        else if (pos > size())
+        {
+            throw new DataSetException("Value position is greater than number of values.");
+        }
+
+        this.values[pos].setValue(null);
+        markValueDirty(pos);
+
+        return this;
+    }
+
+    /**
+     * sets the value at column name with a NULL
+     *
+     * @param columnName TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Record setValueNull(String columnName)
+            throws DataSetException
+    {
+        if ((columnName == null) || (columnName.length() == 0))
+        {
+            throw new DataSetException("You must specify a column name!");
+        }
+
+        setValueNull(schema().index(columnName));
+
+        return this;
+    }
+
+    /**
+     * Determines if this record is a Zombie. A Zombie is a record that has been deleted from the database, but not yet removed
+     * from the DataSet.
+     *
+     * @return a boolean
+     */
+    public boolean isAZombie()
+    {
+        return (this.saveType == Enums.ZOMBIE) ? true : false;
+    }
+
+    /**
+     * If the record is not clean, needs to be saved with an Update, Delete or Insert, it returns true.
+     *
+     * @return boolean
+     */
+    public boolean needsToBeSaved()
+    {
+        return !isAZombie() || !recordIsClean() || toBeSavedWithUpdate() || toBeSavedWithDelete() || toBeSavedWithInsert();
+    }
+
+    /**
+     * Determines whether or not a value stored in the record is clean.
+     *
+     * @param i TODO: DOCUMENT ME!
+     *
+     * @return true if clean
+     */
+    public boolean valueIsClean(int i)
+    {
+        return isClean[i];
+    }
+
+    /**
+     * Determines whether or not a value stored in the record is clean.
+     *
+     * @param column TODO: DOCUMENT ME!
+     *
+     * @return true if clean
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    boolean valueIsClean(String column)
+            throws DataSetException
+    {
+        return isClean[getValue(column).columnNumber()];
+    }
+
+    /**
+     * Goes through all the values in the record to determine if it is clean or not.
+     *
+     * @return true if clean
+     */
+    public boolean recordIsClean()
+    {
+        for (int i = 1; i <= size(); i++)
+        {
+            if (!valueIsClean(i))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * This method refreshes this Record's Value's. It can only be performed on a Record that has not been modified and has been
+     * created with a TableDataSet and corresponding KeyDef.
+     *
+     * @param connection
+     *
+     * @exception DataSetException
+     * @exception SQLException
+     */
+    public void refresh(Connection connection)
+            throws DataSetException, SQLException
+    {
+        if (toBeSavedWithDelete())
+        {
+            return;
+        }
+        else if (toBeSavedWithInsert())
+        {
+            throw new DataSetException("There is no way to refresh a record which has been created with addRecord().");
+        }
+        else if (dataset() instanceof QueryDataSet)
+        {
+            throw new DataSetException("You can only perform a refresh on Records created with a TableDataSet.");
+        }
+
+        PreparedStatement stmt = null;
+
+        try
+        {
+            stmt = connection.prepareStatement(getRefreshQueryString());
+
+            int ps = 1;
+
+            for (int i = 1; i <= dataset().keydef().size(); i++)
+            {
+                Value val = getValue(dataset().keydef().getAttrib(i));
+
+                if (val.isNull())
+                {
+                    throw new DataSetException("You cannot execute an update with a null value for a KeyDef.");
+                }
+
+                val.setPreparedStatementValue(stmt, ps++);
+            }
+
+            ResultSet rs = stmt.executeQuery();
+            rs.next();
+
+            initializeRecord();
+
+            createValues(rs);
+        }
+        catch (SQLException e1)
+        {
+            throw e1;
+        }
+        finally
+        {
+            try
+            {
+                if (stmt != null)
+                {
+                    stmt.close();
+                }
+            }
+            catch (SQLException e2)
+            {
+                throw e2;
+            }
+        }
+    }
+
+    /**
+     * This builds the SELECT statement in order to refresh the contents of this Record. It depends on a valid KeyDef to exist and
+     * it must have been created with a TableDataSet.
+     *
+     * @return the SELECT string
+     *
+     * @exception DataSetException
+     */
+    public String getRefreshQueryString()
+            throws DataSetException
+    {
+        if ((dataset().keydef() == null) || (dataset().keydef().size() == 0))
+        {
+            throw new DataSetException(
+                "You can only perform a getRefreshQueryString on a TableDataSet that was created with a KeyDef.");
+        }
+        else if (dataset() instanceof QueryDataSet)
+        {
+            throw new DataSetException("You can only perform a getRefreshQueryString on Records created with a TableDataSet.");
+        }
+
+        StringBuffer iss1 = new StringBuffer(256);
+        StringBuffer iss2 = new StringBuffer(256);
+        boolean comma = false;
+
+        for (int i = 1; i <= size(); i++)
+        {
+            if (!comma)
+            {
+                iss1.append(schema().column(i).name());
+                comma = true;
+            }
+            else
+            {
+                iss1.append(", ");
+                iss1.append(schema().column(i).name());
+            }
+        }
+
+        comma = false;
+
+        for (int i = 1; i <= dataset().keydef().size(); i++)
+        {
+            String attrib = dataset().keydef().getAttrib(i);
+
+            if (!valueIsClean(attrib))
+            {
+                throw new DataSetException("You cannot do a refresh from the database if the value "
+                    + "for a KeyDef column has been changed with a Record.setValue().");
+            }
+
+            if (!comma)
+            {
+                iss2.append(attrib);
+                iss2.append(" = ?");
+                comma = true;
+            }
+            else
+            {
+                iss2.append(" AND ");
+                iss2.append(attrib);
+                iss2.append(" = ?");
+            }
+        }
+
+        return "SELECT " + iss1.toString() + " FROM " + schema().tableName() + " WHERE " + iss2.toString();
+    }
+
+    /**
+     * TODO: DOCUMENT ME!
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void saveWithoutStatusUpdate()
+            throws DataSetException
+    {
+        throw new DataSetException("Record.saveWithoutStatusUpdate() is not yet implemented.");
+    }
+
+    /**
+     * Gets the schema for the parent DataSet
+     *
+     * @return the schema for the parent DataSet
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public Schema schema()
+            throws DataSetException
+    {
+        if (dataset() != null)
+        {
+            return this.schema;
+        }
+        else
+        {
+            throw new DataSetException("Internal Error: Record DataSet is null");
+        }
+    }
+
+    /**
+     * Gets the DataSet for this Record
+     *
+     * @return the DataSet for this Record
+     */
+    public DataSet dataset()
+    {
+        return this.parentDataSet;
+    }
+
+    /**
+     * Sets the parent DataSet for this record.
+     *
+     * @param ds TODO: DOCUMENT ME!
+     */
+    void setParentDataSet(DataSet ds)
+    {
+        this.parentDataSet = ds;
+    }
+
+    /**
+     * return the value of each column as a string. Not yet implemented!
+     *
+     * @param valueseparator
+     * @param maxwidths
+     *
+     * @return the formatted string
+     *
+     * @exception DataSetException
+     */
+    public String asFormattedString(String valueseparator, int [] maxwidths)
+            throws DataSetException
+    {
+        throw new DataSetException("Not yet implemented!");
+    }
+
+    /**
+     * This returns a representation of this Record
+     *
+     * @return java.lang.String
+     */
+    public String toString()
+    {
+        try
+        {
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            PrintWriter out = new PrintWriter(bout);
+            out.print("{");
+
+            for (int i = 1; i <= size(); i++)
+            {
+                out.print("'" + getValue(i).asString() + "'");
+
+                if (i < size())
+                {
+                    out.print(',');
+                }
+            }
+
+            out.print("}");
+            out.flush();
+
+            return bout.toString();
+        }
+        catch (DataSetException e)
+        {
+            return "";
+        }
+    }
+}

Added: db/torque/village/trunk/src/java/com/workingdogs/village/Schema.java
URL: http://svn.apache.org/viewvc/db/torque/village/trunk/src/java/com/workingdogs/village/Schema.java?rev=590654&view=auto
==============================================================================
--- db/torque/village/trunk/src/java/com/workingdogs/village/Schema.java (added)
+++ db/torque/village/trunk/src/java/com/workingdogs/village/Schema.java Wed Oct 31 05:50:45 2007
@@ -0,0 +1,529 @@
+package com.workingdogs.village;
+
+/*
+ * 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.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * The Schema object represents the <a href="Column.html">Columns</a> in a database table. It contains a collection of <a
+ * href="Column.html">Column</a> objects.
+ *
+ * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
+ * @author John D. McNally
+ * @version $Revision: 568 $
+ */
+public final class Schema
+{
+    /** TODO: DOCUMENT ME! */
+    private String tableName;
+
+    /** TODO: DOCUMENT ME! */
+    private String columnsAttribute;
+
+    /** TODO: DOCUMENT ME! */
+    private int numberOfColumns;
+
+    /** TODO: DOCUMENT ME! */
+    private Column [] columns;
+
+    /** TODO: DOCUMENT ME! */
+    private static Hashtable schemaCache = new Hashtable();
+
+    /**
+     * This attribute is used to complement columns in the event that this schema represents more than one table.  Its keys are
+     * String contains table names and its elements are Hashtables containing columns.
+     */
+    private Hashtable tableHash = null;
+
+    /** TODO: DOCUMENT ME! */
+    private boolean singleTable = true;
+
+    /**
+     * A blank Schema object
+     */
+    public Schema()
+    {
+        this.tableName = "";
+        this.columnsAttribute = null;
+        this.numberOfColumns = 0;
+    }
+
+    /**
+     * Creates a Schema with all columns
+     *
+     * @param conn
+     * @param tableName
+     *
+     * @return an instance of myself
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public Schema schema(Connection conn, String tableName)
+            throws SQLException, DataSetException
+    {
+        return schema(conn, tableName, "*");
+    }
+
+    /**
+     * Creates a Schema with the named columns in the columnsAttribute
+     *
+     * @param conn
+     * @param tableName
+     * @param columnsAttribute
+     *
+     * @return an instance of myself
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public synchronized Schema schema(Connection conn, String tableName, String columnsAttribute)
+            throws SQLException, DataSetException
+    {
+        if (columnsAttribute == null)
+        {
+            columnsAttribute = "*";
+        }
+
+        Statement stmt = null;
+
+        try
+        {
+            String keyValue = conn.getMetaData().getURL() + tableName;
+            Schema tableSchema = (Schema) schemaCache.get(keyValue);
+
+            if (tableSchema == null)
+            {
+                String sql = "SELECT " + columnsAttribute + " FROM " + tableName + " WHERE 1 = -1";
+                stmt = conn.createStatement();
+
+                ResultSet rs = stmt.executeQuery(sql);
+
+                if (rs != null)
+                {
+                    tableSchema = new Schema();
+                    tableSchema.setTableName(tableName);
+                    tableSchema.setAttributes(columnsAttribute);
+                    tableSchema.populate(rs.getMetaData(), tableName);
+                    schemaCache.put(keyValue, tableSchema);
+                }
+                else
+                {
+                    throw new DataSetException("Couldn't retrieve schema for " + tableName);
+                }
+            }
+
+            return tableSchema;
+        }
+        finally
+        {
+            if (stmt != null)
+            {
+                stmt.close();
+            }
+        }
+    }
+
+    /**
+     * Appends data to the tableName that this schema was first created with.
+     *
+     * <P></p>
+     *
+     * @param app String to append to tableName
+     *
+     * @see TableDataSet#tableQualifier(java.lang.String)
+     */
+    void appendTableName(String app)
+    {
+        this.tableName = this.tableName + " " + app;
+    }
+
+    /**
+     * List of columns to select from the table
+     *
+     * @return the list of columns to select from the table
+     */
+    public String attributes()
+    {
+        return this.columnsAttribute;
+    }
+
+    /**
+     * Returns the requested Column object at index i
+     *
+     * @param i
+     *
+     * @return the requested column
+     *
+     * @exception DataSetException
+     */
+    public Column column(int i)
+            throws DataSetException
+    {
+        if (i == 0)
+        {
+            throw new DataSetException("Columns are 1 based");
+        }
+        else if (i > numberOfColumns)
+        {
+            throw new DataSetException("There are only " + numberOfColumns() + " available!");
+        }
+
+        try
+        {
+            return columns[i];
+        }
+        catch (Exception e)
+        {
+            throw new DataSetException("Column number: " + numberOfColumns() + " does not exist!");
+        }
+    }
+
+    /**
+     * Returns the requested Column object by name
+     *
+     * @param colName
+     *
+     * @return the requested column
+     *
+     * @exception DataSetException
+     */
+    public Column column(String colName)
+            throws DataSetException
+    {
+        return column(index(colName));
+    }
+
+    /**
+     * Returns the requested Column object by name
+     *
+     * @param colName
+     *
+     * @return the requested column
+     *
+     * @exception DataSetException
+     */
+    public Column getColumn(String colName)
+            throws DataSetException
+    {
+        int dot = colName.indexOf('.');
+
+        if (dot > 0)
+        {
+            String table = colName.substring(0, dot);
+            String col = colName.substring(dot + 1);
+
+            return getColumn(table, col);
+        }
+
+        return column(index(colName));
+    }
+
+    /**
+     * Returns the requested Column object belonging to the specified table by name
+     *
+     * @param tableName
+     * @param colName
+     *
+     * @return the requested column, null if a column by the specified name does not exist.
+     *
+     * @exception DataSetException
+     */
+    public Column getColumn(String tableName, String colName)
+            throws DataSetException
+    {
+        return (Column) ((Hashtable) tableHash.get(tableName)).get(colName);
+    }
+
+    /**
+     * Returns an array of columns
+     *
+     * @return an array of columns
+     */
+    Column [] getColumns()
+    {
+        return this.columns;
+    }
+
+    /**
+     * returns the table name that this Schema represents
+     *
+     * @return the table name that this Schema represents
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public String getTableName()
+            throws DataSetException
+    {
+        if (singleTable)
+        {
+            return tableName;
+        }
+        else
+        {
+            throw new DataSetException("This schema represents several tables.");
+        }
+    }
+
+    /**
+     * returns all table names that this Schema represents
+     *
+     * @return the table names that this Schema represents
+     */
+    public String [] getAllTableNames()
+    {
+        Enumeration e = tableHash.keys();
+        String [] tableNames = new String[tableHash.size()];
+
+        for (int i = 0; e.hasMoreElements(); i++)
+        {
+            tableNames[i] = (String) e.nextElement();
+        }
+
+        return tableNames;
+    }
+
+    /**
+     * Gets the index position of a named column.  If multiple tables are represented and they have columns with the same name,
+     * this method returns the first one listed, if the table name is not specified.
+     *
+     * @param colName
+     *
+     * @return the requested column index integer
+     *
+     * @exception DataSetException
+     */
+    public int index(String colName)
+            throws DataSetException
+    {
+        int dot = colName.indexOf('.');
+
+        if (dot > 0)
+        {
+            String table = colName.substring(0, dot);
+            String col = colName.substring(dot + 1);
+
+            return index(table, col);
+        }
+
+        for (int i = 1; i <= numberOfColumns(); i++)
+        {
+            if (columns[i].name().equalsIgnoreCase(colName))
+            {
+                return i;
+            }
+        }
+
+        throw new DataSetException("Column name: " + colName + " does not exist!");
+    }
+
+    /**
+     * Gets the index position of a named column.
+     *
+     * @param tableName
+     * @param colName
+     *
+     * @return the requested column index integer
+     *
+     * @exception DataSetException
+     */
+    public int index(String tableName, String colName)
+            throws DataSetException
+    {
+        for (int i = 1; i <= numberOfColumns(); i++)
+        {
+            if (columns[i].name().equalsIgnoreCase(colName) && columns[i].getTableName().equalsIgnoreCase(tableName))
+            {
+                return i;
+            }
+        }
+
+        throw new DataSetException("Column name: " + colName + " does not exist!");
+    }
+
+    /**
+     * Checks to see if this DataSet represents one table in the database.
+     *
+     * @return true if only one table is represented, false otherwise.
+     */
+    public boolean isSingleTable()
+    {
+        return singleTable;
+    }
+
+    /**
+     * Gets the number of columns in this Schema
+     *
+     * @return integer number of columns
+     */
+    public int numberOfColumns()
+    {
+        return this.numberOfColumns;
+    }
+
+    /**
+     * Internal method which populates this Schema object with Columns.
+     *
+     * @param meta The meta data of the ResultSet used to build this Schema.
+     * @param tableName The name of the table referenced in this schema, or null if unknown or multiple tables are involved.
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    void populate(ResultSetMetaData meta, String tableName)
+            throws SQLException, DataSetException
+    {
+        this.numberOfColumns = meta.getColumnCount();
+        columns = new Column[numberOfColumns() + 1];
+
+        for (int i = 1; i <= numberOfColumns(); i++)
+        {
+            Column col = new Column();
+            col.populate(meta, i, tableName);
+            columns[i] = col;
+
+            if ((i > 1) && !col.getTableName().equalsIgnoreCase(columns[i - 1].getTableName()))
+            {
+                singleTable = false;
+            }
+        }
+
+        // Avoid creating a Hashtable in the most common case where only one
+        // table is involved, even though this makes the multiple table case
+        // more expensive because the table/column info is duplicated.
+        if (singleTable)
+        {
+            // If available, use a the caller supplied table name.
+            if ((tableName != null) && (tableName.length() > 0))
+            {
+                setTableName(tableName);
+            }
+            else
+            {
+                // Since there's only one table involved, attempt to set the
+                // table name to that of the first column.  Sybase jConnect
+                // 5.2 and older will fail, in which case we are screwed.
+                try
+                {
+                    setTableName(meta.getTableName(1));
+                }
+                catch (Exception e)
+                {
+                    setTableName("");
+                }
+            }
+        }
+        else
+        {
+            tableHash = new Hashtable((int) ((1.25 * numberOfColumns) + 1));
+
+            for (int i = 1; i <= numberOfColumns(); i++)
+            {
+                if (tableHash.containsKey(columns[i].getTableName()))
+                {
+                    ((Hashtable) tableHash.get(columns[i].getTableName())).put(columns[i].name(), columns[i]);
+                }
+                else
+                {
+                    Hashtable columnHash = new Hashtable((int) ((1.25 * numberOfColumns) + 1));
+                    columnHash.put(columns[i].name(), columns[i]);
+                    tableHash.put(columns[i].getTableName(), columnHash);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the columns to select from the table
+     *
+     * @param attributes comma separated list of column names
+     */
+    void setAttributes(String attributes)
+    {
+        this.columnsAttribute = attributes;
+    }
+
+    /**
+     * Sets the table name that this Schema represents
+     *
+     * @param tableName
+     */
+    void setTableName(String tableName)
+    {
+        this.tableName = tableName;
+    }
+
+    /**
+     * returns the table name that this Schema represents
+     *
+     * @return the table name that this Schema represents
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public String tableName()
+            throws DataSetException
+    {
+        return getTableName();
+    }
+
+    /**
+     * This returns a representation of this Schema
+     *
+     * @return a string
+     */
+    public String toString()
+    {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        PrintWriter out = new PrintWriter(bout);
+        out.print('{');
+
+        for (int i = 1; i <= numberOfColumns; i++)
+        {
+            out.print('\'');
+
+            if (!singleTable)
+            {
+                out.print(columns[i].getTableName() + '.');
+            }
+
+            out.print(columns[i].name() + '\'');
+
+            if (i < numberOfColumns)
+            {
+                out.print(',');
+            }
+        }
+
+        out.print('}');
+        out.flush();
+
+        return bout.toString();
+    }
+}

Added: db/torque/village/trunk/src/java/com/workingdogs/village/SelectStmt.java
URL: http://svn.apache.org/viewvc/db/torque/village/trunk/src/java/com/workingdogs/village/SelectStmt.java?rev=590654&view=auto
==============================================================================
--- db/torque/village/trunk/src/java/com/workingdogs/village/SelectStmt.java (added)
+++ db/torque/village/trunk/src/java/com/workingdogs/village/SelectStmt.java Wed Oct 31 05:50:45 2007
@@ -0,0 +1,53 @@
+package com.workingdogs.village;
+
+/*
+ * 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.
+ */
+
+/**
+ * SelectStmt isn't implemented yet.
+ *
+ * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
+ * @version $Revision: 568 $
+ */
+public class SelectStmt
+{
+    /**
+     * SelectStmt isn't implemented yet.
+     *
+     * @exception DataSetException
+     */
+    public SelectStmt()
+            throws DataSetException
+    {
+        throw new DataSetException("Not Yet Implemented!");
+    }
+
+    /**
+     * SelectStmt isn't implemented yet.
+     *
+     * @param dbType TODO: DOCUMENT ME!
+     *
+     * @exception DataSetException
+     */
+    public SelectStmt(int dbType)
+            throws DataSetException
+    {
+        throw new DataSetException("Not Yet Implemented!");
+    }
+}

Added: db/torque/village/trunk/src/java/com/workingdogs/village/TableDataSet.java
URL: http://svn.apache.org/viewvc/db/torque/village/trunk/src/java/com/workingdogs/village/TableDataSet.java?rev=590654&view=auto
==============================================================================
--- db/torque/village/trunk/src/java/com/workingdogs/village/TableDataSet.java (added)
+++ db/torque/village/trunk/src/java/com/workingdogs/village/TableDataSet.java Wed Oct 31 05:50:45 2007
@@ -0,0 +1,632 @@
+package com.workingdogs.village;
+
+/*
+ * 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.
+ */
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import java.util.Enumeration;
+
+/**
+ * This class is used for doing select/insert/delete/update on the database. A TableDataSet cannot be used to join multiple tables
+ * for an update, if you need join functionality on a select, you should use a <a href="QueryDataSet.html">QueryDataSet</a>.
+ *
+ * <P>
+ * Here is an example usage for this code that gets the first 10 records where column "a" = 1:
+ * <PRE>
+ *  KeyDef kd = new KeyDef().setAttrib("column");
+ *  TableDataSet tds = new TableDataSet(connection, "table_name", kd );
+ *  tds.where ("a=1" ); // WHERE a = 1
+ *  tds.fetchRecords(10); // fetch first 10 records where column a=1
+ *  for ( int i=0;i< tds.size(); i++ )
+ *  {
+ *  Record rec = tds.getRecord(i); // zero based
+ *  String columnA = rec.getValue("a");
+ *  if ( columnA.equals ("1") )
+ *  System.out.print ("We got a column!");
+ *  }
+ *  tds.close();
+ *  </PRE>
+ * </p>
+ *
+ * <P>
+ * It is important to remember to always close() the TableDataSet when you are finished with it.
+ * </p>
+ *
+ * <P>
+ * As you can see, using a TableDataSet makes doing selects from the database trivial. You do not need to write any SQL and it
+ * makes it easy to cache a TableDataSet for future use within your application.
+ * </p>
+ *
+ * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
+ * @version $Revision: 568 $
+ */
+public class TableDataSet
+        extends DataSet
+{
+    /** the optimistic locking column value */
+    private String optimisticLockingCol;
+
+    /** the value for the sql where clause */
+    private String where = null;
+
+    /** the value for the sql order by clause */
+    private String order = null;
+
+    /** the value for the sql other clause */
+    private String other = null;
+
+    // by default this is false;
+
+    /** TODO: DOCUMENT ME! */
+    private boolean refreshOnSave = false;
+
+    /**
+     * Default constructor.
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public TableDataSet()
+            throws SQLException, DataSetException
+    {
+        super();
+    }
+
+    /**
+     * Creates a new TableDataSet object.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     * @param tableName TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet(Connection conn, String tableName)
+            throws SQLException, DataSetException
+    {
+        super(conn, tableName);
+    }
+
+    /**
+     * Creates a new TableDataSet object.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     * @param schema TODO: DOCUMENT ME!
+     * @param keydef TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet(Connection conn, Schema schema, KeyDef keydef)
+            throws SQLException, DataSetException
+    {
+        super(conn, schema, keydef);
+    }
+
+    /**
+     * Creates a new TableDataSet object.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     * @param tableName TODO: DOCUMENT ME!
+     * @param keydef TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet(Connection conn, String tableName, KeyDef keydef)
+            throws SQLException, DataSetException
+    {
+        super(conn, tableName, keydef);
+    }
+
+    /**
+     * Creates a new TableDataSet object.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     * @param tableName TODO: DOCUMENT ME!
+     * @param columns TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet(Connection conn, String tableName, String columns)
+            throws SQLException, DataSetException
+    {
+        super(conn, tableName, columns);
+    }
+
+    /**
+     * Creates a new TableDataSet object.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     * @param tableName TODO: DOCUMENT ME!
+     * @param columns TODO: DOCUMENT ME!
+     * @param keydef TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet(Connection conn, String tableName, String columns, KeyDef keydef)
+            throws SQLException, DataSetException
+    {
+        super(conn, tableName, columns, keydef);
+    }
+
+    /**
+     * Use the TDS fetchRecords instead of the DataSet.fetchRecords
+     *
+     * @return an instance of myself
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public DataSet fetchRecords()
+            throws SQLException, DataSetException
+    {
+        return fetchRecords(-1);
+    }
+
+    /**
+     * Use the TDS fetchRecords instead of the DataSet.fetchRecords
+     *
+     * @param max
+     *
+     * @return an instance of myself
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public DataSet fetchRecords(int max)
+            throws SQLException, DataSetException
+    {
+        return fetchRecords(0, max);
+    }
+
+    /**
+     * Fetch start to max records. start is at Record 0
+     *
+     * @param start
+     * @param max
+     *
+     * @return an instance of myself
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public DataSet fetchRecords(int start, int max)
+            throws SQLException, DataSetException
+    {
+        buildSelectString();
+
+        return super.fetchRecords(start, max);
+    }
+
+    /**
+     * this is a string that contains the columns for the table that this TableDataSet represents.
+     *
+     * @return columns separated by ","
+     */
+    public String attributes()
+    {
+        return super.getColumns();
+    }
+
+    /**
+     * Returns the KeyDef for the DataSet
+     *
+     * @return a keydef
+     */
+    public KeyDef keydef()
+    {
+        return super.keydef();
+    }
+
+    /**
+     * Returns the ResultSet for the DataSet
+     *
+     * @return a ResultSet
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public ResultSet resultSet()
+            throws SQLException, DataSetException
+    {
+        return super.resultSet();
+    }
+
+    /**
+     * Returns the Schema for the DataSet
+     *
+     * @return a Schema
+     */
+    public Schema schema()
+    {
+        return super.schema();
+    }
+
+    /**
+     * Saves all the records in the DataSet.
+     *
+     * @return total number of records updated/inserted/deleted
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public int save()
+            throws SQLException, DataSetException
+    {
+        return save(connection(), false);
+    }
+
+    /**
+     * Saves all the records in the DataSet with the intransaction boolean value.
+     *
+     * @param intransaction TODO: DOCUMENT ME!
+     *
+     * @return total number of records updated/inserted/deleted
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public int save(boolean intransaction)
+            throws SQLException, DataSetException
+    {
+        return save(connection(), intransaction);
+    }
+
+    /**
+     * Saves all the records in the DataSet with the given connection and intransaction boolean value.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     * @param intransaction TODO: DOCUMENT ME!
+     *
+     * @return total number of records updated/inserted/deleted
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public int save(Connection conn, boolean intransaction)
+            throws SQLException, DataSetException
+    {
+        int j = 0;
+
+        for (Enumeration e = records.elements(); e.hasMoreElements();)
+        {
+            Record rec = (Record) e.nextElement();
+            rec.save(conn);
+            j++;
+        }
+
+        // now go through and remove any records
+        // that were previously marked as a zombie by the
+        // delete process
+        removeDeletedRecords();
+
+        return j;
+    }
+
+    /**
+     * Not yet implemented
+     *
+     * @param conn TODO: DOCUMENT ME!
+     *
+     * @return TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public int saveWithoutStatusUpdate(Connection conn)
+            throws SQLException, DataSetException
+    {
+        throw new DataSetException("Not yet implemented!");
+    }
+
+    /**
+     * Hell if I know what this does.
+     *
+     * @return TODO: DOCUMENT ME!
+     */
+    public String debugInfo()
+    {
+        return "Not yet implemented!";
+    }
+
+    /**
+     * Removes any records that are marked as a zombie.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void removeDeletedRecords()
+            throws DataSetException
+    {
+        for (Enumeration e = records.elements(); e.hasMoreElements();)
+        {
+            Record rec = (Record) e.nextElement();
+
+            if (rec.isAZombie())
+            {
+                removeRecord(rec);
+            }
+        }
+    }
+
+    /**
+     * Sets the table column used for optomistic locking.
+     *
+     * @param olc TODO: DOCUMENT ME!
+     */
+    public void setOptimisticLockingColumn(String olc)
+    {
+        this.optimisticLockingCol = olc;
+    }
+
+    /**
+     * Gets the table column used for optomistic locking.
+     *
+     * @return string
+     */
+    public String optimisticLockingCol()
+    {
+        return this.optimisticLockingCol;
+    }
+
+    /**
+     * Sets the value for the SQL portion of the WHERE statement
+     *
+     * @param where TODO: DOCUMENT ME!
+     *
+     * @return instance of self
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet where(String where)
+            throws DataSetException
+    {
+        if (where == null)
+        {
+            throw new DataSetException("null not allowed for where clause");
+        }
+
+        this.where = where;
+
+        return this;
+    }
+
+    /**
+     * Gets the value of the SQL portion of WHERE.
+     *
+     * @return string
+     */
+    String getWhere()
+    {
+        return this.where;
+    }
+
+    /**
+     * Sets the value for the SQL portion of the ORDER statement
+     *
+     * @param order TODO: DOCUMENT ME!
+     *
+     * @return instance of self
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet order(String order)
+            throws DataSetException
+    {
+        if (order == null)
+        {
+            throw new DataSetException("null not allowed for order clause");
+        }
+
+        this.order = order;
+
+        return this;
+    }
+
+    /**
+     * Gets the value of the SQL portion of ORDER.
+     *
+     * @return string
+     */
+    String getOrder()
+    {
+        return this.order;
+    }
+
+    /**
+     * Sets the value for the SQL portion of the OTHER statement
+     *
+     * @param other TODO: DOCUMENT ME!
+     *
+     * @return instance of self
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public TableDataSet other(String other)
+            throws DataSetException
+    {
+        if (other == null)
+        {
+            throw new DataSetException("null not allowed for other clause");
+        }
+
+        this.other = other;
+
+        return this;
+    }
+
+    /**
+     * Gets the value of the SQL portion of OTHER.
+     *
+     * @return string
+     */
+    String getOther()
+    {
+        return this.other;
+    }
+
+    /**
+     * This method refreshes all of the Records stored in this TableDataSet.
+     *
+     * @param conn TODO: DOCUMENT ME!
+     *
+     * @throws SQLException TODO: DOCUMENT ME!
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public void refresh(Connection conn)
+            throws SQLException, DataSetException
+    {
+        for (Enumeration e = records.elements(); e.hasMoreElements();)
+        {
+            Record rec = (Record) e.nextElement();
+            rec.refresh(conn);
+        }
+    }
+
+    /**
+     * Setting this causes each Record to refresh itself when a save() is performed on it.
+     *
+     * <P>
+     * Default value is false.
+     * </p>
+     *
+     * @param val TODO: DOCUMENT ME!
+     */
+    public void setRefreshOnSave(boolean val)
+    {
+        this.refreshOnSave = val;
+    }
+
+    /**
+     * Setting this causes each Record to refresh itself when a save() is performed on it.
+     *
+     * <P>
+     * Default value is false.
+     * </p>
+     *
+     * @return true if it is on; false otherwise
+     */
+    public boolean refreshOnSave()
+    {
+        return this.refreshOnSave;
+    }
+
+    /**
+     * This sets additional SQL for the table name. The string appears after the table name. Sybase users would set this to
+     * "HOLDLOCK" to get repeatable reads.
+     *
+     * <P>
+     * FIXME: Is this right? I don't use Sybase.
+     * </p>
+     *
+     * @param tq TODO: DOCUMENT ME!
+     *
+     * @return an instance of self
+     */
+    public TableDataSet tableQualifier(String tq)
+    {
+        // go directly to schema() cause it is where tableName is stored
+        schema().appendTableName(tq);
+
+        return this;
+    }
+
+    /**
+     * The name of the table for which this TableDataSet was created.
+     *
+     * @return string
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public String tableName()
+            throws DataSetException
+    {
+        return super.tableName();
+    }
+
+    /**
+     * Not yet implemented
+     *
+     * @exception SQLException
+     * @exception DataSetException
+     */
+    public void updateStatus()
+            throws SQLException, DataSetException
+    {
+        throw new DataSetException("Not yet implemented!");
+    }
+
+    /**
+     * Builds the select string that was used to populate this TableDataSet.
+     *
+     * @return SQL select string
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    public String getSelectString()
+            throws DataSetException
+    {
+        buildSelectString();
+
+        return this.selectString.toString();
+    }
+
+    /**
+     * Used by getSelectString to build the select string that was used to populate this TableDataSet.
+     *
+     * @throws DataSetException TODO: DOCUMENT ME!
+     */
+    private void buildSelectString()
+            throws DataSetException
+    {
+        if (selectString == null)
+        {
+            selectString = new StringBuffer(256);
+        }
+        else
+        {
+            selectString.setLength(0);
+        }
+
+        selectString.append("SELECT ");
+        selectString.append(schema().attributes());
+        selectString.append(" FROM ");
+        selectString.append(schema().tableName());
+
+        if ((this.where != null) && (this.where.length() > 0))
+        {
+            selectString.append(" WHERE " + this.where);
+        }
+
+        if ((this.order != null) && (this.order.length() > 0))
+        {
+            selectString.append(" ORDER BY " + this.order);
+        }
+
+        if ((this.other != null) && (this.other.length() > 0))
+        {
+            selectString.append(this.other);
+        }
+    }
+}



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


Mime
View raw message