blob: 982c5da1dc676052ba0093d7ed4d3607998d8524 [file] [log] [blame]
/***************************************************************************
* Copyright (c) 2004 - 2008 Eike Stepper, Germany.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
**************************************************************************/
package org.eclipse.emf.cdo.server.internal.db;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOClassRef;
import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.model.resource.CDOResourceNodeClass;
import org.eclipse.emf.cdo.common.model.resource.CDOResourcePackage;
import org.eclipse.emf.cdo.server.IPackageManager;
import org.eclipse.emf.cdo.server.db.IClassMapping;
import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreReader;
import org.eclipse.emf.cdo.server.db.IObjectTypeCache;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eike Stepper
*/
public class HorizontalMappingStrategy extends MappingStrategy
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalMappingStrategy.class);
private IObjectTypeCache objectTypeCache;
public HorizontalMappingStrategy()
{
}
public String getType()
{
return "horizontal";
}
public IObjectTypeCache getObjectTypeCache()
{
return objectTypeCache;
}
public void setObjectTypeCache(IObjectTypeCache objectTypeCache)
{
this.objectTypeCache = objectTypeCache;
}
public CDOClassRef readObjectType(IDBStoreReader storeReader, CDOID id)
{
return objectTypeCache.getObjectType(storeReader, id);
}
protected CDOClassRef readObjectTypeFromClassesWithObjectInfo(IDBStoreReader storeReader, CDOID id)
{
String prefix = "SELECT DISTINCT " + CDODBSchema.ATTRIBUTES_CLASS + " FROM ";
String suffix = " WHERE " + CDODBSchema.ATTRIBUTES_ID + "=" + id;
for (CDOClass cdoClass : getClassesWithObjectInfo())
{
IClassMapping mapping = getClassMapping(cdoClass);
if (mapping != null)
{
IDBTable table = mapping.getTable();
if (table != null)
{
String sql = prefix + table + suffix;
if (TRACER.isEnabled())
{
TRACER.trace(sql);
}
ResultSet resultSet = null;
try
{
resultSet = storeReader.getStatement().executeQuery(sql);
if (resultSet.next())
{
int classID = resultSet.getInt(1);
return getClassRef(storeReader, classID);
}
}
catch (SQLException ex)
{
throw new DBException(ex);
}
finally
{
DBUtil.close(resultSet);
}
}
}
}
throw new DBException("No object with id " + id);
}
@Override
protected IClassMapping createClassMapping(CDOClass cdoClass)
{
if (cdoClass.isAbstract())
{
return null;
}
return new HorizontalClassMapping(this, cdoClass);
}
@Override
protected List<CDOClass> getClassesWithObjectInfo()
{
List<CDOClass> result = new ArrayList<CDOClass>();
IPackageManager packageManager = getStore().getRepository().getPackageManager();
for (CDOPackage cdoPackage : packageManager.getPackages())
{
for (CDOClass cdoClass : cdoPackage.getConcreteClasses())
{
if (!cdoClass.isRoot())
{
result.add(cdoClass);
}
}
}
return result;
}
@Override
protected void doActivate() throws Exception
{
super.doActivate();
if (objectTypeCache == null)
{
objectTypeCache = createObjectTypeCache(getStore());
LifecycleUtil.activate(objectTypeCache);
}
}
@Override
protected String[] getResourceQueries(CDOID folderID, String name, boolean exactMatch)
{
CDOResourcePackage resourcePackage = getStore().getRepository().getPackageManager().getCDOResourcePackage();
String[] queries = new String[2];
IClassMapping resourceFolderMapping = getClassMapping(resourcePackage.getCDOResourceFolderClass());
queries[0] = getResourceQuery(folderID, name, exactMatch, resourceFolderMapping);
IClassMapping resourceMapping = getClassMapping(resourcePackage.getCDOResourceClass());
queries[1] = getResourceQuery(folderID, name, exactMatch, resourceMapping);
return queries;
}
protected String getResourceQuery(CDOID folderID, String name, boolean exactMatch, IClassMapping classMapping)
{
CDOResourcePackage resourcePackage = getStore().getRepository().getPackageManager().getCDOResourcePackage();
CDOResourceNodeClass resourceNodeClass = resourcePackage.getCDOResourceNodeClass();
IDBTable table = classMapping.getTable();
IDBField nameField = classMapping.getAttributeMapping(resourceNodeClass.getCDONameFeature()).getField();
StringBuilder builder = new StringBuilder();
builder.append("SELECT ");
builder.append(CDODBSchema.ATTRIBUTES_ID);
builder.append(" FROM ");
builder.append(table);
builder.append(" WHERE ");
builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
builder.append("=");
builder.append(CDOIDUtil.getLong(folderID));
if (exactMatch || name != null)
{
builder.append(" AND ");
builder.append(nameField);
if (exactMatch)
{
if (name == null)
{
builder.append(" IS NULL");
}
else
{
builder.append("=\'");
builder.append(name);
builder.append("\'");
}
}
else
{
// Here: name != null
builder.append(" LIKE \'");
builder.append(name);
builder.append("%\'");
}
}
String sql = builder.toString();
return sql;
}
@Override
protected void doDeactivate() throws Exception
{
LifecycleUtil.deactivate(objectTypeCache);
objectTypeCache = null;
super.doDeactivate();
}
protected IObjectTypeCache createObjectTypeCache(IDBStore store)
{
ObjectTypeCache cache = new ObjectTypeCache();
cache.setMappingStrategy(this);
return cache;
}
}