
org.zoodb.tools.ZooCompareDb Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parent Show documentation
Show all versions of parent Show documentation
ZooDB Java JDO Object Database.
The newest version!
/*
* Copyright 2009-2013 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 .
*
* See the README and COPYING files for further information.
*/
package org.zoodb.tools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import org.zoodb.jdo.api.ZooClass;
import org.zoodb.jdo.api.ZooField;
import org.zoodb.jdo.api.ZooHandle;
import org.zoodb.jdo.api.ZooJdoProperties;
import org.zoodb.jdo.api.ZooSchema;
import org.zoodb.jdo.internal.util.Util;
public class ZooCompareDb {
private static boolean logToConsole = false;
private static StringBuilder out;
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Error: Please provide two databases.");
System.out.println("Usage: ");
System.out.println(" ZooCompareDb ");
}
String db1 = args[0];
String db2 = args[1];
if (!ZooHelper.getDataStoreManager().dbExists(db1)) {
System.err.println("ERROR Database not found: " + db1);
return;
}
if (!ZooHelper.getDataStoreManager().dbExists(db2)) {
System.err.println("ERROR Database not found: " + db2);
return;
}
System.out.println("Checking databases: " + db1 + " <--> " + db2);
run(db1, db2);
System.out.println("Comparing databases finished.");
}
public static String run(String db1, String db2) {
PersistenceManager pm1 = null;
PersistenceManager pm2 = null;
try {
out = new StringBuilder(); //do this only here for repeated calls from tests
ZooJdoProperties props1 = new ZooJdoProperties(db1);
PersistenceManagerFactory pmf1 = JDOHelper.getPersistenceManagerFactory(props1);
pm1 = pmf1.getPersistenceManager();
pm1.currentTransaction().begin();
ZooJdoProperties props2 = new ZooJdoProperties(db2);
PersistenceManagerFactory pmf2 = JDOHelper.getPersistenceManagerFactory(props2);
pm2 = pmf2.getPersistenceManager();
pm2.currentTransaction().begin();
List commonClasses = compareClasses(pm1, pm2);
compareInstances(pm1, pm2, commonClasses);
return out.toString();
} finally {
if (pm1 != null) {
pm1.currentTransaction().rollback();
pm1.close();
}
if (pm2 != null) {
pm2.currentTransaction().rollback();
pm2.close();
}
}
}
private static List compareClasses(PersistenceManager pm1, PersistenceManager pm2) {
//List of classes that are identical in both databases
List commonClasses = new ArrayList();
for (ZooClass cls1: ZooSchema.locateAllClasses(pm1)) {
boolean isValid = true;
if (cls1.getName().contains("ZooClass")) {
isValid = false;
continue;
}
ZooClass cls2 = ZooSchema.locateClass(pm2, cls1.getName());
if (cls2 == null) {
log("Class not found in db2: " + cls1);
isValid = false;
continue;
}
for (ZooField f1: cls1.getAllFields()) {
ZooField f2 = cls2.getField(f1.getName());
if (f2 == null) {
log("Class field not found in db2: " + cls1.getName() + "." + f1.getName());
isValid = false;
continue;
}
if (!f1.getTypeName().equals(f2.getTypeName())) {
log("Class field type differ for: " + cls1.getName() + "." + f1.getName() +
" " + f1.getTypeName() + " vs " + f2.getTypeName());
isValid = false;
continue;
}
}
for (ZooField f2: cls2.getAllFields()) {
ZooField f1 = cls1.getField(f2.getName());
if (f1 == null) {
log("Class field not found in db1: " + cls1.getName() + "." + f2.getName());
isValid = false;
continue;
}
}
if (isValid) {
commonClasses.add(cls1);
}
}
for (ZooClass cls2: ZooSchema.locateAllClasses(pm2)) {
if (cls2.getName().contains("ZooClass")) {
continue;
}
ZooClass cls1 = ZooSchema.locateClass(pm1, cls2.getName());
if (cls1 == null) {
log("Class not found in db1: " + cls2);
continue;
}
}
return commonClasses;
}
private static void compareInstances(PersistenceManager pm1,
PersistenceManager pm2, List commonClasses) {
for (ZooClass cls1: commonClasses) {
ZooClass cls2 = ZooSchema.locateClass(pm2, cls1.getName());
Iterator i1 = cls1.getHandleIterator(false);
while (i1.hasNext()) {
ZooHandle hdl1 = i1.next();
ZooHandle hdl2 = ZooSchema.getHandle(pm2, hdl1.getOid());
if (hdl2 == null) {
log("Object not found in db2: " + Util.oidToString(hdl1.getOid()) + " " + cls1);
continue;
}
//compare object type
if (!hdl1.getType().getName().equals(hdl2.getType().getName())) {
log("Object has different classes: " + Util.oidToString(hdl1.getOid()) +
" " + cls1 + " vs " + hdl2.getType());
continue;
}
//compare object data
for (ZooField f1: cls1.getAllFields()) {
ZooField f2 = cls2.getField(f1.getName());
Object v1 = f1.getValue(hdl1);
Object v2 = f2.getValue(hdl2);
if (v1 == v2) {
//e.g. null
continue;
}
if (v1.getClass() != v2.getClass()) {
//For arrays this also covers dimensions and inner type
log("Field value has different type: " + Util.oidToString(hdl1.getOid()) +
" " + cls1 + "." + f1.getName() + ": " +
v1.getClass() + " vs " + v1.getClass());
continue;
}
if (v1.getClass().isArray() && arrayEquals(v1, v2)) {
continue;
}
if ((v1 == null && v2 != null) || !v1.equals(v2)) {
log("Field has different values: " + Util.oidToString(hdl1.getOid()) +
" " + cls1 + "." + f1.getName() + ": " +
f1.getValue(hdl1) + " vs " + f2.getValue(hdl2));
continue;
}
}
}
}
//reverse check
for (ZooClass cls1: commonClasses) {
ZooClass cls2 = ZooSchema.locateClass(pm2, cls1.getName());
Iterator i2 = cls2.getHandleIterator(false);
while (i2.hasNext()) {
ZooHandle hdl2 = i2.next();
ZooHandle hdl1 = ZooSchema.getHandle(pm1, hdl2.getOid());
if (hdl1 == null) {
log("Object not found in db1: " + Util.oidToString(hdl2.getOid()) + " " + cls2);
continue;
}
}
}
}
private static boolean arrayEquals(Object v1, Object v2) {
if (v1.getClass().getComponentType() == Boolean.TYPE) {
return Arrays.equals((boolean[])v1, (boolean[])v2);
}
if (v1.getClass().getComponentType() == Byte.TYPE) {
return Arrays.equals((byte[])v1, (byte[])v2);
}
if (v1.getClass().getComponentType() == Character.TYPE) {
return Arrays.equals((char[])v1, (char[])v2);
}
if (v1.getClass().getComponentType() == Double.TYPE) {
return Arrays.equals((double[])v1, (double[])v2);
}
if (v1.getClass().getComponentType() == Float.TYPE) {
return Arrays.equals((float[])v1, (float[])v2);
}
if (v1.getClass().getComponentType() == Integer.TYPE) {
return Arrays.equals((int[])v1, (int[])v2);
}
if (v1.getClass().getComponentType() == Long.TYPE) {
return Arrays.equals((long[])v1, (long[])v2);
}
if (v1.getClass().getComponentType() == Short.TYPE) {
return Arrays.equals((short[])v1, (short[])v2);
}
return Arrays.deepEquals((Object[])v1, (Object[])v2);
}
private static void log(String s) {
if (logToConsole) {
System.out.println(s);
} else {
out.append(s + '\n');
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy