openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wisnes...@apache.org
Subject svn commit: r525252 - in /incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql: AbstractDB2Dictionary.java DB2Dictionary.java
Date Tue, 03 Apr 2007 19:35:00 GMT
Author: wisneskid
Date: Tue Apr  3 12:34:59 2007
New Revision: 525252

URL: http://svn.apache.org/viewvc?view=rev&rev=525252
Log:
changes for JIRA OPENJPA-182

Modified:
    incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
    incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java

Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java?view=diff&rev=525252&r1=525251&r2=525252
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
(original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java
Tue Apr  3 12:34:59 2007
@@ -52,7 +52,7 @@
         supportsLockingWithOrderClause = false;
         supportsLockingWithOuterJoin = false;
         supportsLockingWithInnerJoin = false;
-        supportsLockingWithSelectRange = false;
+        supportsLockingWithSelectRange = true;
 
         requiresAutoCommitForMetaData = true;
         requiresAliasForSubselect = true;

Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java?view=diff&rev=525252&r1=525251&r2=525252
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
(original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
Tue Apr  3 12:34:59 2007
@@ -15,13 +15,15 @@
  */
 package org.apache.openjpa.jdbc.sql;
 
+import java.lang.reflect.Method;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
 import java.util.Arrays;
-
+import java.util.StringTokenizer;
 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
 import org.apache.openjpa.jdbc.schema.Sequence;
+import org.apache.openjpa.lib.log.Log;
 
 /**
  * Dictionary for IBM DB2 database.
@@ -31,7 +33,18 @@
 
     public String optimizeClause = "optimize for";
     public String rowClause = "row";
-
+    private int db2ServerType = 0; 
+    private static final int  db2ISeriesV5R3AndEarlier = 1;
+    private static final int db2UDBV81OrEarlier = 2;
+    private static final int db2ZOSV8x = 3;
+    private static final int db2UDBV82AndLater = 4;
+    private static final int  db2ISeriesV5R4AndLater = 5;
+	private static final String  forUpdateOfClause="FOR UPDATE OF";
+    private static final String  withRSClause="WITH RS";
+    private static final String  withRRClause="WITH RR";
+    private static final String  useKeepUpdateLockClause= "USE AND KEEP UPDATE LOCKS";
+    private static final String  useKeepExclusiveLockClause="USE AND KEEP EXCLUSIVE LOCKS";
+    private static final String  forReadOnlyClause = "FOR READ ONLY";
     public DB2Dictionary() {
         platform = "DB2";
         validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
@@ -170,6 +183,18 @@
     	if (isJDBC3(metaData)) {
 			int maj = metaData.getDatabaseMajorVersion();
 	    	int min = metaData.getDatabaseMinorVersion();
+	    	
+	    	// Determine the type of DB2 database
+	    	if (isDB2ISeriesV5R3AndEarlier(metaData))
+	    	    db2ServerType =db2ISeriesV5R3AndEarlier;
+	    	else if (isDB2UDBV81OrEarlier(metaData,maj,min))
+	    	    db2ServerType =db2UDBV81OrEarlier;
+	    	else if (isDB2ZOSV8x(metaData,maj))
+	    	    db2ServerType =db2ZOSV8x;
+	    	else if (isDB2UDBV82AndLater(metaData,maj,min))
+	    	    db2ServerType=db2UDBV82AndLater;
+	    	else if (isDB2ISeriesV5R4AndLater(metaData))
+	    	    db2ServerType=db2ISeriesV5R4AndLater;
 
 	    	if (maj >= 9 || (maj == 8 && min >= 2)) {
 	    		supportsLockingWithMultipleTables = true;
@@ -198,13 +223,221 @@
         }
     }
     
+    /** Get the update clause for the query based on the 
+     * updateClause and isolationLevel hints
+     */
+    public String getForUpdateClause(JDBCFetchConfiguration fetch, boolean forUpdate) {
+        String isolationLevel = null;
+        Boolean updateClause = null;
+        DatabaseMetaData metaData = null;
+        StringBuffer forUpdateString = new StringBuffer();
+        try {
+            // Determine the update clause/isolationLevel the hint 
+            // overrides the persistence.xml value
+            if (fetch != null && fetch.getHint("openjpa.hint.updateClause")
+                !=null )
+                updateClause = (Boolean)fetch.
+                getHint("openjpa.hint.updateClause");
+            else 
+                updateClause = forUpdate;
+            if (fetch != null &&fetch.getHint("openjpa.hint.isolationLevel")
+                !=null )
+                isolationLevel = (String)fetch.
+                getHint("openjpa.hint.isolationLevel");
+            else 
+                isolationLevel = conf.getTransactionIsolation();
+            if (updateClause == false)
+                //This sql is not for update so add FOR Read Only clause
+                forUpdateString.append(" ").append(forReadOnlyClause)
+                .append(" ");
+            else if (updateClause == true){
+
+                switch(db2ServerType){
+                case db2ISeriesV5R3AndEarlier:
+                case db2UDBV81OrEarlier: 
+                    if (isolationLevel.equals("read-uncommitted"))
+                        forUpdateString.append(" ").append(withRSClause)
+                        .append(" ").append(forUpdateOfClause).append(" ");
+                    else
+                        forUpdateString.append(" ").append(forUpdateOfClause)
+                        .append(" ");
+                    break;   
+                case db2ZOSV8x:
+                case db2UDBV82AndLater: 
+                    if (isolationLevel.equals("serializable"))
+                        forUpdateString.append(" ").append(withRRClause)
+                        .append(" ").append(useKeepUpdateLockClause)
+                        .append(" ");
+                    else
+                        forUpdateString.append(" ").append(withRSClause)
+                        .append(" ").append(useKeepUpdateLockClause)
+                        .append(" ");	
+                    break;
+                case db2ISeriesV5R4AndLater:
+                    if (isolationLevel.equals("serializable"))
+                        forUpdateString.append(" ").append(withRRClause)
+                        .append(" ").append(useKeepExclusiveLockClause)
+                        .append(" ");
+                    else
+                        forUpdateString.append(" ").append(withRSClause)
+                        .append(" ").append(useKeepExclusiveLockClause)
+                        .append(" ");	
+                }
+            }
+        }    
+        catch (Exception e) {
+            if (log.isTraceEnabled())
+                log.error(e.toString(),e);
+        }
+        return forUpdateString.toString();
+    }  
+
+   
+    /** Override the DBDictionary toSelect to call getOptimizeClause and append 
+     *   to the select string
+     */   
+    public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch,
+       SQLBuffer from, SQLBuffer where, SQLBuffer group,
+       SQLBuffer having, SQLBuffer order,
+       boolean distinct, boolean forUpdate, long start, long end,
+       int expectedResultCount) {
+       String forUpdateString = getForUpdateClause(fetch,forUpdate);
+       SQLBuffer selString = toOperation(getSelectOperation(fetch), 
+            selects, from, where,
+            group, having, order, distinct,
+            forUpdate, start, end,forUpdateString);
+        return selString;
+    }
+
+    public boolean isDB2UDBV82AndLater(DatabaseMetaData metadata, int maj,
+        int min) throws SQLException {
+        boolean match = false;
+        if (metadata.getDatabaseProductVersion().indexOf("SQL") != -1 
+            && ((maj ==8 && min >=2) ||(maj >=8)))
+            match = true; 
+        return match;
+    }
+
+    public boolean isDB2ZOSV8x(DatabaseMetaData metadata,int maj)
+       throws SQLException {
+       boolean match = false;
+       if (metadata.getDatabaseProductVersion().indexOf("DSN") != -1 
+           && maj ==8 )
+           match = true; 
+        return match;
+    }
+
+    public boolean isDB2ISeriesV5R3AndEarlier(DatabaseMetaData metadata)
+       throws SQLException {
+       boolean match = false;
+       if (metadata.getDatabaseProductVersion().indexOf("AS") != -1 
+           && generateVersionNumber(metadata.getDatabaseProductVersion())
+           <= 530 )
+           match = true; 
+       return match;
+    }
+
+    public boolean isDB2ISeriesV5R4AndLater(DatabaseMetaData metadata)
+       throws SQLException {
+       boolean match = false;
+       if (metadata.getDatabaseProductVersion().indexOf("AS") != -1 
+           && generateVersionNumber(metadata.getDatabaseProductVersion())
+           >= 540 )
+           match = true; 
+      return match;
+    }
+
+    public boolean isDB2UDBV81OrEarlier(DatabaseMetaData metadata,int maj, 
+        int min) throws SQLException {
+        boolean match = false;
+        if (metadata.getDatabaseProductVersion().indexOf("SQL") != -1 &&
+           ((maj ==8 && min <=1)|| maj <8 ))
+            match = true; 
+        return match;
+    }
+
+    /** Get the version number for the ISeries
+     */ 
+    protected  int generateVersionNumber(String versionString) {
+        String s = versionString.substring(versionString.indexOf('V'));
+        s = s.toUpperCase(); 
+        int i = -1;
+        StringTokenizer stringtokenizer = new StringTokenizer(s, "VRM", false);
+        if (stringtokenizer.countTokens() == 3)
+        {
+            String s1 = stringtokenizer.nextToken();
+            s1 = s1 + stringtokenizer.nextToken();
+            s1 = s1 + stringtokenizer.nextToken();
+            i = Integer.parseInt(s1);
+        }
+        return i;
+    }
+ 
+       
+    /**
+     * Override the toOperationMethod of DBDictionary to pass the 
+     * forUpdateString.
+     */
+    protected SQLBuffer toOperation(String op, SQLBuffer selects, 
+        SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having, 
+        SQLBuffer order, boolean distinct, boolean forUpdate, long start, 
+        long end,String forUpdateString) {
+        SQLBuffer buf = new SQLBuffer(this);
+        buf.append(op);
+        boolean range = start != 0 || end != Long.MAX_VALUE;
+        if (range && rangePosition == RANGE_PRE_DISTINCT)
+            appendSelectRange(buf, start, end);
+        if (distinct)
+            buf.append(" DISTINCT");
+        if (range && rangePosition == RANGE_POST_DISTINCT)
+            appendSelectRange(buf, start, end);
+        buf.append(" ").append(selects).append(" FROM ").append(from);
+
+        if (where != null && !where.isEmpty())
+            buf.append(" WHERE ").append(where);
+        if (group != null && !group.isEmpty())
+            buf.append(" GROUP BY ").append(group);
+        if (having != null && !having.isEmpty()) {
+            assertSupport(supportsHaving, "SupportsHaving");
+            buf.append(" HAVING ").append(having);
+        }
+        if (order != null && !order.isEmpty())
+            buf.append(" ORDER BY ").append(order);
+        if (range && rangePosition == RANGE_POST_SELECT)
+            appendSelectRange(buf, start, end);
+
+        if (!simulateLocking ) {
+            assertSupport(supportsSelectForUpdate, "SupportsSelectForUpdate");
+            buf.append(" ").append(forUpdateString);
+        }
+        if (range && rangePosition == RANGE_POST_LOCK)
+            appendSelectRange(buf, start, end);
+        return buf;
+    }
+
     public SQLBuffer toSelect(Select sel, boolean forUpdate,
         JDBCFetchConfiguration fetch) {
-        SQLBuffer buf = super.toSelect(sel, forUpdate, fetch); 
+        sel.addJoinClassConditions();
+        boolean update = forUpdate && sel.getFromSelect() == null;
+        SQLBuffer select = getSelects(sel, false, update);
+        SQLBuffer ordering = null;
+        if (!sel.isAggregate() || sel.getGrouping() != null)
+            ordering = sel.getOrdering();
+        SQLBuffer from;
+        if (sel.getFromSelect() != null)
+            from = getFromSelect(sel, forUpdate);
+        else
+            from = getFrom(sel, update);
+        SQLBuffer where = getWhere(sel, update);
+        String forUpdateString = getForUpdateClause(fetch,forUpdate);
+        SQLBuffer buf = toOperation(getSelectOperation(fetch), select,
+            from, where,sel.getGrouping(), sel.getHaving(),  ordering,
+            sel.isDistinct(), forUpdate, sel.getStartIndex(),
+            sel.getEndIndex(),forUpdateString);
         if (sel.getExpectedResultCount() > 0)
             buf.append(" ").append(optimizeClause).append(" ").
-                append(String.valueOf(sel.getExpectedResultCount())).
-                append(" ").append(rowClause);
+            append(String.valueOf(sel.getExpectedResultCount())).
+            append(" ").append(rowClause);
         return buf;
     }
 }



Mime
View raw message