blob: 93f4e6e99c03dc0de46c1ba9801082476f7f8c96 [file] [log] [blame]
/*
* Copyright (c) 2010-2013 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 - major refactoring
*/
package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.mapping.IClassMapping;
import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBConnection;
import org.eclipse.net4j.db.IDBPreparedStatement;
import org.eclipse.net4j.db.IDBPreparedStatement.ReuseProbability;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Eike Stepper
* @since 2.0
*/
public class HorizontalBranchingMappingStrategy extends AbstractHorizontalMappingStrategy
{
public HorizontalBranchingMappingStrategy()
{
}
public boolean hasAuditSupport()
{
return true;
}
public boolean hasBranchingSupport()
{
return true;
}
public boolean hasDeltaSupport()
{
return false;
}
@Override
protected IClassMapping doCreateClassMapping(EClass eClass)
{
return new HorizontalBranchingClassMapping(this, eClass);
}
@Override
public IListMapping doCreateListMapping(EClass containingClass, EStructuralFeature feature)
{
return new BranchingListTableMapping(this, containingClass, feature);
}
@Override
public IListMapping doCreateFeatureMapMapping(EClass containingClass, EStructuralFeature feature)
{
return new BranchingFeatureMapTableMapping(this, containingClass, feature);
}
@Override
public String getListJoin(String attrTable, String listTable)
{
String join = getListJoinBasic(attrTable, listTable);
return modifyListJoin(attrTable, listTable, join, false);
}
@Override
protected String getListJoinForRawExport(String attrTable, String listTable)
{
String join = getListJoinBasic(attrTable, listTable);
return modifyListJoin(attrTable, listTable, join, true);
}
protected String getListJoinBasic(String attrTable, String listTable)
{
return super.getListJoin(attrTable, listTable);
}
protected String modifyListJoin(String attrTable, String listTable, String join, boolean forRawExport)
{
join += " AND " + attrTable + "." + ATTRIBUTES_VERSION;
join += "=" + listTable + "." + LIST_REVISION_VERSION;
join += " AND " + attrTable + "." + ATTRIBUTES_BRANCH;
join += "=" + listTable + "." + LIST_REVISION_BRANCH;
return join;
}
@Override
protected void rawImportReviseOldRevisions(IDBConnection connection, IDBTable table, OMMonitor monitor)
{
String sqlUpdate = "UPDATE " + table + " SET " + ATTRIBUTES_REVISED + "=? WHERE " + ATTRIBUTES_ID + "=? AND "
+ ATTRIBUTES_BRANCH + "=? AND " + ATTRIBUTES_VERSION + "=?";
String sqlQuery = "SELECT cdo1." + ATTRIBUTES_ID + ", cdo1." + ATTRIBUTES_BRANCH + ", cdo1." + ATTRIBUTES_VERSION
+ ", cdo2." + ATTRIBUTES_CREATED + " FROM " + table + " cdo1, " + table + " cdo2 WHERE cdo1." + ATTRIBUTES_ID
+ "=cdo2." + ATTRIBUTES_ID + " AND cdo1." + ATTRIBUTES_BRANCH + "=cdo2." + ATTRIBUTES_BRANCH + " AND (cdo1."
+ ATTRIBUTES_VERSION + "=cdo2." + ATTRIBUTES_VERSION + "-1 OR (cdo1." + ATTRIBUTES_VERSION + "+cdo2."
+ ATTRIBUTES_VERSION + "=-1 AND cdo1." + ATTRIBUTES_VERSION + ">cdo2." + ATTRIBUTES_VERSION + ")) AND cdo1."
+ ATTRIBUTES_REVISED + "=0";
IIDHandler idHandler = getStore().getIDHandler();
IDBPreparedStatement stmtUpdate = connection.prepareStatement(sqlUpdate, ReuseProbability.MEDIUM);
IDBPreparedStatement stmtQuery = connection.prepareStatement(sqlQuery, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY, ReuseProbability.MEDIUM);
ResultSet resultSet = null;
try
{
resultSet = stmtQuery.executeQuery();
int size = DBUtil.getRowCount(resultSet);
if (size == 0)
{
return;
}
monitor.begin(2 * size);
while (resultSet.next())
{
CDOID id = idHandler.getCDOID(resultSet, 1);
int branch = resultSet.getInt(2);
int version = resultSet.getInt(3);
long revised = resultSet.getLong(4) - 1L;
stmtUpdate.setLong(1, revised);
idHandler.setCDOID(stmtUpdate, 2, id);
stmtUpdate.setInt(3, branch);
stmtUpdate.setInt(4, version);
stmtUpdate.addBatch();
monitor.worked();
}
Async async = monitor.forkAsync(size);
try
{
stmtUpdate.executeBatch();
}
finally
{
async.stop();
}
}
catch (SQLException ex)
{
throw new DBException(ex);
}
finally
{
DBUtil.close(resultSet);
DBUtil.close(stmtQuery);
DBUtil.close(stmtUpdate);
monitor.done();
}
}
@Override
protected void rawImportUnreviseNewRevisions(IDBConnection connection, IDBTable table, long fromCommitTime,
long toCommitTime, OMMonitor monitor)
{
String sql = "UPDATE " + table + " SET " + ATTRIBUTES_REVISED + "=0 WHERE " + ATTRIBUTES_BRANCH + ">=0 AND "
+ ATTRIBUTES_CREATED + "<=" + toCommitTime + " AND " + ATTRIBUTES_REVISED + ">" + toCommitTime + " AND "
+ ATTRIBUTES_VERSION + ">0";
IDBPreparedStatement stmt = connection.prepareStatement(sql, ReuseProbability.MEDIUM);
try
{
monitor.begin();
Async async = monitor.forkAsync();
try
{
stmt.executeUpdate();
}
finally
{
async.stop();
}
}
catch (SQLException ex)
{
throw new DBException(ex);
}
finally
{
DBUtil.close(stmt);
monitor.done();
}
}
}