Db4o provides special API which can help you to move classes between packages (Java)/namespaces(.NET), rename classes or fields:
Java:
Db4o.configure().objectClass("package.class").rename("newPackage.newClass")
Db4o.configure().objectClass("package.class").objectField("oldField").rename("newField")
The safe order of actions for rename calls is:
After that you will only see the new classes/fields in ObjectManager, the old ones will be gone.
Let's look how it works on an example. We will use initial class Pilot:
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02
03
package com.db4odoc.refactoring; 04
05
public class Pilot { 06
private String name; 07
08
public Pilot(String name) { 09
this.name = name; 10
} 11
12
public String getName() { 13
return name; 14
} 15
16
public String toString() { 17
return name; 18
} 19
}
and change it to the new class PilotNew renaming field and changing package/namespace at the same time:
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02
03
package com.db4odoc.refactoring; 04
05
public class PilotNew { 06
private String identity; 07
08
private int points; 09
10
public PilotNew(String name, int points) { 11
this.identity = name; 12
this.points = points; 13
} 14
15
public String getIdentity() { 16
return identity; 17
} 18
19
public String toString() { 20
return identity + "/" + points; 21
} 22
}
First let's create a database and fill it with some values:
01private static void setObjects(){ 02
new File(DB4O_FILE_NAME).delete(); 03
ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 04
try { 05
Pilot pilot = new Pilot("Rubens Barrichello"); 06
container.set(pilot); 07
pilot = new Pilot("Michael Schumacher"); 08
container.set(pilot); 09
} finally { 10
container.close(); 11
} 12
}
1private static void checkDB(){ 2
ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 3
try { 4
ObjectSet result=container.get(new Object()); 5
listResult(result); 6
} finally { 7
container.close(); 8
} 9
}
We already have PilotNew class so we can go on with renaming:
1private static void changeClass(){ 2
Configuration configuration = Db4o.newConfiguration(); 3
configuration.objectClass(Pilot.class).rename("com.db4odoc.f1.refactoring.PilotNew"); 4
configuration.objectClass(PilotNew.class).objectField("name").rename("identity"); 5
ObjectContainer container = Db4o.openFile(configuration, DB4O_FILE_NAME); 6
container.close(); 7
}
Now the data for the old Pilot class should be transferred to the new PilotNew class, and "name" field data should be stored in "identity" field.
To make our check more complicated let's add some data for our new class:
01private static void setNewObjects(){ 02
ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 03
try { 04
PilotNew pilot = new PilotNew("Rubens Barrichello",99); 05
container.set(pilot); 06
pilot = new PilotNew("Michael Schumacher",100); 07
container.set(pilot); 08
} finally { 09
container.close(); 10
} 11
}
We can check what is stored in the database now:
1private static void retrievePilotNew(){ 2
ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 3
try { 4
ObjectSet result = container.query(PilotNew.class); 5
listResult(result); 6
} finally { 7
container.close(); 8
} 9
}
There is one thing to remember. The rename feature is intended to rename a class from one name to the other. Internally this will rename the meta-information. If you will try to rename class to the name that is already stored in the database, the renaming will fail, because the name is reserved. In our example it will happen if setNewObjects method will be called before changeClass.