Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.db')
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingUnitSupport.java30
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping3.java22
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingUnitSupport.java34
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java67
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java104
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java129
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java515
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java372
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/UnitMappingTable.java317
17 files changed, 1287 insertions, 369 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java
index 4b80d68f95..78b9747bcd 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStoreAccessor.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.cdo.server.db;
import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreAccessor.UnitSupport;
import org.eclipse.net4j.db.IDBConnection;
@@ -23,7 +24,7 @@ import java.sql.Connection;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface IDBStoreAccessor extends IStoreAccessor.Raw
+public interface IDBStoreAccessor extends IStoreAccessor.Raw, UnitSupport
{
public IDBStore getStore();
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingUnitSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingUnitSupport.java
new file mode 100644
index 0000000000..65e8e77d33
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMappingUnitSupport.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+
+import java.sql.SQLException;
+
+/**
+ * An extension interface for {@link IClassMapping class mappings} that support <i>units</i>.
+ *
+ * @author Eike Stepper
+ * @since 4.4
+ */
+public interface IClassMappingUnitSupport extends IClassMapping
+{
+ public void readUnitRevisions(IDBStoreAccessor accessor, CDOBranchPoint branchPoint, CDOID rootID,
+ CDORevisionHandler revisionHandler) throws SQLException;
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping3.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping3.java
new file mode 100644
index 0000000000..8fc37c5a4e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+/**
+ * Extension interface to {@link IListMapping2}.
+ *
+ * @author Eike Stepper
+ * @since 4.4
+ */
+public interface IListMapping3 extends IListMapping2
+{
+ public void setClassMapping(IClassMapping classMapping);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingUnitSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingUnitSupport.java
new file mode 100644
index 0000000000..c97e0f363b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingUnitSupport.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IIDHandler;
+
+import org.eclipse.net4j.util.collection.MoveableList;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Interface to complement {@link IListMapping} in order to provide unit support.
+ *
+ * @author Eike Stepper
+ * @since 4.4
+ */
+public interface IListMappingUnitSupport extends IListMapping
+{
+ public ResultSet queryUnitEntries(IDBStoreAccessor accessor, IIDHandler idHandler, CDOID rootID) throws SQLException;
+
+ public void readUnitEntries(ResultSet resultSet, IIDHandler idHandler, CDOID id, MoveableList<Object> list)
+ throws SQLException;
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
index 6b42da68b6..efc86e0dc7 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/CDODBSchema.java
@@ -35,13 +35,13 @@ public class CDODBSchema
public static final IDBTable PROPERTIES = INSTANCE.addTable("cdo_properties"); //$NON-NLS-1$
public static final IDBField PROPERTIES_NAME = //
- PROPERTIES.addField("name", DBType.VARCHAR, 255, true); //$NON-NLS-1$
+ PROPERTIES.addField("name", DBType.VARCHAR, 255, true); //$NON-NLS-1$
public static final IDBField PROPERTIES_VALUE = //
- PROPERTIES.addField("value", DBType.LONGVARCHAR); //$NON-NLS-1$
+ PROPERTIES.addField("value", DBType.LONGVARCHAR); //$NON-NLS-1$
public static final IDBIndex INDEX_PROPERTIES_PK = //
- PROPERTIES.addIndex(IDBIndex.Type.PRIMARY_KEY, PROPERTIES_NAME);
+ PROPERTIES.addIndex(IDBIndex.Type.PRIMARY_KEY, PROPERTIES_NAME);
public static final String SQL_DELETE_PROPERTIES = "DELETE FROM " + PROPERTIES + " WHERE " + PROPERTIES_NAME + "=?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -60,19 +60,19 @@ public class CDODBSchema
public static final IDBTable PACKAGE_UNITS = INSTANCE.addTable("cdo_package_units"); //$NON-NLS-1$
public static final IDBField PACKAGE_UNITS_ID = //
- PACKAGE_UNITS.addField("id", DBType.VARCHAR, 255, true); //$NON-NLS-1$
+ PACKAGE_UNITS.addField("id", DBType.VARCHAR, 255, true); //$NON-NLS-1$
public static final IDBField PACKAGE_UNITS_ORIGINAL_TYPE = //
- PACKAGE_UNITS.addField("original_type", DBType.INTEGER); //$NON-NLS-1$
+ PACKAGE_UNITS.addField("original_type", DBType.INTEGER); //$NON-NLS-1$
public static final IDBField PACKAGE_UNITS_TIME_STAMP = //
- PACKAGE_UNITS.addField("time_stamp", DBType.BIGINT); //$NON-NLS-1$
+ PACKAGE_UNITS.addField("time_stamp", DBType.BIGINT); //$NON-NLS-1$
public static final IDBField PACKAGE_UNITS_PACKAGE_DATA = //
- PACKAGE_UNITS.addField("package_data", DBType.BLOB); //$NON-NLS-1$
+ PACKAGE_UNITS.addField("package_data", DBType.BLOB); //$NON-NLS-1$
public static final IDBIndex INDEX_PACKAGE_UNITS_PK = //
- PACKAGE_UNITS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_UNITS_ID);
+ PACKAGE_UNITS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_UNITS_ID);
/**
* DBTable cdo_packages
@@ -80,22 +80,22 @@ public class CDODBSchema
public static final IDBTable PACKAGE_INFOS = INSTANCE.addTable("cdo_package_infos"); //$NON-NLS-1$
public static final IDBField PACKAGE_INFOS_URI = //
- PACKAGE_INFOS.addField("uri", DBType.VARCHAR, 255, true); //$NON-NLS-1$
+ PACKAGE_INFOS.addField("uri", DBType.VARCHAR, 255, true); //$NON-NLS-1$
public static final IDBField PACKAGE_INFOS_PARENT = //
- PACKAGE_INFOS.addField("parent", DBType.VARCHAR, 255); //$NON-NLS-1$
+ PACKAGE_INFOS.addField("parent", DBType.VARCHAR, 255); //$NON-NLS-1$
public static final IDBField PACKAGE_INFOS_UNIT = //
- PACKAGE_INFOS.addField("unit", DBType.VARCHAR, 255); //$NON-NLS-1$
+ PACKAGE_INFOS.addField("unit", DBType.VARCHAR, 255); //$NON-NLS-1$
public static final IDBIndex INDEX_PACKAGE_INFOS_PK = //
- PACKAGE_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_INFOS_URI);
+ PACKAGE_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, PACKAGE_INFOS_URI);
public static final IDBIndex INDEX_PACKAGE_INFOS_PARENT = //
- PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_PARENT);
+ PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_PARENT);
public static final IDBIndex INDEX_PACKAGE_INFOS_UNIT = //
- PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_UNIT);
+ PACKAGE_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, PACKAGE_INFOS_UNIT);
/**
* DBTable cdo_branches
@@ -103,19 +103,19 @@ public class CDODBSchema
public static final IDBTable BRANCHES = INSTANCE.addTable("cdo_branches"); //$NON-NLS-1$
public static final IDBField BRANCHES_ID = //
- BRANCHES.addField("id", DBType.INTEGER, true); //$NON-NLS-1$
+ BRANCHES.addField("id", DBType.INTEGER, true); //$NON-NLS-1$
public static final IDBField BRANCHES_NAME = //
- BRANCHES.addField("name", DBType.VARCHAR); //$NON-NLS-1$
+ BRANCHES.addField("name", DBType.VARCHAR); //$NON-NLS-1$
public static final IDBField BRANCHES_BASE_BRANCH_ID = //
- BRANCHES.addField("base_id", DBType.INTEGER); //$NON-NLS-1$
+ BRANCHES.addField("base_id", DBType.INTEGER); //$NON-NLS-1$
public static final IDBField BRANCHES_BASE_TIMESTAMP = //
- BRANCHES.addField("base_time", DBType.BIGINT); //$NON-NLS-1$
+ BRANCHES.addField("base_time", DBType.BIGINT); //$NON-NLS-1$
public static final IDBIndex INDEX_BRANCHES_ID = //
- BRANCHES.addIndex(IDBIndex.Type.PRIMARY_KEY, BRANCHES_ID);
+ BRANCHES.addIndex(IDBIndex.Type.PRIMARY_KEY, BRANCHES_ID);
public static final String SQL_CREATE_BRANCH = "INSERT INTO " + BRANCHES + " (" + BRANCHES_ID + ", " + BRANCHES_NAME //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ ", " + BRANCHES_BASE_BRANCH_ID + ", " + BRANCHES_BASE_TIMESTAMP + ") VALUES (?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -139,33 +139,32 @@ public class CDODBSchema
public static final IDBTable COMMIT_INFOS = INSTANCE.addTable("cdo_commit_infos"); //$NON-NLS-1$
public static final IDBField COMMIT_INFOS_TIMESTAMP = //
- COMMIT_INFOS.addField("commit_time", DBType.BIGINT, true); //$NON-NLS-1$
+ COMMIT_INFOS.addField("commit_time", DBType.BIGINT, true); //$NON-NLS-1$
public static final IDBField COMMIT_INFOS_PREVIOUS_TIMESTAMP = //
- COMMIT_INFOS.addField("previous_time", DBType.BIGINT); //$NON-NLS-1$
+ COMMIT_INFOS.addField("previous_time", DBType.BIGINT); //$NON-NLS-1$
public static final IDBField COMMIT_INFOS_BRANCH = //
- COMMIT_INFOS.addField("branch_id", DBType.INTEGER); //$NON-NLS-1$
+ COMMIT_INFOS.addField("branch_id", DBType.INTEGER); //$NON-NLS-1$
public static final IDBField COMMIT_INFOS_USER = //
- COMMIT_INFOS.addField("user_id", DBType.VARCHAR); //$NON-NLS-1$
+ COMMIT_INFOS.addField("user_id", DBType.VARCHAR); //$NON-NLS-1$
public static final IDBField COMMIT_INFOS_COMMENT = //
- COMMIT_INFOS.addField("commit_comment", DBType.VARCHAR); //$NON-NLS-1$
+ COMMIT_INFOS.addField("commit_comment", DBType.VARCHAR); //$NON-NLS-1$
public static final IDBIndex INDEX_COMMIT_INFOS_PK = //
- COMMIT_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, COMMIT_INFOS_TIMESTAMP);
+ COMMIT_INFOS.addIndex(IDBIndex.Type.PRIMARY_KEY, COMMIT_INFOS_TIMESTAMP);
public static final IDBIndex INDEX_COMMIT_INFOS_BRANCH = //
- COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_BRANCH);
+ COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_BRANCH);
public static final IDBIndex INDEX_COMMIT_INFOS_USER = //
- COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_USER);
+ COMMIT_INFOS.addIndex(IDBIndex.Type.NON_UNIQUE, COMMIT_INFOS_USER);
public static final String SQL_CREATE_COMMIT_INFO = "INSERT INTO " + COMMIT_INFOS + "(" + COMMIT_INFOS_TIMESTAMP //$NON-NLS-1$ //$NON-NLS-2$
+ ", " + COMMIT_INFOS_PREVIOUS_TIMESTAMP + ", " + COMMIT_INFOS_BRANCH + ", " + COMMIT_INFOS_USER + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- + COMMIT_INFOS_COMMENT + ") "
- + "VALUES (?, ?, ?, ?, ?)"; //$NON-NLS-1$
+ + COMMIT_INFOS_COMMENT + ") " + "VALUES (?, ?, ?, ?, ?)"; //$NON-NLS-2$
/**
* DBTable cdo_lobs
@@ -173,19 +172,19 @@ public class CDODBSchema
public static final IDBTable LOBS = INSTANCE.addTable("cdo_lobs"); //$NON-NLS-1$
public static final IDBField LOBS_ID = //
- LOBS.addField("id", DBType.VARCHAR, 64, true); //$NON-NLS-1$
+ LOBS.addField("id", DBType.VARCHAR, 64, true); //$NON-NLS-1$
public static final IDBField LOBS_SIZE = //
- LOBS.addField("lsize", DBType.BIGINT); //$NON-NLS-1$
+ LOBS.addField("lsize", DBType.BIGINT); //$NON-NLS-1$
public static final IDBField LOBS_BDATA = //
- LOBS.addField("bdata", DBType.BLOB); //$NON-NLS-1$
+ LOBS.addField("bdata", DBType.BLOB); //$NON-NLS-1$
public static final IDBField LOBS_CDATA = //
- LOBS.addField("cdata", DBType.CLOB); //$NON-NLS-1$
+ LOBS.addField("cdata", DBType.CLOB); //$NON-NLS-1$
public static final IDBIndex INDEX_LOBS_ID = //
- LOBS.addIndex(IDBIndex.Type.PRIMARY_KEY, LOBS_ID);
+ LOBS.addIndex(IDBIndex.Type.PRIMARY_KEY, LOBS_ID);
public static final String SQL_QUERY_LOBS = "SELECT 1 FROM " + CDODBSchema.LOBS + " WHERE " + CDODBSchema.LOBS_ID //$NON-NLS-1$ //$NON-NLS-2$
+ "=?"; //$NON-NLS-1$
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
index 9efd29ccc8..48df638948 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
@@ -32,6 +32,7 @@ import org.eclipse.emf.cdo.server.db.IMetaDataManager;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.IMappingConstants;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.UnitMappingTable;
import org.eclipse.emf.cdo.server.internal.db.messages.Messages;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalSession;
@@ -115,6 +116,8 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
private DurableLockingManager durableLockingManager = new DurableLockingManager(this);
+ private UnitMappingTable unitMappingTable;
+
private IMappingStrategy mappingStrategy;
private IDBDatabase database;
@@ -237,6 +240,11 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
return durableLockingManager;
}
+ public UnitMappingTable getUnitMappingTable()
+ {
+ return unitMappingTable;
+ }
+
public Timer getConnectionKeepAliveTimer()
{
return connectionKeepAliveTimer;
@@ -640,6 +648,12 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
LifecycleUtil.activate(durableLockingManager);
LifecycleUtil.activate(mappingStrategy);
+ if (repository.isSupportingUnits())
+ {
+ unitMappingTable = new UnitMappingTable(mappingStrategy);
+ unitMappingTable.activate();
+ }
+
setRevisionTemporality(mappingStrategy.hasAuditSupport() ? RevisionTemporality.AUDITING : RevisionTemporality.NONE);
setRevisionParallelism(
mappingStrategy.hasBranchingSupport() ? RevisionParallelism.BRANCHING : RevisionParallelism.NONE);
@@ -659,6 +673,7 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
@Override
protected void doDeactivate() throws Exception
{
+ LifecycleUtil.deactivate(unitMappingTable);
LifecycleUtil.deactivate(mappingStrategy);
LifecycleUtil.deactivate(durableLockingManager);
LifecycleUtil.deactivate(metaDataManager);
@@ -961,7 +976,7 @@ public class DBStore extends Store implements IDBStore, IMappingConstants, CDOAl
};
private static final SchemaMigrator[] SCHEMA_MIGRATORS = { NO_MIGRATION_NEEDED, NON_AUDIT_MIGRATION,
- LOB_SIZE_MIGRATION, NO_MIGRATION_NEEDED };
+ LOB_SIZE_MIGRATION, NO_MIGRATION_NEEDED };
static
{
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
index 834cbca7b9..90514b8911 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
@@ -39,6 +39,7 @@ import org.eclipse.emf.cdo.server.ISession;
import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.server.IStoreAccessor.DurableLocking2;
import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
@@ -49,6 +50,7 @@ import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.UnitMappingTable;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader3;
@@ -63,8 +65,11 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalUnitManager;
+import org.eclipse.emf.cdo.spi.server.InternalUnitManager.InternalObjectAttacher;
import org.eclipse.emf.cdo.spi.server.StoreAccessor;
+import org.eclipse.net4j.db.BatchedStatement;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBConnection;
@@ -118,10 +123,10 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
private ConnectionKeepAliveTask connectionKeepAliveTask;
- private Set<CDOID> newObjects = new HashSet<CDOID>();
-
private CDOID maxID = CDOID.NULL;
+ private InternalObjectAttacher objectAttacher;
+
public DBStoreAccessor(DBStore store, ISession session) throws DBException
{
super(store, session);
@@ -133,17 +138,17 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
}
@Override
- public DBStore getStore()
+ public final DBStore getStore()
{
return (DBStore)super.getStore();
}
- public IDBConnection getDBConnection()
+ public final IDBConnection getDBConnection()
{
return connection;
}
- public Connection getConnection()
+ public final Connection getConnection()
{
return connection;
}
@@ -480,17 +485,17 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
{
super.applyIDMappings(context, monitor);
+ DBStore store = getStore();
+ IIDHandler idHandler = store.getIDHandler();
+
// Remember maxID because it may have to be adjusted if the repository is BACKUP or CLONE. See bug 325097.
boolean adjustMaxID = !context.getBranchPoint().getBranch().isLocal()
- && getStore().getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE;
-
- IIDHandler idHandler = getStore().getIDHandler();
+ && store.getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE;
// Remember CDOIDs of new objects. They are cleared after writeRevisions()
for (InternalCDORevision revision : context.getNewObjects())
{
CDOID id = revision.getID();
- newObjects.add(id);
if (adjustMaxID && idHandler.compare(id, maxID) > 0)
{
@@ -560,24 +565,52 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
}
@Override
- protected void writeRevisions(InternalCDORevision[] revisions, CDOBranch branch, OMMonitor monitor)
+ protected void writeNewObjectRevisions(InternalCommitContext context, InternalCDORevision[] newObjects,
+ CDOBranch branch, OMMonitor monitor)
+ {
+ writeRevisions(context, true, newObjects, branch, monitor);
+ }
+
+ @Override
+ protected void writeDirtyObjectRevisions(InternalCommitContext context, InternalCDORevision[] dirtyObjects,
+ CDOBranch branch, OMMonitor monitor)
+ {
+ writeRevisions(context, false, dirtyObjects, branch, monitor);
+ }
+
+ protected void writeRevisions(InternalCommitContext context, boolean attachNewObjects,
+ InternalCDORevision[] revisions, CDOBranch branch, OMMonitor monitor)
{
try
{
monitor.begin(revisions.length);
for (InternalCDORevision revision : revisions)
{
- boolean mapType = newObjects.contains(revision.getID());
- writeRevision(revision, mapType, true, monitor.fork());
+ writeRevision(revision, attachNewObjects, true, monitor.fork());
+ }
+
+ if (attachNewObjects)
+ {
+ InternalRepository repository = getStore().getRepository();
+ if (repository.isSupportingUnits())
+ {
+ InternalUnitManager unitManager = repository.getUnitManager();
+ objectAttacher = unitManager.attachObjects(context);
+ }
}
}
finally
{
- newObjects.clear();
monitor.done();
}
}
+ @Override
+ protected void writeRevisions(InternalCDORevision[] revisions, CDOBranch branch, OMMonitor monitor)
+ {
+ throw new UnsupportedOperationException();
+ }
+
protected void writeRevision(InternalCDORevision revision, boolean mapType, boolean revise, OMMonitor monitor)
{
if (TRACER.isEnabled())
@@ -708,6 +741,12 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
getStore().getIDHandler().adjustLastObjectID(maxID);
maxID = CDOID.NULL;
}
+
+ if (objectAttacher != null)
+ {
+ objectAttacher.finishedCommit(true);
+ objectAttacher = null;
+ }
}
finally
{
@@ -730,6 +769,12 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
@Override
protected final void doRollback(IStoreAccessor.CommitContext commitContext)
{
+ if (objectAttacher != null)
+ {
+ objectAttacher.finishedCommit(false);
+ objectAttacher = null;
+ }
+
getStore().getMetaDataManager().clearMetaIDMappings();
if (TRACER.isEnabled())
@@ -758,6 +803,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
DBStore store = getStore();
connection = store.getDatabase().getConnection();
connectionKeepAliveTask = new ConnectionKeepAliveTask(this);
+ objectAttacher = null;
long keepAlivePeriod = ConnectionKeepAliveTask.EXECUTION_PERIOD;
Map<String, String> storeProps = store.getProperties();
@@ -1443,6 +1489,38 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
manager.unlock(this, durableLockingID);
}
+ public List<CDOID> readUnitRoots()
+ {
+ UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
+ return unitMappingTable.readUnitRoots(this);
+ }
+
+ public void readUnit(IView view, CDOID rootID, CDORevisionHandler revisionHandler)
+ {
+ UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
+ unitMappingTable.readUnitRevisions(this, view, rootID, revisionHandler);
+ }
+
+ public Object initUnit(IView view, CDOID rootID, CDORevisionHandler revisionHandler, Set<CDOID> initializedIDs,
+ long timeStamp)
+ {
+ UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
+ return unitMappingTable.initUnit(this, timeStamp, view, rootID, revisionHandler, initializedIDs);
+ }
+
+ public void finishUnit(IView view, CDOID rootID, CDORevisionHandler revisionHandler, long timeStamp,
+ Object initResult, List<CDOID> ids)
+ {
+ UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
+ unitMappingTable.finishUnit((BatchedStatement)initResult, rootID, ids, timeStamp);
+ }
+
+ public void writeUnits(Map<CDOID, CDOID> unitMappings, long timeStamp)
+ {
+ UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
+ unitMappingTable.writeUnitMappings(this, unitMappings, timeStamp);
+ }
+
/**
* @author Stefan Winkler
*/
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java
index 71ad7546e0..77abb2bd05 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MetaDataManager.java
@@ -238,8 +238,11 @@ public class MetaDataManager extends Lifecycle implements IMetaDataManager
try
{
- String sql = "INSERT INTO " + CDODBSchema.PACKAGE_UNITS + " VALUES (?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$
+ String sql = "INSERT INTO " + CDODBSchema.PACKAGE_UNITS + " (" + CDODBSchema.PACKAGE_UNITS_ID + ", " //$NON-NLS-1$ //$NON-NLS-2$
+ + CDODBSchema.PACKAGE_UNITS_ORIGINAL_TYPE + ", " + CDODBSchema.PACKAGE_UNITS_TIME_STAMP + ", "
+ + CDODBSchema.PACKAGE_UNITS_PACKAGE_DATA + ") VALUES (?, ?, ?, ?)";
DBUtil.trace(sql);
+
IDBPreparedStatement stmt = connection.prepareStatement(sql, ReuseProbability.MEDIUM);
try
@@ -311,7 +314,8 @@ public class MetaDataManager extends Lifecycle implements IMetaDataManager
String parentURI = packageInfo.getParentURI();
String unitID = packageInfo.getPackageUnit().getID();
- String sql = "INSERT INTO " + CDODBSchema.PACKAGE_INFOS + " VALUES (?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$
+ String sql = "INSERT INTO " + CDODBSchema.PACKAGE_INFOS + " (" + CDODBSchema.PACKAGE_INFOS_URI + ", " //$NON-NLS-1$ //$NON-NLS-2$
+ + CDODBSchema.PACKAGE_INFOS_PARENT + ", " + CDODBSchema.PACKAGE_INFOS_UNIT + ") VALUES (?, ?, ?)";
DBUtil.trace(sql);
IDBPreparedStatement stmt = connection.prepareStatement(sql, ReuseProbability.MEDIUM);
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java
index 9c2b20d146..040285c0db 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/UUIDHandler.java
@@ -63,6 +63,7 @@ public class UUIDHandler extends Lifecycle implements IIDHandler
public int compare(CDOID id1, CDOID id2)
{
+ // UUIDs are not generated in strictly ordered form.
throw new UnsupportedOperationException();
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
index 9552980072..78590284f4 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
@@ -55,6 +55,7 @@ import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
@@ -828,6 +829,21 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
public abstract IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature);
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ deactivateClassMappings();
+ super.doDeactivate();
+ }
+
+ protected void deactivateClassMappings()
+ {
+ for (IClassMapping classMapping : classMappings.values())
+ {
+ LifecycleUtil.deactivate(classMapping);
+ }
+ }
+
private static Set<CDOFeatureType> doGetForceIndexes(IMappingStrategy mappingStrategy)
{
return CDOFeatureType.readCombination(mappingStrategy.getProperties().get(Props.FORCE_INDEXES));
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java
index 695e803227..b68f84dc8c 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java
@@ -13,7 +13,8 @@ package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping2;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping3;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.ecore.EClass;
@@ -22,7 +23,7 @@ import org.eclipse.emf.ecore.EStructuralFeature;
/**
* @author Stefan Winkler
*/
-public abstract class AbstractBasicListTableMapping implements IListMapping2, IMappingConstants
+public abstract class AbstractBasicListTableMapping implements IListMapping3, IMappingConstants
{
private IMappingStrategy mappingStrategy;
@@ -70,5 +71,10 @@ public abstract class AbstractBasicListTableMapping implements IListMapping2, IM
builder.append(toIndex - 1);
}
+ public void setClassMapping(IClassMapping classMapping)
+ {
+ // Subclasses may override.
+ }
+
public abstract void rawDeleted(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java
index 2efd6d6307..31581f12f7 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java
@@ -31,6 +31,7 @@ import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping3;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
@@ -51,6 +52,7 @@ import org.eclipse.net4j.db.ddl.IDBIndex;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.spi.db.ddl.InternalDBIndex;
+import org.eclipse.net4j.util.lifecycle.IDeactivateable;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -79,7 +81,7 @@ import java.util.Set;
* @author Eike Stepper
* @since 2.0
*/
-public abstract class AbstractHorizontalClassMapping implements IClassMapping, IMappingConstants
+public abstract class AbstractHorizontalClassMapping implements IClassMapping, IMappingConstants, IDeactivateable
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalClassMapping.class);
@@ -142,7 +144,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
primaryKey.addIndexField(branchField);
}
- table.addIndex(IDBIndex.Type.NON_UNIQUE, ATTRIBUTES_ID, ATTRIBUTES_REVISED);
+ table.addIndex(IDBIndex.Type.NON_UNIQUE, ATTRIBUTES_REVISED);
}
}
@@ -175,6 +177,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
mapping = mappingStrategy.createListMapping(eClass, feature);
}
+ if (mapping instanceof IListMapping3)
+ {
+ ((IListMapping3)mapping).setClassMapping(this);
+ }
+
listMappings.add(mapping);
// Add field for list sizes
@@ -294,9 +301,10 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
}
stmt.setMaxRows(1); // Optimization: only 1 row
-
resultSet = stmt.executeQuery();
- if (!resultSet.next())
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ if (!readValuesFromResultSet(resultSet, idHandler, revision, false))
{
if (TRACER.isEnabled())
{
@@ -306,69 +314,95 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
return false;
}
- revision.setVersion(resultSet.getInt(ATTRIBUTES_VERSION));
+ return true;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ }
+ }
- long timeStamp = resultSet.getLong(ATTRIBUTES_CREATED);
+ /**
+ * Read the revision's values from the DB.
+ *
+ * @return <code>true</code> if the revision has been read successfully.<br>
+ * <code>false</code> if the revision does not exist in the DB.
+ */
+ protected final boolean readValuesFromResultSet(ResultSet resultSet, IIDHandler idHandler,
+ InternalCDORevision revision, boolean forUnit)
+ {
+ try
+ {
+ if (resultSet.next())
+ {
+ long timeStamp = resultSet.getLong(ATTRIBUTES_CREATED);
+ CDOBranchPoint branchPoint = revision.getBranch().getPoint(timeStamp);
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- CDOBranchPoint branchPoint = revision.getBranch().getPoint(timeStamp);
+ if (forUnit)
+ {
+ revision.setID(idHandler.getCDOID(resultSet, ATTRIBUTES_ID));
+ }
- revision.setBranchPoint(branchPoint);
- revision.setRevised(resultSet.getLong(ATTRIBUTES_REVISED));
- revision.setResourceID(idHandler.getCDOID(resultSet, ATTRIBUTES_RESOURCE));
- revision.setContainerID(idHandler.getCDOID(resultSet, ATTRIBUTES_CONTAINER));
- revision.setContainingFeatureID(resultSet.getInt(ATTRIBUTES_FEATURE));
+ revision.setBranchPoint(branchPoint);
+ revision.setVersion(resultSet.getInt(ATTRIBUTES_VERSION));
+ revision.setRevised(resultSet.getLong(ATTRIBUTES_REVISED));
+ revision.setResourceID(idHandler.getCDOID(resultSet, ATTRIBUTES_RESOURCE));
+ revision.setContainerID(idHandler.getCDOID(resultSet, ATTRIBUTES_CONTAINER));
+ revision.setContainingFeatureID(resultSet.getInt(ATTRIBUTES_FEATURE));
- for (ITypeMapping mapping : valueMappings)
- {
- EStructuralFeature feature = mapping.getFeature();
- if (feature.isUnsettable())
+ for (ITypeMapping mapping : valueMappings)
{
- IDBField field = unsettableFields.get(feature);
- if (!resultSet.getBoolean(field.getName()))
+ EStructuralFeature feature = mapping.getFeature();
+ if (feature.isUnsettable())
{
- // isSet==false -- setValue: null
- revision.setValue(feature, null);
- continue;
+ IDBField field = unsettableFields.get(feature);
+ if (!resultSet.getBoolean(field.getName()))
+ {
+ // isSet==false -- setValue: null
+ revision.setValue(feature, null);
+ continue;
+ }
}
- }
- mapping.readValueToRevision(resultSet, revision);
- }
+ mapping.readValueToRevision(resultSet, revision);
+ }
- if (listSizeFields != null)
- {
- for (Map.Entry<EStructuralFeature, IDBField> listSizeEntry : listSizeFields.entrySet())
+ if (listSizeFields != null)
{
- EStructuralFeature feature = listSizeEntry.getKey();
- IDBField field = listSizeEntry.getValue();
- int size = resultSet.getInt(field.getName());
+ for (Map.Entry<EStructuralFeature, IDBField> listSizeEntry : listSizeFields.entrySet())
+ {
+ EStructuralFeature feature = listSizeEntry.getKey();
+ IDBField field = listSizeEntry.getValue();
+ int size = resultSet.getInt(field.getName());
- // ensure the listSize (TODO: remove assertion)
- CDOList list = revision.getList(feature, size);
+ // ensure the listSize (TODO: remove assertion)
+ CDOList list = revision.getList(feature, size);
- for (int i = 0; i < size; i++)
- {
- list.add(InternalCDOList.UNINITIALIZED);
- }
+ for (int i = 0; i < size; i++)
+ {
+ list.add(InternalCDOList.UNINITIALIZED);
+ }
- if (list.size() != size)
- {
- Assert.isTrue(false);
+ if (list.size() != size)
+ {
+ Assert.isTrue(false);
+ }
}
}
+
+ return true;
}
- return true;
+ return false;
}
catch (SQLException ex)
{
throw new DBException(ex);
}
- finally
- {
- DBUtil.close(resultSet);
- }
}
protected final void readLists(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
@@ -926,6 +960,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I
protected abstract void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision);
+ public Exception deactivate()
+ {
+ return null;
+ }
+
protected static void appendTypeMappingNames(StringBuilder builder, Collection<ITypeMapping> typeMappings)
{
if (typeMappings != null)
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java
index 3583e2e2c5..9e1cdc6240 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java
@@ -36,11 +36,14 @@ import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
import org.eclipse.emf.cdo.server.db.IIDHandler;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingUnitSupport;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
@@ -75,7 +78,8 @@ import java.util.List;
* @author Stefan Winkler
* @author Lothar Werzinger
*/
-public class AuditListTableMappingWithRanges extends AbstractBasicListTableMapping implements IListMappingDeltaSupport
+public class AuditListTableMappingWithRanges extends AbstractBasicListTableMapping
+ implements IListMappingDeltaSupport, IListMappingUnitSupport
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AuditListTableMappingWithRanges.class);
@@ -84,6 +88,11 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
*/
private static final int FINAL_VERSION = Integer.MAX_VALUE;
+ private static final String SQL_ORDER_BY_INDEX = " ORDER BY " + LIST_IDX;
+
+ private static final boolean CHECK_UNIT_ENTRIES = Boolean
+ .getBoolean("org.eclipse.emf.cdo.server.db.checkUnitEntries");
+
/**
* The table of this mapping.
*/
@@ -97,7 +106,7 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
// --------- SQL strings - see initSQLStrings() -----------------
private String sqlSelectChunksPrefix;
- private String sqlOrderByIndex;
+ private String sqlSelectUnitEntries;
private String sqlInsertEntry;
@@ -172,8 +181,6 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
builder.append(">?)"); //$NON-NLS-1$
sqlSelectChunksPrefix = builder.toString();
- sqlOrderByIndex = " ORDER BY " + LIST_IDX; //$NON-NLS-1$
-
// ----------------- insert entry -----------------
builder = new StringBuilder("INSERT INTO "); //$NON-NLS-1$
builder.append(tableName);
@@ -271,6 +278,26 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
sqlDeleteList = builder.toString();
}
+ @Override
+ public void setClassMapping(IClassMapping classMapping)
+ {
+ InternalRepository repository = (InternalRepository)getMappingStrategy().getStore().getRepository();
+ if (repository.isSupportingUnits())
+ {
+ String listTableName = getTable().getName();
+ String attributesTableName = classMapping.getDBTables().get(0).getName();
+
+ sqlSelectUnitEntries = "SELECT " + (CHECK_UNIT_ENTRIES ? ATTRIBUTES_ID + ", " : "") + "cdo_list." + LIST_VALUE + //
+ " FROM " + listTableName + " cdo_list, " + attributesTableName + ", " + UnitMappingTable.UNITS + //
+ " WHERE " + UnitMappingTable.UNITS_ELEM + "=" + ATTRIBUTES_ID + //
+ " AND " + ATTRIBUTES_ID + "=cdo_list." + LIST_REVISION_ID + //
+ " AND " + UnitMappingTable.UNITS_UNIT + "=?" + //
+ " AND cdo_list." + LIST_REVISION_VERSION_ADDED + "<=" + ATTRIBUTES_VERSION + //
+ " AND (cdo_list." + LIST_REVISION_VERSION_REMOVED + " IS NULL OR cdo_list." + LIST_REVISION_VERSION_REMOVED
+ + ">" + ATTRIBUTES_VERSION + ") ORDER BY cdo_list." + LIST_REVISION_ID + ", cdo_list." + LIST_IDX;
+ }
+ }
+
public Collection<IDBTable> getDBTables()
{
return Collections.singleton(table);
@@ -301,7 +328,7 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
getFeature().getName(), revision.getID(), revision.getVersion());
}
- String sql = sqlSelectChunksPrefix + sqlOrderByIndex;
+ String sql = sqlSelectChunksPrefix + SQL_ORDER_BY_INDEX;
IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.HIGH);
@@ -365,7 +392,7 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
builder.append(where);
}
- builder.append(sqlOrderByIndex);
+ builder.append(SQL_ORDER_BY_INDEX);
String sql = builder.toString();
IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
@@ -536,6 +563,259 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
throw new UnsupportedOperationException("Raw deletion does not work in range-based mappings");
}
+ public ResultSet queryUnitEntries(IDBStoreAccessor accessor, IIDHandler idHandler, CDOID rootID) throws SQLException
+ {
+ IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlSelectUnitEntries,
+ ReuseProbability.MEDIUM);
+ idHandler.setCDOID(stmt, 1, rootID);
+ return stmt.executeQuery();
+ }
+
+ public void readUnitEntries(ResultSet resultSet, IIDHandler idHandler, CDOID id, MoveableList<Object> list)
+ throws SQLException
+ {
+ int size = list.size();
+ for (int i = 0; i < size; i++)
+ {
+ resultSet.next();
+
+ if (CHECK_UNIT_ENTRIES)
+ {
+ CDOID checkID = idHandler.getCDOID(resultSet, 1);
+ if (checkID != id)
+ {
+ throw new IllegalStateException("Result set does not deliver expected result");
+ }
+ }
+
+ Object value = typeMapping.readValue(resultSet);
+ list.set(i, value);
+ }
+ }
+
+ private void addEntry(IDBStoreAccessor accessor, CDOID id, int version, int index, Object value)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adding value for feature() {0}.{1} index {2} of {3}v{4} : {5}", //$NON-NLS-1$
+ getContainingClass().getName(), getFeature().getName(), index, id, version, value);
+ }
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertEntry, ReuseProbability.HIGH);
+
+ try
+ {
+ int column = 1;
+ idHandler.setCDOID(stmt, column++, id);
+ stmt.setInt(column++, version);
+ stmt.setInt(column++, index);
+ typeMapping.setValue(stmt, column++, value);
+
+ DBUtil.update(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ catch (IllegalStateException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ private void removeEntry(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion, int index)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4}", //$NON-NLS-1$
+ getContainingClass().getName(), getFeature().getName(), index, id, newVersion);
+ }
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlDeleteEntry, ReuseProbability.HIGH);
+
+ try
+ {
+ // try to delete a temporary entry first
+ int column = 1;
+ idHandler.setCDOID(stmt, column++, id);
+ stmt.setInt(column++, index);
+ stmt.setInt(column++, newVersion);
+
+ int result = DBUtil.update(stmt, false);
+ if (result == 1)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("removeEntry deleted: {0}", index); //$NON-NLS-1$
+ }
+ }
+ else if (result > 1)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("removeEntry Too many results: {0}: {1}", index, result); //$NON-NLS-1$
+ }
+
+ throw new DBException("Too many results"); //$NON-NLS-1$
+ }
+ else
+ {
+ // no temporary entry found, so mark the entry as removed
+ DBUtil.close(stmt);
+ stmt = accessor.getDBConnection().prepareStatement(sqlRemoveEntry, ReuseProbability.HIGH);
+
+ column = 1;
+ stmt.setInt(column++, newVersion);
+ idHandler.setCDOID(stmt, column++, id);
+ stmt.setInt(column++, index);
+
+ DBUtil.update(stmt, true);
+ }
+ }
+ catch (SQLException e)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$
+ getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage());
+ }
+
+ throw new DBException(e);
+ }
+ catch (IllegalStateException e)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$
+ getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage());
+ }
+
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ private Object getValue(IDBStoreAccessor accessor, CDOID id, int index)
+ {
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlGetValue, ReuseProbability.HIGH);
+ Object result = null;
+
+ try
+ {
+ int column = 1;
+ idHandler.setCDOID(stmt, column++, id);
+ stmt.setInt(column++, index);
+
+ ResultSet resultSet = stmt.executeQuery();
+ if (!resultSet.next())
+ {
+ throw new DBException("getValue() expects exactly one result");
+ }
+
+ result = typeMapping.readValue(resultSet);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read value (index {0}) from result set: {1}", index, result); //$NON-NLS-1$
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+
+ return result;
+ }
+
+ public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere,
+ QueryXRefsContext context, String idString)
+ {
+
+ String tableName = getTable().getName();
+ String listJoin = getMappingStrategy().getListJoin("a_t", "l_t");
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT l_t."); //$NON-NLS-1$
+ builder.append(LIST_REVISION_ID);
+ builder.append(", l_t."); //$NON-NLS-1$
+ builder.append(LIST_VALUE);
+ builder.append(", l_t."); //$NON-NLS-1$
+ builder.append(LIST_IDX);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(tableName);
+ builder.append(" l_t, ");//$NON-NLS-1$
+ builder.append(mainTableName);
+ builder.append(" a_t WHERE ");//$NON-NLS-1$
+ builder.append("a_t.");//$NON-NLS-1$
+ builder.append(mainTableWhere);
+ builder.append(listJoin);
+ builder.append(" AND "); //$NON-NLS-1$
+ builder.append(LIST_VALUE);
+ builder.append(" IN "); //$NON-NLS-1$
+ builder.append(idString);
+ String sql = builder.toString();
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Query XRefs (list): {0}", sql);
+ }
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.MEDIUM);
+ ResultSet resultSet = null;
+
+ try
+ {
+ resultSet = stmt.executeQuery();
+ while (resultSet.next())
+ {
+ CDOID sourceID = idHandler.getCDOID(resultSet, 1);
+ CDOID targetID = idHandler.getCDOID(resultSet, 2);
+ int idx = resultSet.getInt(3);
+
+ boolean more = context.addXRef(targetID, sourceID, (EReference)getFeature(), idx);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" add XRef to context: src={0}, tgt={1}, idx={2}", sourceID, targetID, idx);
+ }
+
+ if (!more)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(" result limit reached. Ignoring further results.");
+ }
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ DBUtil.close(stmt);
+ }
+ }
+
public void processDelta(final IDBStoreAccessor accessor, final CDOID id, final int branchId, int oldVersion,
final int newVersion, long created, CDOListFeatureDelta delta)
{
@@ -890,227 +1170,4 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi
}
}
}
-
- private void addEntry(IDBStoreAccessor accessor, CDOID id, int version, int index, Object value)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Adding value for feature() {0}.{1} index {2} of {3}v{4} : {5}", //$NON-NLS-1$
- getContainingClass().getName(), getFeature().getName(), index, id, version, value);
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertEntry, ReuseProbability.HIGH);
-
- try
- {
- int column = 1;
- idHandler.setCDOID(stmt, column++, id);
- stmt.setInt(column++, version);
- stmt.setInt(column++, index);
- typeMapping.setValue(stmt, column++, value);
-
- DBUtil.update(stmt, true);
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- catch (IllegalStateException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(stmt);
- }
- }
-
- private void removeEntry(IDBStoreAccessor accessor, CDOID id, int oldVersion, int newVersion, int index)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4}", //$NON-NLS-1$
- getContainingClass().getName(), getFeature().getName(), index, id, newVersion);
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlDeleteEntry, ReuseProbability.HIGH);
-
- try
- {
- // try to delete a temporary entry first
- int column = 1;
- idHandler.setCDOID(stmt, column++, id);
- stmt.setInt(column++, index);
- stmt.setInt(column++, newVersion);
-
- int result = DBUtil.update(stmt, false);
- if (result == 1)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("removeEntry deleted: {0}", index); //$NON-NLS-1$
- }
- }
- else if (result > 1)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("removeEntry Too many results: {0}: {1}", index, result); //$NON-NLS-1$
- }
-
- throw new DBException("Too many results"); //$NON-NLS-1$
- }
- else
- {
- // no temporary entry found, so mark the entry as removed
- DBUtil.close(stmt);
- stmt = accessor.getDBConnection().prepareStatement(sqlRemoveEntry, ReuseProbability.HIGH);
-
- column = 1;
- stmt.setInt(column++, newVersion);
- idHandler.setCDOID(stmt, column++, id);
- stmt.setInt(column++, index);
-
- DBUtil.update(stmt, true);
- }
- }
- catch (SQLException e)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$
- getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage());
- }
-
- throw new DBException(e);
- }
- catch (IllegalStateException e)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Removing value for feature() {0}.{1} index {2} of {3}v{4} FAILED {5}", //$NON-NLS-1$
- getContainingClass().getName(), getFeature().getName(), index, id, newVersion, e.getMessage());
- }
-
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(stmt);
- }
- }
-
- private Object getValue(IDBStoreAccessor accessor, CDOID id, int index)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlGetValue, ReuseProbability.HIGH);
- Object result = null;
-
- try
- {
- int column = 1;
- idHandler.setCDOID(stmt, column++, id);
- stmt.setInt(column++, index);
-
- ResultSet resultSet = stmt.executeQuery();
- if (!resultSet.next())
- {
- throw new DBException("getValue() expects exactly one result");
- }
-
- result = typeMapping.readValue(resultSet);
- if (TRACER.isEnabled())
- {
- TRACER.format("Read value (index {0}) from result set: {1}", index, result); //$NON-NLS-1$
- }
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(stmt);
- }
-
- return result;
- }
-
- public final boolean queryXRefs(IDBStoreAccessor accessor, String mainTableName, String mainTableWhere,
- QueryXRefsContext context, String idString)
- {
-
- String tableName = getTable().getName();
- String listJoin = getMappingStrategy().getListJoin("a_t", "l_t");
-
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT l_t."); //$NON-NLS-1$
- builder.append(LIST_REVISION_ID);
- builder.append(", l_t."); //$NON-NLS-1$
- builder.append(LIST_VALUE);
- builder.append(", l_t."); //$NON-NLS-1$
- builder.append(LIST_IDX);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(tableName);
- builder.append(" l_t, ");//$NON-NLS-1$
- builder.append(mainTableName);
- builder.append(" a_t WHERE ");//$NON-NLS-1$
- builder.append("a_t.");//$NON-NLS-1$
- builder.append(mainTableWhere);
- builder.append(listJoin);
- builder.append(" AND "); //$NON-NLS-1$
- builder.append(LIST_VALUE);
- builder.append(" IN "); //$NON-NLS-1$
- builder.append(idString);
- String sql = builder.toString();
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Query XRefs (list): {0}", sql);
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sql, ReuseProbability.MEDIUM);
- ResultSet resultSet = null;
-
- try
- {
- resultSet = stmt.executeQuery();
- while (resultSet.next())
- {
- CDOID sourceID = idHandler.getCDOID(resultSet, 1);
- CDOID targetID = idHandler.getCDOID(resultSet, 2);
- int idx = resultSet.getInt(3);
-
- boolean more = context.addXRef(targetID, sourceID, (EReference)getFeature(), idx);
- if (TRACER.isEnabled())
- {
- TRACER.format(" add XRef to context: src={0}, tgt={1}, idx={2}", sourceID, targetID, idx);
- }
-
- if (!more)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format(" result limit reached. Ignoring further results.");
- }
-
- return false;
- }
- }
-
- return true;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- DBUtil.close(resultSet);
- DBUtil.close(stmt);
- }
- }
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
index 63d4e1840c..504c82dbe0 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java
@@ -20,6 +20,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
@@ -35,18 +36,29 @@ import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingUnitSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingUnitSupport;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.DBStore;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.spi.common.revision.StubCDORevision;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBPreparedStatement;
import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability;
+import org.eclipse.net4j.db.IDBResultSet;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.collection.MoveableList;
+import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
+import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -54,28 +66,38 @@ import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
+import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
/**
* @author Eike Stepper
* @since 2.0
*/
public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
- implements IClassMappingAuditSupport, IClassMappingDeltaSupport
+ implements IClassMappingAuditSupport, IClassMappingDeltaSupport, IClassMappingUnitSupport
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalAuditClassMapping.class);
private String sqlInsertAttributes;
- private String sqlSelectCurrentAttributes;
-
- private String sqlSelectAllObjectIDs;
+ private String sqlSelectAttributesCurrent;
private String sqlSelectAttributesByTime;
private String sqlSelectAttributesByVersion;
+ private String sqlSelectUnitCurrent;
+
+ private String sqlSelectUnitByTime;
+
+ private String sqlSelectAllObjectIDs;
+
private String sqlReviseAttributes;
private String sqlRawDeleteAttributes;
@@ -98,47 +120,25 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
private void initSQLStrings()
{
// ----------- Select Revision ---------------------------
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_VERSION);
- builder.append(", "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_CREATED);
- builder.append(", "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_REVISED);
- builder.append(", "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_RESOURCE);
- builder.append(", "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_CONTAINER);
- builder.append(", "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_FEATURE);
- appendTypeMappingNames(builder, getValueMappings());
- appendFieldNames(builder, getUnsettableFields());
- appendFieldNames(builder, getListSizeFields());
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(getTable());
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_ID);
- builder.append("=? AND ("); //$NON-NLS-1$
- String sqlSelectAttributesPrefix = builder.toString();
- builder.append(ATTRIBUTES_REVISED);
- builder.append("=0)"); //$NON-NLS-1$
- sqlSelectCurrentAttributes = builder.toString();
+ String[] strings = buildSQLSelects(false);
+ String sqlSelectAttributesPrefix = strings[0];
+ sqlSelectAttributesCurrent = strings[1];
+ sqlSelectAttributesByTime = strings[2];
- builder = new StringBuilder(sqlSelectAttributesPrefix);
- builder.append(ATTRIBUTES_CREATED);
- builder.append("<=? AND ("); //$NON-NLS-1$
- builder.append(ATTRIBUTES_REVISED);
- builder.append("=0 OR "); //$NON-NLS-1$
- builder.append(ATTRIBUTES_REVISED);
- builder.append(">=?))"); //$NON-NLS-1$
- sqlSelectAttributesByTime = builder.toString();
-
- builder = new StringBuilder(sqlSelectAttributesPrefix);
+ StringBuilder builder = new StringBuilder(sqlSelectAttributesPrefix);
builder.append("ABS(");
builder.append(ATTRIBUTES_VERSION);
- builder.append(")=?)"); //$NON-NLS-1$
+ builder.append(")=?"); //$NON-NLS-1$
sqlSelectAttributesByVersion = builder.toString();
+ InternalRepository repository = (InternalRepository)getMappingStrategy().getStore().getRepository();
+ if (repository.isSupportingUnits())
+ {
+ strings = buildSQLSelects(true);
+ sqlSelectUnitCurrent = strings[1];
+ sqlSelectUnitByTime = strings[2];
+ }
+
// ----------- Insert Attributes -------------------------
builder = new StringBuilder();
builder.append("INSERT INTO "); //$NON-NLS-1$
@@ -200,6 +200,92 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
sqlRawDeleteAttributes = builder.toString();
}
+ private String[] buildSQLSelects(boolean forUnits)
+ {
+ String[] strings = new String[3];
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT "); //$NON-NLS-1$
+ if (forUnits)
+ {
+ builder.append(ATTRIBUTES_ID);
+ builder.append(", "); //$NON-NLS-1$
+ }
+
+ builder.append(ATTRIBUTES_VERSION);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_CREATED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_REVISED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_RESOURCE);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_CONTAINER);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_FEATURE);
+ appendTypeMappingNames(builder, getValueMappings());
+ appendFieldNames(builder, getUnsettableFields());
+ appendFieldNames(builder, getListSizeFields());
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable());
+
+ if (forUnits)
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(UnitMappingTable.UNITS);
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_ID);
+ builder.append("="); //$NON-NLS-1$
+ builder.append(UnitMappingTable.UNITS);
+ builder.append("."); //$NON-NLS-1$
+ builder.append(UnitMappingTable.UNITS_ELEM);
+ builder.append(" AND "); //$NON-NLS-1$
+ builder.append(UnitMappingTable.UNITS);
+ builder.append("."); //$NON-NLS-1$
+ builder.append(UnitMappingTable.UNITS_UNIT);
+ builder.append("=?"); //$NON-NLS-1$
+ builder.append(" AND "); //$NON-NLS-1$
+ }
+ else
+ {
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_ID);
+ builder.append("=? AND "); //$NON-NLS-1$
+ }
+
+ strings[0] = builder.toString();
+
+ builder.append(ATTRIBUTES_REVISED);
+ builder.append("=0"); //$NON-NLS-1$
+
+ if (forUnits)
+ {
+ builder.append(" ORDER BY "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_ID);
+ }
+
+ strings[1] = builder.toString();
+
+ builder = new StringBuilder(strings[0]);
+ builder.append("("); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_CREATED);
+ builder.append("<=? AND ("); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_REVISED);
+ builder.append("=0 OR "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_REVISED);
+ builder.append(">=?))"); //$NON-NLS-1$
+
+ if (forUnits)
+ {
+ builder.append(" ORDER BY "); //$NON-NLS-1$
+ builder.append(ATTRIBUTES_ID);
+ }
+
+ strings[2] = builder.toString();
+
+ return strings;
+ }
+
public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
{
IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
@@ -217,7 +303,7 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
}
else
{
- stmt = accessor.getDBConnection().prepareStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
+ stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesCurrent, ReuseProbability.HIGH);
idHandler.setCDOID(stmt, 1, revision.getID());
}
@@ -593,6 +679,210 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping
return builder.toString();
}
+ public void readUnitRevisions(IDBStoreAccessor accessor, CDOBranchPoint branchPoint, CDOID rootID,
+ CDORevisionHandler revisionHandler) throws SQLException
+ {
+ DBStore store = (DBStore)getMappingStrategy().getStore();
+ InternalRepository repository = store.getRepository();
+ CDOBranchPoint head = repository.getBranchManager().getMainBranch().getHead();
+ EClass eClass = getEClass();
+
+ IIDHandler idHandler = store.getIDHandler();
+ IDBPreparedStatement stmt = null;
+ int oldFetchSize = -1;
+
+ try
+ {
+ long timeStamp = branchPoint.getTimeStamp();
+ if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ stmt = accessor.getDBConnection().prepareStatement(sqlSelectUnitByTime, ReuseProbability.MEDIUM);
+ idHandler.setCDOID(stmt, 1, rootID);
+ stmt.setLong(2, timeStamp);
+ stmt.setLong(3, timeStamp);
+ }
+ else
+ {
+ stmt = accessor.getDBConnection().prepareStatement(sqlSelectUnitCurrent, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmt, 1, rootID);
+ }
+
+ AsnychronousListFiller listFiller = new AsnychronousListFiller(accessor, rootID, revisionHandler);
+ ConcurrencyUtil.execute(repository, listFiller);
+
+ oldFetchSize = stmt.getFetchSize();
+ stmt.setFetchSize(100000);
+ IDBResultSet resultSet = stmt.executeQuery();
+
+ for (;;)
+ {
+ InternalCDORevision revision = store.createRevision(eClass, null);
+ revision.setBranchPoint(head);
+
+ if (!readValuesFromResultSet(resultSet, idHandler, revision, true))
+ {
+ break;
+ }
+
+ listFiller.schedule(revision);
+ }
+
+ listFiller.await();
+ }
+ finally
+ {
+ if (oldFetchSize != -1)
+ {
+ stmt.setFetchSize(oldFetchSize);
+ }
+
+ DBUtil.close(stmt);
+ }
+ }
+
+ private class AsnychronousListFiller implements Runnable
+ {
+ private final BlockingQueue<InternalCDORevision> queue = new LinkedBlockingQueue<InternalCDORevision>();
+
+ private final CountDownLatch latch = new CountDownLatch(1);
+
+ private final IDBStoreAccessor accessor;
+
+ private final CDOID rootID;
+
+ private final DBStore store;
+
+ private final IIDHandler idHandler;
+
+ private final IListMappingUnitSupport[] listMappings;
+
+ private final ResultSet[] resultSets;
+
+ private final CDORevisionHandler revisionHandler;
+
+ private Throwable exception;
+
+ public AsnychronousListFiller(IDBStoreAccessor accessor, CDOID rootID, CDORevisionHandler revisionHandler)
+ {
+ this.accessor = accessor;
+ this.rootID = rootID;
+ this.revisionHandler = revisionHandler;
+
+ store = (DBStore)accessor.getStore();
+ idHandler = store.getIDHandler();
+
+ List<IListMapping> tmp = getListMappings();
+ int size = tmp.size();
+
+ listMappings = new IListMappingUnitSupport[size];
+ resultSets = new ResultSet[size];
+
+ int i = 0;
+ for (IListMapping listMapping : tmp)
+ {
+ listMappings[i++] = (IListMappingUnitSupport)listMapping;
+ }
+ }
+
+ public void schedule(InternalCDORevision revision)
+ {
+ queue.offer(revision);
+ }
+
+ public void await() throws SQLException
+ {
+ // Schedule an end marker revision.
+ schedule(new StubCDORevision(getEClass()));
+
+ try
+ {
+ latch.await();
+ }
+ catch (InterruptedException ex)
+ {
+ throw new TimeoutRuntimeException();
+ }
+
+ if (exception instanceof RuntimeException)
+ {
+ throw (RuntimeException)exception;
+ }
+
+ if (exception instanceof Error)
+ {
+ throw (Error)exception;
+ }
+
+ if (exception instanceof SQLException)
+ {
+ throw (SQLException)exception;
+ }
+
+ if (exception instanceof Exception)
+ {
+ throw WrappedException.wrap((Exception)exception);
+ }
+ }
+
+ public void run()
+ {
+ try
+ {
+ while (store.isActive())
+ {
+ InternalCDORevision revision = queue.poll(1, TimeUnit.SECONDS);
+ if (revision == null)
+ {
+ continue;
+ }
+
+ if (revision instanceof StubCDORevision)
+ {
+ return;
+ }
+
+ readUnitEntries(revision);
+ }
+ }
+ catch (Throwable ex)
+ {
+ exception = ex;
+ }
+ finally
+ {
+ latch.countDown();
+ }
+ }
+
+ private void readUnitEntries(InternalCDORevision revision) throws SQLException
+ {
+ CDOID id = revision.getID();
+
+ for (int i = 0; i < listMappings.length; i++)
+ {
+ IListMappingUnitSupport listMapping = listMappings[i];
+ EStructuralFeature feature = listMapping.getFeature();
+
+ MoveableList<Object> list = revision.getList(feature);
+ int size = list.size();
+ if (size != 0)
+ {
+ if (resultSets[i] == null)
+ {
+ resultSets[i] = listMapping.queryUnitEntries(accessor, idHandler, rootID);
+ }
+
+ listMapping.readUnitEntries(resultSets[i], idHandler, id, list);
+ }
+ }
+
+ synchronized (revisionHandler)
+ {
+ revisionHandler.handleRevision(revision);
+ }
+ }
+ }
+
/**
* @author Stefan Winkler
*/
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java
index 3a3b6795a2..85c1855bf7 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java
@@ -368,6 +368,8 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi
{
if (hasLists)
{
+ // Reading all list rows of an object is not atomic.
+ // After all row reads are done, check the revision version again (see below).
stmtVersion = accessor.getDBConnection().prepareStatement(sqlSelectCurrentVersion, ReuseProbability.HIGH);
stmtVersion.setMaxRows(1); // Optimization: only 1 row
idHandler.setCDOID(stmtVersion, 1, id);
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java
index cade3cb771..5787470f50 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ObjectTypeTable.java
@@ -21,6 +21,7 @@ import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
@@ -213,7 +214,7 @@ public class ObjectTypeTable extends AbstractObjectTypeMapper implements IMappin
{
super.doActivate();
- IDBStore store = getMappingStrategy().getStore();
+ final IDBStore store = getMappingStrategy().getStore();
final DBType idType = store.getIDHandler().getDBType();
final int idLength = store.getIDColumnLength();
@@ -230,6 +231,12 @@ public class ObjectTypeTable extends AbstractObjectTypeMapper implements IMappin
table.addField(ATTRIBUTES_CLASS, idType, idLength);
table.addField(ATTRIBUTES_CREATED, DBType.BIGINT);
table.addIndex(IDBIndex.Type.PRIMARY_KEY, ATTRIBUTES_ID);
+
+ InternalRepository repository = (InternalRepository)store.getRepository();
+ if (repository.isSupportingUnits())
+ {
+ table.addIndex(IDBIndex.Type.NON_UNIQUE, ATTRIBUTES_CLASS);
+ }
}
});
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/UnitMappingTable.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/UnitMappingTable.java
new file mode 100644
index 0000000000..4bdacb754f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/UnitMappingTable.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2010-2014 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - bug 259402
+ * Stefan Winkler - redesign (prepared statements)
+ * Stefan Winkler - bug 276926
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.server.IView;
+import org.eclipse.emf.cdo.server.db.IDBStore;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IIDHandler;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingUnitSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.BatchedStatement;
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBConnection;
+import org.eclipse.net4j.db.IDBDatabase;
+import org.eclipse.net4j.db.IDBDatabase.RunnableWithSchema;
+import org.eclipse.net4j.db.IDBPreparedStatement;
+import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability;
+import org.eclipse.net4j.db.ddl.IDBIndex;
+import org.eclipse.net4j.db.ddl.IDBSchema;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+
+import org.eclipse.emf.ecore.EClass;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public class UnitMappingTable extends Lifecycle implements IMappingConstants
+{
+ public static final String UNITS = "CDO_UNITS"; //$NON-NLS-1$
+
+ public static final String UNITS_ELEM = "CDO_ELEM"; //$NON-NLS-1$
+
+ public static final String UNITS_UNIT = "CDO_UNIT"; //$NON-NLS-1$
+
+ // public static final String UNITS_CREATED = "CDO_CREATED"; //$NON-NLS-1$
+
+ private static final String SQL_SELECT_ROOTS = "SELECT DISTINCT " + UNITS_UNIT + " FROM " + UNITS;
+
+ private static final String SQL_INSERT_MAPPINGS = "INSERT INTO " + UNITS + " (" + UNITS_ELEM + ", " + UNITS_UNIT
+ + ") VALUES (?, ?)";
+
+ private static final String SQL_SELECT_CLASSES = "SELECT DISTINCT " + ATTRIBUTES_CLASS + " FROM " + UNITS + ", "
+ + CDODBSchema.CDO_OBJECTS + " WHERE " + UNITS_ELEM + "=" + ATTRIBUTES_ID + " AND " + UNITS_UNIT + "=?";
+
+ private static final int WRITE_UNIT_MAPPING_BATCH_SIZE = 100000;
+
+ private final IMappingStrategy mappingStrategy;
+
+ private IDBTable table;
+
+ public UnitMappingTable(IMappingStrategy mappingStrategy)
+ {
+ this.mappingStrategy = mappingStrategy;
+ }
+
+ public List<CDOID> readUnitRoots(IDBStoreAccessor accessor)
+ {
+ List<CDOID> rootIDs = new ArrayList<CDOID>();
+ IIDHandler idHandler = mappingStrategy.getStore().getIDHandler();
+ Statement stmt = null;
+
+ try
+ {
+ stmt = accessor.getDBConnection().createStatement();
+
+ if (DBUtil.isTracerEnabled())
+ {
+ DBUtil.trace(stmt.toString());
+ }
+
+ ResultSet resultSet = stmt.executeQuery(SQL_SELECT_ROOTS);
+ while (resultSet.next())
+ {
+ CDOID rootID = idHandler.getCDOID(resultSet, 1);
+ rootIDs.add(rootID);
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+
+ return rootIDs;
+ }
+
+ public void readUnitRevisions(IDBStoreAccessor accessor, IView view, CDOID rootID, CDORevisionHandler revisionHandler)
+ {
+ IDBStore store = mappingStrategy.getStore();
+ IIDHandler idHandler = store.getIDHandler();
+ IMetaDataManager metaDataManager = store.getMetaDataManager();
+
+ IDBConnection connection = accessor.getDBConnection();
+ IDBPreparedStatement stmt = connection.prepareStatement(SQL_SELECT_CLASSES, ReuseProbability.HIGH);
+ int oldFetchSize = -1;
+
+ try
+ {
+ idHandler.setCDOID(stmt, 1, rootID);
+
+ oldFetchSize = stmt.getFetchSize();
+ stmt.setFetchSize(100000);
+ ResultSet resultSet = stmt.executeQuery();
+
+ while (resultSet.next())
+ {
+ CDOID classID = idHandler.getCDOID(resultSet, 1);
+ EClass eClass = (EClass)metaDataManager.getMetaInstance(classID);
+
+ IClassMappingUnitSupport classMapping = (IClassMappingUnitSupport)mappingStrategy.getClassMapping(eClass);
+ classMapping.readUnitRevisions(accessor, view, rootID, revisionHandler);
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ if (oldFetchSize != -1)
+ {
+ try
+ {
+ stmt.setFetchSize(oldFetchSize);
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ }
+
+ DBUtil.close(stmt);
+ }
+ }
+
+ public BatchedStatement initUnit(IDBStoreAccessor accessor, long timeStamp, IView view, CDOID rootID,
+ CDORevisionHandler revisionHandler, Set<CDOID> initializedIDs)
+ {
+ IIDHandler idHandler = mappingStrategy.getStore().getIDHandler();
+ IDBConnection connection = accessor.getDBConnection();
+ BatchedStatement stmt = DBUtil.batched(connection.prepareStatement(SQL_INSERT_MAPPINGS, ReuseProbability.HIGH),
+ WRITE_UNIT_MAPPING_BATCH_SIZE);
+
+ try
+ {
+ CDORevision revision = view.getRevision(rootID);
+
+ initUnit(stmt, view, rootID, revisionHandler, initializedIDs, timeStamp, idHandler, revision);
+ return stmt;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ // Don't close the statement; that's done later in finishUnit().
+ }
+ }
+
+ private void initUnit(BatchedStatement stmt, IView view, CDOID rootID, CDORevisionHandler revisionHandler,
+ Set<CDOID> initializedIDs, long timeStamp, IIDHandler idHandler, CDORevision revision) throws SQLException
+ {
+ revisionHandler.handleRevision(revision);
+
+ CDOID id = revision.getID();
+ initializedIDs.add(id);
+
+ writeUnitMapping(stmt, rootID, timeStamp, idHandler, id);
+
+ List<CDORevision> children = CDORevisionUtil.getChildRevisions(revision, view, true);
+ for (CDORevision child : children)
+ {
+ initUnit(stmt, view, rootID, revisionHandler, initializedIDs, timeStamp, idHandler, child);
+ }
+ }
+
+ public void finishUnit(BatchedStatement stmt, CDOID rootID, List<CDOID> ids, long timeStamp)
+ {
+ IDBStore store = mappingStrategy.getStore();
+ IIDHandler idHandler = store.getIDHandler();
+ Connection connection = null;
+
+ try
+ {
+ connection = stmt.getConnection();
+
+ for (CDOID id : ids)
+ {
+ writeUnitMapping(stmt, rootID, timeStamp, idHandler, id);
+ }
+ }
+ catch (SQLException ex)
+ {
+ DBUtil.rollbackSilently(connection);
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+
+ try
+ {
+ connection.commit();
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ }
+
+ public void writeUnitMappings(IDBStoreAccessor accessor, Map<CDOID, CDOID> unitMappings, long timeStamp)
+ {
+ IIDHandler idHandler = mappingStrategy.getStore().getIDHandler();
+ IDBConnection connection = accessor.getDBConnection();
+ BatchedStatement stmt = DBUtil.batched(connection.prepareStatement(SQL_INSERT_MAPPINGS, ReuseProbability.HIGH),
+ WRITE_UNIT_MAPPING_BATCH_SIZE);
+
+ try
+ {
+ for (Entry<CDOID, CDOID> entry : unitMappings.entrySet())
+ {
+ CDOID id = entry.getKey();
+ CDOID rootID = entry.getValue();
+ writeUnitMapping(stmt, rootID, timeStamp, idHandler, id);
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ private void writeUnitMapping(BatchedStatement stmt, CDOID rootID, long timeStamp, IIDHandler idHandler, CDOID id)
+ throws SQLException
+ {
+ idHandler.setCDOID(stmt, 1, id);
+ idHandler.setCDOID(stmt, 2, rootID);
+ // stmt.setLong(3, timeStamp);
+ stmt.executeUpdate();
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+
+ IDBStore store = mappingStrategy.getStore();
+ final DBType idType = store.getIDHandler().getDBType();
+ final int idLength = store.getIDColumnLength();
+
+ IDBDatabase database = store.getDatabase();
+ table = database.getSchema().getTable(UNITS);
+ if (table == null)
+ {
+ database.updateSchema(new RunnableWithSchema()
+ {
+ public void run(IDBSchema schema)
+ {
+ table = schema.addTable(UNITS);
+ table.addField(UNITS_ELEM, idType, idLength, true);
+ table.addField(UNITS_UNIT, idType, idLength);
+ // table.addField(UNITS_CREATED, DBType.BIGINT);
+ table.addIndex(IDBIndex.Type.PRIMARY_KEY, UNITS_ELEM);
+ table.addIndex(IDBIndex.Type.NON_UNIQUE, UNITS_UNIT);
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ table = null;
+ super.doDeactivate();
+ }
+}

Back to the top