### Eclipse Workspace Patch 1.0 #P org.eclipse.emf.cdo.tests Index: src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java =================================================================== RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/tests/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java,v retrieving revision 1.2 diff -u -r1.2 RepositoryConfig.java --- src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java 9 Nov 2008 10:56:30 -0000 1.2 +++ src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java 11 Nov 2008 14:28:49 -0000 @@ -337,6 +337,24 @@ } } + public static class DBHsqldbPrepStmt extends DBHsqldb + { + private static final long serialVersionUID = 1L; + + public static final DBHsqldbPrepStmt HSQLDB_HORIZONTAL_PREPSTMT = new DBHsqldbPrepStmt("HsqldbHorizontalPrepStmt"); + + public DBHsqldbPrepStmt(String name) + { + super(name); + } + + @Override + protected IJDBCDelegateProvider createDelegateProvider() + { + return CDODBUtil.createPreparedStatementJDBCDelegateProvider(); + } + } + /** * @author Eike Stepper */ @@ -408,6 +426,24 @@ } } + public static class DBDerbyPrepStmt extends DBDerby + { + private static final long serialVersionUID = 1L; + + public static final DBDerbyPrepStmt DERBY_HORIZONTAL_PREPSTMT = new DBDerbyPrepStmt("DerbyHorizontalPrepStmt"); + + public DBDerbyPrepStmt(String name) + { + super(name); + } + + @Override + protected IJDBCDelegateProvider createDelegateProvider() + { + return CDODBUtil.createPreparedStatementJDBCDelegateProvider(); + } + } + /** * @author Simon McDuff */ @@ -521,4 +557,23 @@ return CDODBUtil.createNonPreparedStatementJDBCDelegateProvider(); } } + + public static class DBMysqlPrepStmt extends DBMysql + { + private static final long serialVersionUID = 1L; + + public static final DBMysqlPrepStmt MYSQL_HORIZONTAL_PREPSTMT = new DBMysqlPrepStmt("MysqlHorizontalPrepStmt"); + + public DBMysqlPrepStmt(String name) + { + super(name); + } + + @Override + protected IJDBCDelegateProvider createDelegateProvider() + { + return CDODBUtil.createPreparedStatementJDBCDelegateProvider(); + } + } + } Index: src/org/eclipse/emf/cdo/tests/config/IConstants.java =================================================================== RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/tests/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java,v retrieving revision 1.3 diff -u -r1.3 IConstants.java --- src/org/eclipse/emf/cdo/tests/config/IConstants.java 9 Nov 2008 10:56:30 -0000 1.3 +++ src/org/eclipse/emf/cdo/tests/config/IConstants.java 11 Nov 2008 14:28:49 -0000 @@ -35,10 +35,16 @@ public static final RepositoryConfig DB_HSQL_HORIZONTAL = RepositoryConfig.DBHsqldbNonPrepStmt.HSQLDB_HORIZONTAL; + public static final RepositoryConfig DB_HSQL_HORIZONTAL_PREPSTMT = RepositoryConfig.DBHsqldbPrepStmt.HSQLDB_HORIZONTAL_PREPSTMT; + public static final RepositoryConfig DB_DERBY_HORIZONTAL = RepositoryConfig.DBDerbyNonPrepStmt.DERBY_HORIZONTAL; + public static final RepositoryConfig DB_DERBY_HORIZONTAL_PREPSTMT = RepositoryConfig.DBDerbyPrepStmt.DERBY_HORIZONTAL_PREPSTMT; + public static final RepositoryConfig DB_MYSQL_HORIZONTAL = RepositoryConfig.DBMysqlNonPrepStmt.MYSQL_HORIZONTAL; + public static final RepositoryConfig DB_MYSQL_HORIZONTAL_PREPSTMT = RepositoryConfig.DBMysqlPrepStmt.MYSQL_HORIZONTAL_PREPSTMT; + public static final SessionConfig JVM = SessionConfig.JVM.INSTANCE; public static final SessionConfig TCP = SessionConfig.TCP.INSTANCE; #P org.eclipse.emf.cdo.server.db Index: plugin.xml =================================================================== RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.db/plugin.xml,v retrieving revision 1.10 diff -u -r1.10 plugin.xml --- plugin.xml 9 Nov 2008 10:56:34 -0000 1.10 +++ plugin.xml 11 Nov 2008 14:28:50 -0000 @@ -46,6 +46,10 @@ class="org.eclipse.emf.cdo.server.internal.db.jdbc.NonPreparedStatementJDBCDelegateProvider" type="nonPreparedStatement"> + + Index: src/org/eclipse/emf/cdo/server/db/CDODBUtil.java =================================================================== RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/CDODBUtil.java,v retrieving revision 1.11 diff -u -r1.11 CDODBUtil.java --- src/org/eclipse/emf/cdo/server/db/CDODBUtil.java 9 Nov 2008 10:56:33 -0000 1.11 +++ src/org/eclipse/emf/cdo/server/db/CDODBUtil.java 11 Nov 2008 14:28:50 -0000 @@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.server.internal.db.HorizontalMappingStrategy; import org.eclipse.emf.cdo.server.internal.db.bundle.OM; import org.eclipse.emf.cdo.server.internal.db.jdbc.NonPreparedStatementJDBCDelegateProvider; +import org.eclipse.emf.cdo.server.internal.db.jdbc.PreparedStatementJDBCDelegateProvider; import org.eclipse.net4j.db.IDBAdapter; import org.eclipse.net4j.db.IDBConnectionProvider; @@ -73,6 +74,14 @@ } /** + * @since 2.0 + */ + public static IJDBCDelegateProvider createPreparedStatementJDBCDelegateProvider() + { + return new PreparedStatementJDBCDelegateProvider(); + } + + /** * 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. * Index: src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java =================================================================== RCS file: src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java diff -N src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegateProvider.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.db.jdbc; + +import org.eclipse.emf.cdo.server.db.IJDBCDelegate; +import org.eclipse.emf.cdo.server.db.IJDBCDelegateProvider; + +/** + * @author Eike Stepper + */ +public class PreparedStatementJDBCDelegateProvider implements IJDBCDelegateProvider +{ + + public IJDBCDelegate getJDBCDelegate() + { + return new PreparedStatementJDBCDelegate(); + } + +} Index: src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java =================================================================== RCS file: src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java diff -N src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/emf/cdo/server/internal/db/jdbc/PreparedStatementJDBCDelegate.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,316 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.db.jdbc; + +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.IAttributeMapping; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; +import org.eclipse.emf.cdo.server.internal.db.ServerInfo; +import org.eclipse.emf.cdo.server.internal.db.bundle.OM; +import org.eclipse.emf.cdo.spi.common.InternalCDORevision; + +import org.eclipse.net4j.db.DBException; +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.List; + +/** + * @author Stefan WInkler + * @since 2.0 + */ +public class PreparedStatementJDBCDelegate extends AbstractJDBCDelegate +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, PreparedStatementJDBCDelegate.class); + + private static final String SQL_UPDATE_REVISE_VERSION = " SET " + CDODBSchema.ATTRIBUTES_REVISED + " = ? WHERE " + + CDODBSchema.ATTRIBUTES_ID + " = ? AND " + CDODBSchema.ATTRIBUTES_VERSION + " = ?"; + + private static final String SQL_UPDATE_REVISE_UNREVISED = " SET " + CDODBSchema.ATTRIBUTES_REVISED + " = ? WHERE " + + CDODBSchema.ATTRIBUTES_ID + " = ? AND " + CDODBSchema.ATTRIBUTES_REVISED + " = 0"; + + private static final String SQL_INSERT_REFERENCE_WITH_DBID = " VALUES (?, ?, ?, ?, ?)"; + + private static final String SQL_INSERT_REFERENCE = " VALUES (?, ?, ?, ?)"; + + @Override + protected void doInsertAttributes(String tableName, CDORevision rev, List attributeMappings, + boolean withFullRevisionInfo) + { + PreparedStatement stmt = null; + StringBuilder sql = new StringBuilder(); + InternalCDORevision revision = (InternalCDORevision)rev; + + if (attributeMappings == null) + { + attributeMappings = Collections.emptyList(); + } + + sql.append("INSERT INTO "); + sql.append(tableName); + sql.append(" VALUES (?, ?, "); + if (withFullRevisionInfo) + { + sql.append("?, ?, ?, ?, ?, ?"); + } + for (int i = 0; i < attributeMappings.size(); i++) + { + sql.append(", ?"); + } + sql.append(")"); + + int col = 1; + + try + { + if (TRACER.isEnabled()) + { + TRACER.format("{0} ({1})", sql.toString(), revision.toString()); + } + stmt = getConnection().prepareStatement(sql.toString()); + stmt.setLong(col++, CDOIDUtil.getLong(revision.getID())); + stmt.setInt(col++, revision.getVersion()); + + if (withFullRevisionInfo) + { + stmt.setInt(col++, ServerInfo.getDBID(revision.getCDOClass())); + stmt.setLong(col++, revision.getCreated()); + stmt.setLong(col++, revision.getRevised()); + stmt.setLong(col++, CDOIDUtil.getLong(revision.getResourceID())); + stmt.setLong(col++, CDOIDUtil.getLong((CDOID)revision.getContainerID())); + stmt.setInt(col++, revision.getContainingFeatureID()); + } + + for (IAttributeMapping attributeMapping : attributeMappings) + { + Object value = attributeMapping.getRevisionValue(revision); + stmt.setObject(col++, value); + } + stmt.execute(); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); + } + } + + @Override + protected void doInsertReference(String tableName, int dbId, long source, int version, int i, long target) + { + PreparedStatement stmt = null; + + try + { + StringBuilder sql = new StringBuilder("INSERT INTO "); + sql.append(tableName); + sql.append(dbId != 0 ? SQL_INSERT_REFERENCE_WITH_DBID : SQL_INSERT_REFERENCE); + + int idx = 1; + + stmt = getConnection().prepareStatement(sql.toString()); + + if (dbId != 0) + { + stmt.setInt(idx++, dbId); + } + stmt.setLong(idx++, source); + stmt.setInt(idx++, version); + stmt.setInt(idx++, i); + stmt.setLong(idx++, target); + + if (TRACER.isEnabled()) + { + TRACER.format("{0} ({1},{2},{3},{4},{5})", sql.toString(), dbId, source, version, i, target); + } + + stmt.execute(); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); + } + } + + @Override + protected void doUpdateRevised(String tableName, long revisedStamp, long cdoid, int version) + { + PreparedStatement stmt = null; + + try + { + StringBuilder sql = new StringBuilder("UPDATE "); + sql.append(tableName); + sql.append(SQL_UPDATE_REVISE_VERSION); + + stmt = getConnection().prepareStatement(sql.toString()); + stmt.setLong(1, revisedStamp); + stmt.setLong(2, cdoid); + stmt.setInt(3, version); + + if (TRACER.isEnabled()) + { + TRACER.format("{0} ({1},{2},{3})", sql.toString(), revisedStamp, cdoid, version); + } + + stmt.execute(); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); + } + } + + @Override + protected void doUpdateRevised(String tableName, long revisedStamp, long cdoid) + { + PreparedStatement stmt = null; + + try + { + StringBuilder sql = new StringBuilder("UPDATE "); + sql.append(tableName); + sql.append(SQL_UPDATE_REVISE_UNREVISED); + + stmt = getConnection().prepareStatement(sql.toString()); + stmt.setLong(1, revisedStamp); + stmt.setLong(2, cdoid); + + if (TRACER.isEnabled()) + { + TRACER.format("{0} ({1},{2})", sql.toString(), revisedStamp, cdoid); + } + + stmt.execute(); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); + } + } + + @Override + protected ResultSet doSelectRevisionAttributes(String tableName, long revisionId, + List attributeMappings, boolean hasFullRevisionInfo, String where) throws SQLException + { + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); + builder.append(CDODBSchema.ATTRIBUTES_VERSION); + builder.append(", "); + builder.append(CDODBSchema.ATTRIBUTES_CREATED); + + if (hasFullRevisionInfo) + { + 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 (IAttributeMapping attributeMapping : attributeMappings) + { + builder.append(", "); + builder.append(attributeMapping.getField()); + } + + builder.append(" FROM "); + builder.append(tableName); + builder.append(" WHERE "); + builder.append(CDODBSchema.ATTRIBUTES_ID); + builder.append("= ? AND ("); + builder.append(where); + builder.append(")"); + String sql = builder.toString(); + if (TRACER.isEnabled()) + { + TRACER.format("{0} ({1})", sql, revisionId); + } + + PreparedStatement pstmt = getConnection().prepareStatement(sql); + pstmt.setLong(1, revisionId); + return pstmt.executeQuery(); + } + + @Override + protected ResultSet doSelectRevisionReferences(String tableName, long sourceId, int version, int dbFeatureID, + String where) throws SQLException + { + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); + builder.append(CDODBSchema.REFERENCES_TARGET); + builder.append(" FROM "); + builder.append(tableName); + builder.append(" WHERE "); + if (dbFeatureID != 0) + { + builder.append(CDODBSchema.REFERENCES_FEATURE); + builder.append("= ? AND "); + } + + builder.append(CDODBSchema.REFERENCES_SOURCE); + builder.append("= ? AND "); + builder.append(CDODBSchema.REFERENCES_VERSION); + builder.append("= ? "); + + if (where != null) + { + builder.append(where); + } + + builder.append(" ORDER BY "); + builder.append(CDODBSchema.REFERENCES_IDX); + + String sql = builder.toString(); + + if (TRACER.isEnabled()) + { + TRACER.trace(sql); + } + + PreparedStatement pstmt = getConnection().prepareStatement(sql); + int idx = 1; + + if (dbFeatureID != 0) + { + pstmt.setInt(idx++, dbFeatureID); + } + + pstmt.setLong(idx++, sourceId); + pstmt.setInt(idx++, version); + return pstmt.executeQuery(); + } + +}