Author: tfischer
Date: Fri Feb 15 00:30:18 2013
New Revision: 1446412

URL: http://svn.apache.org/r1446412
Log:
TORQUE-266      Add row level locking (select for update) 

Modified:
    
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
    
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java
    
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
    
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java

Modified: 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
URL: 
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java?rev=1446412&r1=1446411&r2=1446412&view=diff
==============================================================================
--- 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
 (original)
+++ 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
 Fri Feb 15 00:30:18 2013
@@ -158,6 +158,9 @@ public class Criteria
     /** The having clause in a query. */
     private Criterion having = null;
 
+    /** Whether a FOR UPDATE clause should be added. */
+    private boolean forUpdate = false;
+
     /** The criterion objects, keyed by the column. */
     private Criterion topLevelCriterion;
 
@@ -394,6 +397,41 @@ public class Criteria
     }
 
     /**
+     * Sets that FOR UPDATE clause should be added to the query.
+     *
+     * @return this object.
+     */
+    public Criteria forUpdate()
+    {
+        forUpdate = true;
+        return this;
+    }
+
+    /**
+     * Sets whether FOR UPDATE clause should be added to the query.
+     *
+     * @param forUpdate true if a FOR UPDATE clause should be added,
+     *        false if not.
+     *
+     * @return this object.
+     */
+    public Criteria setForUpdate(boolean forUpdate)
+    {
+        this.forUpdate = forUpdate;
+        return this;
+    }
+
+    /**
+     * Returns whether a FOR UPDATE clause is added.
+     *
+     * @return true if a FOR UPDATE clause is added, false otherwise.
+     */
+    public boolean isForUpdate()
+    {
+        return forUpdate;
+    }
+
+    /**
      * Adds a join to the criteria, E.g. to create the condition
      * <p>
      * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID

Modified: 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java
URL: 
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java?rev=1446412&r1=1446411&r2=1446412&view=diff
==============================================================================
--- 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java
 (original)
+++ 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java
 Fri Feb 15 00:30:18 2013
@@ -83,6 +83,8 @@ public class Query
     private static final String OFFSET = " OFFSET ";
     /** Constant for text " SET ROWCOUNT ". */
     private static final String SET_ROWCOUNT = " SET ROWCOUNT ";
+    /** Constant for text " FOR UPDATE". */
+    private static final String FOR_UPDATE = " FOR UPDATE";
 
     /**
      * The select modifiers. E.g. DISTINCT.
@@ -151,6 +153,11 @@ public class Query
      */
     private String rowcount;
 
+    /**
+     * Whether a FOR UPDATE clause should be rendered.
+     */
+    private boolean forUpdate;
+
     /** The type of the statement. */
     private Type type = Type.SELECT;
 
@@ -387,6 +394,29 @@ public class Query
     }
 
     /**
+     * Sets whether FOR UPDATE clause should be added to the query.
+     *
+     * @param forUpdate true if a FOR UPDATE clause should be added,
+     *        false if not.
+     *
+     * @return this object.
+     */
+    public void setForUpdate(boolean forUpdate)
+    {
+        this.forUpdate = forUpdate;
+    }
+
+    /**
+     * Returns whether a FOR UPDATE clause is added.
+     *
+     * @return true if a FOR UPDATE clause is added, false otherwise.
+     */
+    public boolean isForUpdate()
+    {
+        return forUpdate;
+    }
+
+    /**
      * True if this query has a limit clause registered.
      *
      * @return true if a limit clause exists.
@@ -553,6 +583,10 @@ public class Query
         {
             stringBuilder.append(postLimit);
         }
+        if (Type.SELECT == type && forUpdate)
+        {
+            stringBuilder.append(FOR_UPDATE);
+        }
 
         return stringBuilder;
     }

Modified: 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
URL: 
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java?rev=1446412&r1=1446411&r2=1446412&view=diff
==============================================================================
--- 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
 (original)
+++ 
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
 Fri Feb 15 00:30:18 2013
@@ -170,6 +170,7 @@ public final class SqlBuilder
         processOrderBy(crit, sqlStatement);
         processLimits(crit, sqlStatement);
         processFromElements(crit, sqlStatement);
+        processForUpdate(crit, sqlStatement);
         sqlStatement.setFetchSize(crit.getFetchSize());
 
         return sqlStatement;
@@ -674,6 +675,19 @@ public final class SqlBuilder
     }
 
     /**
+     * Adds a possible FOR UPDATE Clause to the query
+     *
+     * @param criteria the criteria from which the query should be built.
+     * @param query the query to build.
+     */
+    private static void processForUpdate(
+            final Criteria criteria,
+            final Query query)
+    {
+        query.setForUpdate(criteria.isForUpdate());
+    }
+
+    /**
      * Returns the tablename which can be added to a From Clause.
      * This takes care of any aliases that might be defined.
      * For example, if an alias "a" for the table AUTHOR is defined

Modified: 
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
URL: 
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java?rev=1446412&r1=1446411&r2=1446412&view=diff
==============================================================================
--- 
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
 (original)
+++ 
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
 Fri Feb 15 00:30:18 2013
@@ -27,7 +27,6 @@ import java.util.List;
 import org.apache.torque.BaseTestCase;
 import org.apache.torque.Column;
 import org.apache.torque.ColumnImpl;
-import org.apache.torque.Database;
 import org.apache.torque.TorqueException;
 import org.apache.torque.criteria.Criteria;
 import org.apache.torque.criteria.Criterion;
@@ -1464,6 +1463,66 @@ public class SqlBuilderTest extends Base
             query.toString());
     }
 
+    public void testLimitOracle() throws Exception
+    {
+        Criteria criteria = new Criteria();
+        criteria.addSelectColumn(stringColumnMap);
+        criteria.setLimit(20);
+        criteria.setDbName(databaseOracle.getName());
+        Query query = SqlBuilder.buildQuery(criteria);
+        assertEquals("SELECT B.* FROM ("
+                + " SELECT A.*, rownum AS TORQUE$ROWNUM FROM "
+                + "( SELECT TABLE.COLUMN1 FROM TABLE ) A  ) B"
+                + " WHERE  B.TORQUE$ROWNUM <= 20",
+            query.toString());
+    }
+
+    public void testOffsetOracle() throws Exception
+    {
+        Criteria criteria = new Criteria();
+        criteria.addSelectColumn(stringColumnMap);
+        criteria.setOffset(10);
+        criteria.setDbName(databaseOracle.getName());
+        Query query = SqlBuilder.buildQuery(criteria);
+        assertEquals("SELECT B.* FROM ("
+                + " SELECT A.*, rownum AS TORQUE$ROWNUM FROM "
+                + "( SELECT TABLE.COLUMN1 FROM TABLE ) A  ) B"
+                + " WHERE  B.TORQUE$ROWNUM > 10",
+            query.toString());
+    }
+
+    public void testLimitOffsetOracle() throws Exception
+    {
+        Criteria criteria = new Criteria();
+        criteria.addSelectColumn(stringColumnMap);
+        criteria.setLimit(20);
+        criteria.setOffset(10);
+        criteria.setDbName(databaseOracle.getName());
+        Query query = SqlBuilder.buildQuery(criteria);
+        assertEquals("SELECT B.* FROM ("
+                + " SELECT A.*, rownum AS TORQUE$ROWNUM FROM "
+                + "( SELECT TABLE.COLUMN1 FROM TABLE ) A  ) B"
+                + " WHERE  B.TORQUE$ROWNUM > 10 AND B.TORQUE$ROWNUM <= 30",
+            query.toString());
+    }
+
+    public void testSelectForUpdate() throws Exception
+    {
+        Criteria criteria = new Criteria()
+            .addSelectColumn(stringColumnMap)
+            .setLimit(20)
+            .setOffset(10)
+            .forUpdate();
+        criteria.setDbName(databaseOracle.getName());
+        Query query = SqlBuilder.buildQuery(criteria);
+        assertEquals("SELECT B.* FROM ("
+                + " SELECT A.*, rownum AS TORQUE$ROWNUM FROM "
+                + "( SELECT TABLE.COLUMN1 FROM TABLE ) A  ) B"
+                + " WHERE  B.TORQUE$ROWNUM > 10 AND B.TORQUE$ROWNUM <= 30"
+                + " FOR UPDATE",
+            query.toString());
+    }
+
     public void testHaving() throws Exception
     {
         Criteria criteria = new Criteria();



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

Reply via email to