/*
* Copyright 2009-2016 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.test.testutil;
import java.lang.reflect.Field;
import java.util.Properties;
import javax.jdo.JDOException;
import javax.jdo.JDOHelper;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import org.zoodb.jdo.ZooJdoHelper;
import org.zoodb.jdo.ZooJdoProperties;
import org.zoodb.jdo.impl.PersistenceManagerImpl;
import org.zoodb.schema.ZooClass;
import org.zoodb.tools.ZooDebug;
import org.zoodb.tools.ZooHelper;
public class TestTools {
private static final String DB_NAME = "TestDb";
private static PersistenceManager pm;
public static void createDb(String dbName) {
if (ZooHelper.dbExists(dbName)) {
removeDb(dbName);
}
ZooDebug.setTesting(true);
ZooHelper.createDb(dbName);
}
/**
* Create the default database.
*/
public static void createDb() {
createDb(DB_NAME);
}
/**
* Remove the default database.
*/
public static void removeDb() {
removeDb(DB_NAME);
}
public static void removeDb(String dbName) {
if (!ZooHelper.dbExists(dbName)) {
return;
}
try {
closePM();
} catch (JDOException e) {
e.printStackTrace();
}
//TODO implement loop ala http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 ?
//-> Entry from 23-MARCH-2005 #2
// for (int i = 0; i < 100; i++) {
// System.gc();
// System.runFinalization();
// //Thread.sleep(100);
// }
try {
ZooHelper.removeDb(dbName);
} catch (JDOUserException e) {
//ignore
}
}
/**
* Varargs does not seem to work with generics.
* @param classes
*/
public static void defineSchema(Class<?> ... classes) {
defineSchema(DB_NAME, classes);
}
public static void defineSchema(String dbName, Class<?> ... classes) {
Properties props = new ZooJdoProperties(dbName);
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
PersistenceManager pm = null;
try {
pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
for (Class<?> cls: classes) {
ZooJdoHelper.schema(pm).addClass(cls);
}
pm.currentTransaction().commit();
} finally {
safeClose(pmf, pm);
}
}
public static void removeSchema(Class<?> ... classes) {
Properties props = new ZooJdoProperties(DB_NAME);
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
PersistenceManager pm = null;
try {
pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
for (Class<?> cls: classes) {
ZooClass c = ZooJdoHelper.schema(pm).getClass(cls);
if (c != null) {
c.remove();
}
}
pm.currentTransaction().commit();
} finally {
safeClose(pmf, pm);
}
}
public static PersistenceManager openPM() {
ZooJdoProperties props = new ZooJdoProperties(DB_NAME);
//for the tests we prefer manual creation
props.setZooAutoCreateSchema(false);
return openPM(props);
}
public static PersistenceManager openPM(ZooJdoProperties props) {
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
pm = pmf.getPersistenceManager();
return pm;
}
public static PersistenceManager openPM(String databaseName) {
ZooJdoProperties props = new ZooJdoProperties(databaseName);
return openPM(props);
}
public static void closePM(PersistenceManager pm) {
PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
if (!pm.isClosed()) {
try {
if (pm.currentTransaction().isActive()) {
pm.currentTransaction().rollback();
}
pm.close();
} catch (Exception e) {
e.printStackTrace();
((PersistenceManagerImpl)pm).getSession().close();
}
}
pmf.close();
TestTools.pm = null;
//close files that may still be open
if (ZooDebug.isTesting()) {
ZooDebug.closeOpenFiles();
//ZooDebug.setTesting(false);
}
}
public static void closePM() {
if (pm != null) {
closePM(pm);
} else {
//close files that may still be open
if (ZooDebug.isTesting()) {
ZooDebug.closeOpenFiles();
//ZooDebug.setTesting(false);
}
}
}
/**
*
* @return Full path of the default DB.
*/
public static String getDbFileName() {
return ZooHelper.getDataStoreManager().getDbPath(DB_NAME);
}
public static String getDbName() {
return DB_NAME;
}
public static void dropInstances(Class<?> ... classes) {
Properties props = new ZooJdoProperties(DB_NAME);
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
PersistenceManager pm = null;
try {
pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
for (Class<?> cls: classes) {
ZooJdoHelper.schema(pm).getClass(cls).dropInstances();
}
pm.currentTransaction().commit();
} finally {
safeClose(pmf, pm);
}
}
private static void safeClose(PersistenceManagerFactory pmf, PersistenceManager pm) {
if (pm != null) {
if (pm.currentTransaction().isActive()) {
pm.currentTransaction().rollback();
}
pm.close();
}
if (pmf != null) {
pmf.close();
}
}
public static ZooJdoProperties getProps() {
return new ZooJdoProperties(DB_NAME);
}
public static void defineIndex(String dbName, Class<?> cls, String fieldName,
boolean isUnique) {
Properties props = new ZooJdoProperties(dbName);
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
PersistenceManager pm = null;
try {
pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
ZooClass s = ZooJdoHelper.schema(pm).getClass(cls);
s.getField(fieldName).createIndex(isUnique);
pm.currentTransaction().commit();
} finally {
safeClose(pmf, pm);
}
}
public static void defineIndex(Class<?> cls, String fieldName, boolean isUnique) {
defineIndex(DB_NAME, cls, fieldName, isUnique);
}
public static void removeIndex(String dbName, Class<?> cls, String fieldName) {
Properties props = new ZooJdoProperties(dbName);
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
PersistenceManager pm = null;
try {
pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
ZooClass s = ZooJdoHelper.schema(pm).getClass(cls);
s.getField(fieldName).removeIndex();
pm.currentTransaction().commit();
} finally {
safeClose(pmf, pm);
}
}
public static void removeIndex(Class<?> cls, String fieldName) {
removeIndex(DB_NAME, cls, fieldName);
}
/**
* Reflection tool to get direct access to Java fields.
* @param fName
* @param obj
* @return The value of the field. Primitives are auto-boxed into according instances.
*/
public static Object getFieldValue(String fName, Object obj) {
try {
Class<?> cls = obj.getClass();
Field f = cls.getDeclaredField(fName);
f.setAccessible(true);
return f.get(obj);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}