/*
 * Copyright (c) 2007-2016, 2018-2020 Eike Stepper (Loehne, 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 - 271444: [DB] Multiple refactorings bug 271444
 *    Andre Dietisheim - bug 256649
 *    Caspar De Groot - maintenance
 */
package org.eclipse.emf.cdo.server.internal.db;

import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
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.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
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.CDORevisionCacheAdder;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.server.IQueryHandler;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.ISession;
import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.server.IStoreAccessor.DurableLocking2;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.server.StoreThreadLocal;
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.db.IMetaDataManager;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy2;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping;
import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.UnitMappingTable;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader4;
import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalUnitManager;
import org.eclipse.emf.cdo.spi.server.InternalUnitManager.InternalObjectAttacher;
import org.eclipse.emf.cdo.spi.server.StoreAccessor;

import org.eclipse.net4j.db.BatchedStatement;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBConnection;
import org.eclipse.net4j.db.IDBDatabase;
import org.eclipse.net4j.db.IDBPreparedStatement;
import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability;
import org.eclipse.net4j.db.IDBSchemaTransaction;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.internal.db.ddl.DBField;
import org.eclipse.net4j.spi.db.DBAdapter;
import org.eclipse.net4j.util.ConsumerWithException;
import org.eclipse.net4j.util.HexUtil;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.TrackableTimerTask;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * @author Eike Stepper
 */
public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, BranchLoader4, DurableLocking2
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, DBStoreAccessor.class);

  private IDBConnection connection;

  private ConnectionKeepAliveTask connectionKeepAliveTask;

  private CDOID maxID = CDOID.NULL;

  private InternalObjectAttacher objectAttacher;

  private List<IDBTable> createdTables;

  public DBStoreAccessor(DBStore store, ISession session) throws DBException
  {
    super(store, session);
  }

  public DBStoreAccessor(DBStore store, ITransaction transaction) throws DBException
  {
    super(store, transaction);
  }

  @Override
  public final DBStore getStore()
  {
    return (DBStore)super.getStore();
  }

  @Override
  public final IDBConnection getDBConnection()
  {
    return connection;
  }

  @Override
  public final Connection getConnection()
  {
    return connection;
  }

  @Override
  @Deprecated
  public org.eclipse.emf.cdo.server.db.IPreparedStatementCache getStatementCache()
  {
    return new org.eclipse.emf.cdo.server.db.IPreparedStatementCache()
    {
      @Override
      public void setConnection(Connection connection)
      {
        // Do nothing
      }

      @Override
      public IDBPreparedStatement getPreparedStatement(String sql, ReuseProbability reuseProbability)
      {
        org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability converted = //
            org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability.values()[reuseProbability.ordinal()];

        return connection.prepareStatement(sql, converted);
      }

      @Override
      public void releasePreparedStatement(PreparedStatement ps)
      {
        DBUtil.close(ps);
      }
    };
  }

  @Override
  public DBStoreChunkReader createChunkReader(InternalCDORevision revision, EStructuralFeature feature)
  {
    return new DBStoreChunkReader(this, revision, feature);
  }

  @Override
  public IDBSchemaTransaction openSchemaTransaction()
  {
    DBStore store = getStore();
    DBAdapter dbAdapter = (DBAdapter)store.getDBAdapter();
    IDBDatabase database = store.getDatabase();

    return dbAdapter.openSchemaTransaction(database, connection);
  }

  /**
   * Returns an iterator that iterates over all objects in the store and makes their CDOIDs available for processing.
   * This method is supposed to be called very infrequently, for example during the recovery from a crash.
   *
   * @since 2.0
   * @deprecated Not used by the framework anymore.
   */
  @Deprecated
  public CloseableIterator<CDOID> readObjectIDs()
  {
    if (TRACER.isEnabled())
    {
      TRACER.trace("Selecting object IDs"); //$NON-NLS-1$
    }

    return getStore().getMappingStrategy().readObjectIDs(this);
  }

  public CDOClassifierRef readObjectType(CDOID id)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Selecting object type: {0}", id); //$NON-NLS-1$
    }

    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    return mappingStrategy.readObjectType(this, id);
  }

  @Override
  public EClass getObjectType(CDOID id)
  {
    IRepository repository = getStore().getRepository();
    if (id.equals(repository.getRootResourceID()))
    {
      return EresourcePackage.Literals.CDO_RESOURCE;
    }

    EClass result = repository.getRevisionManager().getObjectType(id);
    if (result != null)
    {
      return result;
    }

    CommitContext commitContext = StoreThreadLocal.getCommitContext();
    if (commitContext != null)
    {
      InternalCDORevision revision = commitContext.getNewRevisions().get(id);
      if (revision != null)
      {
        return revision.getEClass();
      }
    }

    CDOClassifierRef type = readObjectType(id);
    if (type != null)
    {
      CDOPackageRegistry packageRegistry = repository.getPackageRegistry();
      return (EClass)type.resolve(packageRegistry);
    }

    return null;
  }

  @Override
  public InternalCDORevision readRevision(CDOID id, CDOBranchPoint branchPoint, int listChunk, CDORevisionCacheAdder cache)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Selecting revision {0} from {1}", id, branchPoint); //$NON-NLS-1$
    }

    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();

    EClass eClass = getObjectType(id);
    if (eClass != null)
    {
      InternalCDORevision revision = getStore().createRevision(eClass, id);
      revision.setBranchPoint(branchPoint); // This is part of the search criterion, being replaced later

      IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
      if (mapping.readRevision(this, revision, listChunk))
      {
        int version = revision.getVersion();
        if (version < CDOBranchVersion.UNSPECIFIED_VERSION)
        {
          return new DetachedCDORevision(eClass, id, revision.getBranch(), -version, revision.getTimeStamp(), revision.getRevised());
        }

        return revision;
      }
    }

    // Reading failed - revision does not exist.
    return null;
  }

  @Override
  public InternalCDORevision readRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int listChunk, CDORevisionCacheAdder cache)
  {
    DBStore store = getStore();
    EClass eClass = getObjectType(id);

    IMappingStrategy mappingStrategy = store.getMappingStrategy();
    IClassMapping mapping = mappingStrategy.getClassMapping(eClass);

    InternalCDORevision revision = store.createRevision(eClass, id);
    revision.setVersion(branchVersion.getVersion());
    revision.setBranchPoint(branchVersion.getBranch().getHead());

    boolean success = false;

    if (mappingStrategy.hasAuditSupport())
    {
      if (TRACER.isEnabled())
      {
        TRACER.format("Selecting revision {0} from {1}", id, branchVersion); //$NON-NLS-1$
      }

      // If audit support is present, just use the audit method
      success = ((IClassMappingAuditSupport)mapping).readRevisionByVersion(this, revision, listChunk);
      if (success && revision.getVersion() < CDOBranchVersion.FIRST_VERSION - 1)
      {
        // it is detached revision
        revision = new DetachedCDORevision(eClass, id, revision.getBranch(), -revision.getVersion(), revision.getTimeStamp(), revision.getRevised());

      }
    }
    else
    {
      // If audit support is not present, we still have to provide a method
      // to readRevisionByVersion because TransactionCommitContext.computeDirtyObject
      // needs to lookup the base revision for a change. Hence we emulate this
      // behavior by getting the current revision and asserting that the version
      // has not changed. This is valid because if the version has changed,
      // we are in trouble because of a conflict anyways.
      if (TRACER.isEnabled())
      {
        TRACER.format("Selecting current base revision: {0}", id); //$NON-NLS-1$
      }

      success = mapping.readRevision(this, revision, listChunk);

      if (success && revision.getVersion() != branchVersion.getVersion())
      {
        throw new IllegalStateException("Can only retrieve current version " + revision.getVersion() + " for " + id //$NON-NLS-1$ //$NON-NLS-2$
            + " - version requested was " + branchVersion); //$NON-NLS-1$
      }
    }

    return success ? revision : null;
  }

  /**
   * @since 2.0
   */
  @Override
  public void queryResources(QueryResourcesContext context)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    mappingStrategy.queryResources(this, context);
  }

  @Override
  public void queryXRefs(QueryXRefsContext context)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    mappingStrategy.queryXRefs(this, context);
  }

  @Override
  public IQueryHandler getQueryHandler(CDOQueryInfo info)
  {
    String queryLanguage = info.getQueryLanguage();
    if (StringUtil.equalsUpperOrLowerCase(queryLanguage, SQLQueryHandler.QUERY_LANGUAGE))
    {
      return new SQLQueryHandler(this);
    }

    return null;
  }

  @Override
  public void queryLobs(List<byte[]> ids)
  {
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_QUERY_LOBS, ReuseProbability.MEDIUM);
    ResultSet resultSet = null;

    try
    {
      for (Iterator<byte[]> it = ids.iterator(); it.hasNext();)
      {
        byte[] id = it.next();
        stmt.setString(1, HexUtil.bytesToHex(id));

        try
        {
          resultSet = stmt.executeQuery();
          if (!resultSet.next())
          {
            it.remove();
          }
        }
        finally
        {
          DBUtil.close(resultSet);
        }
      }
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(stmt);
    }
  }

  @Override
  public void loadLob(byte[] id, OutputStream out) throws IOException
  {
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_LOAD_LOB, ReuseProbability.MEDIUM);
    ResultSet resultSet = null;

    try
    {
      stmt.setString(1, HexUtil.bytesToHex(id));
      resultSet = stmt.executeQuery();
      resultSet.next();

      long size = resultSet.getLong(1);
      InputStream inputStream = resultSet.getBinaryStream(2);
      if (resultSet.wasNull())
      {
        Reader reader = resultSet.getCharacterStream(3);
        IOUtil.copyCharacter(reader, new OutputStreamWriter(out), size);
      }
      else
      {
        IOUtil.copyBinary(inputStream, out, size);
      }
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(resultSet);
      DBUtil.close(stmt);
    }
  }

  @Override
  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
  {
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_HANDLE_LOBS, ReuseProbability.LOW);
    ResultSet resultSet = null;

    try
    {
      resultSet = stmt.executeQuery();
      while (resultSet.next())
      {
        byte[] id = HexUtil.hexToBytes(resultSet.getString(1));
        long size = resultSet.getLong(2);
        InputStream inputStream = resultSet.getBinaryStream(3);
        if (resultSet.wasNull())
        {
          Reader reader = resultSet.getCharacterStream(4);
          Writer out = handler.handleClob(id, size);
          if (out != null)
          {
            try
            {
              IOUtil.copyCharacter(reader, out, size);
            }
            finally
            {
              IOUtil.close(out);
            }
          }
        }
        else
        {
          OutputStream out = handler.handleBlob(id, size);
          if (out != null)
          {
            try
            {
              IOUtil.copyBinary(inputStream, out, size);
            }
            finally
            {
              IOUtil.close(out);
            }
          }
        }
      }
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(resultSet);
      DBUtil.close(stmt);
    }
  }

  @Override
  protected void applyIDMappings(InternalCommitContext context, OMMonitor monitor)
  {
    super.applyIDMappings(context, monitor);

    DBStore store = getStore();
    IIDHandler idHandler = store.getIDHandler();

    // Remember maxID because it may have to be adjusted if the repository is BACKUP or CLONE. See bug 325097.
    boolean adjustMaxID = !context.getBranchPoint().getBranch().isLocal() && store.getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE;

    // Remember CDOIDs of new objects. They are cleared after writeRevisions()
    for (InternalCDORevision revision : context.getNewObjects())
    {
      CDOID id = revision.getID();

      if (adjustMaxID && (CDOIDUtil.isNull(maxID) || idHandler.compare(id, maxID) > 0))
      {
        maxID = id;
      }
    }
  }

  @Deprecated
  @Override
  protected void writeCommitInfo(CDOBranch branch, long timeStamp, long previousTimeStamp, String userID, String comment, OMMonitor monitor)
  {
    writeCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment, null, monitor);
  }

  @Override
  protected void writeCommitInfo(CDOBranch branch, long timeStamp, long previousTimeStamp, String userID, String comment, CDOBranchPoint mergeSource,
      OMMonitor monitor)
  {
    CommitInfoTable commitInfoTable = getStore().getCommitInfoTable();
    if (commitInfoTable != null)
    {
      commitInfoTable.writeCommitInfo(this, branch, timeStamp, previousTimeStamp, userID, comment, mergeSource, monitor);
    }
  }

  @Override
  protected void writeRevisionDeltas(InternalCDORevisionDelta[] revisionDeltas, CDOBranch branch, long created, OMMonitor monitor)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();

    if (!mappingStrategy.hasDeltaSupport())
    {
      throw new UnsupportedOperationException("Mapping strategy does not support revision deltas"); //$NON-NLS-1$
    }

    monitor.begin(revisionDeltas.length);
    try
    {
      for (InternalCDORevisionDelta delta : revisionDeltas)
      {
        writeRevisionDelta(delta, created, monitor.fork());
      }
    }
    finally
    {
      monitor.done();
    }
  }

  protected void writeRevisionDelta(InternalCDORevisionDelta delta, long created, OMMonitor monitor)
  {
    CDOID id = delta.getID();
    EClass eClass = getObjectType(id);
    IClassMappingDeltaSupport mapping = (IClassMappingDeltaSupport)getStore().getMappingStrategy().getClassMapping(eClass);
    mapping.writeRevisionDelta(this, delta, created, monitor);
  }

  @Override
  protected void writeNewObjectRevisions(InternalCommitContext context, InternalCDORevision[] newObjects, CDOBranch branch, OMMonitor monitor)
  {
    writeRevisions(context, true, newObjects, branch, monitor);
  }

  @Override
  protected void writeDirtyObjectRevisions(InternalCommitContext context, InternalCDORevision[] dirtyObjects, CDOBranch branch, OMMonitor monitor)
  {
    writeRevisions(context, false, dirtyObjects, branch, monitor);
  }

  protected void writeRevisions(InternalCommitContext context, boolean attachNewObjects, InternalCDORevision[] revisions, CDOBranch branch, OMMonitor monitor)
  {
    try
    {
      monitor.begin(revisions.length);
      for (InternalCDORevision revision : revisions)
      {
        writeRevision(revision, attachNewObjects, true, monitor.fork());
      }

      if (attachNewObjects)
      {
        InternalRepository repository = getStore().getRepository();
        if (repository.isSupportingUnits())
        {
          InternalUnitManager unitManager = repository.getUnitManager();
          objectAttacher = unitManager.attachObjects(context);
        }
      }
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  protected void writeRevisions(InternalCDORevision[] revisions, CDOBranch branch, OMMonitor monitor)
  {
    throw new UnsupportedOperationException();
  }

  protected void writeRevision(InternalCDORevision revision, boolean firstRevision, boolean revise, OMMonitor monitor)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Writing revision: {0}", revision); //$NON-NLS-1$
    }

    EClass eClass = revision.getEClass();

    IClassMapping mapping = getStore().getMappingStrategy().getClassMapping(eClass);
    mapping.writeRevision(this, revision, firstRevision, revise, monitor);
  }

  @Override
  protected boolean needsRevisionPostProcessing()
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    if (mappingStrategy instanceof IMappingStrategy2)
    {
      return ((IMappingStrategy2)mappingStrategy).needsRevisionPostProcessing();
    }

    return super.needsRevisionPostProcessing();
  }

  @Override
  protected void postProcessRevisions(InternalCommitContext context, OMMonitor monitor)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    if (mappingStrategy instanceof IMappingStrategy2)
    {
      ((IMappingStrategy2)mappingStrategy).postProcessRevisions(this, context, monitor);
    }
  }

  /*
   * XXX Eike: change API from CDOID[] to CDOIDAndVersion[]
   */
  @Override
  protected void detachObjects(CDOID[] detachedObjects, CDOBranch branch, long timeStamp, OMMonitor monitor)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    monitor.begin(detachedObjects.length);

    try
    {
      InternalCDORevisionManager revisionManager = getStore().getRepository().getRevisionManager();
      for (CDOID id : detachedObjects)
      {
        // TODO when CDOIDAndVersion is available:
        // CDOID id = idAndVersion.getID(); //
        // int version = idAndVersion.getVersion(); //

        // but for now:

        InternalCDORevision revision = revisionManager.getRevision(id, branch.getHead(), CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, true);
        int version = ObjectUtil.equals(branch, revision.getBranch()) ? revision.getVersion() + 1 : CDOBranchVersion.FIRST_VERSION;

        if (TRACER.isEnabled())
        {
          TRACER.format("Detaching object: {0}", id); //$NON-NLS-1$
        }

        EClass eClass = getObjectType(id);
        IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
        mapping.detachObject(this, id, version, branch, timeStamp, monitor.fork());
      }
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  protected CDOID getNextCDOID(CDORevision revision)
  {
    return getStore().getIDHandler().getNextCDOID(revision);
  }

  @Override
  protected void writeBlob(byte[] id, long size, InputStream inputStream) throws IOException
  {
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_WRITE_BLOB, ReuseProbability.MEDIUM);

    try
    {
      stmt.setString(1, HexUtil.bytesToHex(id));
      stmt.setLong(2, size);
      stmt.setBinaryStream(3, inputStream, (int)size);

      DBUtil.update(stmt, true);
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(stmt);
    }
  }

  @Override
  protected void writeClob(byte[] id, long size, Reader reader) throws IOException
  {
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_WRITE_CLOB, ReuseProbability.MEDIUM);

    try
    {
      stmt.setString(1, HexUtil.bytesToHex(id));
      stmt.setLong(2, size);
      stmt.setCharacterStream(3, reader, (int)size);

      DBUtil.update(stmt, true);
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(stmt);
    }
  }

  @Override
  protected final void doCommit(OMMonitor monitor)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("--- DB COMMIT ---"); //$NON-NLS-1$
    }

    Async async = null;
    monitor.begin();

    try
    {
      try
      {
        async = monitor.forkAsync();
        getConnection().commit();

        if (maxID != CDOID.NULL)
        {
          // See bug 325097
          getStore().getIDHandler().adjustLastObjectID(maxID);
          maxID = CDOID.NULL;
        }

        if (objectAttacher != null)
        {
          objectAttacher.finishedCommit(true);
          objectAttacher = null;
        }
      }
      finally
      {
        if (async != null)
        {
          async.stop();
        }
      }
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  protected final void doRollback(IStoreAccessor.CommitContext commitContext)
  {
    if (objectAttacher != null)
    {
      objectAttacher.finishedCommit(false);
      objectAttacher = null;
    }

    IDBStore store = getStore();
    IMetaDataManager metaDataManager = store.getMetaDataManager();
    metaDataManager.clearMetaIDMappings();

    if (TRACER.isEnabled())
    {
      TRACER.format("--- DB ROLLBACK ---"); //$NON-NLS-1$
    }

    try
    {
      connection.rollback();
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }

    // Bug 298632: Must rollback DBSchema to its prior state and drop the tables
    IMappingStrategy mappingStrategy = store.getMappingStrategy();
    mappingStrategy.removeMapping(connection, commitContext.getNewPackageUnits());
  }

  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();

    DBStore store = getStore();
    connection = store.getDatabase().getConnection();
    connectionKeepAliveTask = new ConnectionKeepAliveTask(this);
    objectAttacher = null;

    long keepAlivePeriod = ConnectionKeepAliveTask.EXECUTION_PERIOD;
    Map<String, String> storeProps = store.getProperties();
    if (storeProps != null)
    {
      String value = storeProps.get(IDBStore.Props.CONNECTION_KEEPALIVE_PERIOD);
      if (value != null)
      {
        keepAlivePeriod = Long.parseLong(value) * 60L * 1000L;
      }
    }

    store.getConnectionKeepAliveTimer().schedule(connectionKeepAliveTask, keepAlivePeriod, keepAlivePeriod);
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    connectionKeepAliveTask.cancel();
    connectionKeepAliveTask = null;

    DBUtil.close(connection);
    connection = null;

    super.doDeactivate();
  }

  @Override
  protected void doPassivate() throws Exception
  {
    // this is called when the accessor is put back into the pool
    // we want to make sure that no DB lock is held (see Bug 276926)
    getConnection().rollback();

    if (createdTables != null)
    {
      createdTables.clear();
      createdTables = null;
    }
  }

  @Override
  protected void doUnpassivate() throws Exception
  {
    // do nothing
  }

  @Override
  public EPackage[] loadPackageUnit(InternalCDOPackageUnit packageUnit)
  {
    IMetaDataManager metaDataManager = getStore().getMetaDataManager();
    return metaDataManager.loadPackageUnit(getConnection(), packageUnit);
  }

  @Override
  public Collection<InternalCDOPackageUnit> readPackageUnits()
  {
    IMetaDataManager metaDataManager = getStore().getMetaDataManager();
    return metaDataManager.readPackageUnits(getConnection());
  }

  @Override
  protected void doWrite(InternalCommitContext context, OMMonitor monitor)
  {
    boolean wasTrackConstruction = DBField.isTrackConstruction();

    try
    {
      Map<String, String> properties = getStore().getProperties();
      if (properties != null)
      {
        String prop = properties.get(IDBStore.Props.FIELD_CONSTRUCTION_TRACKING);
        if (prop != null)
        {
          DBField.trackConstruction(Boolean.valueOf(prop));
        }
      }

      super.doWrite(context, monitor);
    }
    finally
    {
      DBField.trackConstruction(wasTrackConstruction);
    }
  }

  @Override
  public void writePackageUnits(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
  {
    monitor.begin(2);

    try
    {
      DBStore store = getStore();
      Connection connection = getConnection();

      IMetaDataManager metaDataManager = store.getMetaDataManager();
      metaDataManager.writePackageUnits(connection, packageUnits, monitor.fork());

      IMappingStrategy mappingStrategy = store.getMappingStrategy();
      mappingStrategy.createMapping(connection, packageUnits, monitor.fork());
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
  {
    checkBranchingSupport();
    if (branchID == NEW_BRANCH)
    {
      branchID = getStore().getNextBranchID();
    }
    else if (branchID == NEW_LOCAL_BRANCH)
    {
      branchID = getStore().getNextLocalBranchID();
    }

    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_CREATE_BRANCH, ReuseProbability.LOW);

    try
    {
      stmt.setInt(1, branchID);
      stmt.setString(2, branchInfo.getName());
      stmt.setInt(3, branchInfo.getBaseBranchID());
      stmt.setLong(4, branchInfo.getBaseTimeStamp());

      DBUtil.update(stmt, true);
      getConnection().commit();
      return Pair.create(branchID, branchInfo.getBaseTimeStamp());
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(stmt);
    }
  }

  @Override
  public BranchInfo loadBranch(int branchID)
  {
    checkBranchingSupport();
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_LOAD_BRANCH, ReuseProbability.HIGH);
    ResultSet resultSet = null;

    try
    {
      stmt.setInt(1, branchID);

      resultSet = stmt.executeQuery();
      if (!resultSet.next())
      {
        throw new DBException("Branch with ID " + branchID + " does not exist");
      }

      String name = resultSet.getString(1);
      int baseBranchID = resultSet.getInt(2);
      long baseTimeStamp = resultSet.getLong(3);
      return new BranchInfo(name, baseBranchID, baseTimeStamp);
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(resultSet);
      DBUtil.close(stmt);
    }
  }

  @Override
  public SubBranchInfo[] loadSubBranches(int baseID)
  {
    checkBranchingSupport();
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_LOAD_SUB_BRANCHES, ReuseProbability.HIGH);
    ResultSet resultSet = null;

    try
    {
      stmt.setInt(1, baseID);

      resultSet = stmt.executeQuery();
      List<SubBranchInfo> result = new ArrayList<>();
      while (resultSet.next())
      {
        int id = resultSet.getInt(1);
        String name = resultSet.getString(2);
        long baseTimeStamp = resultSet.getLong(3);
        result.add(new SubBranchInfo(id, name, baseTimeStamp));
      }

      return result.toArray(new SubBranchInfo[result.size()]);
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(resultSet);
      DBUtil.close(stmt);
    }
  }

  private void execSQL(String sql, ConsumerWithException<IDBPreparedStatement, SQLException> preparer)
  {
    IDBPreparedStatement stmt = connection.prepareStatement(sql, ReuseProbability.LOW);

    try
    {
      if (preparer != null)
      {
        preparer.accept(stmt);
      }

      DBUtil.update(stmt, true);
      getConnection().commit();
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(stmt);
    }
  }

  private void checkAuditingSupport()
  {
    if (!getStore().getMappingStrategy().hasAuditSupport())
    {
      throw new UnsupportedOperationException("Mapping strategy does not support auditing"); //$NON-NLS-1$
    }
  }

  private void checkBranchingSupport()
  {
    if (!getStore().getMappingStrategy().hasBranchingSupport())
    {
      throw new UnsupportedOperationException("Mapping strategy does not support branching"); //$NON-NLS-1$
    }
  }

  @Override
  public int loadBranches(int startID, int endID, CDOBranchHandler handler)
  {
    int count = 0;
    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_LOAD_BRANCHES, ReuseProbability.HIGH);
    ResultSet resultSet = null;

    InternalRepository repository = getSession().getManager().getRepository();
    InternalCDOBranchManager branchManager = repository.getBranchManager();

    try
    {
      stmt.setInt(1, startID);
      stmt.setInt(2, endID > 0 ? endID : Integer.MAX_VALUE);

      resultSet = stmt.executeQuery();
      while (resultSet.next())
      {
        int branchID = resultSet.getInt(1);
        String name = resultSet.getString(2);
        int baseBranchID = resultSet.getInt(3);
        long baseTimeStamp = resultSet.getLong(4);

        InternalCDOBranch branch = branchManager.getBranch(branchID, new BranchInfo(name, baseBranchID, baseTimeStamp));
        handler.handleBranch(branch);
        ++count;
      }

      return count;
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(resultSet);
      DBUtil.close(stmt);
    }
  }

  @Override
  @Deprecated
  public void deleteBranch(int branchID)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  @Deprecated
  public void renameBranch(int branchID, String newName)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public void renameBranch(int branchID, String oldName, String newName)
  {
    checkBranchingSupport();

    IDBPreparedStatement stmt = connection.prepareStatement(CDODBSchema.SQL_RENAME_BRANCH, ReuseProbability.LOW);

    try
    {
      stmt.setString(1, newName);
      stmt.setInt(2, branchID);

      DBUtil.update(stmt, true);
      getConnection().commit();
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(stmt);
    }
  }

  @Override
  public CDOBranchPoint changeTag(AtomicInteger modCount, String oldName, String newName, CDOBranchPoint branchPoint)
  {
    checkAuditingSupport();

    switch (InternalCDOBranchManager.getTagChangeKind(oldName, newName, branchPoint))
    {
    case CREATED:
    {
      // CREATE
      execSQL(CDODBSchema.SQL_CREATE_TAG, stmt -> {
        stmt.setString(1, newName);
        stmt.setInt(2, branchPoint.getBranch().getID());
        stmt.setLong(3, branchPoint.getTimeStamp());
      });

      break;
    }

    case RENAMED:
    {
      // RENAME
      execSQL(CDODBSchema.SQL_RENAME_TAG, stmt -> {
        stmt.setString(1, newName);
        stmt.setString(2, oldName);
      });

      break;
    }

    case MOVED:
    {
      // MOVE
      execSQL(CDODBSchema.SQL_MOVE_TAG, stmt -> {
        stmt.setInt(1, branchPoint.getBranch().getID());
        stmt.setLong(2, branchPoint.getTimeStamp());
        stmt.setString(3, oldName);
      });

      break;
    }

    case DELETED:
    {
      // DELETE
      execSQL(CDODBSchema.SQL_DELETE_TAG, stmt -> {
        stmt.setString(1, oldName);
      });

      break;
    }
    }

    // Repository.changeTag() takes care of the proper result value;
    return null;
  }

  @Override
  public void loadTags(String name, Consumer<BranchInfo> handler)
  {
    checkAuditingSupport();

    boolean single = name != null;
    String sql = single ? CDODBSchema.SQL_LOAD_TAG : CDODBSchema.SQL_LOAD_TAGS;
    IDBPreparedStatement stmt = connection.prepareStatement(sql, ReuseProbability.LOW);
    ResultSet resultSet = null;

    try
    {
      if (single)
      {
        stmt.setString(1, name);
      }

      resultSet = stmt.executeQuery();
      while (resultSet.next())
      {
        int c = 0;

        if (!single)
        {
          name = resultSet.getString(++c);
        }

        int branchID = resultSet.getInt(++c);
        long timeStamp = resultSet.getLong(++c);
        handler.accept(new BranchInfo(name, branchID, timeStamp));
      }
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(resultSet);
      DBUtil.close(stmt);
    }
  }

  @Override
  public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
  {
    CommitInfoTable commitInfoTable = getStore().getCommitInfoTable();
    if (commitInfoTable != null)
    {
      commitInfoTable.loadCommitInfos(this, branch, startTime, endTime, handler);
    }
  }

  @Override
  public Set<CDOID> readChangeSet(OMMonitor monitor, CDOChangeSetSegment... segments)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    return mappingStrategy.readChangeSet(this, monitor, segments);
  }

  @Override
  public void handleRevisions(EClass eClass, CDOBranch branch, long timeStamp, boolean exactTime, CDORevisionHandler handler)
  {
    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    mappingStrategy.handleRevisions(this, eClass, branch, timeStamp, exactTime, new DBRevisionHandler(handler));
  }

  @Override
  public void rawExport(CDODataOutput out, int fromBranchID, int toBranchID, long fromCommitTime, long toCommitTime) throws IOException
  {
    DBStore store = getStore();
    InternalRepository repository = store.getRepository();

    if (repository.getIDGenerationLocation() == IDGenerationLocation.STORE)
    {
      out.writeCDOID(store.getIDHandler().getLastObjectID()); // See bug 325097
    }

    Connection connection = getConnection();

    String where = " WHERE " + CDODBSchema.BRANCHES_ID + " BETWEEN " + fromBranchID + " AND " + toBranchID;
    DBUtil.serializeTable(out, connection, CDODBSchema.BRANCHES, null, where);

    CommitInfoTable commitInfoTable = store.getCommitInfoTable();
    if (commitInfoTable != null)
    {
      out.writeBoolean(true);
      commitInfoTable.rawExport(connection, out, fromCommitTime, toCommitTime);
    }
    else
    {
      out.writeBoolean(false);
    }

    DurableLockingManager durableLockingManager = store.getDurableLockingManager();
    durableLockingManager.rawExport(connection, out, fromCommitTime, toCommitTime);

    IIDHandler idHandler = store.getIDHandler();
    idHandler.rawExport(connection, out, fromCommitTime, toCommitTime);

    // IMetaDataManager metaDataManager = store.getMetaDataManager();
    // metaDataManager.rawExport(connection, out, fromCommitTime, toCommitTime);

    IMappingStrategy mappingStrategy = store.getMappingStrategy();
    mappingStrategy.rawExport(this, out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
  }

  @Override
  public void rawImport(CDODataInput in, int fromBranchID, int toBranchID, long fromCommitTime, long toCommitTime, OMMonitor monitor) throws IOException
  {
    DBStore store = getStore();
    IIDHandler idHandler = store.getIDHandler();
    if (store.getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE)
    {
      idHandler.setLastObjectID(in.readCDOID()); // See bug 325097
    }

    IMappingStrategy mappingStrategy = store.getMappingStrategy();
    int size = mappingStrategy.getClassMappings().size();
    int commitWork = 5;
    monitor.begin(commitWork + size + commitWork);

    Collection<InternalCDOPackageUnit> packageUnits = new HashSet<>();
    Connection connection = getConnection();

    try
    {
      DBUtil.deserializeTable(in, connection, CDODBSchema.BRANCHES, monitor.fork());

      CommitInfoTable commitInfoTable = store.getCommitInfoTable();
      if (in.readBoolean())
      {
        if (commitInfoTable == null)
        {
          throw new IllegalStateException("Commit info table is missing");
        }

        commitInfoTable.rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());
      }
      else
      {
        if (commitInfoTable != null)
        {
          throw new IllegalStateException("Commit info data is expected but missing");
        }
      }

      DurableLockingManager durableLockingManager = store.getDurableLockingManager();
      durableLockingManager.rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());

      idHandler.rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());

      // rawImportPackageUnits(in, fromCommitTime, toCommitTime, packageUnits, monitor.fork());

      IDBSchemaTransaction schemaTransaction = openSchemaTransaction();

      try
      {
        mappingStrategy.rawImport(this, in, fromCommitTime, toCommitTime, monitor.fork(size));
        schemaTransaction.commit();
      }
      finally
      {
        schemaTransaction.close();
      }

      rawCommit(commitWork, monitor);
    }
    catch (RuntimeException ex)
    {
      rawRollback(packageUnits);
      throw ex;
    }
    catch (IOException ex)
    {
      rawRollback(packageUnits);
      throw ex;
    }
    finally
    {
      monitor.done();
    }
  }

  private void rawRollback(Collection<InternalCDOPackageUnit> packageUnits)
  {
    try
    {
      Connection connection = getConnection();
      connection.rollback();
    }
    catch (SQLException ex)
    {
      OM.LOG.error(ex);
    }

    getStore().getMappingStrategy().removeMapping(getConnection(), packageUnits.toArray(new InternalCDOPackageUnit[packageUnits.size()]));
  }

  protected void rawImportPackageUnits(CDODataInput in, long fromCommitTime, long toCommitTime, Collection<InternalCDOPackageUnit> packageUnits,
      OMMonitor monitor) throws IOException
  {
    monitor.begin(2);

    try
    {
      DBStore store = getStore();
      IMetaDataManager metaDataManager = store.getMetaDataManager();
      Connection connection = getConnection();

      Collection<InternalCDOPackageUnit> imported = //
          metaDataManager.rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());
      packageUnits.addAll(imported);

      if (!packageUnits.isEmpty())
      {
        InternalRepository repository = store.getRepository();
        InternalCDOPackageRegistry packageRegistry = repository.getPackageRegistry(false);

        for (InternalCDOPackageUnit packageUnit : packageUnits)
        {
          packageRegistry.putPackageUnit(packageUnit);
        }

        IMappingStrategy mappingStrategy = store.getMappingStrategy();

        // Use another connection because CREATE TABLE (which is called in createMapping)
        // on H2 databases does a commit.
        Connection connection2 = null;

        try
        {
          connection2 = store.getConnection();

          mappingStrategy.createMapping(connection2, packageUnits.toArray(new InternalCDOPackageUnit[packageUnits.size()]), monitor.fork());
        }
        finally
        {
          DBUtil.close(connection2);
        }
      }
      else
      {
        monitor.worked();
      }
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  public void rawStore(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
  {
    writePackageUnits(packageUnits, monitor);
  }

  @Override
  public void rawStore(InternalCDORevision revision, OMMonitor monitor)
  {
    CDOID id = revision.getID();
    EClass eClass = revision.getEClass();

    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    CDOClassifierRef classifierRef = mappingStrategy.readObjectType(this, id);

    boolean firstRevision = classifierRef == null;
    if (!firstRevision)
    {
      boolean namesMatch = classifierRef.getClassifierName().equals(eClass.getName());
      boolean packagesMatch = classifierRef.getPackageURI().equals(eClass.getEPackage().getNsURI());
      if (!namesMatch || !packagesMatch)
      {
        throw new IllegalStateException();
      }
    }

    writeRevision(revision, firstRevision, false, monitor);
    getStore().getIDHandler().adjustLastObjectID(id);
  }

  @Override
  public void rawStore(byte[] id, long size, InputStream inputStream) throws IOException
  {
    writeBlob(id, size, inputStream);
  }

  @Override
  public void rawStore(byte[] id, long size, Reader reader) throws IOException
  {
    writeClob(id, size, reader);
  }

  @Override
  public void rawStore(CDOBranch branch, long timeStamp, long previousTimeStamp, String userID, String comment, OMMonitor monitor)
  {
    writeCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment, null, monitor);
  }

  @Override
  public void rawStore(CDOBranch branch, long timeStamp, long previousTimeStamp, String userID, String comment, CDOBranchPoint mergeSource, OMMonitor monitor)
  {
    writeCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment, mergeSource, monitor);
  }

  @Override
  public void rawDelete(CDOID id, int version, CDOBranch branch, EClass eClass, OMMonitor monitor)
  {
    if (eClass == null)
    {
      eClass = getObjectType(id);
    }

    IMappingStrategy mappingStrategy = getStore().getMappingStrategy();
    IClassMapping mapping = mappingStrategy.getClassMapping(eClass);
    if (mapping instanceof AbstractHorizontalClassMapping)
    {
      AbstractHorizontalClassMapping m = (AbstractHorizontalClassMapping)mapping;
      m.rawDelete(this, id, version, branch, monitor);
    }
    else
    {
      throw new UnsupportedOperationException("rawDelete() is not supported by " + mapping.getClass().getName());
    }
  }

  @Override
  public void rawCommit(double commitWork, OMMonitor monitor)
  {
    monitor.begin();
    Async async = monitor.forkAsync();

    try
    {
      Connection connection = getConnection();
      connection.commit();
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
    finally
    {
      async.stop();
      monitor.done();
    }
  }

  @Override
  public LockArea createLockArea(String userID, CDOBranchPoint branchPoint, boolean readOnly, Map<CDOID, LockGrade> locks)
  {
    return createLockArea(null, userID, branchPoint, readOnly, locks);
  }

  @Override
  public LockArea createLockArea(String durableLockingID, String userID, CDOBranchPoint branchPoint, boolean readOnly, Map<CDOID, LockGrade> locks)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    return manager.createLockArea(this, durableLockingID, userID, branchPoint, readOnly, locks);
  }

  @Override
  public void updateLockArea(LockArea area)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    manager.updateLockArea(this, area);
  }

  @Override
  public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    return manager.getLockArea(this, durableLockingID);
  }

  @Override
  public void getLockAreas(String userIDPrefix, Handler handler)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    manager.getLockAreas(this, userIDPrefix, handler);
  }

  @Override
  public void deleteLockArea(String durableLockingID)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    manager.deleteLockArea(this, durableLockingID);
  }

  @Override
  public void lock(String durableLockingID, LockType type, Collection<? extends Object> objectsToLock)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    manager.lock(this, durableLockingID, type, objectsToLock);
  }

  @Override
  public void unlock(String durableLockingID, LockType type, Collection<? extends Object> objectsToUnlock)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    manager.unlock(this, durableLockingID, type, objectsToUnlock);
  }

  @Override
  public void unlock(String durableLockingID)
  {
    DurableLockingManager manager = getStore().getDurableLockingManager();
    manager.unlock(this, durableLockingID);
  }

  @Override
  public List<CDOID> readUnitRoots()
  {
    UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
    return unitMappingTable.readUnitRoots(this);
  }

  @Override
  public void readUnit(IView view, CDOID rootID, CDORevisionHandler revisionHandler, OMMonitor monitor)
  {
    UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
    unitMappingTable.readUnitRevisions(this, view, rootID, revisionHandler, monitor);
  }

  @Override
  public Object initUnit(IView view, CDOID rootID, CDORevisionHandler revisionHandler, Set<CDOID> initializedIDs, long timeStamp, OMMonitor monitor)
  {
    UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
    return unitMappingTable.initUnit(this, timeStamp, view, rootID, revisionHandler, initializedIDs, monitor);
  }

  @Override
  public void finishUnit(IView view, CDOID rootID, CDORevisionHandler revisionHandler, long timeStamp, Object initResult, List<CDOID> ids)
  {
    UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
    unitMappingTable.finishUnit((BatchedStatement)initResult, rootID, ids, timeStamp);
  }

  @Override
  public void writeUnits(Map<CDOID, CDOID> unitMappings, long timeStamp)
  {
    UnitMappingTable unitMappingTable = getStore().getUnitMappingTable();
    unitMappingTable.writeUnitMappings(this, unitMappings, timeStamp);
  }

  @Override
  public void tableCreated(IDBTable table)
  {
    if (createdTables == null)
    {
      createdTables = new ArrayList<>();
    }

    createdTables.add(table);
  }

  /**
   * @author Stefan Winkler
   */
  private static final class ConnectionKeepAliveTask extends TrackableTimerTask
  {
    public static final long EXECUTION_PERIOD = 1000 * 60 * 60 * 4; // 4 hours

    private DBStoreAccessor accessor;

    public ConnectionKeepAliveTask(DBStoreAccessor accessor)
    {
      this.accessor = accessor;
    }

    @Override
    public void run()
    {
      if (accessor == null)
      {
        return;
      }

      Statement stmt = null;

      try
      {
        if (TRACER.isEnabled())
        {
          TRACER.trace("DB connection keep-alive task activated"); //$NON-NLS-1$
        }

        Connection connection = accessor.getConnection();
        stmt = connection.createStatement();
        stmt.executeQuery("SELECT 1 FROM " + CDODBSchema.PROPERTIES); //$NON-NLS-1$
      }
      catch (java.sql.SQLException ex)
      {
        OM.LOG.error("DB connection keep-alive failed", ex); //$NON-NLS-1$

        // Assume the connection has failed.
        try
        {
          LifecycleUtil.deactivate(accessor);
          LifecycleUtil.activate(accessor);
        }
        catch (Exception ex2)
        {
          OM.LOG.error("DB connection reconnect failed", ex2); //$NON-NLS-1$
        }
      }
      catch (Exception ex) // Important: Do not throw any unchecked exceptions to the TimerThread!!!
      {
        OM.LOG.error("DB connection keep-alive failed", ex); //$NON-NLS-1$
      }
      finally
      {
        DBUtil.close(stmt);
      }
    }

    @Override
    public boolean cancel()
    {
      accessor = null;
      return super.cancel();
    }
  }
}
