| /* |
| * Copyright (c) 2010-2014 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| * Stefan Winkler - bug 259402 |
| * Stefan Winkler - redesign (prepared statements) |
| * Stefan Winkler - bug 276926 |
| */ |
| package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal; |
| |
| import org.eclipse.emf.cdo.common.id.CDOID; |
| import org.eclipse.emf.cdo.common.model.CDOClassifierRef; |
| import org.eclipse.emf.cdo.common.protocol.CDODataInput; |
| import org.eclipse.emf.cdo.common.protocol.CDODataOutput; |
| import org.eclipse.emf.cdo.server.db.IDBStore; |
| import org.eclipse.emf.cdo.server.db.IDBStoreAccessor; |
| import org.eclipse.emf.cdo.server.db.IIDHandler; |
| import org.eclipse.emf.cdo.server.internal.db.CDODBSchema; |
| |
| import org.eclipse.net4j.db.DBException; |
| import org.eclipse.net4j.db.DBType; |
| import org.eclipse.net4j.db.DBUtil; |
| import org.eclipse.net4j.db.IDBDatabase; |
| import org.eclipse.net4j.db.IDBDatabase.RunnableWithSchema; |
| import org.eclipse.net4j.db.IDBPreparedStatement; |
| import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability; |
| import org.eclipse.net4j.db.ddl.IDBIndex; |
| import org.eclipse.net4j.db.ddl.IDBSchema; |
| import org.eclipse.net4j.db.ddl.IDBTable; |
| import org.eclipse.net4j.util.om.monitor.OMMonitor; |
| |
| import org.eclipse.emf.ecore.EClass; |
| |
| import java.io.IOException; |
| import java.sql.Connection; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.Statement; |
| |
| /** |
| * @author Eike Stepper |
| * @since 4.0 |
| */ |
| public class ObjectTypeTable extends AbstractObjectTypeMapper implements IMappingConstants |
| { |
| private IDBTable table; |
| |
| private String sqlDelete; |
| |
| private String sqlInsert; |
| |
| private String sqlSelect; |
| |
| public ObjectTypeTable() |
| { |
| } |
| |
| public final CDOClassifierRef getObjectType(IDBStoreAccessor accessor, CDOID id) |
| { |
| IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); |
| IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlSelect, ReuseProbability.MAX); |
| |
| try |
| { |
| idHandler.setCDOID(stmt, 1, id); |
| |
| if (DBUtil.isTracerEnabled()) |
| { |
| DBUtil.trace(stmt.toString()); |
| } |
| |
| ResultSet resultSet = stmt.executeQuery(); |
| |
| if (!resultSet.next()) |
| { |
| if (DBUtil.isTracerEnabled()) |
| { |
| DBUtil.trace("ClassID for CDOID " + id + " not found"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return null; |
| } |
| |
| CDOID classID = idHandler.getCDOID(resultSet, 1); |
| EClass eClass = (EClass)getMetaDataManager().getMetaInstance(classID); |
| return new CDOClassifierRef(eClass); |
| } |
| catch (SQLException ex) |
| { |
| throw new DBException(ex); |
| } |
| finally |
| { |
| DBUtil.close(stmt); |
| } |
| } |
| |
| public final boolean putObjectType(IDBStoreAccessor accessor, long timeStamp, CDOID id, EClass type) |
| { |
| IDBStore store = getMappingStrategy().getStore(); |
| IIDHandler idHandler = store.getIDHandler(); |
| IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsert, ReuseProbability.MAX); |
| |
| try |
| { |
| idHandler.setCDOID(stmt, 1, id); |
| idHandler.setCDOID(stmt, 2, getMetaDataManager().getMetaID(type, timeStamp)); |
| stmt.setLong(3, timeStamp); |
| |
| if (DBUtil.isTracerEnabled()) |
| { |
| DBUtil.trace(stmt.toString()); |
| } |
| |
| int result = stmt.executeUpdate(); |
| if (result != 1) |
| { |
| throw new DBException("Object type could not be inserted: " + id); //$NON-NLS-1$ |
| } |
| |
| return true; |
| } |
| catch (SQLException ex) |
| { |
| if (store.getDBAdapter().isDuplicateKeyException(ex)) |
| { |
| // Unique key violation can occur in rare cases (merging new objects from other branches) |
| return false; |
| } |
| |
| throw new DBException(ex); |
| } |
| finally |
| { |
| DBUtil.close(stmt); |
| } |
| } |
| |
| public final boolean removeObjectType(IDBStoreAccessor accessor, CDOID id) |
| { |
| IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); |
| IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlDelete, ReuseProbability.MAX); |
| |
| try |
| { |
| idHandler.setCDOID(stmt, 1, id); |
| |
| if (DBUtil.isTracerEnabled()) |
| { |
| DBUtil.trace(stmt.toString()); |
| } |
| |
| int result = stmt.executeUpdate(); |
| return result == 1; |
| } |
| catch (SQLException ex) |
| { |
| throw new DBException(ex); |
| } |
| finally |
| { |
| DBUtil.close(stmt); |
| } |
| } |
| |
| public CDOID getMaxID(Connection connection, IIDHandler idHandler) |
| { |
| Statement stmt = null; |
| ResultSet resultSet = null; |
| |
| try |
| { |
| stmt = connection.createStatement(); |
| resultSet = stmt.executeQuery("SELECT MAX(" + ATTRIBUTES_ID + ") FROM " + table); |
| |
| if (resultSet.next()) |
| { |
| return idHandler.getCDOID(resultSet, 1); |
| } |
| |
| return null; |
| } |
| catch (SQLException ex) |
| { |
| throw new DBException(ex); |
| } |
| finally |
| { |
| DBUtil.close(resultSet); |
| DBUtil.close(stmt); |
| } |
| } |
| |
| public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime) |
| throws IOException |
| { |
| String where = " WHERE " + ATTRIBUTES_CREATED + " BETWEEN " + fromCommitTime + " AND " + toCommitTime; |
| DBUtil.serializeTable(out, connection, table, null, where); |
| } |
| |
| public void rawImport(Connection connection, CDODataInput in, OMMonitor monitor) throws IOException |
| { |
| DBUtil.deserializeTable(in, connection, table, monitor); |
| } |
| |
| @Override |
| protected void doActivate() throws Exception |
| { |
| super.doActivate(); |
| |
| IDBStore store = getMappingStrategy().getStore(); |
| final DBType idType = store.getIDHandler().getDBType(); |
| final int idLength = store.getIDColumnLength(); |
| |
| IDBDatabase database = store.getDatabase(); |
| table = database.getSchema().getTable(CDODBSchema.CDO_OBJECTS); |
| if (table == null) |
| { |
| database.updateSchema(new RunnableWithSchema() |
| { |
| public void run(IDBSchema schema) |
| { |
| table = schema.addTable(CDODBSchema.CDO_OBJECTS); |
| table.addField(ATTRIBUTES_ID, idType, idLength, true); |
| table.addField(ATTRIBUTES_CLASS, idType, idLength); |
| table.addField(ATTRIBUTES_CREATED, DBType.BIGINT); |
| table.addIndex(IDBIndex.Type.PRIMARY_KEY, ATTRIBUTES_ID); |
| } |
| }); |
| } |
| |
| sqlSelect = "SELECT " + ATTRIBUTES_CLASS + " FROM " + table + " WHERE " + ATTRIBUTES_ID + "=?"; |
| sqlInsert = "INSERT INTO " + table + "(" + ATTRIBUTES_ID + "," + ATTRIBUTES_CLASS + "," + ATTRIBUTES_CREATED |
| + ") VALUES (?, ?, ?)"; |
| sqlDelete = "DELETE FROM " + table + " WHERE " + ATTRIBUTES_ID + "=?"; |
| } |
| |
| @Override |
| protected void doDeactivate() throws Exception |
| { |
| sqlDelete = null; |
| sqlInsert = null; |
| sqlSelect = null; |
| table = null; |
| super.doDeactivate(); |
| } |
| } |