diff options
18 files changed, 623 insertions, 64 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java index bc3ec95a14..80b5223ea8 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java @@ -48,9 +48,6 @@ public abstract class MappingStrategy extends Lifecycle implements IMappingStrat { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, MappingStrategy.class); - @Deprecated - public static final String PROP_MAPPING_PRECEDENCE = "mappingPrecedence"; - public static final String PROP_TO_MANY_REFERENCE_MAPPING = "toManyReferenceMapping"; public static final String PROP_TO_ONE_REFERENCE_MAPPING = "toOneReferenceMapping"; @@ -102,12 +99,6 @@ public abstract class MappingStrategy extends Lifecycle implements IMappingStrat this.properties = properties; } - public Precedence getPrecedence() - { - String value = getProperties().get(PROP_MAPPING_PRECEDENCE); - return value == null ? Precedence.STRATEGY : Precedence.valueOf(value); - } - public ToMany getToMany() { String value = getProperties().get(PROP_TO_MANY_REFERENCE_MAPPING); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java index c62da171cf..822e5989e7 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java @@ -261,7 +261,7 @@ public class Repository extends Container<IRepositoryElement> implements IReposi protected void activateRepository() throws Exception { LifecycleUtil.activate(store); - packageManager.activate(); + LifecycleUtil.activate(packageManager); if (store.wasCrashed()) { store.repairAfterCrash(); @@ -269,17 +269,17 @@ public class Repository extends Container<IRepositoryElement> implements IReposi setLastMetaID(store.getLastMetaID()); - sessionManager.activate(); - resourceManager.activate(); - revisionManager.activate(); + LifecycleUtil.activate(sessionManager); + LifecycleUtil.activate(resourceManager); + LifecycleUtil.activate(revisionManager); } protected void deactivateRepository() { - revisionManager.deactivate(); - resourceManager.deactivate(); - sessionManager.deactivate(); - packageManager.deactivate(); + LifecycleUtil.deactivate(revisionManager); + LifecycleUtil.deactivate(resourceManager); + LifecycleUtil.deactivate(sessionManager); + LifecycleUtil.deactivate(packageManager); LifecycleUtil.deactivate(store); } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RepositoryConfigurator.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RepositoryConfigurator.java index 7e9e2192e5..40ef4a028a 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RepositoryConfigurator.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RepositoryConfigurator.java @@ -109,7 +109,6 @@ public class RepositoryConfigurator Element storeConfig = getStoreConfig(repositoryConfig); IStore store = configureStore(storeConfig); - store.setRepository(repository); repository.setStore(store); Map<String, String> properties = getProperties(repositoryConfig, 1); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java index f0410c73cf..b4751fae5a 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java @@ -16,7 +16,7 @@ import org.eclipse.emf.cdo.internal.server.bundle.OM; import org.eclipse.emf.cdo.internal.server.protocol.CDOServerProtocol; import org.eclipse.emf.cdo.internal.server.protocol.InvalidationNotification; import org.eclipse.emf.cdo.protocol.CDOProtocolConstants; -import org.eclipse.emf.cdo.protocol.CDOProtocolView.Type; +import org.eclipse.emf.cdo.protocol.CDOProtocolView; import org.eclipse.emf.cdo.protocol.id.CDOID; import org.eclipse.emf.cdo.protocol.id.CDOIDObject; import org.eclipse.emf.cdo.protocol.id.CDOIDProvider; @@ -124,42 +124,58 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider return views.get(viewID); } - public void notifyViewsChanged(Session session, int viewID, byte kind) - { - if (kind == CDOProtocolConstants.VIEW_CLOSED) - { - IView view = views.remove(viewID); - if (view != null) - { - fireElementRemovedEvent(view); - } - } - else - { - IView view = createView(kind, viewID); - views.put(viewID, view); - fireElementAddedEvent(view); - } - } - - private IView createView(byte kind, int viewID) + public void changeView(int viewID, byte kind) { switch (kind) { + case CDOProtocolConstants.VIEW_CLOSED: + closeView(viewID); + break; + case CDOProtocolConstants.VIEW_TRANSACTION: - return new Transaction(this, viewID); + openView(viewID, CDOProtocolView.Type.TRANSACTION); + break; case CDOProtocolConstants.VIEW_READONLY: - return new View(this, viewID, Type.READONLY); + openView(viewID, CDOProtocolView.Type.READONLY); case CDOProtocolConstants.VIEW_AUDIT: - return new View(this, viewID, Type.AUDIT); + openView(viewID, CDOProtocolView.Type.AUDIT); default: throw new ImplementationError("Invalid kind: " + kind); } } + public IView closeView(int viewID) + { + IView view = views.remove(viewID); + if (view != null) + { + fireElementRemovedEvent(view); + } + + return view; + } + + public IView openView(int viewID, CDOProtocolView.Type type) + { + IView view = createView(viewID, type); + views.put(viewID, view); + fireElementAddedEvent(view); + return view; + } + + private IView createView(int viewID, CDOProtocolView.Type type) + { + if (type == CDOProtocolView.Type.TRANSACTION) + { + return new Transaction(this, viewID); + } + + return new View(this, viewID, type); + } + public void notifyInvalidation(long timeStamp, List<CDOID> dirtyIDs) { try diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ViewsChangedIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ViewsChangedIndication.java index e6bce97ca0..286d0bfd18 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ViewsChangedIndication.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ViewsChangedIndication.java @@ -38,9 +38,9 @@ public class ViewsChangedIndication extends CDOServerIndication // Indication { int viewID = in.readInt(); byte kind = in.readByte(); - CDOServerProtocol protocol = (CDOServerProtocol)getProtocol(); + CDOServerProtocol protocol = getProtocol(); Session session = protocol.getSession(); - session.notifyViewsChanged(session, viewID, kind); + session.changeView(viewID, kind); } @Override diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java index a4f94b07a1..0b21ee6edc 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java @@ -47,9 +47,8 @@ public final class CDOServerUtil { Repository repository = new Repository(); repository.setName(name); - repository.setProperties(props); repository.setStore(store); - store.setRepository(repository); + repository.setProperties(props); return repository; } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java index 6afab287f1..199a2c67ef 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java @@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.server; import org.eclipse.emf.cdo.internal.server.protocol.CDOServerProtocol; import org.eclipse.emf.cdo.protocol.CDOProtocolSession; +import org.eclipse.emf.cdo.protocol.CDOProtocolView; import org.eclipse.net4j.util.container.IContainer; @@ -23,4 +24,8 @@ public interface ISession extends CDOProtocolSession, IContainer<IView> public ISessionManager getSessionManager(); public CDOServerProtocol getProtocol(); + + public IView openView(int viewID, CDOProtocolView.Type type); + + public IView closeView(int viewID); } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java index b6840ff90e..3d00fa14b5 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java @@ -10,6 +10,7 @@ **************************************************************************/ package org.eclipse.emf.cdo.server; +import org.eclipse.emf.cdo.internal.server.Repository; import org.eclipse.emf.cdo.protocol.id.CDOIDLibraryDescriptor; import org.eclipse.emf.cdo.protocol.id.CDOIDLibraryProvider; import org.eclipse.emf.cdo.protocol.id.CDOIDObjectFactory; @@ -20,6 +21,9 @@ import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; */ public interface IStore extends IRepositoryElement { + /** + * Internal method. Should only be called by {@link Repository#setStore(IStore)}. + */ public void setRepository(IRepository repository); public String getStoreType(); diff --git a/plugins/org.eclipse.emf.cdo.tests/.classpath b/plugins/org.eclipse.emf.cdo.tests/.classpath index d2d2655389..9989588abd 100644 --- a/plugins/org.eclipse.emf.cdo.tests/.classpath +++ b/plugins/org.eclipse.emf.cdo.tests/.classpath @@ -4,5 +4,6 @@ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="net4j"/> + <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.net4j.db.hsqldb"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF index 917b4d7562..c667ec34b1 100644 --- a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF @@ -13,11 +13,12 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)", org.eclipse.net4j.jvm;resolution:=optional;visibility:=reexport, org.eclipse.net4j.tcp;resolution:=optional;visibility:=reexport, org.eclipse.emf.cdo.server;visibility:=reexport, + org.eclipse.emf.cdo.server.db;visibility:=reexport, org.eclipse.emf.cdo;visibility:=reexport, org.eclipse.emf.cdo.tests.mango;visibility:=reexport, org.eclipse.emf.cdo.tests.model1;visibility:=reexport, - org.eclipse.emf.cdo.tests.model2, - org.eclipse.emf.cdo.tests.model3, + org.eclipse.emf.cdo.tests.model2;visibility:=reexport, + org.eclipse.emf.cdo.tests.model3;visibility:=reexport, org.junit;visibility:=reexport Export-Package: org.eclipse.emf.cdo.tests, org.eclipse.net4j.tests diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java index c205cfd332..e50dbee4dc 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java @@ -171,7 +171,6 @@ public class ChunkingWithMEMTest extends AbstractCDOTest repository.setName(REPOSITORY_NAME); repository.setProperties(props); repository.setStore(store); - store.setRepository(repository); return repository; } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/DBStoreHorizontalTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/DBStoreHorizontalTest.java new file mode 100644 index 0000000000..25a9c2181c --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/DBStoreHorizontalTest.java @@ -0,0 +1,174 @@ +/*************************************************************************** + * 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.tests.store; + +import org.eclipse.emf.cdo.internal.server.Transaction; +import org.eclipse.emf.cdo.server.IStore; +import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; +import org.eclipse.emf.cdo.server.internal.db.DBStore; +import org.eclipse.emf.cdo.server.internal.db.HorizontalMappingStrategy; +import org.eclipse.emf.cdo.server.internal.db.MappingStrategy; +import org.eclipse.emf.cdo.server.internal.db.ToMany; +import org.eclipse.emf.cdo.server.internal.db.ToOne; + +import org.eclipse.net4j.db.DBUtil; +import org.eclipse.net4j.db.IDBConnectionProvider; +import org.eclipse.net4j.db.hsqldb.HSQLDBDataSource; +import org.eclipse.net4j.db.internal.hsqldb.HSQLDBAdapter; +import org.eclipse.net4j.internal.db.DataSourceConnectionProvider; +import org.eclipse.net4j.util.WrappedException; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public class DBStoreHorizontalTest extends TestLogic +{ + private HorizontalMappingStrategy mappingStrategy; + + private HSQLDBAdapter dbAdapter; + + private IDBConnectionProvider dbConnectionProvider; + + private DBStore store; + + public DBStoreHorizontalTest() + { + } + + @Override + protected void doTearDown() throws Exception + { + store.getDBSchema().drop(dbAdapter, dbConnectionProvider); + super.doTearDown(); + CDODBSchema.INSTANCE.drop(dbAdapter, dbConnectionProvider); + } + + @Override + protected IStore createStore() + { + mappingStrategy = createMappingStrategy(); + dbAdapter = createDBAdapter(); + dbConnectionProvider = createDBConnectionProvider(); + + store = new DBStore(); + store.setMappingStrategy(mappingStrategy); + store.setDbAdapter(dbAdapter); + store.setDbConnectionProvider(dbConnectionProvider); + return store; + } + + protected IDBConnectionProvider createDBConnectionProvider() + { + HSQLDBDataSource dataSource = new HSQLDBDataSource(); + dataSource.setDatabase("jdbc:hsqldb:mem:storetest"); + dataSource.setUser("sa"); + + return new DataSourceConnectionProvider(dataSource); + } + + protected HSQLDBAdapter createDBAdapter() + { + return new HSQLDBAdapter(); + } + + protected HorizontalMappingStrategy createMappingStrategy() + { + Map<String, String> props = new HashMap<String, String>(); + props.put(MappingStrategy.PROP_TO_MANY_REFERENCE_MAPPING, ToMany.PER_CLASS.toString()); + props.put(MappingStrategy.PROP_TO_ONE_REFERENCE_MAPPING, ToOne.LIKE_ATTRIBUTES.toString()); + + HorizontalMappingStrategy mappingStrategy = new HorizontalMappingStrategy(); + mappingStrategy.setProperties(props); + return mappingStrategy; + } + + private void verifyRowCount(int expectedRows, String tableName) + { + int actuaRowsl = query("select count(*) from " + tableName); + assertEquals("Rows in " + tableName.toUpperCase(), expectedRows, actuaRowsl); + } + + private int query(String sql) + { + Connection connection = null; + Statement statement = null; + ResultSet resultSet = null; + + try + { + connection = store.getConnection(); + statement = connection.createStatement(); + resultSet = statement.executeQuery(sql); + if (!resultSet.next()) + { + return 0; + } + + return resultSet.getInt(1); + } + catch (Exception ex) + { + throw WrappedException.wrap(ex); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(statement); + DBUtil.close(connection); + } + } + + @Override + protected void verifyCreateModel1(Transaction transaction) + { + verifyRowCount(1, "cdo_repository"); + verifyRowCount(1, "cdo_packages"); + verifyRowCount(11, "cdo_classes"); + verifyRowCount(8, "cdo_supertypes"); + verifyRowCount(26, "cdo_features"); + } + + @Override + protected void verifyCreateModel2(Transaction transaction) + { + verifyRowCount(1, "cdo_repository"); + verifyRowCount(2, "cdo_packages"); + verifyRowCount(12, "cdo_classes"); + verifyRowCount(9, "cdo_supertypes"); + verifyRowCount(28, "cdo_features"); + } + + @Override + protected void verifyCreateModel3(Transaction transaction) + { + verifyRowCount(1, "cdo_repository"); + verifyRowCount(1, "cdo_packages"); + verifyRowCount(1, "cdo_classes"); + verifyRowCount(0, "cdo_supertypes"); + verifyRowCount(1, "cdo_features"); + } + + @Override + protected void verifyCreateMango(Transaction transaction) + { + verifyRowCount(1, "cdo_repository"); + verifyRowCount(1, "cdo_packages"); + verifyRowCount(2, "cdo_classes"); + verifyRowCount(0, "cdo_supertypes"); + verifyRowCount(3, "cdo_features"); + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/TestLogic.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/TestLogic.java new file mode 100644 index 0000000000..489f659268 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/TestLogic.java @@ -0,0 +1,262 @@ +/*************************************************************************** + * 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.tests.store; + +import org.eclipse.emf.cdo.internal.server.Repository; +import org.eclipse.emf.cdo.internal.server.Session; +import org.eclipse.emf.cdo.internal.server.Transaction; +import org.eclipse.emf.cdo.internal.server.Transaction.TransactionPackageManager; +import org.eclipse.emf.cdo.internal.server.protocol.CDOServerProtocol; +import org.eclipse.emf.cdo.protocol.CDOProtocolView; +import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; +import org.eclipse.emf.cdo.protocol.model.CDOModelUtil; +import org.eclipse.emf.cdo.protocol.model.CDOPackage; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; +import org.eclipse.emf.cdo.server.IStore; +import org.eclipse.emf.cdo.server.IRepository.Props; +import org.eclipse.emf.cdo.tests.mango.MangoPackage; +import org.eclipse.emf.cdo.tests.model1.Model1Package; +import org.eclipse.emf.cdo.tests.model2.Model2Package; +import org.eclipse.emf.cdo.tests.model3.Model3Package; +import org.eclipse.emf.cdo.util.EMFUtil; + +import org.eclipse.emf.internal.cdo.CDOSessionImpl; +import org.eclipse.emf.internal.cdo.util.ModelUtil; + +import org.eclipse.net4j.tests.AbstractOMTest; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EcorePackage; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public abstract class TestLogic extends AbstractOMTest +{ + public static final String REPOSITORY_NAME = "repo1"; + + protected Repository repository; + + public TestLogic() + { + } + + @Override + protected void doSetUp() throws Exception + { + repository = createRepository(); + repository.activate(); + } + + @Override + protected void doTearDown() throws Exception + { + repository.deactivate(); + repository = null; + } + + protected Repository createRepository() + { + Map<String, String> props = new HashMap<String, String>(); + props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, Boolean.toString(withRevisionDeltaSupport())); + props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000"); + props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000"); + + Map<String, String> testProperties = getTestProperties(); + if (testProperties != null) + { + props.putAll(testProperties); + } + + Repository repository = new Repository(); + repository.setName(REPOSITORY_NAME); + repository.setProperties(props); + repository.setStore(createStore()); + return repository; + } + + protected boolean withRevisionDeltaSupport() + { + return false; + } + + protected Map<String, String> getTestProperties() + { + return null; + } + + protected abstract IStore createStore(); + + public void testCreateModel1() throws Exception + { + CommitTemplate template = new CommitTemplate(); + template.addNewPackage(Model1Package.eINSTANCE); + Transaction transaction = template.run(); + verifyCreateModel1(transaction); + template.dispose(); + } + + protected abstract void verifyCreateModel1(Transaction transaction); + + public void testCreateModel2() throws Exception + { + CommitTemplate template = new CommitTemplate(); + template.addNewPackage(Model1Package.eINSTANCE); + template.addNewPackage(Model2Package.eINSTANCE); + Transaction transaction = template.run(); + verifyCreateModel2(transaction); + template.dispose(); + } + + protected abstract void verifyCreateModel2(Transaction transaction); + + public void testCreateModel3() throws Exception + { + CommitTemplate template = new CommitTemplate(); + template.addNewPackage(Model3Package.eINSTANCE); + Transaction transaction = template.run(); + verifyCreateModel3(transaction); + template.dispose(); + } + + protected abstract void verifyCreateModel3(Transaction transaction); + + public void testCreateMango() throws Exception + { + CommitTemplate template = new CommitTemplate(); + template.addNewPackage(MangoPackage.eINSTANCE); + Transaction transaction = template.run(); + verifyCreateMango(transaction); + template.dispose(); + } + + protected abstract void verifyCreateMango(Transaction transaction); + + /** + * @author Eike Stepper + */ + protected class CommitTemplate + { + private int viewID; + + private CDOServerProtocol protocol; + + private Session session; + + private Transaction transaction; + + private List<CDOPackage> newPackages = new ArrayList<CDOPackage>(); + + private List<CDORevision> newObjects = new ArrayList<CDORevision>(); + + private List<CDORevisionDelta> dirtyObjectDeltas = new ArrayList<CDORevisionDelta>(); + + public CommitTemplate() + { + this(1); + protocol = createProtocol(); + session = repository.getSessionManager().openSession(protocol, true); + protocol.setInfraStructure(session); + transaction = createTransaction(session); + transaction.preCommit(); + } + + public CommitTemplate(int viewID) + { + this.viewID = viewID; + } + + public Session getSession() + { + return session; + } + + public Transaction run() throws Exception + { + transaction.commit(getNewPackages(), getNewObjects(), getDirtyObjectDeltas()); + transaction.postCommit(true); + return transaction; + } + + public void dispose() + { + protocol.deactivate(); + } + + public CDOPackage addNewPackage(EPackage ePackage) + { + String uri = ePackage.getNsURI(); + String parentURI = ModelUtil.getParentURI(ePackage); + String name = ePackage.getName(); + boolean dynamic = EMFUtil.isDynamicEPackage(ePackage); + String ecore = null; + CDOIDMetaRange idRange = null; + + if (parentURI == null) + { + if (!EcorePackage.eINSTANCE.getNsURI().equals(uri)) + { + ecore = EMFUtil.ePackageToString(ePackage, EPackage.Registry.INSTANCE); + } + + idRange = CDOSessionImpl.registerEPackage(ePackage, 1, null, null); + } + + TransactionPackageManager packageManager = transaction.getPackageManager(); + CDOPackage cdoPackage = CDOModelUtil.createPackage(packageManager, uri, name, ecore, dynamic, idRange, parentURI); + ModelUtil.initializeCDOPackage(ePackage, cdoPackage); + packageManager.addPackage(cdoPackage); + newPackages.add(cdoPackage); + return cdoPackage; + } + + public void addNewObject(CDORevision newObject) + { + newObjects.add(newObject); + } + + public void addDirtyObjectDelta(CDORevisionDelta dirtyObjectDelta) + { + dirtyObjectDeltas.add(dirtyObjectDelta); + } + + protected CDOServerProtocol createProtocol() + { + return new CDOServerProtocol(); + } + + protected Transaction createTransaction(Session session) + { + return (Transaction)session.openView(viewID, CDOProtocolView.Type.TRANSACTION); + } + + private CDOPackage[] getNewPackages() + { + return newPackages.toArray(new CDOPackage[newPackages.size()]); + } + + private CDORevision[] getNewObjects() + { + return newObjects.toArray(new CDORevision[newObjects.size()]); + } + + private CDORevisionDelta[] getDirtyObjectDeltas() + { + return dirtyObjectDeltas.toArray(new CDORevisionDelta[dirtyObjectDeltas.size()]); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java index 8357886f63..552aaa4422 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java @@ -431,7 +431,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD } CDOIDMetaRange range = CDOIDUtil.createMetaRange(metaIDRange.getLowerBound(), 0); - range = registerMetaInstance((InternalEObject)ePackage, range); + range = registerMetaInstance((InternalEObject)ePackage, range, idToMetaInstanceMap, metaInstanceToIDMap); if (range.size() != metaIDRange.size()) { throw new IllegalStateException("range.size() != metaIDRange.size()"); @@ -440,17 +440,22 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD public CDOIDMetaRange registerEPackage(EPackage ePackage) { - CDOIDTemp lowerBound = new CDOIDTempMetaImpl(lastTempMetaID + 1); - CDOIDMetaRange range = CDOIDUtil.createMetaRange(lowerBound, 0); - range = registerMetaInstance((InternalEObject)ePackage, range); + CDOIDMetaRange range = registerEPackage(ePackage, lastTempMetaID + 1, idToMetaInstanceMap, metaInstanceToIDMap); lastTempMetaID = ((CDOIDTemp)range.getUpperBound()).getIntValue(); return range; } - /** - * TODO Synchronize? - */ - private CDOIDMetaRange registerMetaInstance(InternalEObject metaInstance, CDOIDMetaRange range) + public static CDOIDMetaRange registerEPackage(EPackage ePackage, int firstMetaID, + Map<CDOID, InternalEObject> idToMetaInstances, Map<InternalEObject, CDOID> metaInstanceToIDs) + { + CDOIDTemp lowerBound = new CDOIDTempMetaImpl(firstMetaID); + CDOIDMetaRange range = CDOIDUtil.createMetaRange(lowerBound, 0); + range = registerMetaInstance((InternalEObject)ePackage, range, idToMetaInstances, metaInstanceToIDs); + return range; + } + + public static CDOIDMetaRange registerMetaInstance(InternalEObject metaInstance, CDOIDMetaRange range, + Map<CDOID, InternalEObject> idToMetaInstances, Map<InternalEObject, CDOID> metaInstanceToIDs) { range = range.increase(); CDOID id = range.getUpperBound(); @@ -459,19 +464,25 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD TRACER.format("Registering meta instance: {0} <-> {1}", id, metaInstance); } - if (idToMetaInstanceMap.put(id, metaInstance) != null) + if (idToMetaInstances != null) { - throw new IllegalStateException("Duplicate meta ID: " + id + " --> " + metaInstance); + if (idToMetaInstances.put(id, metaInstance) != null) + { + throw new IllegalStateException("Duplicate meta ID: " + id + " --> " + metaInstance); + } } - if (metaInstanceToIDMap.put(metaInstance, id) != null) + if (metaInstanceToIDs != null) { - throw new IllegalStateException("Duplicate metaInstance: " + metaInstance + " --> " + id); + if (metaInstanceToIDs.put(metaInstance, id) != null) + { + throw new IllegalStateException("Duplicate metaInstance: " + metaInstance + " --> " + id); + } } for (EObject content : metaInstance.eContents()) { - range = registerMetaInstance((InternalEObject)content, range); + range = registerMetaInstance((InternalEObject)content, range, idToMetaInstances, metaInstanceToIDs); } return range; diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java index 13f126eb0c..de216e5f6b 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java @@ -20,6 +20,7 @@ import javax.sql.DataSource; import java.sql.Connection; import java.sql.Driver; import java.sql.Statement; +import java.util.Collection; import java.util.Set; /** @@ -41,6 +42,10 @@ public interface IDBAdapter public boolean createTable(IDBTable table, Statement statement) throws DBException; + public Collection<IDBTable> dropTables(Iterable<? extends IDBTable> tables, Connection connection) throws DBException; + + public boolean dropTable(IDBTable table, Statement statement); + public String mangleTableName(String name, int attempt); public String mangleFieldName(String name, int attempt); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java index 7008f01f3c..c4b4c65ba6 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBSchema.java @@ -32,7 +32,13 @@ public interface IDBSchema extends IDBSchemaElement public Set<IDBTable> create(IDBAdapter dbAdapter, Connection connection) throws DBException; + public Set<IDBTable> create(IDBAdapter dbAdapter, DataSource dataSource) throws DBException; + public Set<IDBTable> create(IDBAdapter dbAdapter, IDBConnectionProvider connectionProvider) throws DBException; - public Set<IDBTable> create(IDBAdapter dbAdapter, DataSource dataSource) throws DBException; + public void drop(IDBAdapter dbAdapter, Connection connection) throws DBException; + + public void drop(IDBAdapter dbAdapter, DataSource dataSource) throws DBException; + + public void drop(IDBAdapter dbAdapter, IDBConnectionProvider connectionProvider) throws DBException; } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java index 5a7e2e62ac..56afa34d13 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBAdapter.java @@ -28,8 +28,11 @@ import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -142,6 +145,63 @@ public abstract class DBAdapter implements IDBAdapter return created; } + public Collection<IDBTable> dropTables(Iterable<? extends IDBTable> tables, Connection connection) throws DBException + { + List<IDBTable> droppedTables = new ArrayList<IDBTable>(); + Statement statement = null; + + try + { + statement = connection.createStatement(); + for (IDBTable table : tables) + { + if (dropTable(table, statement)) + { + droppedTables.add(table); + } + } + } + catch (SQLException ex) + { + OM.LOG.error(ex); + } + finally + { + DBUtil.close(statement); + } + + return droppedTables; + } + + public boolean dropTable(IDBTable table, Statement statement) + { + try + { + String sql = getDropTableSQL(table); + if (TRACER.isEnabled()) + { + TRACER.trace(sql); + } + + statement.execute(sql); + return true; + } + catch (SQLException ex) + { + if (TRACER.isEnabled()) + { + TRACER.trace(ex.getMessage()); + } + + return false; + } + } + + protected String getDropTableSQL(IDBTable table) + { + return "DROP TABLE " + table; + } + public String mangleTableName(String name, int attempt) { return mangleName(name, getMaximumTableNameLength(), attempt); @@ -200,6 +260,7 @@ public abstract class DBAdapter implements IDBAdapter { TRACER.trace(sql); } + statement.execute(sql); DBIndex[] indices = table.getIndices(); diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java index ff32a4e083..d3e281ee8b 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBSchema.java @@ -93,6 +93,11 @@ public class DBSchema extends DBSchemaElement implements IDBSchema return dbAdapter.createTables(tables.values(), connection); } + public Set<IDBTable> create(IDBAdapter dbAdapter, DataSource dataSource) throws DBException + { + return create(dbAdapter, DBUtil.createConnectionProvider(dataSource)); + } + public Set<IDBTable> create(IDBAdapter dbAdapter, IDBConnectionProvider connectionProvider) throws DBException { Connection connection = null; @@ -108,9 +113,29 @@ public class DBSchema extends DBSchemaElement implements IDBSchema } } - public Set<IDBTable> create(IDBAdapter dbAdapter, DataSource dataSource) throws DBException + public void drop(IDBAdapter dbAdapter, Connection connection) throws DBException { - return create(dbAdapter, DBUtil.createConnectionProvider(dataSource)); + dbAdapter.dropTables(tables.values(), connection); + } + + public void drop(IDBAdapter dbAdapter, DataSource dataSource) throws DBException + { + drop(dbAdapter, DBUtil.createConnectionProvider(dataSource)); + } + + public void drop(IDBAdapter dbAdapter, IDBConnectionProvider connectionProvider) throws DBException + { + Connection connection = null; + + try + { + connection = connectionProvider.getConnection(); + drop(dbAdapter, connection); + } + finally + { + DBUtil.close(connection); + } } void assertUnlocked() throws DBException |