/*
* Copyright (c) 2012 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* HUMBOLDT EU Integrated Project #030962
* Data Harmonisation Panel <http://www.dhpanel.eu>
*/
package eu.esdihumboldt.hale.common.instance.orient.storage;
import java.io.File;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
/**
* Represents a local Orient database
*
* @author Simon Templer
*/
public class LocalOrientDB {
/**
* Database reference for reading holding a lock
*/
private class ReadReference implements DatabaseReference<ODatabaseDocumentTx> {
private ODatabaseDocumentTx database;
private final boolean createLock;
/**
* Create a new read reference.
*
* @param lock if a lock should be created for the reference
*/
public ReadReference(boolean lock) {
this.createLock = lock;
}
/**
* @see DatabaseReference#getDatabase()
*/
@Override
public ODatabaseDocumentTx getDatabase() {
if (database == null) {
if (createLock) {
dbLock.readLock().lock();
}
// database = pool.acquire(dbURI, "reader", "reader");
database = new ODatabaseDocumentTx(dbURI).open("reader", "reader");
}
return database;
}
/**
* @see DatabaseReference#dispose(boolean)
*/
@Override
public void dispose(boolean closeConnection) {
if (database != null) {
if (closeConnection) {
// pool.release(database)
database.close();
}
if (createLock) {
dbLock.readLock().unlock();
}
}
}
/**
* @see DatabaseReference#dispose()
*/
@Override
public void dispose() {
dispose(true);
}
}
/**
* Database reference for writing holding a lock
*/
private class WriteReference implements DatabaseReference<ODatabaseDocumentTx> {
private ODatabaseDocumentTx database;
/**
* @see DatabaseReference#getDatabase()
*/
@Override
public ODatabaseDocumentTx getDatabase() {
if (database == null) {
// XXX could eventually use read lock
dbLock.writeLock().lock();
// database = new ODatabaseDocumentTx(dbURI).open("writer", "writer");
// writer use doesn't seem to be supported any more (as of
// 1.0rc8)
// database = pool.acquire(dbURI, "admin", "admin");
database = new ODatabaseDocumentTx(dbURI).open("admin", "admin");
}
return database;
}
/**
* @see DatabaseReference#dispose(boolean)
*/
@Override
public void dispose(boolean closeConnection) {
if (database != null) {
if (closeConnection) {
// pool.release(database)
database.close();
}
// XXX could eventually use read lock
dbLock.writeLock().unlock();
}
}
/**
* @see DatabaseReference#dispose()
*/
@Override
public void dispose() {
dispose(true);
}
}
private final ReadWriteLock dbLock = new ReentrantReadWriteLock();
private final String dbURI;
// private final ODatabaseDocumentPool pool;
/**
* Create a local Orient database. It will delete database that exists
* previously at the same location.
*
* @param location the data base location
*/
public LocalOrientDB(File location) {
super();
dbURI = "local:" + location.getAbsolutePath();
// pool = new ODatabaseDocumentPool();
// pool.setup(1,10);
// XXX close pool? when?
ODatabaseDocumentTx db = new ODatabaseDocumentTx(dbURI);
try {
// delete the database if it already exists
db.drop();
} catch (Throwable e) {
// ignore
}
// create the database
db.create();
db.close();
}
/**
* Get a database reference with read access.<br>
* <br>
* NOTE: Getting the database reference locks a read lock on the database.
* {@link DatabaseReference#dispose()} must be called when the database
* reference isn't needed any more.
*
* @return the database reference
*/
public DatabaseReference<ODatabaseDocumentTx> openRead() {
return new ReadReference(true);
}
/**
* Get a database reference with read access.<br>
*
* @param lock if a read lock should be created,
* {@link DatabaseReference#dispose()} must be called when the
* database reference isn't needed any more
* @return the database reference
*/
public DatabaseReference<ODatabaseDocumentTx> openRead(boolean lock) {
return new ReadReference(lock);
}
/**
* Get a database reference with write access.<br>
* <br>
* NOTE: Getting the database reference locks a write lock on the database.
* {@link DatabaseReference#dispose()} must be called when the database
* reference isn't needed any more.
*
* @return the database reference
*/
public DatabaseReference<ODatabaseDocumentTx> openWrite() {
return new WriteReference();
}
/**
* Delete the database and recreate it.
*/
public void clear() {
dbLock.writeLock().lock();
try {
@SuppressWarnings("resource")
ODatabaseDocumentTx db = new ODatabaseDocumentTx(dbURI).open("admin", "admin");
// delete the database if it already exists
db.drop();
// create the database
db.create();
db.close();
} finally {
dbLock.writeLock().unlock();
}
}
/**
* Delete the database.
*/
public void delete() {
dbLock.writeLock().lock();
try {
@SuppressWarnings("resource")
ODatabaseDocumentTx db = new ODatabaseDocumentTx(dbURI).open("admin", "admin");
// delete the database if it already exists
db.drop();
db.close();
} finally {
dbLock.writeLock().unlock();
}
}
}