blob: 970a166624638d5738a65a203448ed7cba06b626 [file] [log] [blame]
/*
* Copyright (c) 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
*/
package org.eclipse.net4j.internal.db;
import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.DBUtil.RunnableWithConnection;
import org.eclipse.net4j.db.IDBSchemaTransaction;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.delta.IDBDeltaVisitor;
import org.eclipse.net4j.db.ddl.delta.IDBSchemaDelta;
import org.eclipse.net4j.internal.db.ddl.DelegatingDBSchema;
import org.eclipse.net4j.internal.db.ddl.DelegatingDBSchemaElement;
import org.eclipse.net4j.internal.db.ddl.delta.DBSchemaDelta;
import org.eclipse.net4j.spi.db.DBAdapter;
import org.eclipse.net4j.spi.db.ddl.InternalDBSchema;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @author Eike Stepper
*/
public final class DBSchemaTransaction implements IDBSchemaTransaction, RunnableWithConnection<DBSchemaDelta>
{
private DBDatabase database;
private DBConnection connection;
private IDBSchema oldSchema;
private IDBSchema workingCopy;
public DBSchemaTransaction(DBDatabase database)
{
this.database = database;
oldSchema = database.getSchema();
IDBSchema copy = DBUtil.copySchema(oldSchema);
workingCopy = DelegatingDBSchemaElement.wrap(copy);
}
public DBDatabase getDatabase()
{
return database;
}
public DBConnection getConnection()
{
return connection;
}
public void setConnection(DBConnection connection)
{
this.connection = connection;
}
public IDBSchema getWorkingCopy()
{
return workingCopy;
}
public DBSchemaDelta ensureSchema(IDBSchema schema, IDBDeltaVisitor.Filter.Policy policy)
{
IDBSchema workingCopy = getWorkingCopy();
IDBDeltaVisitor.Copier copier = new IDBDeltaVisitor.Copier(policy);
IDBSchemaDelta delta = schema.compare(workingCopy);
delta.accept(copier);
DBSchemaDelta result = (DBSchemaDelta)copier.getResult();
result.setName(workingCopy.getName());
result.applyTo(workingCopy);
return result;
}
public DBSchemaDelta ensureSchema(IDBSchema schema)
{
return ensureSchema(schema, DEFAULT_ENSURE_SCHEMA_POLICY);
}
public DBSchemaDelta getSchemaDelta()
{
return (DBSchemaDelta)workingCopy.compare(oldSchema);
}
public DBSchemaDelta commit()
{
if (connection == null)
{
return DBUtil.execute(database, this);
}
try
{
DBSchemaDelta result = run(connection);
connection.commit();
return result;
}
catch (SQLException ex)
{
DBUtil.rollbackSilently(connection);
throw new DBException(ex);
}
}
public DBSchemaDelta run(Connection connection) throws SQLException
{
DBSchemaDelta delta = getSchemaDelta();
try
{
((InternalDBSchema)oldSchema).unlock();
DBAdapter adapter = database.getAdapter();
adapter.updateSchema(connection, oldSchema, delta);
((DelegatingDBSchema)workingCopy).setDelegate(oldSchema);
}
finally
{
((InternalDBSchema)oldSchema).lock();
doClose(delta);
}
return delta;
}
public void close()
{
doClose(null);
}
private void doClose(DBSchemaDelta delta)
{
if (!isClosed())
{
database.closeSchemaTransaction(delta);
connection = null;
oldSchema = null;
workingCopy = null;
}
}
public boolean isClosed()
{
return workingCopy == null;
}
}