You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ke...@apache.org on 2013/02/03 19:51:45 UTC

[2/2] git commit: ISIS-221: Added native paging support to SQL-OS using LIMIT keyword

Updated Branches:
  refs/heads/master 5254a6dcb -> 4c6530c6b


ISIS-221: Added native paging support to SQL-OS using LIMIT keyword


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/4c6530c6
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/4c6530c6
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/4c6530c6

Branch: refs/heads/master
Commit: 4c6530c6b20e9907c915b72985fa0a55888602ed
Parents: 3a28f3a
Author: Kevin Meyer <ke...@apache.org>
Authored: Sun Feb 3 19:48:49 2013 +0100
Committer: Kevin Meyer <ke...@apache.org>
Committed: Sun Feb 3 19:48:49 2013 +0100

----------------------------------------------------------------------
 .../org/apache/isis/objectstore/sql/Defaults.java  |   10 +++
 .../apache/isis/objectstore/sql/ObjectMapping.java |    2 +-
 .../isis/objectstore/sql/SqlObjectStore.java       |   27 +++++---
 .../isis/objectstore/sql/auto/AutoMapper.java      |   49 +++++++--------
 .../apache/isis/objectstore/sql/DefaultsTest.java  |   12 ++++
 .../sql/common/SqlIntegrationTestData.java         |    9 +++
 6 files changed, 72 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/4c6530c6/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/Defaults.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/Defaults.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/Defaults.java
index 64309f2..1433faf 100755
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/Defaults.java
+++ b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/Defaults.java
@@ -357,4 +357,14 @@ public class Defaults {
     }
     // }}
 
+    /**
+     * Based on the database engine, return a LIMIT start, count clause. 
+     * 
+     * @param startIndex
+     * @param rowCount
+     */
+    public static String getLimitsClause(long startIndex, long rowCount) {
+        return String.format("LIMIT %d, %d", startIndex, rowCount);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4c6530c6/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/ObjectMapping.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/ObjectMapping.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/ObjectMapping.java
index 002ceaa..d0dac05 100644
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/ObjectMapping.java
+++ b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/ObjectMapping.java
@@ -32,7 +32,7 @@ public interface ObjectMapping {
 
     void destroyObject(DatabaseConnector connector, ObjectAdapter object);
 
-    Vector<ObjectAdapter> getInstances(DatabaseConnector connector, ObjectSpecification spec);
+    Vector<ObjectAdapter> getInstances(DatabaseConnector connector, ObjectSpecification spec, long startIndex, long rowCount);
 
     Vector<ObjectAdapter> getInstances(DatabaseConnector connector, ObjectSpecification spec, String title);
 

http://git-wip-us.apache.org/repos/asf/isis/blob/4c6530c6/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/SqlObjectStore.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/SqlObjectStore.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/SqlObjectStore.java
index d36cc83..ecc201e 100644
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/SqlObjectStore.java
+++ b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/SqlObjectStore.java
@@ -47,9 +47,11 @@ import org.apache.isis.core.runtime.persistence.objectstore.transaction.DestroyO
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommand;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommandContext;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.SaveObjectCommand;
+import org.apache.isis.core.runtime.persistence.query.PersistenceQueryBuiltInAbstract;
 import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindAllInstances;
 import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindByPattern;
 import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindByTitle;
+import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindPaged;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceQuery;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
@@ -328,7 +330,10 @@ public final class SqlObjectStore implements ObjectStoreSpi {
         if (query instanceof PersistenceQueryFindByTitle) {
             return findByTitle((PersistenceQueryFindByTitle) query);
         } else if (query instanceof PersistenceQueryFindAllInstances) {
-            return getAllInstances((PersistenceQueryFindAllInstances) query);
+            return getAllInstances((PersistenceQueryFindAllInstances) query, 0, 0);
+        } else if (query instanceof PersistenceQueryFindPaged) {
+            PersistenceQueryFindPaged findQuery = (PersistenceQueryFindPaged) query;
+            return getAllInstances((PersistenceQueryFindPaged) query, findQuery.getStart(), findQuery.getCount());
         } else if (query instanceof PersistenceQueryFindByPattern) {
             return findByPattern((PersistenceQueryFindByPattern) query);
         } else {
@@ -343,7 +348,7 @@ public final class SqlObjectStore implements ObjectStoreSpi {
         try {
             final List<ObjectAdapter> matchingInstances = Lists.newArrayList();
 
-            addSpecQueryInstances(specification, connector, query, matchingInstances);
+            addSpecQueryInstances(specification, connector, query, matchingInstances, 0, 0);
             return matchingInstances;
 
         } finally {
@@ -352,7 +357,7 @@ public final class SqlObjectStore implements ObjectStoreSpi {
     }
 
     private void addSpecQueryInstances(final ObjectSpecification specification, final DatabaseConnector connector,
-        final PersistenceQueryFindByPattern query, final List<ObjectAdapter> matchingInstances) {
+        final PersistenceQueryFindByPattern query, final List<ObjectAdapter> matchingInstances, long startIndex, long rowCount) {
 
         if (specification.isAbstract() == false) {
             final ObjectMapping mapper = objectMappingLookup.getMapping(specification, connector);
@@ -363,39 +368,39 @@ public final class SqlObjectStore implements ObjectStoreSpi {
         if (specification.hasSubclasses()) {
             final List<ObjectSpecification> subclasses = specification.subclasses();
             for (final ObjectSpecification subclassSpec : subclasses) {
-                addSpecQueryInstances(subclassSpec, connector, query, matchingInstances);
+                addSpecQueryInstances(subclassSpec, connector, query, matchingInstances, startIndex, rowCount);
             }
         }
     }
 
-    private List<ObjectAdapter> getAllInstances(final PersistenceQueryFindAllInstances criteria) {
+    private List<ObjectAdapter> getAllInstances(final PersistenceQueryBuiltInAbstract criteria, final long startIndex, final long rowCount) {
         final ObjectSpecification spec = criteria.getSpecification();
-        return allInstances(spec);
+        return allInstances(spec, startIndex, rowCount);
     }
 
-    private List<ObjectAdapter> allInstances(final ObjectSpecification spec) {
+    private List<ObjectAdapter> allInstances(final ObjectSpecification spec, long startIndex, long rowCount) {
         final DatabaseConnector connector = connectionPool.acquire();
         final List<ObjectAdapter> matchingInstances = Lists.newArrayList();
 
-        addSpecInstances(spec, connector, matchingInstances);
+        addSpecInstances(spec, connector, matchingInstances, startIndex, rowCount);
 
         connectionPool.release(connector);
         return matchingInstances;
     }
 
     private void addSpecInstances(final ObjectSpecification spec, final DatabaseConnector connector,
-        final List<ObjectAdapter> matchingInstances) {
+        final List<ObjectAdapter> matchingInstances, long startIndex, long rowCount) {
 
         if (!spec.isAbstract()) {
             final ObjectMapping mapper = objectMappingLookup.getMapping(spec, connector);
-            final List<ObjectAdapter> instances = mapper.getInstances(connector, spec);
+            final List<ObjectAdapter> instances = mapper.getInstances(connector, spec, startIndex, rowCount);
             matchingInstances.addAll(instances);
         }
 
         if (spec.hasSubclasses()) {
             final List<ObjectSpecification> subclasses = spec.subclasses();
             for (final ObjectSpecification subclassSpec : subclasses) {
-                addSpecInstances(subclassSpec, connector, matchingInstances);
+                addSpecInstances(subclassSpec, connector, matchingInstances, startIndex, rowCount);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/4c6530c6/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
index 05fbf57..c8933df 100644
--- a/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
+++ b/component/objectstore/sql/sql-impl/src/main/java/org/apache/isis/objectstore/sql/auto/AutoMapper.java
@@ -66,8 +66,7 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
     private final TitleMapping titleMapping;
     private final boolean useVersioning;
 
-    public AutoMapper(final String className, final String parameterBase, final FieldMappingLookup lookup,
-        final ObjectMappingLookup objectMapperLookup) {
+    public AutoMapper(final String className, final String parameterBase, final FieldMappingLookup lookup, final ObjectMappingLookup objectMapperLookup) {
         super(className, parameterBase, lookup, objectMapperLookup);
         idMapping = lookup.createIdMapping();
         versionMapping = lookup.createVersionMapping();
@@ -162,16 +161,15 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
     }
 
     @Override
-    public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec) {
+    public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec, final long startIndex, final long rowCount) {
         final StringBuffer sql = createSelectStatement();
         final Vector<ObjectAdapter> instances = new Vector<ObjectAdapter>();
-        loadInstancesToVector(connector, spec, completeSelectStatement(sql), instances);
+        loadInstancesToVector(connector, spec, completeSelectStatement(sql, startIndex, rowCount), instances);
         return instances;
     }
 
     @Override
-    public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec,
-        final PersistenceQueryFindByPattern query) {
+    public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec, final PersistenceQueryFindByPattern query) {
         final Vector<ObjectAdapter> instances = new Vector<ObjectAdapter>();
 
         final StringBuffer sql = createSelectStatement();
@@ -247,20 +245,19 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
             }
         }
         // if (foundFields > 0) {
-        loadInstancesToVector(connector, spec, completeSelectStatement(sql), instances);
+        loadInstancesToVector(connector, spec, completeSelectStatement(sql, 0, 0), instances);
         // }
         return instances;
     }
 
     @Override
-    public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec,
-        final String title) {
+    public Vector<ObjectAdapter> getInstances(final DatabaseConnector connector, final ObjectSpecification spec, final String title) {
         final Vector<ObjectAdapter> instances = new Vector<ObjectAdapter>();
 
         final StringBuffer sql = createSelectStatement();
         sql.append(" WHERE ");
         titleMapping.appendWhereClause(sql, title);
-        loadInstancesToVector(connector, spec, completeSelectStatement(sql), instances);
+        loadInstancesToVector(connector, spec, completeSelectStatement(sql, 0, 0), instances);
         return instances;
     }
 
@@ -269,7 +266,7 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
         final StringBuffer sql = createSelectStatement();
         sql.append(" WHERE ");
         idMapping.appendWhereClause(connector, sql, (RootOid) typedOid);
-        final Results rs = connector.select(completeSelectStatement(sql));
+        final Results rs = connector.select(completeSelectStatement(sql, 0, 0));
         final ObjectSpecification objectSpec = getSpecificationLoader().lookupBySpecId(typedOid.getObjectSpecId());
         if (rs.next()) {
             return loadMappedObject(connector, objectSpec, rs);
@@ -299,13 +296,20 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
         sql.append(" from " + table);
         return sql;
     } /*
-       * if (whereClause != null) { sql.append(" WHERE "); sql.append(whereClause); } else if (whereClause != null) {
+       * if (whereClause != null) { sql.append(" WHERE ");
+       * sql.append(whereClause); } else if (whereClause != null) {
        * sql.append(" WHERE "); idMapping.appendWhereClause(sql, oid); }
        */
 
-    private String completeSelectStatement(final StringBuffer sql) {
+    private String completeSelectStatement(final StringBuffer sql, final long startIndex, final long rowCount) {
         sql.append(" order by ");
         idMapping.appendColumnNames(sql);
+
+        if ((startIndex != 0) || (rowCount != 0)) {
+            sql.append(" ");
+            sql.append(Defaults.getLimitsClause(startIndex, rowCount));
+        }
+
         return sql.toString();
     }
 
@@ -316,8 +320,8 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
                 mapping.initializeField(adapter, rs);
             }
             /*
-             * for (int i = 0; i < oneToManyProperties.length; i++) { /* Need to set up collection to be a ghost before
-             * we access as below
+             * for (int i = 0; i < oneToManyProperties.length; i++) { /* Need to
+             * set up collection to be a ghost before we access as below
              */
             // CollectionAdapter collection = (CollectionAdapter)
             /*
@@ -337,8 +341,7 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
         }
     }
 
-    private void loadInstancesToVector(final DatabaseConnector connector, final ObjectSpecification cls,
-        final String selectStatment, final Vector<ObjectAdapter> instances) {
+    private void loadInstancesToVector(final DatabaseConnector connector, final ObjectSpecification cls, final String selectStatment, final Vector<ObjectAdapter> instances) {
         LOG.debug("loading instances from SQL " + table);
 
         try {
@@ -356,8 +359,7 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
         }
     }
 
-    private ObjectAdapter loadMappedObject(final DatabaseConnector connector, final ObjectSpecification cls,
-        final Results rs) {
+    private ObjectAdapter loadMappedObject(final DatabaseConnector connector, final ObjectSpecification cls, final Results rs) {
         final Oid oid = idMapping.recreateOid(rs, specification);
         final ObjectAdapter adapter = getAdapter(cls, oid);
 
@@ -390,14 +392,12 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
             }
         } else {
             rs.close();
-            throw new SqlObjectStoreException("Unable to load data from " + table + " with id "
-                + object.getOid().enString(getOidMarshaller()));
+            throw new SqlObjectStoreException("Unable to load data from " + table + " with id " + object.getOid().enString(getOidMarshaller()));
         }
     }
 
     @Override
-    public void resolveCollection(final DatabaseConnector connector, final ObjectAdapter object,
-        final ObjectAssociation field) {
+    public void resolveCollection(final DatabaseConnector connector, final ObjectAdapter object, final ObjectAssociation field) {
         if (collectionMappers.length > 0) {
             final DatabaseConnector secondConnector = connector.getConnectionPool().acquire();
             for (final CollectionMapper collectionMapper : collectionMappers) {
@@ -495,8 +495,7 @@ public class AutoMapper extends AbstractAutoMapper implements ObjectMapping, Deb
 
     @Override
     public String toString() {
-        return "AutoMapper [table=" + table + ",id=" + idMapping + ",noColumns=" + fieldMappingByField.size()
-            + ",specification=" + specification.getFullIdentifier() + "]";
+        return "AutoMapper [table=" + table + ",id=" + idMapping + ",noColumns=" + fieldMappingByField.size() + ",specification=" + specification.getFullIdentifier() + "]";
     }
 
     // //////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/4c6530c6/component/objectstore/sql/sql-impl/src/test/java/org/apache/isis/objectstore/sql/DefaultsTest.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-impl/src/test/java/org/apache/isis/objectstore/sql/DefaultsTest.java b/component/objectstore/sql/sql-impl/src/test/java/org/apache/isis/objectstore/sql/DefaultsTest.java
index 4813f71..12ddb4e 100644
--- a/component/objectstore/sql/sql-impl/src/test/java/org/apache/isis/objectstore/sql/DefaultsTest.java
+++ b/component/objectstore/sql/sql-impl/src/test/java/org/apache/isis/objectstore/sql/DefaultsTest.java
@@ -46,4 +46,16 @@ public class DefaultsTest {
         Defaults.initialise(prefix, config);
         Assert.assertThat(Defaults.getTablePrefix(), is(""));
     }
+    
+    @Test 
+    public void checkLimitStatement(){
+        final String prefix = "isis.persistor.sql";
+        final IsisConfigurationDefault config = new IsisConfigurationDefault();
+        Defaults.initialise(prefix, config);
+        
+        final long startIndex=0;
+        final long rowCount=0;
+        
+        Assert.assertThat(Defaults.getLimitsClause(startIndex, rowCount), is("LIMIT 0, 0"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4c6530c6/component/objectstore/sql/sql-tests-common/src/main/java/org/apache/isis/objectstore/sql/common/SqlIntegrationTestData.java
----------------------------------------------------------------------
diff --git a/component/objectstore/sql/sql-tests-common/src/main/java/org/apache/isis/objectstore/sql/common/SqlIntegrationTestData.java b/component/objectstore/sql/sql-tests-common/src/main/java/org/apache/isis/objectstore/sql/common/SqlIntegrationTestData.java
index 37a954b..768b307 100644
--- a/component/objectstore/sql/sql-tests-common/src/main/java/org/apache/isis/objectstore/sql/common/SqlIntegrationTestData.java
+++ b/component/objectstore/sql/sql-tests-common/src/main/java/org/apache/isis/objectstore/sql/common/SqlIntegrationTestData.java
@@ -228,6 +228,9 @@ public abstract class SqlIntegrationTestData extends SqlIntegrationTestCommonBas
         testTimeStamp();
         testDateTimezoneIssue();
         testDateTime();
+        
+        // Test LIMIT statement
+        testLimitCount();
 
         // Must be here so that the Isis framework is initialised for the next test package.
         setFixtureInitializationState(State.INITIALIZE);
@@ -585,6 +588,12 @@ public abstract class SqlIntegrationTestData extends SqlIntegrationTestCommonBas
 
         factory.update(sqlDataClass);
     }
+    
+    private void testLimitCount() {
+        //
+        final List<SimpleClass> subset = factory.someSimpleClasses(0, 2);
+        assertEquals(2, subset.size());
+    }
 
     private void testFindByMatchString() {
         final SimpleClass simpleClassMatch = new SimpleClass();