diff options
author | Eike Stepper | 2010-04-18 12:32:35 +0000 |
---|---|---|
committer | Eike Stepper | 2010-04-18 12:32:35 +0000 |
commit | 26310122fc84bf8ba85192cec565fa175b236965 (patch) | |
tree | 10a98448d337576828102ee6373d701b870d1f5b /plugins | |
parent | 0899bf2ae89bea3ec3b8c06ec0a7ae0394d91b78 (diff) | |
download | cdo-26310122fc84bf8ba85192cec565fa175b236965.tar.gz cdo-26310122fc84bf8ba85192cec565fa175b236965.tar.xz cdo-26310122fc84bf8ba85192cec565fa175b236965.zip |
[256936] Support for Offline Mode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=256936
Diffstat (limited to 'plugins')
16 files changed, 809 insertions, 147 deletions
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 b00b43f23f..5763f95be8 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 @@ -25,6 +25,7 @@ import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; import java.sql.PreparedStatement; @@ -41,6 +42,11 @@ import java.util.Set; public interface IClassMapping { /** + * @since 3.0 + */ + public EClass getEClass(); + + /** * Returns all DB tables which are used by this class and all its contained features. * * @return a collection of all tables of this class and all its contained features. @@ -59,6 +65,11 @@ public interface IClassMapping public IListMapping getListMapping(EStructuralFeature feature); /** + * @since 3.0 + */ + public List<IListMapping> getListMappings(); + + /** * Read a revision. The branch and timestamp to be read are derived from the branchPoint which is set to the Revision. * Note that non-audit stores only support {@link CDOBranchPoint#UNSPECIFIED_DATE} and non-branching stores only * support the main branch. 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 45eebd850f..fc94e17d2f 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 @@ -15,6 +15,8 @@ import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.model.CDOClassifierRef; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.server.IStoreAccessor; import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext; @@ -32,6 +34,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.ENamedElement; import org.eclipse.emf.ecore.EStructuralFeature; +import java.io.IOException; import java.sql.Connection; import java.util.Map; import java.util.Set; @@ -267,4 +270,15 @@ public interface IMappingStrategy * @since 3.0 */ public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments); + + /** + * @since 3.0 + */ + public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, long startTime, long endTime) + throws IOException; + + /** + * @since 3.0 + */ + public void rawImport(IDBStoreAccessor accessor, CDODataInput in) throws IOException; } 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 0a6889fe43..584c09be10 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 @@ -22,6 +22,8 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.model.CDOPackageRegistry; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheAdder; @@ -70,6 +72,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; +import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -812,6 +815,18 @@ public class DBStoreAccessor extends LongIDStoreAccessor implements IDBStoreAcce mappingStrategy.handleRevisions(this, eClass, branch, timeStamp, new DBRevisionHandler(handler)); } + public void rawExport(CDODataOutput out, long startTime, long endTime) throws IOException + { + IMappingStrategy mappingStrategy = getStore().getMappingStrategy(); + mappingStrategy.rawExport(this, out, startTime, endTime); + } + + public void rawImport(CDODataInput in) throws IOException + { + IMappingStrategy mappingStrategy = getStore().getMappingStrategy(); + mappingStrategy.rawImport(this, in); + } + /** * @author Stefan Winkler */ diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java index ebb0e58fff..1ab11f8a53 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java @@ -323,7 +323,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping return mappingStrategy; } - protected final EClass getEClass() + public final EClass getEClass() { return eClass; } 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 97cd8b5c2c..b251839d7e 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 @@ -14,6 +14,8 @@ 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.CDOClassifierRef; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.eresource.CDOResourceNode; import org.eclipse.emf.cdo.eresource.EresourcePackage; @@ -21,6 +23,7 @@ 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.db.mapping.IListMapping; import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; import org.eclipse.emf.cdo.server.internal.db.bundle.OM; import org.eclipse.emf.cdo.server.internal.db.mapping.AbstractMappingStrategy; @@ -35,6 +38,7 @@ import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.emf.ecore.EClass; +import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -101,6 +105,84 @@ public abstract class AbstractHorizontalMappingStrategy extends AbstractMappingS } } + public void rawExport(IDBStoreAccessor accessor, CDODataOutput out, long startTime, long endTime) throws IOException + { + StringBuilder builder = new StringBuilder(); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(CDODBSchema.ATTRIBUTES_CREATED); + builder.append("<=? AND ("); //$NON-NLS-1$ + builder.append(CDODBSchema.ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(CDODBSchema.ATTRIBUTES_REVISED); + builder.append(">=?))"); //$NON-NLS-1$ + + String attrSuffix = builder.toString(); + Connection connection = accessor.getConnection(); + + for (IClassMapping classMapping : getClassMappings().values()) + { + EClass eClass = classMapping.getEClass(); + out.writeCDOClassifierRef(eClass); + + IDBTable table = classMapping.getDBTables().get(0); + DBUtil.writeTable(out, connection, table, attrSuffix); + + for (IListMapping listMapping : classMapping.getListMappings()) + { + rawExportList(out, connection, listMapping, table, attrSuffix); + } + } + } + + protected void rawExportList(CDODataOutput out, Connection connection, IListMapping listMapping, IDBTable attrTable, + String attrSuffix) throws IOException + { + for (IDBTable table : listMapping.getDBTables()) + { + String listSuffix = ", " + table + attrSuffix; + String listJoin = getListJoin(attrTable, table); + if (listJoin != null) + { + listSuffix += listSuffix + " AND " + listJoin; + } + + DBUtil.writeTable(out, connection, table, listSuffix); + } + } + + public void rawImport(IDBStoreAccessor accessor, CDODataInput in) throws IOException + { + Connection connection = accessor.getConnection(); + + for (;;) + { + EClass eClass = (EClass)in.readCDOClassifierRefAndResolve(); + IClassMapping classMapping = getClassMapping(eClass); + + IDBTable table = classMapping.getDBTables().get(0); + DBUtil.readTable(in, connection, table); + + for (IListMapping listMapping : classMapping.getListMappings()) + { + rawImportList(in, connection, listMapping); + } + } + } + + protected void rawImportList(CDODataInput in, Connection connection, IListMapping listMapping) + throws IOException + { + for (IDBTable table : listMapping.getDBTables()) + { + DBUtil.readTable(in, connection, table); + } + } + + protected String getListJoin(IDBTable attrTable, IDBTable listTable) + { + return " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_ID + "=" + listTable + "." + CDODBSchema.LIST_REVISION_ID; + } + @Override protected Collection<EClass> getClassesWithObjectInfo() { 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 a76fb4793d..5ccc016ca9 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 @@ -13,6 +13,9 @@ 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.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; @@ -59,4 +62,13 @@ public class HorizontalAuditMappingStrategy extends AbstractHorizontalMappingStr { return new AuditFeatureMapTableMapping(this, containingClass, feature); } + + @Override + protected String getListJoin(IDBTable attrTable, IDBTable listTable) + { + String join = super.getListJoin(attrTable, listTable); + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION + "=" + listTable + "." + + CDODBSchema.LIST_REVISION_VERSION; + return join; + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java index 689323f98d..809212cbcf 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditMappingStrategyWithRanges.java @@ -14,6 +14,8 @@ 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.net4j.db.ddl.IDBTable; + import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; @@ -59,4 +61,11 @@ public class HorizontalAuditMappingStrategyWithRanges extends AbstractHorizontal { return new AuditFeatureMapTableMappingWithRanges(this, containingClass, feature); } + + @Override + protected String getListJoin(IDBTable attrTable, IDBTable listTable) + { + // TODO: implement HorizontalAuditMappingStrategyWithRanges.getListJoin(attrTable, listTable) + throw new UnsupportedOperationException(); + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java index 6b89329024..989bdb3750 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingMappingStrategy.java @@ -13,6 +13,9 @@ 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.cdo.server.internal.db.CDODBSchema; + +import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; @@ -59,4 +62,15 @@ public class HorizontalBranchingMappingStrategy extends AbstractHorizontalMappin { return new BranchingFeatureMapTableMapping(this, containingClass, feature); } + + @Override + protected String getListJoin(IDBTable attrTable, IDBTable listTable) + { + String join = super.getListJoin(attrTable, listTable); + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_VERSION + "=" + listTable + "." + + CDODBSchema.LIST_REVISION_VERSION; + join += " AND " + attrTable + "." + CDODBSchema.ATTRIBUTES_BRANCH + "=" + listTable + "." + + CDODBSchema.LIST_REVISION_BRANCH; + return join; + } } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java index 62c85c13de..7fc42eb492 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java @@ -20,6 +20,8 @@ import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDTemp; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.model.CDOClassifierRef; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheAdder; @@ -56,6 +58,7 @@ import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -692,6 +695,16 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS throw new UnsupportedOperationException(); } + public void rawExport(CDODataOutput out, long startTime, long endTime) throws IOException + { + throw new UnsupportedOperationException(); + } + + public void rawImport(CDODataInput in) throws IOException + { + throw new UnsupportedOperationException(); + } + @Override protected void doDeactivate() throws Exception { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java index 02446a47ae..27b1ec220e 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java @@ -18,6 +18,8 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler; import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheAdder; import org.eclipse.emf.cdo.common.util.CDOQueryInfo; @@ -39,6 +41,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -331,6 +334,18 @@ public class MEMStoreAccessor extends LongIDStoreAccessor return null; } + public void rawExport(CDODataOutput out, long startTime, long endTime) throws IOException + { + // TODO: implement MEMStoreAccessor.rawExport(out, startTime, endTime) + throw new UnsupportedOperationException(); + } + + public void rawImport(CDODataInput in) throws IOException + { + // TODO: implement MEMStoreAccessor.rawImport(in) + throw new UnsupportedOperationException(); + } + @Override protected void doActivate() throws Exception { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java index 558dc17839..88aa707ddd 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java @@ -15,6 +15,8 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDMetaRange; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheAdder; import org.eclipse.emf.cdo.common.util.CDOQueryInfo; @@ -34,6 +36,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; +import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; @@ -188,6 +191,16 @@ public interface IStoreAccessor extends IQueryHandlerProvider, BranchLoader, Com */ public void rollback(); + /** + * @since 3.0 + */ + public void rawExport(CDODataOutput out, long startTime, long endTime) throws IOException; + + /** + * @since 3.0 + */ + public void rawImport(CDODataInput in) throws IOException; + public void release(); /** diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java index 825ac7c7e7..24835b3566 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java @@ -11,101 +11,453 @@ */ package org.eclipse.net4j.db; -import java.util.Date; +import org.eclipse.net4j.util.io.ExtendedDataInput; +import org.eclipse.net4j.util.io.ExtendedDataOutput; +import org.eclipse.net4j.util.io.IOUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; /** * @author Eike Stepper */ public enum DBType { - BOOLEAN(16), // - BIT(-7), // - TINYINT(-6), // - SMALLINT(5), // - INTEGER(4), // - BIGINT(-5), // - FLOAT(6), // - REAL(7), // - DOUBLE(8), // - NUMERIC(2), // - DECIMAL(3), // - CHAR(1), // - VARCHAR(12), // - LONGVARCHAR(-1, "LONG VARCHAR"), // //$NON-NLS-1$ - CLOB(2005), // + BOOLEAN(16) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + boolean value = resultSet.getBoolean(column); + out.writeBoolean(value); + } - DATE(91) + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + boolean value = in.readBoolean(); + statement.setBoolean(column, value); + } + }, + + BIT(-7) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + boolean value = resultSet.getBoolean(column); + out.writeBoolean(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + boolean value = in.readBoolean(); + statement.setBoolean(column, value); + } + }, + + TINYINT(-6) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + byte value = resultSet.getByte(column); + out.writeByte(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + byte value = in.readByte(); + statement.setByte(column, value); + } + }, + + SMALLINT(5) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + short value = resultSet.getShort(column); + out.writeShort(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + short value = in.readShort(); + statement.setShort(column, value); + } + }, + + INTEGER(4) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + int value = resultSet.getInt(column); + out.writeInt(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + int value = in.readInt(); + statement.setInt(column, value); + } + }, + + BIGINT(-5) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + long value = resultSet.getLong(column); + out.writeLong(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + long value = in.readLong(); + statement.setLong(column, value); + } + }, + + FLOAT(6) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + float value = resultSet.getFloat(column); + out.writeFloat(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + float value = in.readFloat(); + statement.setFloat(column, value); + } + }, + + REAL(7) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + float value = resultSet.getFloat(column); + out.writeFloat(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + float value = in.readFloat(); + statement.setFloat(column, value); + } + }, + + DOUBLE(8) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + double value = resultSet.getDouble(column); + out.writeDouble(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + double value = in.readDouble(); + statement.setDouble(column, value); + } + }, + + NUMERIC(2) { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException { + // TODO: implement DBType.NUMERIC.writeValue() throw new UnsupportedOperationException(); } - }, // - TIME(92) + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + // TODO: implement DBType.NUMERIC.readValue() + throw new UnsupportedOperationException(); + } + }, + + DECIMAL(3) { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException { + // TODO: implement DBType.DECIMAL.writeValue() throw new UnsupportedOperationException(); } - }, // - TIMESTAMP(93) + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + // TODO: implement DBType.DECIMAL.readValue() + throw new UnsupportedOperationException(); + } + }, + + CHAR(1) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + String value = resultSet.getString(column); + out.writeString(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + String value = in.readString(); + statement.setString(column, value); + } + }, + + VARCHAR(12) { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + String value = resultSet.getString(column); + out.writeString(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException { - if (value instanceof Date) + String value = in.readString(); + statement.setString(column, value); + } + }, + + LONGVARCHAR(-1, "LONG VARCHAR") //$NON-NLS-1$ + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + String value = resultSet.getString(column); + out.writeString(value); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + String value = in.readString(); + statement.setString(column, value); + } + }, + + CLOB(2005) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + Clob value = resultSet.getClob(column); + long length = value.length(); + Reader reader = value.getCharacterStream(); + + try { - Date date = (Date)value; - builder.append("'"); //$NON-NLS-1$ - builder.append(new java.sql.Timestamp(date.getTime())); - builder.append("'"); //$NON-NLS-1$ + out.writeLong(length); + while (length-- > 0) + { + int c = reader.read(); + out.writeChar(c); + } } - else + finally { - throw new IllegalArgumentException("Not a java.util.Date: " + value); //$NON-NLS-1$ + IOUtil.close(reader); } } - }, // + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + // TODO: implement DBType.CLOB.readValue() + throw new UnsupportedOperationException(); + } + }, + + DATE(91) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + java.sql.Date value = resultSet.getDate(column); + out.writeLong(value.getTime()); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + long value = in.readLong(); + statement.setDate(column, new java.sql.Date(value)); + } + }, + + TIME(92) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + java.sql.Time value = resultSet.getTime(column); + out.writeLong(value.getTime()); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + long value = in.readLong(); + statement.setTime(column, new java.sql.Time(value)); + } + }, + + TIMESTAMP(93) + { + @Override + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + java.sql.Timestamp value = resultSet.getTimestamp(column); + out.writeLong(value.getTime()); + out.writeInt(value.getNanos()); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + long value = in.readLong(); + int nanos = in.readInt(); + java.sql.Timestamp timeStamp = new java.sql.Timestamp(value); + timeStamp.setNanos(nanos); + statement.setTimestamp(column, timeStamp); + } + }, BINARY(-2) { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException { + // TODO: implement DBType.BINARY.writeValue() throw new UnsupportedOperationException(); } - }, // + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + // TODO: implement DBType.BINARY.readValue() + throw new UnsupportedOperationException(); + } + }, VARBINARY(-3) { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException { + // TODO: implement DBType.VARBINARY.writeValue() throw new UnsupportedOperationException(); } - }, // + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException + { + // TODO: implement DBTypeVARBINARY.readValue() + throw new UnsupportedOperationException(); + } + }, LONGVARBINARY(-4, "LONG VARBINARY") //$NON-NLS-1$ { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + // TODO: implement DBType.LONGVARBINARY.writeValue() + throw new UnsupportedOperationException(); + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException { + // TODO: implement DBType.LONGVARBINARY.readValue() throw new UnsupportedOperationException(); } - }, // + }, BLOB(2004) { @Override - public void appendValue(StringBuilder builder, Object value) + public void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, IOException + { + Blob value = resultSet.getBlob(column); + long length = value.length(); + InputStream stream = value.getBinaryStream(); + + try + { + out.writeLong(length); + while (length-- > 0) + { + int b = stream.read(); + out.writeByte(b + Byte.MIN_VALUE); + } + } + finally + { + IOUtil.close(stream); + } + } + + @Override + public void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException { + // TODO: implement DBType.BLOB.readValue() throw new UnsupportedOperationException(); } - }; // + }; private int code; @@ -132,33 +484,24 @@ public enum DBType return keyword == null ? super.toString() : keyword; } + /** + * @since 3.0 + */ + public abstract void writeValue(ExtendedDataOutput out, ResultSet resultSet, int column) throws SQLException, + IOException; + + /** + * @since 3.0 + */ + public abstract void readValue(ExtendedDataInput in, PreparedStatement statement, int column) throws SQLException, + IOException; + @Override public String toString() { return getKeyword(); } - public void appendValue(StringBuilder builder, Object value) - { - if (value == null) - { - builder.append("NULL"); //$NON-NLS-1$ - } - else - { - if (value instanceof String || value instanceof Character) - { - builder.append("'"); //$NON-NLS-1$ - builder.append(value); - builder.append("'"); //$NON-NLS-1$ - } - else - { - builder.append(value); - } - } - } - /** * @since 3.0 */ diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java index afe8b75035..867a9020bf 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java @@ -17,14 +17,18 @@ import org.eclipse.net4j.internal.db.DataSourceConnectionProvider; import org.eclipse.net4j.internal.db.bundle.OM; import org.eclipse.net4j.spi.db.DBSchema; import org.eclipse.net4j.util.ReflectUtil; +import org.eclipse.net4j.util.io.ExtendedDataInput; +import org.eclipse.net4j.util.io.ExtendedDataOutput; import org.eclipse.net4j.util.om.trace.ContextTracer; import javax.sql.DataSource; +import java.io.IOException; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -271,7 +275,7 @@ public final class DBUtil for (String tableName : DBUtil.getAllTableNames(connection, dbName)) { String sql = "DROP TABLE " + tableName; //$NON-NLS-1$ - DBUtil.trace(sql); + trace(sql); statement.execute(sql); } } @@ -384,8 +388,7 @@ public final class DBUtil builder.append(")"); //$NON-NLS-1$ } - String sql = builder.toString(); - trace(sql); + String sql = trace(builder.toString()); Statement statement = null; ResultSet resultSet = null; @@ -474,8 +477,7 @@ public final class DBUtil builder.append(where); } - String sql = builder.toString(); - trace(sql); + String sql = trace(builder.toString()); Statement statement = null; ResultSet resultSet = null; @@ -563,11 +565,144 @@ public final class DBUtil return result[0]; } - public static void trace(String sql) + /** + * @since 3.0 + */ + public static void writeTable(ExtendedDataOutput out, Connection connection, IDBTable table, String sqlSuffix) + throws DBException, IOException + { + IDBField[] fields = table.getFields(); + + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + for (int i = 0; i < fields.length; i++) + { + if (i > 0) + { + builder.append(", "); //$NON-NLS-1$ + } + + builder.append(fields[i]); + } + + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(table); + if (sqlSuffix != null) + { + builder.append(sqlSuffix); + } + + String sql = trace(builder.toString()); + Statement statement = null; + ResultSet resultSet = null; + + try + { + statement = connection.createStatement(); + + try + { + resultSet = statement.executeQuery(sql); + while (resultSet.next()) + { + out.writeBoolean(true); + for (int i = 0; i < fields.length; i++) + { + IDBField field = fields[i]; + field.getType().writeValue(out, resultSet, i); + } + } + + out.writeBoolean(false); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + close(resultSet); + } + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + close(statement); + } + } + + /** + * @since 3.0 + */ + public static void readTable(ExtendedDataInput in, Connection connection, IDBTable table) throws IOException + { + IDBField[] fields = table.getFields(); + + StringBuilder builder = new StringBuilder(); + StringBuilder params = new StringBuilder(); + + builder.append("INSERT INTO "); //$NON-NLS-1$ + builder.append(table); + builder.append("("); //$NON-NLS-1$ + + for (int i = 0; i < fields.length; i++) + { + if (i > 0) + { + builder.append(", "); //$NON-NLS-1$ + params.append(", "); //$NON-NLS-1$ + } + + builder.append(fields[i]); + params.append("?"); //$NON-NLS-1$ + } + + builder.append(") VALUES ("); //$NON-NLS-1$ + builder.append(params.toString()); + builder.append(")"); //$NON-NLS-1$ + + String sql = trace(builder.toString()); + PreparedStatement statement = null; + + try + { + statement = connection.prepareStatement(sql); + while (in.readBoolean()) + { + for (int i = 0; i < fields.length; i++) + { + IDBField field = fields[i]; + field.getType().readValue(in, statement, i); + } + + statement.addBatch(); + } + + statement.executeBatch(); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + close(statement); + } + } + + /** + * @since 3.0 + */ + public static String trace(String sql) { if (TRACER.isEnabled()) { TRACER.trace(sql); } + + return sql; } } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java index cea587f73e..2814d435f6 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/ddl/IDBField.java @@ -4,7 +4,7 @@ * 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 */ @@ -47,6 +47,4 @@ public interface IDBField extends IDBSchemaElement public String formatPrecision(); public String formatPrecisionAndScale(); - - public void appendValue(StringBuilder builder, Object value); } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java index 02a6ceba3f..90ea6f734d 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/ddl/DBField.java @@ -4,7 +4,7 @@ * 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 */ @@ -165,16 +165,4 @@ public class DBField extends DBSchemaElement implements IDBField return "(" + getPrecision() + ", " + scale + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - - public void appendValue(StringBuilder builder, Object value) - { - if (value == null) - { - builder.append("NULL"); //$NON-NLS-1$ - } - else - { - type.appendValue(builder, value); - } - } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java index bf487dd171..ab98f166d3 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java @@ -57,6 +57,28 @@ public final class ExtendedIOUtil } } + public static byte[] readByteArray(DataInput in) throws IOException + { + int length = in.readInt(); + if (length < 0) + { + return null; + } + + byte[] b; + try + { + b = new byte[length]; + } + catch (Throwable t) + { + throw new IOException("Unable to allocate " + length + " bytes"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + in.readFully(b); + return b; + } + public static void writeObject(final DataOutput out, Object object) throws IOException { ObjectOutput wrapper = null; @@ -79,69 +101,6 @@ public final class ExtendedIOUtil wrapper.writeObject(object); } - public static void writeString(DataOutput out, String str) throws IOException - { - if (str != null) - { - int size = str.length(); - int start = 0; - do - { - out.writeBoolean(true); - int chunk = Math.min(size, MAX_UTF_CHARS); - int end = start + chunk; - out.writeUTF(str.substring(start, end)); - start = end; - size -= chunk; - } while (size > 0); - } - - out.writeBoolean(false); - } - - /** - * @since 3.0 - */ - public static void writeEnum(DataOutput out, Enum<?> literal) throws IOException - { - int ordinal = literal.ordinal(); - int size = literal.getDeclaringClass().getEnumConstants().length; - if (size <= Byte.MAX_VALUE) - { - out.writeByte(ordinal); - } - else if (size <= Short.MAX_VALUE) - { - out.writeShort(ordinal); - } - else - { - out.writeInt(ordinal); - } - } - - public static byte[] readByteArray(DataInput in) throws IOException - { - int length = in.readInt(); - if (length < 0) - { - return null; - } - - byte[] b; - try - { - b = new byte[length]; - } - catch (Throwable t) - { - throw new IOException("Unable to allocate " + length + " bytes"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - in.readFully(b); - return b; - } - public static Object readObject(final DataInput in) throws IOException { return readObject(in, (ClassResolver)null); @@ -204,6 +163,26 @@ public final class ExtendedIOUtil } } + public static void writeString(DataOutput out, String str) throws IOException + { + if (str != null) + { + int size = str.length(); + int start = 0; + do + { + out.writeBoolean(true); + int chunk = Math.min(size, MAX_UTF_CHARS); + int end = start + chunk; + out.writeUTF(str.substring(start, end)); + start = end; + size -= chunk; + } while (size > 0); + } + + out.writeBoolean(false); + } + public static String readString(DataInput in) throws IOException { boolean more = in.readBoolean(); @@ -226,6 +205,27 @@ public final class ExtendedIOUtil /** * @since 3.0 */ + public static void writeEnum(DataOutput out, Enum<?> literal) throws IOException + { + int ordinal = literal.ordinal(); + int size = literal.getDeclaringClass().getEnumConstants().length; + if (size <= Byte.MAX_VALUE) + { + out.writeByte(ordinal); + } + else if (size <= Short.MAX_VALUE) + { + out.writeShort(ordinal); + } + else + { + out.writeInt(ordinal); + } + } + + /** + * @since 3.0 + */ public static <T extends Enum<?>> T readEnum(DataInput in, Class<T> type) throws IOException { T[] literals = type.getEnumConstants(); |