svn commit: r1139851 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1139851 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java

doogie-3
Author: doogie
Date: Sun Jun 26 18:07:18 2011
New Revision: 1139851

URL: http://svn.apache.org/viewvc?rev=1139851&view=rev
Log:
FEATURE: When doing bulk creation of tables, foreign key indices,
and declared indices, do the work in parallel.  Also, when the database
does not support wildcard looking of primary key info, do the per-table
lookup in parallel.

Modified:
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java?rev=1139851&r1=1139850&r2=1139851&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java Sun Jun 26 18:07:18 2011
@@ -42,6 +42,7 @@ import javolution.util.FastMap;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import org.ofbiz.base.concurrent.ExecutionPool;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilTimer;
 import org.ofbiz.base.util.UtilValidate;
@@ -232,6 +233,7 @@ public class DatabaseUtil {
             Debug.logError(message, module);
             return;
         }
+        List<Future<CreateTableCallable>> tableFutures = FastList.newInstance();
         for (ModelEntity entity: modelEntityList) {
             curEnt++;
 
@@ -420,20 +422,13 @@ public class DatabaseUtil {
 
                 if (addMissing) {
                     // create the table
-                    String errMsg = createTable(entity, modelEntities, false);
-                    if (UtilValidate.isNotEmpty(errMsg)) {
-                        message = "Could not create table [" + tableName + "]: " + errMsg;
-                        Debug.logError(message, module);
-                        if (messages != null) messages.add(message);
-                    } else {
-                        entitiesAdded.add(entity);
-                        message = "Created table [" + tableName + "]";
-                        Debug.logImportant(message, module);
-                        if (messages != null) messages.add(message);
-                    }
+                    tableFutures.add(submitWork(new CreateTableCallable(entity, modelEntities, tableName)));
                 }
             }
         }
+        for (CreateTableCallable tableCallable: ExecutionPool.getAllFutures(tableFutures)) {
+            tableCallable.updateData(messages, entitiesAdded);
+        }
 
         timer.timerString("After Individual Table/Column Check");
 
@@ -447,11 +442,20 @@ public class DatabaseUtil {
         // for each newly added table, add fk indices
         if (datasourceInfo.useFkIndices) {
             int totalFkIndices = 0;
+            List<Future<AbstractCountingCallable>> fkIndicesFutures = FastList.newInstance();
             for (ModelEntity curEntity: entitiesAdded) {
                 if (curEntity.getRelationsOneSize() > 0) {
-                    totalFkIndices += this.createForeignKeyIndices(curEntity, datasourceInfo.constraintNameClipLength, messages);
+                    fkIndicesFutures.add(submitWork(new AbstractCountingCallable(curEntity, modelEntities) {
+                        public AbstractCountingCallable call() throws Exception {
+                            count = createForeignKeyIndices(entity, datasourceInfo.constraintNameClipLength, messages);
+                            return this;
+                        }
+                    }));
                 }
             }
+            for (AbstractCountingCallable fkIndicesCallable: ExecutionPool.getAllFutures(fkIndicesFutures)) {
+                totalFkIndices += fkIndicesCallable.updateData(messages);
+            }
             if (totalFkIndices > 0) Debug.logImportant("==== TOTAL Foreign Key Indices Created: " + totalFkIndices, module);
         }
 
@@ -467,11 +471,21 @@ public class DatabaseUtil {
         // for each newly added table, add declared indexes
         if (datasourceInfo.useIndices) {
             int totalDis = 0;
+            List<Future<AbstractCountingCallable>> disFutures = FastList.newInstance();
             for (ModelEntity curEntity: entitiesAdded) {
                 if (curEntity.getIndexesSize() > 0) {
-                    totalDis += this.createDeclaredIndices(curEntity, messages);
+                    disFutures.add(submitWork(new AbstractCountingCallable(curEntity,  modelEntities) {
+                    public AbstractCountingCallable call() throws Exception {
+                        count = createDeclaredIndices(entity, messages);
+                        return this;
+                    }
+                }));
+
                 }
             }
+            for (AbstractCountingCallable disCallable: ExecutionPool.getAllFutures(disFutures)) {
+                totalDis += disCallable.updateData(messages);
+            }
             if (totalDis > 0) Debug.logImportant("==== TOTAL Declared Indices Created: " + totalDis, module);
         }
 
@@ -1188,6 +1202,17 @@ public class DatabaseUtil {
         return tableNames;
     }
 
+    private AbstractCountingCallable createPrimaryKeyFetcher(final DatabaseMetaData dbData, final String lookupSchemaName, final boolean needsUpperCase, final Map<String, Map<String, ColumnCheckInfo>> colInfo, final Collection<String> messages, final String curTable) {
+        return new AbstractCountingCallable(null, null) {
+            public AbstractCountingCallable call() throws Exception {
+                Debug.logInfo("Fetching primary keys for " + curTable, module);
+                ResultSet rsPks = dbData.getPrimaryKeys(null, lookupSchemaName, curTable);
+                count = checkPrimaryKeyInfo(rsPks, lookupSchemaName, needsUpperCase, colInfo, messages);
+                return this;
+            }
+        };
+    }
+
     public Map<String, Map<String, ColumnCheckInfo>> getColumnInfo(Set<String> tableNames, boolean getPks, Collection<String> messages) {
         // if there are no tableNames, don't even try to get the columns
         if (tableNames.size() == 0) {
@@ -1317,10 +1342,13 @@ public class DatabaseUtil {
                     }
                     if (pkCount == 0) {
                         Debug.logInfo("Searching in " + tableNames.size() + " tables for primary key fields ...", module);
+                        List<Future<AbstractCountingCallable>> pkFetcherFutures = FastList.newInstance();
                         for (String curTable: tableNames) {
                             curTable = curTable.substring(curTable.indexOf('.') + 1); //cut off schema name
-                            ResultSet rsPks = dbData.getPrimaryKeys(null, lookupSchemaName, curTable);
-                            pkCount += checkPrimaryKeyInfo(rsPks, lookupSchemaName, needsUpperCase, colInfo, messages);
+                            pkFetcherFutures.add(submitWork(createPrimaryKeyFetcher(dbData, lookupSchemaName, needsUpperCase, colInfo, messages, curTable)));
+                        }
+                        for (AbstractCountingCallable pkFetcherCallable: ExecutionPool.getAllFutures(pkFetcherFutures)) {
+                            pkCount += pkFetcherCallable.updateData(messages);
                         }
                     }
 
@@ -1662,6 +1690,66 @@ public class DatabaseUtil {
         return indexInfo;
     }
 
+    private class CreateTableCallable implements Callable<CreateTableCallable> {
+        private final ModelEntity entity;
+        private final Map<String, ModelEntity> modelEntities;
+        private final String tableName;
+        private String message;
+        private boolean success;
+
+        protected CreateTableCallable(ModelEntity entity, Map<String, ModelEntity> modelEntities, String tableName) {
+            this.entity = entity;
+            this.modelEntities = modelEntities;
+            this.tableName = tableName;
+        }
+
+        public CreateTableCallable call() throws Exception {
+            String errMsg = createTable(entity, modelEntities, false);
+            if (UtilValidate.isNotEmpty(errMsg)) {
+                this.success = false;
+                this.message = "Could not create table [" + tableName + "]: " + errMsg;
+                Debug.logError(this.message, module);
+            } else {
+                this.success = true;
+                this.message = "Created table [" + tableName + "]";
+                Debug.logImportant(this.message, module);
+            }
+            return this;
+        }
+
+        protected void updateData(Collection<String> messages, List<ModelEntity> entitiesAdded) {
+            if (this.success) {
+                entitiesAdded.add(entity);
+                if (messages != null) {
+                    messages.add(this.message);
+                }
+            } else {
+                if (messages != null) {
+                    messages.add(this.message);
+                }
+            }
+        }
+    }
+
+    private abstract class AbstractCountingCallable<T extends AbstractCountingCallable<T>> implements Callable<T> {
+        protected final ModelEntity entity;
+        protected final Map<String, ModelEntity> modelEntities;
+        protected final List<String> messages = FastList.newInstance();
+        protected int count;
+
+        protected AbstractCountingCallable(ModelEntity entity, Map<String, ModelEntity> modelEntities) {
+            this.entity = entity;
+            this.modelEntities = modelEntities;
+        }
+
+        protected int updateData(Collection<String> messages) {
+            if (messages != null && UtilValidate.isNotEmpty(this.messages)) {
+                messages.addAll(messages);
+            }
+            return count;
+        }
+    }
+
     /* ====================================================================== */
 
     /* ====================================================================== */