summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Winkler2009-04-16 07:38:24 (EDT)
committerStefan Winkler2009-04-16 07:38:24 (EDT)
commit1a6330dd049c7a38b0137065877799cd356fc432 (patch)
tree52b8ce7fabb72f0316c58b514bfa1c583c6cc959
parent3dab375c44ab2c80d50ddb0587676c9fc7d3e6d3 (diff)
downloadcdo-1a6330dd049c7a38b0137065877799cd356fc432.zip
cdo-1a6330dd049c7a38b0137065877799cd356fc432.tar.gz
cdo-1a6330dd049c7a38b0137065877799cd356fc432.tar.bz2
Audit and Non-Audit working.
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/plugin.xml6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java127
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java33
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java3
-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.java58
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java360
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java15
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java (renamed from plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ListTableAuditMapping.java)235
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java61
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/FieldInfo.java42
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java520
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java583
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java51
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java392
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt - nonaudit).launch20
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt).launch20
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java19
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java128
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java23
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java295
28 files changed, 2396 insertions, 691 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/plugin.xml b/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
index 016d911..4a30c67 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
+++ b/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
@@ -26,12 +26,12 @@
<extension
point="org.eclipse.emf.cdo.server.db.mappingStrategies">
<mappingStrategy
- class="org.eclipse.emf.cdo.server.internal.db.mapping.HorizontalMappingStrategy"
+ class="org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy"
type="horizontal">
</mappingStrategy>
<mappingStrategy
- class="org.eclipse.emf.cdo.server.internal.db.mapping.VerticalMappingStrategy"
- type="vertical">
+ class="org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditMappingStrategy"
+ type="horizontalNonAudit">
</mappingStrategy>
</extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
index d420078..7b28a91 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java
@@ -16,17 +16,26 @@ import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.DBStore;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalNonAuditMappingStrategy;
+import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.IDBConnectionProvider;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
/**
* @author Eike Stepper
*/
@@ -64,6 +73,14 @@ public final class CDODBUtil
}
/**
+ * @since 2.0
+ */
+ public static IMappingStrategy createHorizontalNonAuditMappingStrategy()
+ {
+ return new HorizontalNonAuditMappingStrategy();
+ }
+
+ /**
* Can only be used when Eclipse is running. In standalone scenarios create the mapping strategy instance by directly
* calling the constructor of the mapping strategy class.
*
@@ -117,6 +134,27 @@ public final class CDODBUtil
return CDOIDUtil.getLong(id);
}
+ /**
+ * @since 2.0
+ */
+ public static int sqlUpdate(PreparedStatement stmt, boolean exactlyOne) throws SQLException
+ {
+ DBUtil.trace(stmt.toString());
+ int result = stmt.executeUpdate();
+
+ // basic check of update result
+ if (exactlyOne && result != 1)
+ {
+ throw new IllegalStateException(stmt.toString() + " returned Update count " + result + " (expected: 1)");
+ }
+ else if (result == Statement.EXECUTE_FAILED)
+ {
+ throw new IllegalStateException(stmt.toString() + " returned EXECUTE_FAILED.");
+ }
+
+ return result;
+ }
+
// public static CDODBStoreManager getStoreManager(IDBAdapter dbAdapter,
// DataSource dataSource)
// {
@@ -134,4 +172,93 @@ public final class CDODBUtil
// DataSource dataSource = DBUtil.createDataSource(properties, "datasource");
// return getStoreManager(dbAdapter, dataSource);
// }
+
+ /**
+ * For debugging purposes ONLY!
+ *
+ * @since 2.0
+ */
+ public static void sqlDump(Connection conn, String sql)
+ {
+ ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDODBUtil.class);
+ ResultSet rs = null;
+ try
+ {
+ TRACER.format("Dumping output of {0}", sql);
+ rs = conn.createStatement().executeQuery(sql);
+ int numCol = rs.getMetaData().getColumnCount();
+
+ StringBuilder row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
+ {
+ row.append(String.format("%10s | ", rs.getMetaData().getColumnLabel(c)));
+ }
+
+ TRACER.trace(row.toString());
+
+ row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
+ {
+ row.append("-----------+--");
+ }
+
+ TRACER.trace(row.toString());
+
+ while (rs.next())
+ {
+ row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
+ {
+ row.append(String.format("%10s | ", rs.getString(c)));
+ }
+
+ TRACER.trace(row.toString());
+ }
+
+ row = new StringBuilder();
+ for (int c = 1; c <= numCol; c++)
+ {
+ row.append("-----------+-");
+ }
+
+ TRACER.trace(row.toString());
+ }
+ catch (SQLException ex)
+ {
+ // NOP
+ }
+ finally
+ {
+ if (rs != null)
+ {
+ try
+ {
+ rs.close();
+ }
+ catch (SQLException ex)
+ {
+ // NOP
+ }
+ }
+ }
+ }
+
+ /**
+ * For debugging purposes ONLY!
+ *
+ * @since 2.0
+ */
+ public static void sqlDump(IDBConnectionProvider connectionProvider, String sql)
+ {
+ Connection connection = connectionProvider.getConnection();
+ try
+ {
+ sqlDump(connection, sql);
+ }
+ finally
+ {
+ DBUtil.close(connection);
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
index 535a1ef..2a27b70 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IClassMapping.java
@@ -18,6 +18,8 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
import java.sql.PreparedStatement;
import java.util.Collection;
@@ -42,4 +44,6 @@ public interface IClassMapping
PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
boolean exactMatch, long timeStamp);
+ IListMapping getListMapping(EStructuralFeature feature);
+
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java
index b8ae852..53f3274 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMapping.java
@@ -11,6 +11,7 @@
*/
package org.eclipse.emf.cdo.server.db.mapping;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
@@ -18,6 +19,8 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
import java.util.Collection;
import java.util.List;
@@ -36,4 +39,12 @@ public interface IListMapping
void readChunks(IDBStoreChunkReader dbStoreChunkReader, List<Chunk> chunks, String string);
Collection<IDBTable> getDBTables();
+
+ EStructuralFeature getFeature();
+
+ /**
+ * Hook with which a list mapping is notified that a containing object has been revised. Can be implemented in order
+ * to clean up lists of revised objects.
+ */
+ void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java
new file mode 100644
index 0000000..5bdcd16
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IListMappingDeltaSupport.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public interface IListMappingDeltaSupport
+{
+ void removeListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int index);
+
+ void insertListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, Object value);
+
+ void clearList(IDBStoreAccessor accessor, CDOID id);
+
+ void setListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, Object value);
+
+ void moveListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int oldPosition, int newPosition);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
index a2aa001..0b056ca 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/IMappingStrategy.java
@@ -87,8 +87,6 @@ public interface IMappingStrategy
public IClassMapping getClassMapping(EClass eClass);
- public IListMapping getListMapping(EStructuralFeature feature);
-
public boolean hasDeltaSupport();
public void queryResources(IDBStoreAccessor dbStoreAccessor, QueryResourcesContext context);
@@ -102,5 +100,4 @@ public interface IMappingStrategy
public long repairAfterCrash(IDBAdapter dbAdapter, Connection connection);
public void setProperties(Map<String, String> properties);
-
}
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 b81502b..705373c 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
@@ -80,7 +80,7 @@ public class DBStore extends LongIDStore implements IDBStore
@ExcludeFromDump
private transient StoreAccessorPool writerPool = new StoreAccessorPool(this, null);
- private MetaDataManager metaDataManager;
+ private IMetaDataManager metaDataManager;
public DBStore()
{
@@ -215,6 +215,7 @@ public class DBStore extends LongIDStore implements IDBStore
((ILifecycle)metaDataManager).activate();
Connection connection = getConnection();
+ LifecycleUtil.activate(mappingStrategy);
try
{
@@ -228,7 +229,6 @@ public class DBStore extends LongIDStore implements IDBStore
reStart(connection);
}
- LifecycleUtil.activate(mappingStrategy);
dbSchema = createSchema();
connection.commit();
@@ -365,4 +365,17 @@ public class DBStore extends LongIDStore implements IDBStore
{
return metaDataManager;
}
+
+ @Override
+ public Set<ChangeFormat> getSupportedChangeFormats()
+ {
+ if (mappingStrategy.hasDeltaSupport())
+ {
+ return set(ChangeFormat.DELTA);
+ }
+ else
+ {
+ return set(ChangeFormat.REVISION);
+ }
+ }
}
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 b9c88aa..e6d1d7f 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
@@ -23,8 +23,8 @@ import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.mapping.IAuditSupport;
-import org.eclipse.emf.cdo.server.db.mapping.IDeltaSupport;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IDeltaSupport;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
@@ -199,26 +199,45 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
{
IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
- if (!mappingStrategy.hasAuditSupport())
- {
- throw new UnsupportedOperationException("Mapping strategy does not support audits.");
- }
-
EClass eClass = getObjectType(id);
InternalCDORevision revision = (InternalCDORevision)CDORevisionUtil.create(eClass, id);
- IAuditSupport mapping = (IAuditSupport)mappingStrategy.getClassMapping(eClass);
+ IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
- if (TRACER.isEnabled())
+ boolean success = false;
+
+ if (mappingStrategy.hasAuditSupport())
{
- TRACER.format("Selecting revision: {0}, version={1}", id, version);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Selecting revision: {0}, version={1}", id, version);
+ }
+
+ // if audit support is present, just use the audit method
+ success = ((IAuditSupport)mapping).readRevisionByVersion(this, revision, version, referenceChunk);
}
- if (mapping.readRevisionByVersion(this, revision, version, referenceChunk))
+ else
{
- return revision;
+ // if audit support is not present, we still have to provide a method
+ // to readRevisionByVersion because TransactionCommitContext.computeDirtyObject
+ // needs to lookup the base revision for a change. Hence we emulate this
+ // behavior by getting the current revision and asserting that the version
+ // has not changed. This is valid because if the version has changed,
+ // we are in trouble because of a conflict anyways.
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Selecting current base revision: {0}", id);
+ }
+
+ success = mapping.readRevision(this, revision, referenceChunk);
+
+ if (success && revision.getVersion() != version)
+ {
+ throw new IllegalStateException("Can only retrieve current version " + revision.getVersion() + " for " + id
+ + " - version requested was " + version + ".");
+ }
}
- // Reading failed - revision does not exist.
- return null;
+ return success ? revision : null;
}
/**
@@ -360,9 +379,17 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
monitor.begin();
Async async = monitor.forkAsync();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("--- DB COMMIT ---");
+ }
+
try
{
getConnection().commit();
+
+ // CDODBUtil.sqlDump(getStore().getDBConnectionProvider(), "select * from CDOResourceFolder");
+ // CDODBUtil.sqlDump(getStore().getDBConnectionProvider(), "select * from CDOResource");
}
catch (SQLException ex)
{
@@ -378,6 +405,11 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce
@Override
protected final void rollback(IStoreAccessor.CommitContext commitContext)
{
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("--- DB ROLLBACK ---");
+ }
+
try
{
getConnection().rollback();
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java
index 1f17eaa..d05d157 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.server.internal.db;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
+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.IMappingStrategy;
import org.eclipse.emf.cdo.spi.server.StoreChunkReader;
@@ -33,7 +34,8 @@ public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChun
{
super(accessor, revision, feature);
IMappingStrategy mappingStrategy = accessor.getStore().getMappingStrategy();
- referenceMapping = mappingStrategy.getListMapping(feature);
+ IClassMapping mapping = mappingStrategy.getClassMapping(revision.getEClass());
+ referenceMapping = mapping.getListMapping(feature);
}
@Override
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 e313063..d6238f3 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
@@ -35,7 +35,6 @@ import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.collection.CloseableIterator;
-import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
@@ -79,14 +78,11 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
private Map<String, String> properties;
- private Map<Pair<EClass, EStructuralFeature>, IListMapping> listMappings;
-
private Map<EClass, IClassMapping> classMappings;
public AbstractMappingStrategy()
{
classMappings = new HashMap<EClass, IClassMapping>();
- listMappings = new HashMap<Pair<EClass, EStructuralFeature>, IListMapping>();
}
// -- property related methods -----------------------------------------
@@ -345,11 +341,6 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
tables.addAll(mapping.getDBTables());
}
- for (IListMapping mapping : listMappings.values())
- {
- tables.addAll(mapping.getDBTables());
- }
-
return tables;
}
@@ -435,23 +426,10 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
public final IListMapping createListMapping(EClass containingClass, EStructuralFeature feature)
{
- IListMapping mapping = doCreateManyMapping(containingClass, feature);
- if (mapping != null)
- {
- listMappings.put(new Pair<EClass, EStructuralFeature>(containingClass, feature), mapping);
- }
+ IListMapping mapping = doCreateListMapping(containingClass, feature);
return mapping;
}
- public abstract IListMapping doCreateManyMapping(EClass containingClass, EStructuralFeature feature);
-
- public final Map<Pair<EClass, EStructuralFeature>, IListMapping> getListMappings()
- {
- return listMappings;
- }
+ public abstract IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature);
- public final IListMapping getListMapping(EStructuralFeature feature)
- {
- return listMappings.get(feature);
- }
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java
index 2fc3740..f423cff 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java
@@ -23,8 +23,6 @@ import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EStructuralFeature;
import java.sql.PreparedStatement;
@@ -156,15 +154,17 @@ public abstract class TypeMapping implements ITypeMapping
@Override
public Object getResultSetValue(ResultSet resultSet, int column) throws SQLException
{
- EEnum type = (EEnum)getFeature().getEType();
- int value = resultSet.getInt(column);
- return type.getEEnumLiteral(value);
+ // see Bug 271941
+ return resultSet.getInt(column);
+ // EEnum type = (EEnum)getFeature().getEType();
+ // int value = resultSet.getInt(column);
+ // return type.getEEnumLiteral(value);
}
@Override
protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
{
- super.doSetValue(stmt, index, ((EEnumLiteral)value).getValue());
+ super.doSetValue(stmt, index, value);
}
}
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
new file mode 100644
index 0000000..a78b702
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java
@@ -0,0 +1,360 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IMetaDataManager;
+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.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBIndex;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public abstract class AbstractHorizontalClassMapping implements IClassMapping
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalClassMapping.class);
+
+ private EClass eClass;
+
+ private IDBTable table;
+
+ private AbstractHorizontalMappingStrategy mappingStrategy;
+
+ private List<ITypeMapping> valueMappings;
+
+ private List<IListMapping> listMappings;
+
+ public AbstractHorizontalClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ this.mappingStrategy = mappingStrategy;
+ this.eClass = eClass;
+
+ initTable();
+ initFeatures();
+ }
+
+ private void initTable()
+ {
+ String name = getMappingStrategy().getTableName(eClass);
+ table = getMappingStrategy().getStore().getDBSchema().addTable(name);
+
+ IDBField idField = table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER, true);
+ table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT, true);
+ IDBField revisedField = table.addField(CDODBSchema.ATTRIBUTES_REVISED, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_RESOURCE, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT, true);
+ table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER, true);
+
+ table.addIndex(IDBIndex.Type.NON_UNIQUE, idField, revisedField);
+ }
+
+ private void initFeatures()
+ {
+ EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
+
+ if (features == null)
+ {
+ valueMappings = Collections.emptyList();
+ listMappings = Collections.emptyList();
+ }
+ else
+ {
+ valueMappings = createValueMappings(features);
+ listMappings = createListMappings(features);
+ }
+ }
+
+ private List<ITypeMapping> createValueMappings(EStructuralFeature[] features)
+ {
+ List<ITypeMapping> mappings = new ArrayList<ITypeMapping>();
+ for (EStructuralFeature feature : features)
+ {
+ if (!feature.isMany())
+ {
+ ITypeMapping mapping = mappingStrategy.createValueMapping(feature);
+ mapping.createDBField(getTable());
+ mappings.add(mapping);
+ }
+ }
+
+ return mappings;
+ }
+
+ private List<IListMapping> createListMappings(EStructuralFeature[] features)
+ {
+ List<IListMapping> listMappings = new ArrayList<IListMapping>();
+ for (EStructuralFeature feature : features)
+ {
+ if (feature.isMany())
+ {
+ listMappings.add(mappingStrategy.createListMapping(eClass, feature));
+ }
+ }
+
+ return listMappings;
+ }
+
+ /**
+ * 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 readValuesFromStatement(PreparedStatement pstmt, InternalCDORevision revision)
+ {
+ ResultSet resultSet = null;
+ try
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Executing Query: {0}", pstmt.toString());
+ }
+
+ resultSet = pstmt.executeQuery();
+ if (!resultSet.next())
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Resultset was empty.");
+ }
+
+ return false;
+ }
+
+ int i = 1;
+ revision.setVersion(resultSet.getInt(i++));
+ revision.setCreated(resultSet.getLong(i++));
+ revision.setRevised(resultSet.getLong(i++));
+ revision.setResourceID(CDOIDUtil.createLong(resultSet.getLong(i++)));
+
+ // TODO add mapping for external container CDOIDs here ->
+ revision.setContainerID(CDOIDUtil.createLong(resultSet.getLong(i++)));
+ revision.setContainingFeatureID(resultSet.getInt(i++));
+
+ for (ITypeMapping mapping : valueMappings)
+ {
+ mapping.readValueToRevision(resultSet, i++, revision);
+ }
+
+ return true;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ }
+ }
+
+ protected final void readLists(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
+ {
+ for (IListMapping listMapping : listMappings)
+ {
+ listMapping.readValues(accessor, revision, referenceChunk);
+ }
+ }
+
+ public final void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, OMMonitor monitor)
+ {
+ try
+ {
+ monitor.begin(2);
+ reviseObject(accessor, id, revised);
+ monitor.worked(1);
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectRevised(accessor, id, revised);
+ }
+ monitor.worked(1);
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ protected final IMetaDataManager getMetaDataManager()
+ {
+ return getMappingStrategy().getStore().getMetaDataManager();
+ }
+
+ protected final IMappingStrategy getMappingStrategy()
+ {
+ return mappingStrategy;
+ }
+
+ protected final EClass getEClass()
+ {
+ return eClass;
+ }
+
+ public final List<ITypeMapping> getValueMappings()
+ {
+ return valueMappings;
+ }
+
+ public final ITypeMapping getValueMapping(EStructuralFeature feature)
+ {
+ for (ITypeMapping mapping : valueMappings)
+ {
+ if (mapping.getFeature() == feature)
+ {
+ return mapping;
+ }
+ }
+ return null;
+ }
+
+ public final List<IListMapping> getListMappings()
+ {
+ return listMappings;
+ }
+
+ public final IListMapping getListMapping(EStructuralFeature feature)
+ {
+ for (IListMapping mapping : listMappings)
+ {
+ if (mapping.getFeature() == feature)
+ {
+ return mapping;
+ }
+ }
+ return null;
+ }
+
+ protected final IDBTable getTable()
+ {
+ return table;
+ }
+
+ public Collection<IDBTable> getDBTables()
+ {
+ ArrayList<IDBTable> tables = new ArrayList<IDBTable>();
+ tables.add(table);
+
+ for (IListMapping listMapping : listMappings)
+ {
+ tables.addAll(listMapping.getDBTables());
+ }
+
+ return tables;
+ }
+
+ private void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
+ {
+ CDOID folderID = (CDOID)revision.data().getContainerID();
+ String name = (String)revision.data().get(EresourcePackage.eINSTANCE.getCDOResourceNode_Name(), 0);
+
+ CDOID existingID = accessor.readResourceID(folderID, name, CDORevision.UNSPECIFIED_DATE);
+ if (existingID != null && !existingID.equals(revision.getID()))
+ {
+ throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID);
+ }
+ }
+
+ protected void writeLists(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ for (IListMapping listMapping : listMappings)
+ {
+ listMapping.writeValues(accessor, revision);
+ }
+ }
+
+ public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
+ {
+ try
+ {
+ monitor.begin(10);
+
+ CDOID id = revision.getID();
+ if (revision.getVersion() == 1)
+ {
+ mappingStrategy.putObjectType(accessor, id, eClass);
+ }
+ else
+ {
+ long revised = revision.getCreated() - 1;
+ reviseObject(accessor, id, revised);
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectRevised(accessor, id, revised);
+ }
+ }
+
+ monitor.worked();
+
+ if (revision.isResourceFolder() || revision.isResource())
+ {
+ checkDuplicateResources(accessor, revision);
+ }
+
+ monitor.worked();
+
+ // Write attribute table always (even without modeled attributes!)
+ writeValues(accessor, revision);
+
+ monitor.worked();
+
+ // Write list tables only if they exist
+ if (listMappings != null)
+ {
+ writeLists(accessor, revision);
+ }
+
+ monitor.worked(7);
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ protected abstract void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision);
+
+ protected abstract void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java
index 1d718b7..8579cad 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java
@@ -20,12 +20,14 @@ import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IObjectTypeCache;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.AbstractMappingStrategy;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
@@ -42,6 +44,8 @@ import java.util.Collection;
*/
public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingStrategy
{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalMappingStrategy.class);
+
private IObjectTypeCache objectTypeCache;
@Override
@@ -50,6 +54,11 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS
return objectTypeCache.getObjectType(accessor, id);
}
+ public void putObjectType(IDBStoreAccessor accessor, CDOID id, EClass type)
+ {
+ objectTypeCache.putObjectType(accessor, id, type);
+ }
+
@Override
public long repairAfterCrash(IDBAdapter dbAdapter, Connection connection)
{
@@ -129,6 +138,12 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS
while (rset.next())
{
long longID = rset.getLong(1);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Resource Query returned ID {0}", longID);
+ }
+
CDOID id = CDOIDUtil.createLong(longID);
if (!context.addResource(id))
{
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ListTableAuditMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java
index 44e3eaf..c98acee 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/ListTableAuditMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java
@@ -11,10 +11,10 @@
*/
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IDBStoreChunkReader;
import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
@@ -48,9 +48,9 @@ import java.util.List;
* @author Stefan Winkler
* @since 2.0
*/
-public class ListTableAuditMapping implements IListMapping
+public abstract class AbstractListTableMapping implements IListMapping
{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, ListTableAuditMapping.class);
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractListTableMapping.class);
private EStructuralFeature feature;
@@ -68,7 +68,7 @@ public class ListTableAuditMapping implements IListMapping
private EClass containingClass;
- public ListTableAuditMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ public AbstractListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
{
this.mappingStrategy = mappingStrategy;
this.feature = feature;
@@ -83,17 +83,31 @@ public class ListTableAuditMapping implements IListMapping
String tableName = mappingStrategy.getTableName(containingClass, feature);
table = mappingStrategy.getStore().getDBSchema().addTable(tableName);
- IDBField sourceField = table.addField(CDODBSchema.FEATURE_REVISION_ID, DBType.BIGINT);
- IDBField versionField = table.addField(CDODBSchema.FEATURE_REVISION_VERSION, DBType.INTEGER);
+ // add fields for keys (cdo_id, version, feature_id)
+ FieldInfo[] fields = getKeyFields();
+ IDBField[] dbFields = new IDBField[fields.length];
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ dbFields[i] = table.addField(fields[i].getName(), fields[i].getDbType());
+ }
+
+ // add field for list index
IDBField idxField = table.addField(CDODBSchema.FEATURE_IDX, DBType.INTEGER);
+ // add field for value
typeMapping = mappingStrategy.createValueMapping(feature);
typeMapping.createDBField(table, CDODBSchema.FEATURE_TARGET);
- table.addIndex(Type.NON_UNIQUE, sourceField, versionField);
+ // add table indexes
+ table.addIndex(Type.NON_UNIQUE, dbFields);
table.addIndex(Type.NON_UNIQUE, idxField);
}
+ protected abstract FieldInfo[] getKeyFields();
+
+ protected abstract void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException;
+
public Collection<IDBTable> getDBTables()
{
return Arrays.asList(table);
@@ -102,6 +116,7 @@ public class ListTableAuditMapping implements IListMapping
private void initSqlStrings()
{
String tableName = getTable().getName();
+ FieldInfo[] fields = getKeyFields();
// ---------------- SELECT to read chunks ----------------------------
StringBuilder builder = new StringBuilder();
@@ -110,10 +125,21 @@ public class ListTableAuditMapping implements IListMapping
builder.append(" FROM ");
builder.append(tableName);
builder.append(" WHERE ");
- builder.append(CDODBSchema.FEATURE_REVISION_ID);
- builder.append("= ? AND ");
- builder.append(CDODBSchema.FEATURE_REVISION_VERSION);
- builder.append("= ? ");
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ builder.append(fields[i].getName());
+ if (i + 1 < fields.length)
+ {
+ // more to come
+ builder.append("= ? AND ");
+ }
+ else
+ {
+ // last one
+ builder.append("= ? ");
+ }
+ }
sqlSelectChunksPrefix = builder.toString();
@@ -122,15 +148,25 @@ public class ListTableAuditMapping implements IListMapping
// ----------------- INSERT - reference entry -----------------
builder = new StringBuilder("INSERT INTO ");
builder.append(tableName);
- builder.append(" VALUES (?, ?, ?, ?)");
+ builder.append(" VALUES (");
+ for (int i = 0; i < fields.length; i++)
+ {
+ builder.append("?, ");
+ }
+ builder.append(" ?, ?)");
sqlInsertEntry = builder.toString();
}
- protected final EStructuralFeature getFeature()
+ public final EStructuralFeature getFeature()
{
return feature;
}
+ public final EClass getContainingClass()
+ {
+ return containingClass;
+ }
+
protected final IDBTable getTable()
{
return table;
@@ -143,10 +179,14 @@ public class ListTableAuditMapping implements IListMapping
public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
{
+
MoveableList<Object> list = revision.getList(getFeature());
- CDOID id = revision.getID();
- int version = revision.getVersion();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list values for feature {0}.{1} of {2}v{3}", containingClass.getName(), feature.getName(),
+ revision.getID(), revision.getVersion());
+ }
PreparedStatement pstmt = null;
ResultSet resultSet = null;
@@ -155,27 +195,43 @@ public class ListTableAuditMapping implements IListMapping
{
String sql = sqlSelectChunksPrefix + sqlOrderByIndex;
+ pstmt = accessor.getConnection().prepareStatement(sql);
+
+ setKeyFields(pstmt, revision);
+
if (TRACER.isEnabled())
{
- TRACER.trace(sql);
+ TRACER.trace(pstmt.toString());
}
- pstmt = accessor.getConnection().prepareStatement(sql);
-
- pstmt.setLong(1, CDOIDUtil.getLong(id));
- pstmt.setInt(2, version);
resultSet = pstmt.executeQuery();
- while (resultSet.next() && (referenceChunk == CDORevision.UNCHUNKED || --referenceChunk >= 0))
+ while ((referenceChunk == CDORevision.UNCHUNKED || --referenceChunk >= 0) && resultSet.next())
{
- list.add(typeMapping.readValue(resultSet, 1));
+ Object value = typeMapping.readValue(resultSet, 1);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read value for index {0} from result set: {1}", list.size(), value);
+ }
+ list.add(value);
}
// TODO Optimize this?
while (resultSet.next())
{
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Additional value for index {0} ignored due to chunking. Setting uninitialized.", list.size());
+ }
+
list.add(InternalCDORevision.UNINITIALIZED);
}
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list values done for feature {0}.{1} of {2}v{3}", containingClass.getName(), feature
+ .getName(), revision.getID(), revision.getVersion());
+ }
}
catch (SQLException ex)
{
@@ -191,8 +247,11 @@ public class ListTableAuditMapping implements IListMapping
public final void readChunks(IDBStoreChunkReader chunkReader, List<Chunk> chunks, String where)
{
- CDOID source = chunkReader.getRevision().getID();
- int version = chunkReader.getRevision().getVersion();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list chunk values for feature {0}.{1} of {2}v{3}", containingClass.getName(), feature
+ .getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion());
+ }
PreparedStatement pstmt = null;
ResultSet resultSet = null;
@@ -207,15 +266,16 @@ public class ListTableAuditMapping implements IListMapping
builder.append(sqlOrderByIndex);
String sql = builder.toString();
+
+ pstmt = chunkReader.getAccessor().getConnection().prepareStatement(sql);
+
+ setKeyFields(pstmt, chunkReader.getRevision());
+
if (TRACER.isEnabled())
{
- TRACER.trace(sql);
+ TRACER.trace(pstmt.toString());
}
- pstmt = chunkReader.getAccessor().getConnection().prepareStatement(sql);
-
- pstmt.setLong(1, CDOIDUtil.getLong(source));
- pstmt.setInt(2, version);
resultSet = pstmt.executeQuery();
Chunk chunk = null;
@@ -226,19 +286,42 @@ public class ListTableAuditMapping implements IListMapping
while (resultSet.next())
{
Object value = typeMapping.readValue(resultSet, 1);
+
if (chunk == null)
{
chunk = chunks.get(chunkIndex++);
chunkSize = chunk.size();
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Current chunk no. {0} is [start = {1}, size = {2}]", chunkIndex - 1, chunk.getStartIndex(),
+ chunkSize);
+ }
}
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read value for chunk index {0} from result set: {1}", indexInChunk, value);
+ }
chunk.add(indexInChunk++, value);
+
if (indexInChunk == chunkSize)
{
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Chunk finished.");
+ }
+
chunk = null;
indexInChunk = 0;
}
}
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Reading list chunk values done for feature {0}.{1} of {2}v{3}", containingClass.getName(),
+ feature.getName(), chunkReader.getRevision().getID(), chunkReader.getRevision().getVersion());
+ }
}
catch (SQLException ex)
{
@@ -253,38 +336,92 @@ public class ListTableAuditMapping implements IListMapping
public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
{
+ CDOList values = revision.getList(getFeature());
+
+ // if(values.contains(InternalCDORevision.UNINITIALIZED)) {
+ // readUninitializedValues(accessor, values);
+ // }
+
int idx = 0;
- for (Object element : revision.getList(getFeature()))
+ for (Object element : values)
{
- writeValue(accessor, revision.getID(), revision.getVersion(), idx++, element);
+ writeValue(accessor, revision, idx++, element);
}
}
- protected final void writeValue(IDBStoreAccessor accessor, CDOID id, int version, int idx, Object value)
+ // private void readUninitializedValues(IDBStoreAccessor accessor, CDORevision revision, MoveableList<Object> values)
+ // {
+ // CDOID id = revision.getID();
+ // int version = revision.getVersion();
+ //
+ // if (TRACER.isEnabled())
+ // {
+ // TRACER.format("Reading uninitialized list values for feature {0}.{1} of {2}v{3}", containingClass.getName(),
+ // feature.getName(),
+ // id, version);
+ // }
+ //
+ // PreparedStatement pstmt = null;
+ // ResultSet resultSet = null;
+ //
+ // try
+ // {
+ // String sql = sqlSelectChunksPrefix + sqlOrderByIndex;
+ //
+ // pstmt = accessor.getConnection().prepareStatement(sql);
+ //
+ // pstmt.setLong(1, CDOIDUtil.getLong(id));
+ // pstmt.setInt(2, version);
+ // if (TRACER.isEnabled())
+ // {
+ // TRACER.trace(pstmt.toString());
+ // }
+ //
+ // resultSet = pstmt.executeQuery();
+ //
+ // int index = 0;
+ //
+ // while(resultSet.next()) {
+ // if(values.get(index) == InternalCDORevision.UNINITIALIZED) {
+ // Object value = typeMapping.readValue(resultSet, 1);
+ // if (TRACER.isEnabled())
+ // {
+ // TRACER.format("Read value for index {0} from result set: {1}", list.size(), value);
+ // }
+ // }
+ // }
+ // }
+ // catch (SQLException ex)
+ // {
+ // throw new DBException(ex);
+ // }
+ // finally
+ // {
+ // DBUtil.close(resultSet);
+ // DBUtil.close(pstmt);
+ // }
+ // }
+
+ protected final void writeValue(IDBStoreAccessor accessor, CDORevision revision, int idx, Object value)
{
PreparedStatement stmt = null;
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing value for feature {0}.{1} index {2} of {3}v{4} : {5}", containingClass.getName(), feature
+ .getName(), idx, revision.getID(), revision.getVersion(), value);
+ }
+
try
{
stmt = accessor.getConnection().prepareStatement(sqlInsertEntry);
- stmt.setLong(1, CDOIDUtil.getLong(id));
- stmt.setInt(2, version);
- stmt.setInt(3, idx++);
-
- typeMapping.setValue(stmt, 4, value);
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
+ setKeyFields(stmt, revision);
+ int stmtIndex = getKeyFields().length + 1;
+ stmt.setInt(stmtIndex++, idx);
+ typeMapping.setValue(stmt, stmtIndex++, value);
- int result = stmt.executeUpdate();
- // INSERT should affect one row
- if (result != 1)
- {
- throw new IllegalStateException(stmt.toString() + " returned Update count " + result + " (expected: 1)");
- }
+ CDODBUtil.sqlUpdate(stmt, true);
}
catch (SQLException e)
{
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java
new file mode 100644
index 0000000..e249141
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMapping.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.DBType;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class AuditListTableMapping extends AbstractListTableMapping
+{
+ private static final FieldInfo[] KEY_FIELDS = { new FieldInfo(CDODBSchema.FEATURE_REVISION_ID, DBType.BIGINT),
+ new FieldInfo(CDODBSchema.FEATURE_REVISION_VERSION, DBType.INTEGER) };
+
+ public AuditListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ super(mappingStrategy, eClass, feature);
+ }
+
+ @Override
+ protected FieldInfo[] getKeyFields()
+ {
+ return KEY_FIELDS;
+ }
+
+ @Override
+ protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException
+ {
+ stmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(2, revision.getVersion());
+ }
+
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ // the audit list mapping does not care about revised references -> NOP
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/FieldInfo.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/FieldInfo.java
new file mode 100644
index 0000000..ef770ca
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/FieldInfo.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.net4j.db.DBType;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class FieldInfo
+{
+ private String name;
+
+ private DBType dbType;
+
+ public FieldInfo(String name, DBType dbType)
+ {
+ this.name = name;
+ this.dbType = dbType;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public DBType getDbType()
+ {
+ return dbType;
+ }
+}
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 c1cbaff..64fa5a1 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
@@ -13,42 +13,27 @@ package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IMetaDataManager;
import org.eclipse.emf.cdo.server.db.mapping.IAuditSupport;
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.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBIndex;
-import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
/**
* TODO use async monitors
@@ -57,105 +42,29 @@ import java.util.List;
* @author Stefan Winkler
* @since 2.0
*/
-public class HorizontalAuditClassMapping implements IClassMapping, IAuditSupport
+public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping implements IClassMapping, IAuditSupport
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalAuditClassMapping.class);
- private EClass eClass;
-
- private IDBTable table;
-
- private IMappingStrategy mappingStrategy;
-
- private List<ITypeMapping> singleValueFeatureMappings;
-
- private List<IListMapping> manyValueFeatureMappings;
-
- private String sqlReviseAttributes;
-
private String sqlInsertAttributes;
private String sqlSelectCurrentAttributes;
+ private String sqlSelectAllObjectIds;
+
private String sqlSelectAttributesByTime;
private String sqlSelectAttributesByVersion;
- private String sqlSelectAllObjectIds;
+ private String sqlReviseAttributes;
- public HorizontalAuditClassMapping(IMappingStrategy mappingStrategy, EClass eClass)
+ public HorizontalAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
{
- this.mappingStrategy = mappingStrategy;
- this.eClass = eClass;
+ super(mappingStrategy, eClass);
- initTable();
- initFeatures();
initSqlStrings();
}
- private void initTable()
- {
- String name = mappingStrategy.getTableName(eClass);
- table = mappingStrategy.getStore().getDBSchema().addTable(name);
-
- IDBField idField = table.addField(CDODBSchema.ATTRIBUTES_ID, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_VERSION, DBType.INTEGER, true);
- table.addField(CDODBSchema.ATTRIBUTES_CLASS, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_CREATED, DBType.BIGINT, true);
- IDBField revisedField = table.addField(CDODBSchema.ATTRIBUTES_REVISED, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_RESOURCE, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_CONTAINER, DBType.BIGINT, true);
- table.addField(CDODBSchema.ATTRIBUTES_FEATURE, DBType.INTEGER, true);
-
- table.addIndex(IDBIndex.Type.NON_UNIQUE, idField, revisedField);
- }
-
- private void initFeatures()
- {
- EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
-
- if (features == null)
- {
- singleValueFeatureMappings = Collections.emptyList();
- manyValueFeatureMappings = Collections.emptyList();
- }
- else
- {
- singleValueFeatureMappings = createSingleMappings(features);
- manyValueFeatureMappings = createManyMappings(features);
- }
- }
-
- private List<ITypeMapping> createSingleMappings(EStructuralFeature[] features)
- {
- List<ITypeMapping> mappings = new ArrayList<ITypeMapping>();
- for (EStructuralFeature feature : features)
- {
- if (!feature.isMany())
- {
- ITypeMapping mapping = mappingStrategy.createValueMapping(feature);
- mapping.createDBField(getTable());
- mappings.add(mapping);
- }
- }
-
- return mappings;
- }
-
- private List<IListMapping> createManyMappings(EStructuralFeature[] features)
- {
- List<IListMapping> referenceMappings = new ArrayList<IListMapping>();
- for (EStructuralFeature feature : features)
- {
- if (feature.isMany())
- {
- referenceMappings.add(mappingStrategy.createListMapping(eClass, feature));
- }
- }
-
- return referenceMappings;
- }
-
private void initSqlStrings()
{
// ----------- Select Revision ---------------------------
@@ -174,14 +83,14 @@ public class HorizontalAuditClassMapping implements IClassMapping, IAuditSupport
builder.append(", ");
builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
- for (ITypeMapping singleMapping : singleValueFeatureMappings)
+ for (ITypeMapping singleMapping : getValueMappings())
{
builder.append(", ");
builder.append(singleMapping.getField().getName());
}
builder.append(" FROM ");
- builder.append(table.getName());
+ builder.append(getTable().getName());
builder.append(" WHERE ");
builder.append(CDODBSchema.ATTRIBUTES_ID);
builder.append("= ? AND (");
@@ -195,10 +104,12 @@ public class HorizontalAuditClassMapping implements IClassMapping, IAuditSupport
builder = new StringBuilder(sqlSelectAttributesPrefix);
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" <= ? AND ( ");
builder.append(CDODBSchema.ATTRIBUTES_REVISED);
builder.append(" = 0 OR ");
builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(" >= ?)");
+ builder.append(" >= ?))");
sqlSelectAttributesByTime = builder.toString();
@@ -212,10 +123,10 @@ public class HorizontalAuditClassMapping implements IClassMapping, IAuditSupport
// ----------- Insert Attributes -------------------------
builder = new StringBuilder();
builder.append("INSERT INTO ");
- builder.append(table.getName());
+ builder.append(getTable().getName());
builder.append(" VALUES (?, ?, ");
builder.append("?, ?, ?, ?, ?, ?");
- for (int i = 0; i < getSingleValueFeatureMappings().size(); i++)
+ for (int i = 0; i < getValueMappings().size(); i++)
{
builder.append(", ?");
}
@@ -245,237 +156,184 @@ public class HorizontalAuditClassMapping implements IClassMapping, IAuditSupport
sqlSelectAllObjectIds = builder.toString();
}
- public void detachObject(IDBStoreAccessor accessor, CDOID id, long revised, OMMonitor monitor)
- {
- try
- {
- monitor.begin();
- writeRevisedRow(accessor, id, revised);
- monitor.worked(1);
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void checkDuplicateResources(IDBStoreAccessor accessor, CDORevision revision) throws IllegalStateException
- {
- CDOID folderID = (CDOID)revision.data().getContainerID();
- String name = (String)revision.data().get(EresourcePackage.eINSTANCE.getCDOResourceNode_Name(), 0);
-
- CDOID existingID = accessor.readResourceID(folderID, name, revision.getCreated());
- if (existingID != null && !existingID.equals(revision.getID()))
- {
- throw new IllegalStateException("Duplicate resource or folder: " + name + " in folder " + folderID);
- }
- }
-
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, OMMonitor monitor)
+ public boolean readRevisionByTime(IDBStoreAccessor accessor, InternalCDORevision revision, long timeStamp,
+ int referenceChunk)
{
+ PreparedStatement pstmt = null;
try
{
- monitor.begin(10);
-
- if (revision.getVersion() > 1)
- {
- writeRevisedRow(accessor, revision.getID(), revision.getCreated() - 1);
- }
-
- monitor.worked();
-
- if (revision.isResourceFolder() || revision.isResource())
- {
- checkDuplicateResources(accessor, revision);
- }
-
- monitor.worked();
-
- // Write attribute table always (even without modeled attributes!)
- writeAttributes(accessor, revision);
+ // TODO add caching
+ pstmt = accessor.getConnection().prepareStatement(sqlSelectAttributesByTime);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setLong(2, timeStamp);
+ pstmt.setLong(3, timeStamp);
- monitor.worked();
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
- // Write reference tables only if they exist
- if (manyValueFeatureMappings != null)
+ // Read multival tables only if revision exists
+ if (success)
{
- writeReferences(accessor, revision);
+ readLists(accessor, revision, referenceChunk);
}
- monitor.worked(7);
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
}
finally
{
- monitor.done();
+ DBUtil.close(pstmt);
}
}
- protected final void writeAttributes(IDBStoreAccessor accessor, InternalCDORevision revision)
+ public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int version,
+ int referenceChunk)
{
- PreparedStatement stmt = null;
-
+ PreparedStatement pstmt = null;
try
{
- stmt = accessor.getConnection().prepareStatement(sqlInsertAttributes);
-
- int col = 1;
-
- stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
- stmt.setInt(col++, revision.getVersion());
- stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
- stmt.setLong(col++, revision.getCreated());
- stmt.setLong(col++, revision.getRevised());
- stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID()));
- stmt.setLong(col++, CDODBUtil.getLong((CDOID)revision.getContainerID()));
- stmt.setInt(col++, revision.getContainingFeatureID());
+ // TODO add caching
+ pstmt = accessor.getConnection().prepareStatement(sqlSelectAttributesByVersion);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ pstmt.setInt(2, version);
- for (ITypeMapping singleMapping : singleValueFeatureMappings)
- {
- singleMapping.setValueFromRevision(stmt, col++, revision);
- }
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
- if (TRACER.isEnabled())
+ // Read multival tables only if revision exists
+ if (success)
{
- TRACER.trace(stmt.toString());
+ readLists(accessor, revision, referenceChunk);
}
- int result = stmt.executeUpdate();
- // INSERT should insert one row
- if (result != 1)
- {
- throw new IllegalStateException(stmt.toString() + " returned Update count " + result + " (expected: 1)");
- }
+ return success;
}
- catch (SQLException e)
+ catch (SQLException ex)
{
- throw new DBException(e);
+ throw new DBException(ex);
}
finally
{
- DBUtil.close(stmt);
+ DBUtil.close(pstmt);
}
}
- protected final void writeRevisedRow(IDBStoreAccessor accessor, CDOID id, long revised)
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, long timeStamp)
{
- PreparedStatement stmt = null;
+ EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
- try
+ ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+ if (nameValueMapping == null)
{
- stmt = accessor.getConnection().prepareStatement(sqlReviseAttributes);
-
- stmt.setLong(1, revised);
- stmt.setLong(2, CDOIDUtil.getLong(id));
-
- if (TRACER.isEnabled())
- {
- TRACER.trace(stmt.toString());
- }
-
- int result = stmt.executeUpdate();
-
- // only one unrevised row may exist - update count must be 1
- if (result != 1)
- {
- throw new IllegalStateException(stmt.toString() + " returned Update count " + result + " (expected: 1)");
- }
+ throw new ImplementationError(nameFeature + " not found in ClassMapping " + this);
}
- catch (SQLException e)
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append("= ? AND ");
+ builder.append(nameValueMapping.getField().getName());
+ if (name == null)
{
- throw new DBException(e);
+ builder.append(" IS NULL");
}
- finally
+ else
{
- DBUtil.close(stmt);
+ builder.append(exactMatch ? " = ? " : " LIKE ? ");
}
- }
- protected void writeReferences(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- for (IListMapping manyMapping : manyValueFeatureMappings)
+ builder.append(" AND ( ");
+
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
{
- manyMapping.writeValues(accessor, revision);
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 )");
+ }
+ else
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" <= ? AND ( ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" = 0 OR ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(" >= ?))");
}
- }
- public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
- {
PreparedStatement pstmt = null;
try
{
- // TODO add caching
- pstmt = accessor.getConnection().prepareStatement(sqlSelectCurrentAttributes);
- pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ int idx = 1;
- // Read singleval-attribute table always (even without modeled attributes!)
- boolean success = readSingleValuesFromStatement(pstmt, revision);
+ pstmt = accessor.getConnection().prepareStatement(builder.toString());
+ pstmt.setLong(idx++, CDOIDUtil.getLong(folderId));
- // Read multival tables only if revision exists
- if (success)
+ if (name != null)
{
- readMultiValues(accessor, revision, referenceChunk);
+ String queryName = exactMatch ? name : name + "%";
+ nameValueMapping.setValue(pstmt, idx++, queryName);
}
- return success;
+ if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+ {
+ pstmt.setLong(idx++, timeStamp);
+ pstmt.setLong(idx++, timeStamp);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created Resource Query: {0}", pstmt.toString());
+ }
+
+ return pstmt;
}
catch (SQLException ex)
{
+ DBUtil.close(pstmt); // only close on error
throw new DBException(ex);
}
- finally
- {
- DBUtil.close(pstmt);
- }
}
- public boolean readRevisionByTime(IDBStoreAccessor accessor, InternalCDORevision revision, long timeStamp,
- int referenceChunk)
+ public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor)
{
- PreparedStatement pstmt = null;
try
{
- // TODO add caching
- pstmt = accessor.getConnection().prepareStatement(sqlSelectAttributesByTime);
- pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
- pstmt.setLong(2, timeStamp);
- // Read singleval-attribute table always (even without modeled attributes!)
- boolean success = readSingleValuesFromStatement(pstmt, revision);
-
- // Read multival tables only if revision exists
- if (success)
+ if (TRACER.isEnabled())
{
- readMultiValues(accessor, revision, referenceChunk);
+ TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIds);
}
- return success;
+ return accessor.getConnection().prepareStatement(sqlSelectAllObjectIds);
}
catch (SQLException ex)
{
throw new DBException(ex);
}
- finally
- {
- DBUtil.close(pstmt);
- }
}
- public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int version,
- int referenceChunk)
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
{
PreparedStatement pstmt = null;
try
{
// TODO add caching
- pstmt = accessor.getConnection().prepareStatement(sqlSelectAttributesByVersion);
+ pstmt = accessor.getConnection().prepareStatement(sqlSelectCurrentAttributes);
pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
- pstmt.setInt(2, version);
+
// Read singleval-attribute table always (even without modeled attributes!)
- boolean success = readSingleValuesFromStatement(pstmt, revision);
+ boolean success = readValuesFromStatement(pstmt, revision);
// Read multival tables only if revision exists
if (success)
{
- readMultiValues(accessor, revision, referenceChunk);
+ readLists(accessor, revision, referenceChunk);
}
return success;
@@ -490,158 +348,64 @@ public class HorizontalAuditClassMapping implements IClassMapping, IAuditSupport
}
}
- /**
- * Read the revision's attributes 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 readSingleValuesFromStatement(PreparedStatement pstmt, InternalCDORevision revision)
+ @Override
+ protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
{
- ResultSet resultSet = null;
+ PreparedStatement stmt = null;
+
try
{
- resultSet = pstmt.executeQuery();
- if (!resultSet.next())
- {
- return false;
- }
+ stmt = accessor.getConnection().prepareStatement(sqlInsertAttributes);
- int i = 1;
- revision.setVersion(resultSet.getInt(i++));
- revision.setCreated(resultSet.getLong(i++));
- revision.setRevised(resultSet.getLong(i++));
- revision.setResourceID(CDOIDUtil.createLong(resultSet.getLong(i++)));
+ int col = 1;
- // TODO add mapping for external container CDOIDs here ->
- revision.setContainerID(CDOIDUtil.createLong(resultSet.getLong(i++)));
- revision.setContainingFeatureID(resultSet.getInt(i++));
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(col++, revision.getVersion());
+ stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
+ stmt.setLong(col++, revision.getCreated());
+ stmt.setLong(col++, revision.getRevised());
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID()));
+ stmt.setLong(col++, CDODBUtil.getLong((CDOID)revision.getContainerID()));
+ stmt.setInt(col++, revision.getContainingFeatureID());
- for (ITypeMapping singleMapping : singleValueFeatureMappings)
+ for (ITypeMapping mapping : getValueMappings())
{
- singleMapping.readValueToRevision(resultSet, i++, revision);
+ mapping.setValueFromRevision(stmt, col++, revision);
}
- return true;
+ CDODBUtil.sqlUpdate(stmt, true);
}
- catch (SQLException ex)
+ catch (SQLException e)
{
- throw new DBException(ex);
+ throw new DBException(e);
}
finally
{
- DBUtil.close(resultSet);
- }
- }
-
- protected void readMultiValues(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
- {
- for (IListMapping manyMapping : manyValueFeatureMappings)
- {
- manyMapping.readValues(accessor, revision, referenceChunk);
- }
- }
-
- protected final IMetaDataManager getMetaDataManager()
- {
- return getMappingStrategy().getStore().getMetaDataManager();
- }
-
- protected final IMappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- protected final List<ITypeMapping> getSingleValueFeatureMappings()
- {
- return singleValueFeatureMappings;
- }
-
- protected final ITypeMapping getSingleValueFeatureMapping(EStructuralFeature feature)
- {
- for (ITypeMapping mapping : singleValueFeatureMappings)
- {
- if (mapping.getFeature() == feature)
- {
- return mapping;
- }
+ DBUtil.close(stmt);
}
- return null;
- }
-
- protected final IDBTable getTable()
- {
- return table;
- }
-
- public Collection<IDBTable> getDBTables()
- {
- return Arrays.asList(table);
}
- public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
- boolean exactMatch, long timeStamp)
+ @Override
+ protected void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised)
{
- EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
-
- ITypeMapping nameValueMapping = getSingleValueFeatureMapping(nameFeature);
- if (nameValueMapping == null)
- {
- throw new ImplementationError(nameFeature + " not found in ClassMapping " + this);
- }
-
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT ");
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" FROM ");
- builder.append(getTable().getName());
- builder.append(" WHERE ");
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append("= ? AND ");
- builder.append(nameValueMapping.getField().getName());
- builder.append(exactMatch ? " = ? AND (" : " LIKE ? AND (");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-
- if (timeStamp == CDORevision.UNSPECIFIED_DATE)
- {
- builder.append(" = 0 )");
- }
- else
- {
- builder.append(" = 0 OR ");
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(" >= ?)");
- }
+ PreparedStatement stmt = null;
- PreparedStatement pstmt = null;
try
{
- pstmt = accessor.getConnection().prepareStatement(builder.toString());
- pstmt.setLong(1, CDOIDUtil.getLong(folderId));
- nameValueMapping.setValue(pstmt, 2, name);
- if (timeStamp != CDORevision.UNSPECIFIED_DATE)
- {
- pstmt.setLong(3, timeStamp);
- }
+ stmt = accessor.getConnection().prepareStatement(sqlReviseAttributes);
- return pstmt;
- }
- catch (SQLException ex)
- {
- DBUtil.close(pstmt); // only close on error
- throw new DBException(ex);
- }
- }
+ stmt.setLong(1, revised);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
- public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor)
- {
- try
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
{
- return accessor.getConnection().prepareStatement(sqlSelectAllObjectIds);
+ throw new DBException(e);
}
- catch (SQLException ex)
+ finally
{
- throw new DBException(ex);
+ DBUtil.close(stmt);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
index f4073b9..f020625 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategy.java
@@ -25,26 +25,26 @@ import org.eclipse.emf.ecore.EStructuralFeature;
public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStrategy
{
@Override
- public boolean hasAuditSupport()
+ public IClassMapping doCreateClassMapping(EClass eClass)
{
- return true;
+ return new HorizontalAuditClassMapping(this, eClass);
}
@Override
- public boolean hasDeltaSupport()
+ public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
{
- return false;
+ return new AuditListTableMapping(this, containingClass, feature);
}
@Override
- public IClassMapping doCreateClassMapping(EClass eClass)
+ public boolean hasAuditSupport()
{
- return new HorizontalAuditClassMapping(this, eClass);
+ return true;
}
@Override
- public IListMapping doCreateManyMapping(EClass containingClass, EStructuralFeature feature)
+ public boolean hasDeltaSupport()
{
- return new ListTableAuditMapping(this, containingClass, feature);
+ return false;
}
}
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
new file mode 100644
index 0000000..eaaf72e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java
@@ -0,0 +1,583 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+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;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+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.net4j.db.DBException;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.collection.Pair;
+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;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMapping implements IClassMapping,
+ IDeltaSupport
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalNonAuditClassMapping.class);
+
+ private String sqlSelectAllObjectIds;
+
+ private String sqlSelectCurrentAttributes;
+
+ private String sqlInsertAttributes;
+
+ private String sqlDelete;
+
+ private String sqlUpdateAffix;
+
+ private String sqlUpdatePrexix;
+
+ private String sqlUpdateContainerPart;
+
+ private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
+ {
+ @Override
+ protected FeatureDeltaWriter initialValue()
+ {
+ return new FeatureDeltaWriter();
+ };
+ };
+
+ public HorizontalNonAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ super(mappingStrategy, eClass);
+
+ initSqlStrings();
+ }
+
+ private void initSqlStrings()
+ {
+ // ----------- Select Revision ---------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", ");
+ builder.append(singleMapping.getField().getName());
+ }
+
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("= ?");
+
+ sqlSelectCurrentAttributes = builder.toString();
+
+ // ----------- Insert Attributes -------------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO ");
+ builder.append(getTable().getName());
+ builder.append(" VALUES (?, ?, ");
+ builder.append("?, ?, ?, ?, ?, ?");
+ for (int i = 0; i < getValueMappings().size(); i++)
+ {
+ builder.append(", ?");
+ }
+ builder.append(")");
+ sqlInsertAttributes = builder.toString();
+
+ builder = new StringBuilder("DELETE FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" = ? ");
+ sqlDelete = builder.toString();
+
+ // ----------- Select all unrevised Object IDs ------
+ builder = new StringBuilder("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ sqlSelectAllObjectIds = builder.toString();
+
+ // ----------- Update attributes --------------------
+ builder = new StringBuilder("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(" =? ,");
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(" =? ");
+ sqlUpdatePrexix = builder.toString();
+
+ builder = new StringBuilder(", ");
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(" =? ,");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(" =? ,");
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+ builder.append(" =? ");
+ sqlUpdateContainerPart = builder.toString();
+
+ builder = new StringBuilder(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" = ? ");
+ sqlUpdateAffix = builder.toString();
+ }
+
+ @Override
+ protected void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlInsertAttributes);
+
+ int col = 1;
+
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getID()));
+ stmt.setInt(col++, revision.getVersion());
+ stmt.setLong(col++, accessor.getStore().getMetaDataManager().getMetaID(revision.getEClass()));
+ stmt.setLong(col++, revision.getCreated());
+ stmt.setLong(col++, revision.getRevised());
+ stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID()));
+ stmt.setLong(col++, CDODBUtil.getLong((CDOID)revision.getContainerID()));
+ stmt.setInt(col++, revision.getContainingFeatureID());
+
+ for (ITypeMapping mapping : getValueMappings())
+ {
+ mapping.setValueFromRevision(stmt, col++, revision);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ public PreparedStatement createObjectIdStatement(IDBStoreAccessor accessor)
+ {
+ try
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIds);
+ }
+
+ return accessor.getConnection().prepareStatement(sqlSelectAllObjectIds);
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ }
+
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, long timeStamp)
+ {
+ if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+ {
+ throw new IllegalArgumentException("Non-audit store does not support explicit timeStamp in resource query");
+ }
+
+ EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+
+ ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+ if (nameValueMapping == null)
+ {
+ throw new ImplementationError(nameFeature + " not found in ClassMapping " + this);
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT ");
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append("= ? AND ");
+ builder.append(nameValueMapping.getField().getName());
+ if (name == null)
+ {
+ builder.append(" IS NULL");
+ }
+ else
+ {
+ builder.append(exactMatch ? " = ? " : " LIKE ? ");
+ }
+
+ PreparedStatement pstmt = null;
+ try
+ {
+ int idx = 1;
+
+ pstmt = accessor.getConnection().prepareStatement(builder.toString());
+ pstmt.setLong(idx++, CDOIDUtil.getLong(folderId));
+
+ if (name != null)
+ {
+ String queryName = exactMatch ? name : name + "%";
+ nameValueMapping.setValue(pstmt, idx++, queryName);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created Resource Query: {0}", pstmt.toString());
+ }
+
+ return pstmt;
+ }
+ catch (SQLException ex)
+ {
+ DBUtil.close(pstmt); // only close on error
+ throw new DBException(ex);
+ }
+ }
+
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int referenceChunk)
+ {
+ PreparedStatement pstmt = null;
+ try
+ {
+ // TODO add caching
+ pstmt = accessor.getConnection().prepareStatement(sqlSelectCurrentAttributes);
+ pstmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(pstmt, revision);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, referenceChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ DBUtil.close(pstmt);
+ }
+ }
+
+ @Override
+ protected void reviseObject(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlDelete);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
+ OMMonitor monitor)
+ {
+ monitor.begin();
+ Async async = monitor.forkAsync();
+
+ try
+ {
+ FeatureDeltaWriter writer = deltaWriter.get();
+ writer.process(accessor, delta, created);
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
+ {
+ private CDOID id;
+
+ private int newVersion;
+
+ private long created;
+
+ private IDBStoreAccessor accessor;
+
+ private boolean updateContainer = false;
+
+ private List<Pair<ITypeMapping, Object>> attributeChanges;
+
+ private int newContainingFeatureID;
+
+ private CDOID newContainerID;
+
+ private CDOID newResourceID;
+
+ public FeatureDeltaWriter()
+ {
+ attributeChanges = new ArrayList<Pair<ITypeMapping, Object>>();
+ }
+
+ protected void reset()
+ {
+ attributeChanges.clear();
+ updateContainer = false;
+ }
+
+ public void process(IDBStoreAccessor a, CDORevisionDelta d, long c)
+ {
+ // set context
+
+ reset();
+ id = d.getID();
+ newVersion = d.getDirtyVersion();
+ created = c;
+ accessor = a;
+
+ // process revision delta tree
+ d.accept(this);
+
+ // update attributes
+ if (updateContainer)
+ {
+ updateAttributes(accessor, id, newVersion, created, newContainerID, newContainingFeatureID, newResourceID,
+ attributeChanges);
+ }
+ else
+ {
+ updateAttributes(accessor, id, newVersion, created, attributeChanges);
+ }
+ }
+
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ getListMappingDeltaSupport(delta.getFeature()).moveListItem(accessor, id, newVersion, delta.getOldPosition(),
+ delta.getNewPosition());
+ }
+
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ if (delta.getFeature().isMany())
+ {
+ IListMappingDeltaSupport rm = getListMappingDeltaSupport(delta.getFeature());
+ if (rm == null)
+ {
+ throw new IllegalArgumentException("ReferenceMapping for " + delta.getFeature() + " is null!");
+ }
+ rm.setListItem(accessor, id, newVersion, delta.getIndex(), delta.getValue());
+ }
+ else
+ {
+ ITypeMapping am = getValueMapping(delta.getFeature());
+ if (am == null)
+ {
+ throw new IllegalArgumentException("AttributeMapping for " + delta.getFeature() + " is null!");
+ }
+ attributeChanges.add(new Pair<ITypeMapping, Object>(am, delta.getValue()));
+ }
+ }
+
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ // TODO: correct this when DBStore implements unsettable features
+ // see Bugs 259868 and 263010
+ ITypeMapping tm = getValueMapping(delta.getFeature());
+ attributeChanges.add(new Pair<ITypeMapping, Object>(tm, null));
+ }
+
+ public void visit(CDOListFeatureDelta delta)
+ {
+ for (CDOFeatureDelta listChange : delta.getListChanges())
+ {
+ listChange.accept(this);
+ }
+ }
+
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ getListMappingDeltaSupport(delta.getFeature()).clearList(accessor, id);
+ }
+
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ getListMappingDeltaSupport(delta.getFeature()).insertListItem(accessor, id, newVersion, delta.getIndex(),
+ delta.getValue());
+ }
+
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ getListMappingDeltaSupport(delta.getFeature()).removeListItem(accessor, id, newVersion, delta.getIndex());
+ }
+
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ newContainingFeatureID = delta.getContainerFeatureID();
+ newContainerID = (CDOID)delta.getContainerID();
+ newResourceID = delta.getResourceID();
+ updateContainer = true;
+ }
+
+ private IListMappingDeltaSupport getListMappingDeltaSupport(EStructuralFeature feature)
+ {
+ return (IListMappingDeltaSupport)getListMapping(feature);
+ }
+ }
+
+ public void updateAttributes(IDBStoreAccessor accessor, CDOID id, int newVersion, long created, CDOID newContainerId,
+ int newContainingFeatureId, CDOID newResourceId, List<Pair<ITypeMapping, Object>> attributeChanges)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(buildUpdateStatement(attributeChanges, true));
+
+ int col = 1;
+
+ stmt.setInt(col++, newVersion);
+ stmt.setLong(col++, created);
+ stmt.setLong(col++, CDODBUtil.getLong(newResourceId));
+ stmt.setLong(col++, CDODBUtil.getLong(newContainerId));
+ stmt.setInt(col++, newContainingFeatureId);
+
+ for (Pair<ITypeMapping, Object> change : attributeChanges)
+ {
+ change.getElement1().setValue(stmt, col++, change.getElement2());
+ }
+
+ stmt.setLong(col++, CDOIDUtil.getLong(id));
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+
+ }
+
+ public void updateAttributes(IDBStoreAccessor accessor, CDOID id, int newVersion, long created,
+ List<Pair<ITypeMapping, Object>> attributeChanges)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(buildUpdateStatement(attributeChanges, false));
+
+ int col = 1;
+
+ stmt.setInt(col++, newVersion);
+ stmt.setLong(col++, created);
+
+ for (Pair<ITypeMapping, Object> change : attributeChanges)
+ {
+ change.getElement1().setValue(stmt, col++, change.getElement2());
+ }
+
+ stmt.setLong(col++, CDOIDUtil.getLong(id));
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ private String buildUpdateStatement(List<Pair<ITypeMapping, Object>> attributeChanges, boolean withContainment)
+ {
+ StringBuilder builder = new StringBuilder(sqlUpdatePrexix);
+ if (withContainment)
+ {
+ builder.append(sqlUpdateContainerPart);
+ }
+
+ for (Pair<ITypeMapping, Object> change : attributeChanges)
+ {
+ builder.append(", ");
+ builder.append(change.getElement1().getField().getName());
+ builder.append(" =? ");
+ }
+
+ builder.append(sqlUpdateAffix);
+ return builder.toString();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
new file mode 100644
index 0000000..cb89b2f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditMappingStrategy.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class HorizontalNonAuditMappingStrategy extends AbstractHorizontalMappingStrategy
+{
+
+ @Override
+ protected IClassMapping doCreateClassMapping(EClass eClass)
+ {
+ return new HorizontalNonAuditClassMapping(this, eClass);
+ }
+
+ @Override
+ public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
+ {
+ return new NonAuditListTableMapping(this, containingClass, feature);
+ }
+
+ @Override
+ public boolean hasAuditSupport()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean hasDeltaSupport()
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java
new file mode 100644
index 0000000..53f23a2
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/NonAuditListTableMapping.java
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2004 - 2009 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 - major refactoring
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+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.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 2.0
+ */
+public class NonAuditListTableMapping extends AbstractListTableMapping implements IListMapping,
+ IListMappingDeltaSupport
+{
+ private static final FieldInfo[] KEY_FIELDS = { new FieldInfo(CDODBSchema.FEATURE_REVISION_ID, DBType.BIGINT) };
+
+ private static final int TEMP_INDEX = -1;
+
+ private static final int UNBOUNDED_MOVE = -1;
+
+ private String sqlClear;
+
+ private String sqlUpdateValue;
+
+ private String sqlUpdateIndex;
+
+ private String sqlInsertValue;
+
+ private String sqlDeleteItem;
+
+ private String sqlMoveDownWithLimit;
+
+ private String sqlMoveDown;
+
+ private String sqlMoveUpWithLimit;
+
+ private String sqlMoveUp;
+
+ public NonAuditListTableMapping(IMappingStrategy mappingStrategy, EClass eClass, EStructuralFeature feature)
+ {
+ super(mappingStrategy, eClass, feature);
+
+ initSqlStrings();
+ }
+
+ private void initSqlStrings()
+ {
+ // ----------- clear list -------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("DELETE FROM ");
+ builder.append(getTable().getName());
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.FEATURE_REVISION_ID);
+ builder.append(" = ? ");
+
+ sqlClear = builder.toString();
+
+ builder.append(" AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" = ? ");
+
+ sqlDeleteItem = builder.toString();
+
+ // ----------- update one item --------------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.FEATURE_TARGET);
+ builder.append(" = ? ");
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.FEATURE_REVISION_ID);
+ builder.append(" = ? AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" = ? ");
+ sqlUpdateValue = builder.toString();
+
+ // ----------- insert one item --------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO ");
+ builder.append(getTable().getName());
+ builder.append(" VALUES(?, ?, ?) ");
+ sqlInsertValue = builder.toString();
+
+ // ----------- update one item index --------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" = ? ");
+ builder.append(" WHERE ");
+ builder.append(CDODBSchema.FEATURE_REVISION_ID);
+ builder.append(" = ? AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" = ? ");
+ sqlUpdateIndex = builder.toString();
+
+ // ----------- move down --------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" = ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append("-1 WHERE ");
+ builder.append(CDODBSchema.FEATURE_REVISION_ID);
+ builder.append("= ? AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" > ? ");
+ sqlMoveDown = builder.toString();
+
+ builder.append(" AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" <= ?");
+ sqlMoveDownWithLimit = builder.toString();
+
+ // ----------- move up --------------
+ builder = new StringBuilder();
+ builder.append("UPDATE ");
+ builder.append(getTable().getName());
+ builder.append(" SET ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" = ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append("+1 WHERE ");
+ builder.append(CDODBSchema.FEATURE_REVISION_ID);
+ builder.append("= ? AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" >= ? ");
+ sqlMoveUp = builder.toString();
+
+ builder.append(" AND ");
+ builder.append(CDODBSchema.FEATURE_IDX);
+ builder.append(" < ?");
+ sqlMoveUpWithLimit = builder.toString();
+
+ }
+
+ @Override
+ protected FieldInfo[] getKeyFields()
+ {
+ return KEY_FIELDS;
+ }
+
+ @Override
+ protected void setKeyFields(PreparedStatement stmt, CDORevision revision) throws SQLException
+ {
+ stmt.setLong(1, CDOIDUtil.getLong(revision.getID()));
+ }
+
+ public void objectRevised(IDBStoreAccessor accessor, CDOID id, long revised)
+ {
+ clearList(accessor, id);
+ }
+
+ public void clearList(IDBStoreAccessor accessor, CDOID id)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlClear);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ CDODBUtil.sqlUpdate(stmt, false);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ public void insertListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, Object value)
+ {
+ move1up(accessor, id, index, UNBOUNDED_MOVE);
+ insertValue(accessor, id, index, value);
+ }
+
+ private void insertValue(IDBStoreAccessor accessor, CDOID id, int index, Object value)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlInsertValue);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ getTypeMapping().setValue(stmt, 3, value);
+
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ public void moveListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int oldPosition, int newPosition)
+ {
+ if (oldPosition == newPosition)
+ {
+ return;
+ }
+
+ // move element away temporarily
+ updateOneIndex(accessor, id, oldPosition, TEMP_INDEX);
+
+ // move elements in between
+ if (oldPosition < newPosition)
+ {
+ move1down(accessor, id, oldPosition, newPosition);
+ }
+ else
+ {
+ // oldPosition > newPosition -- equal case is handled above
+ move1up(accessor, id, newPosition, oldPosition);
+ }
+
+ // move temporary element to new position
+ updateOneIndex(accessor, id, TEMP_INDEX, newPosition);
+ }
+
+ private void updateOneIndex(IDBStoreAccessor accessor, CDOID id, int oldIndex, int newIndex)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlUpdateIndex);
+ stmt.setInt(1, newIndex);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
+ stmt.setInt(3, oldIndex);
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ public void removeListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int index)
+ {
+ deleteItem(accessor, id, index);
+ move1down(accessor, id, index, UNBOUNDED_MOVE);
+ }
+
+ /**
+ * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with
+ * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down.
+ */
+ private void move1down(IDBStoreAccessor accessor, CDOID id, int index, int upperIndex)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(
+ upperIndex == UNBOUNDED_MOVE ? sqlMoveDown : sqlMoveDownWithLimit);
+
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ if (upperIndex != UNBOUNDED_MOVE)
+ {
+ stmt.setInt(3, upperIndex);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, false);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ /**
+ * Move references downwards to close a gap at position <code>index</code>. Only indexes starting with
+ * <code>index + 1</code> and ending with <code>upperIndex</code> are moved down.
+ */
+ private void move1up(IDBStoreAccessor accessor, CDOID id, int index, int upperIndex)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(upperIndex == UNBOUNDED_MOVE ? sqlMoveUp : sqlMoveUpWithLimit);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ if (upperIndex != UNBOUNDED_MOVE)
+ {
+ stmt.setInt(3, upperIndex);
+ }
+
+ CDODBUtil.sqlUpdate(stmt, false);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ private void deleteItem(IDBStoreAccessor accessor, CDOID id, int index)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlDeleteItem);
+ stmt.setLong(1, CDOIDUtil.getLong(id));
+ stmt.setInt(2, index);
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+
+ public void setListItem(IDBStoreAccessor accessor, CDOID id, int newVersion, int index, Object value)
+ {
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = accessor.getConnection().prepareStatement(sqlUpdateValue);
+ getTypeMapping().setValue(stmt, 1, value);
+ stmt.setLong(2, CDOIDUtil.getLong(id));
+ stmt.setInt(3, index);
+ CDODBUtil.sqlUpdate(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(stmt);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt - nonaudit).launch b/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt - nonaudit).launch
deleted file mode 100644
index 0c6721f..0000000
--- a/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt - nonaudit).launch
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmtNonAudit.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.cdo.tests.AllTestsDBHsqldbPrepStmtNonAudit"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.emf.cdo.tests"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m&#13;&#10;-Xmx512m"/>
-</launchConfiguration>
diff --git a/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt).launch b/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt).launch
deleted file mode 100644
index 619b47f..0000000
--- a/plugins/org.eclipse.emf.cdo.tests/CDO AllTests (DB HsqldbPrepStmt).launch
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldbPrepStmt.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.cdo.tests.AllTestsDBHsqldbPrepStmt"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.emf.cdo.tests"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m&#13;&#10;-Xmx512m"/>
-</launchConfiguration>
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java
index 9c0b5c5..ededa11 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsDBHsqldb.java
@@ -10,6 +10,12 @@
*/
package org.eclipse.emf.cdo.tests;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_248052_Test;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_266982_Test;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
+
+import java.util.List;
+
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -28,4 +34,17 @@ public class AllTestsDBHsqldb extends AllTestsAllConfigs
{
addScenario(parent, COMBINED, DB_HSQL, JVM, NATIVE);
}
+
+ @Override
+ protected void initTestClasses(List<Class<? extends ConfigTest>> testClasses)
+ {
+ super.initTestClasses(testClasses);
+
+ // delta-support not available for audit db-store
+ testClasses.remove(Bugzilla_248052_Test.class);
+
+ // this takes ages ...
+ testClasses.remove(Bugzilla_266982_Test.class);
+
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
index 79be96a..fa86a7f 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
@@ -14,13 +14,18 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.model1.Customer;
import org.eclipse.emf.cdo.tests.model1.SalesOrder;
+import org.eclipse.emf.cdo.tests.model5.GenListOfInt;
+import org.eclipse.emf.cdo.tests.model5.Model5Factory;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
+import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
/**
* @author Eike Stepper
@@ -235,4 +240,127 @@ public class ChunkingTest extends AbstractCDOTest
assertEquals(i - 20, saleOrders.getId());
}
}
+
+ private static final String RESOURCE_PATH = "/test";
+
+ public void testPartiallyLoadedAdd()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().add(9);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ }
+
+ public void testPartiallyLoadedAddAtIndex()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().add(5, 9);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 9, 5, 6, 7, 8);
+ }
+
+ public void testPartiallyLoadedSet()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().set(5, 9);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 9, 6, 7, 8);
+ }
+
+ public void testPartiallyLoadedRemoveIndex()
+ {
+ createInitialList();
+
+ CDOSession session = openSession(getModel5Package());
+ session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.getResource(RESOURCE_PATH);
+
+ GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+ list.getElements().remove(5);
+
+ tx.commit();
+ tx.close();
+ session.close();
+ clearCache(getRepository().getRevisionManager());
+
+ testListResult(0, 1, 2, 3, 4, 6, 7, 8);
+ }
+
+ private void createInitialList()
+ {
+ CDOSession session = openSession(getModel5Package());
+ CDOTransaction tx = session.openTransaction();
+ CDOResource resource = tx.createResource(RESOURCE_PATH);
+
+ GenListOfInt list = Model5Factory.eINSTANCE.createGenListOfInt();
+
+ list.getElements().addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8));
+
+ resource.getContents().add(list);
+
+ tx.commit();
+ tx.close();
+ session.close();
+
+ clearCache(getRepository().getRevisionManager());
+ }
+
+ private void testListResult(Integer... expected)
+ {
+ List<Integer> expectedList = Arrays.asList(expected);
+
+ CDOSession session = openSession(getModel5Package());
+ CDOView view = session.openView();
+ CDOResource resource = view.getResource(RESOURCE_PATH);
+
+ EList<Integer> actualList = ((GenListOfInt)resource.getContents().get(0)).getElements();
+
+ assertEquals("List sizes differ", expectedList.size(), actualList.size());
+
+ for (int index = 0; index < expectedList.size(); index++)
+ {
+ assertEquals("Entry at index " + index + " differs", expectedList.get(index), actualList.get(index));
+ }
+
+ view.close();
+ session.close();
+ }
+
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
index 300b95c..e21e78a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
@@ -335,6 +335,12 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
super.initRepositoryProperties(props);
props.put(IRepository.Props.SUPPORTING_AUDITS, "false");
}
+
+ @Override
+ protected IMappingStrategy createMappingStrategy()
+ {
+ return CDODBUtil.createHorizontalNonAuditMappingStrategy();
+ }
}
/**
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java
index f8daf35..d2d63cd 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/AuditDBStoreIntegrityVerifier.java
@@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditMappingStrategy;
import org.eclipse.net4j.util.collection.Pair;
@@ -42,7 +43,7 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
@Override
protected void doVerify() throws Exception
- {/*
+ {
for (IClassMapping mapping : getClassMappings())
{
if (mapping != null && mapping.getDBTables() != null)
@@ -50,9 +51,8 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
verifyClassMapping(mapping);
}
}
- */
}
-/*
+
private void verifyClassMapping(IClassMapping mapping) throws Exception
{
verifyAtMostOneUnrevised(mapping);
@@ -118,13 +118,14 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
private void verifyReferences(IClassMapping mapping) throws Exception
{
- List<IListMapping> referenceMappings = mapping.getReferenceMappings();
- if (referenceMappings == null)
+ List<IListMapping> listMappings = ((HorizontalAuditClassMapping)mapping).getListMappings();
+ if (listMappings == null)
{
return;
}
- String tableName = mapping.getDBTables().iterator().next().getName();;
+ String tableName = mapping.getDBTables().iterator().next().getName();
+ ;
String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", " + CDODBSchema.ATTRIBUTES_VERSION + " FROM " + tableName;
ArrayList<Pair<Long, Integer>> idVersions = new ArrayList<Pair<Long, Integer>>();
@@ -142,18 +143,18 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
resultSet.close();
}
- for (IManyMapping refMapping : referenceMappings)
+ for (IListMapping listMapping : listMappings)
{
for (Pair<Long, Integer> idVersion : idVersions)
{
- verifyCorrectIndices(refMapping, idVersion.getElement1(), idVersion.getElement2());
+ verifyCorrectIndices(listMapping, idVersion.getElement1(), idVersion.getElement2());
}
}
}
- private void verifyCorrectIndices(IManyMapping refMapping, long id, int version) throws Exception
+ private void verifyCorrectIndices(IListMapping refMapping, long id, int version) throws Exception
{
- String tableName = refMapping.getTable().getName();
+ String tableName = refMapping.getDBTables().iterator().next().getName();
TRACER.format("verifyUniqueIdVersion: {0} for ID{1}v{2} ...", tableName, id, version);
@@ -184,5 +185,5 @@ public class AuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
{
resultSet.close();
}
- }*/
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java
index 5774018..997869c 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/verifier/NonAuditDBStoreIntegrityVerifier.java
@@ -10,26 +10,15 @@
*/
package org.eclipse.emf.cdo.tests.store.verifier;
-import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.IStore;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IManyMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.mapping.HorizontalMappingStrategy;
-
-import org.eclipse.net4j.util.collection.Pair;
-
-import java.sql.ResultSet;
-import java.util.ArrayList;
-import java.util.List;
/**
* @author Stefan Winkler
*/
-public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
+public abstract class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
{
public NonAuditDBStoreIntegrityVerifier(IRepository repo)
{
@@ -38,147 +27,147 @@ public class NonAuditDBStoreIntegrityVerifier extends AbstractDBStoreVerifier
// this is a verifier for non-auditing mode
assertTrue(getStore().getRevisionTemporality() == IStore.RevisionTemporality.NONE);
// ... and for horizontal class mapping
- assertTrue(getStore().getMappingStrategy() instanceof HorizontalMappingStrategy);
- }
-
- @Override
- protected void doVerify() throws Exception
- {
- for (IClassMapping mapping : getClassMappings())
- {
- if (mapping != null && mapping.getTable() != null)
- {
- verifyClassMapping(mapping);
- }
- }
- }
-
- private void verifyClassMapping(IClassMapping mapping) throws Exception
- {
- verifyNoUnrevisedRevisions(mapping);
- verifyUniqueId(mapping);
- verifyReferences(mapping);
- }
-
- /**
- * Verify that there is no row with cdo_revised == 0.
- */
- private void verifyNoUnrevisedRevisions(IClassMapping mapping) throws Exception
- {
- String tableName = mapping.getTable().getName();
- String sql = "SELECT count(1) FROM " + tableName + " WHERE " + CDODBSchema.ATTRIBUTES_REVISED + " <> 0";
- ResultSet resultSet = getStatement().executeQuery(sql);
- try
- {
- assertTrue(resultSet.next());
- assertEquals("Revised revision in table " + tableName, 0, resultSet.getInt(1));
- }
- finally
- {
- resultSet.close();
- }
- }
-
- /**
- * Verify that the id is unique.
- */
- private void verifyUniqueId(IClassMapping mapping) throws Exception
- {
- String tableName = mapping.getTable().getName();
- String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", count(1) FROM " + tableName + " GROUP BY "
- + CDODBSchema.ATTRIBUTES_ID;
-
- ResultSet resultSet = getStatement().executeQuery(sql);
-
- try
- {
- while (resultSet.next())
- {
- assertEquals("Multiple rows for ID " + resultSet.getLong(1), 1, resultSet.getInt(2));
- }
- }
- finally
- {
- resultSet.close();
- }
- }
-
- private void verifyReferences(IClassMapping mapping) throws Exception
- {
- List<IManyMapping> referenceMappings = mapping.getReferenceMappings();
- if (referenceMappings == null)
- {
- return;
- }
-
- String tableName = mapping.getTable().getName();
- String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", " + CDODBSchema.ATTRIBUTES_VERSION + " FROM " + tableName;
-
- ArrayList<Pair<Long, Integer>> idVersions = new ArrayList<Pair<Long, Integer>>();
-
- ResultSet resultSet = getStatement().executeQuery(sql);
- try
- {
- while (resultSet.next())
- {
- idVersions.add(new Pair<Long, Integer>(resultSet.getLong(1), resultSet.getInt(2)));
- }
- }
- finally
- {
- resultSet.close();
- }
-
- for (IManyMapping refMapping : referenceMappings)
- {
- for (Pair<Long, Integer> idVersion : idVersions)
- {
- verifyOnlyLatestReferences(refMapping, idVersion.getElement1(), idVersion.getElement2());
- verifyCorrectIndices(refMapping, idVersion.getElement1());
- }
- }
+ // assertTrue(getStore().getMappingStrategy() instanceof HorizontalMappingStrategy);
}
- /**
- * Verify that no reference with sourceId == ID exist which have another version
- */
- private void verifyOnlyLatestReferences(IManyMapping refMapping, long id, int version) throws Exception
- {
- String tableName = refMapping.getTable().getName();
- String sql = "SELECT count(1) FROM " + tableName + " WHERE " + CDODBSchema.FEATURE_REVISION_ID + "=" + id + " AND "
- + CDODBSchema.FEATURE_REVISION_VERSION + "<>" + version;
-
- ResultSet resultSet = getStatement().executeQuery(sql);
- try
- {
- assertTrue(resultSet.next());
- assertEquals("Table " + tableName + " contains old references for id " + id + "(version should be " + version
- + ")", 0, resultSet.getInt(1));
- }
- finally
- {
- resultSet.close();
- }
- }
-
- private void verifyCorrectIndices(IManyMapping refMapping, long id) throws Exception
- {
- String tableName = refMapping.getTable().getName();
- String sql = "SELECT " + CDODBSchema.FEATURE_IDX + " FROM " + tableName + " WHERE "
- + CDODBSchema.FEATURE_REVISION_ID + "=" + id + " ORDER BY " + CDODBSchema.FEATURE_IDX;
-
- ResultSet resultSet = getStatement().executeQuery(sql);
- int indexShouldBe = 0;
- try
- {
- while (resultSet.next())
- {
- assertEquals("Index " + indexShouldBe + " missing for ID" + id, indexShouldBe++, resultSet.getInt(1));
- }
- }
- finally
- {
- resultSet.close();
- }
- }
+ // @Override
+ // protected void doVerify() throws Exception
+ // {
+ // for (IClassMapping mapping : getClassMappings())
+ // {
+ // if (mapping != null && mapping.getTable() != null)
+ // {
+ // verifyClassMapping(mapping);
+ // }
+ // }
+ // }
+ //
+ // private void verifyClassMapping(IClassMapping mapping) throws Exception
+ // {
+ // verifyNoUnrevisedRevisions(mapping);
+ // verifyUniqueId(mapping);
+ // verifyReferences(mapping);
+ // }
+ //
+ // /**
+ // * Verify that there is no row with cdo_revised == 0.
+ // */
+ // private void verifyNoUnrevisedRevisions(IClassMapping mapping) throws Exception
+ // {
+ // String tableName = mapping.getTable().getName();
+ // String sql = "SELECT count(1) FROM " + tableName + " WHERE " + CDODBSchema.ATTRIBUTES_REVISED + " <> 0";
+ // ResultSet resultSet = getStatement().executeQuery(sql);
+ // try
+ // {
+ // assertTrue(resultSet.next());
+ // assertEquals("Revised revision in table " + tableName, 0, resultSet.getInt(1));
+ // }
+ // finally
+ // {
+ // resultSet.close();
+ // }
+ // }
+ //
+ // /**
+ // * Verify that the id is unique.
+ // */
+ // private void verifyUniqueId(IClassMapping mapping) throws Exception
+ // {
+ // String tableName = mapping.getTable().getName();
+ // String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", count(1) FROM " + tableName + " GROUP BY "
+ // + CDODBSchema.ATTRIBUTES_ID;
+ //
+ // ResultSet resultSet = getStatement().executeQuery(sql);
+ //
+ // try
+ // {
+ // while (resultSet.next())
+ // {
+ // assertEquals("Multiple rows for ID " + resultSet.getLong(1), 1, resultSet.getInt(2));
+ // }
+ // }
+ // finally
+ // {
+ // resultSet.close();
+ // }
+ // }
+ //
+ // private void verifyReferences(IClassMapping mapping) throws Exception
+ // {
+ // List<IManyMapping> referenceMappings = mapping.getReferenceMappings();
+ // if (referenceMappings == null)
+ // {
+ // return;
+ // }
+ //
+ // String tableName = mapping.getTable().getName();
+ // String sql = "SELECT " + CDODBSchema.ATTRIBUTES_ID + ", " + CDODBSchema.ATTRIBUTES_VERSION + " FROM " + tableName;
+ //
+ // ArrayList<Pair<Long, Integer>> idVersions = new ArrayList<Pair<Long, Integer>>();
+ //
+ // ResultSet resultSet = getStatement().executeQuery(sql);
+ // try
+ // {
+ // while (resultSet.next())
+ // {
+ // idVersions.add(new Pair<Long, Integer>(resultSet.getLong(1), resultSet.getInt(2)));
+ // }
+ // }
+ // finally
+ // {
+ // resultSet.close();
+ // }
+ //
+ // for (IManyMapping refMapping : referenceMappings)
+ // {
+ // for (Pair<Long, Integer> idVersion : idVersions)
+ // {
+ // verifyOnlyLatestReferences(refMapping, idVersion.getElement1(), idVersion.getElement2());
+ // verifyCorrectIndices(refMapping, idVersion.getElement1());
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * Verify that no reference with sourceId == ID exist which have another version
+ // */
+ // private void verifyOnlyLatestReferences(IManyMapping refMapping, long id, int version) throws Exception
+ // {
+ // String tableName = refMapping.getTable().getName();
+ // String sql = "SELECT count(1) FROM " + tableName + " WHERE " + CDODBSchema.FEATURE_REVISION_ID + "=" + id + " AND "
+ // + CDODBSchema.FEATURE_REVISION_VERSION + "<>" + version;
+ //
+ // ResultSet resultSet = getStatement().executeQuery(sql);
+ // try
+ // {
+ // assertTrue(resultSet.next());
+ // assertEquals("Table " + tableName + " contains old references for id " + id + "(version should be " + version
+ // + ")", 0, resultSet.getInt(1));
+ // }
+ // finally
+ // {
+ // resultSet.close();
+ // }
+ // }
+ //
+ // private void verifyCorrectIndices(IManyMapping refMapping, long id) throws Exception
+ // {
+ // String tableName = refMapping.getTable().getName();
+ // String sql = "SELECT " + CDODBSchema.FEATURE_IDX + " FROM " + tableName + " WHERE "
+ // + CDODBSchema.FEATURE_REVISION_ID + "=" + id + " ORDER BY " + CDODBSchema.FEATURE_IDX;
+ //
+ // ResultSet resultSet = getStatement().executeQuery(sql);
+ // int indexShouldBe = 0;
+ // try
+ // {
+ // while (resultSet.next())
+ // {
+ // assertEquals("Index " + indexShouldBe + " missing for ID" + id, indexShouldBe++, resultSet.getInt(1));
+ // }
+ // }
+ // finally
+ // {
+ // resultSet.close();
+ // }
+ // }
}