Db4o provides special API which can help you to move classes between packages (Java)/namespaces(.NET), rename classes or fields:
c#:
Db4oFactory.Configure().ObjectClass("package.class").Rename("newPackage.newClass")
Db4oFactory.Configure().ObjectClass("package.class").ObjectField("oldField").Rename("newField")
VB:Db4oFactory.Configure().ObjectClass("package.class").Rename("newPackage.newClass")
Db4oFactory.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 - 2006 db4objects Inc. http://www.db4o.com */ 02
using System; 03
04
namespace Db4objects.Db4odoc.Refactoring 05
{ 06
public class Pilot 07
{ 08
private string _name; 09
10
public Pilot(string name) 11
{ 12
this._name=name; 13
} 14
15
public string Name 16
{ 17
get 18
{ 19
return _name; 20
} 21
set 22
{ 23
_name = value; 24
} 25
} 26
override public string ToString() 27
{ 28
return _name; 29
} 30
} 31
}
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com 02
Imports System 03
04
Namespace Db4objects.Db4odoc.Refactoring 05
Public Class Pilot 06
Private _name As String 07
08
Public Sub New(ByVal name As String) 09
Me._name = name 10
End Sub 11
12
Public Property Name() As String 13
Get 14
Return _name 15
End Get 16
Set(ByVal Value As String) 17
_name = Value 18
End Set 19
End Property 20
Public Overrides Function ToString() As String 21
Return _name 22
End Function 23
End Class 24
End Namespace
and change it to the new class PilotNew renaming field and changing package/namespace at the same time:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
using System; 03
04
namespace Db4objects.Db4odoc.Refactoring 05
{ 06
public class PilotNew 07
{ 08
private string _identity; 09
private int _points; 10
11
public PilotNew(string name, int points) 12
{ 13
_identity = name; 14
_points = points; 15
} 16
17
public string Identity 18
{ 19
get 20
{ 21
return _identity; 22
} 23
} 24
25
override public string ToString() 26
{ 27
return string.Format("{0}/{1}",_identity,_points); 28
} 29
} 30
}
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com 02
Imports System 03
04
Namespace Db4objects.Db4odoc.Refactoring 05
Public Class PilotNew 06
Private _identity As String 07
Private _points As Integer 08
09
Public Sub New(ByVal name As String, ByVal points As Integer) 10
_identity = name 11
_points = points 12
End Sub 13
14
Public ReadOnly Property Identity() As String 15
Get 16
Return _identity 17
End Get 18
End Property 19
20
Public Overrides Function ToString() As String 21
Return String.Format("{0}/{1}", _identity, _points) 22
End Function 23
End Class 24
End Namespace
First let's create a database and fill it with some values:
01public static void SetObjects() 02
{ 03
File.Delete(YapFileName); 04
IObjectContainer oc = Db4oFactory.OpenFile(YapFileName); 05
try 06
{ 07
Pilot pilot = new Pilot("Rubens Barrichello"); 08
oc.Set(pilot); 09
pilot = new Pilot("Michael Schumacher"); 10
oc.Set(pilot); 11
} 12
finally 13
{ 14
oc.Close(); 15
} 16
}
01Public Shared Sub SetObjects() 02
File.Delete(YapFileName) 03
Dim oc As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 04
Try 05
Dim pilot As Pilot = New Pilot("Rubens Barrichello") 06
oc.Set(pilot) 07
pilot = New Pilot("Michael Schumacher") 08
oc.Set(pilot) 09
Finally 10
oc.Close() 11
End Try 12
End Sub
01public static void CheckDB() 02
{ 03
IObjectContainer oc = Db4oFactory.OpenFile(YapFileName); 04
try 05
{ 06
IObjectSet result = oc.Get(typeof(Pilot)); 07
for (int i=0; i< result.Size();i++) 08
{ 09
Pilot pilot = (Pilot)result[i]; 10
System.Console.WriteLine("Pilot="+ pilot); 11
} 12
} 13
finally 14
{ 15
oc.Close(); 16
} 17
}
01Public Shared Sub CheckDB() 02
Dim oc As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03
Try 04
Dim result As IObjectSet = oc.Get(GetType(Pilot)) 05
Dim i As Integer 06
For i = 0 To result.Size() - 1 Step i + 1 07
Dim pilot As Pilot = CType(result(i), Pilot) 08
System.Console.WriteLine("Pilot=" + pilot.ToString()) 09
Next 10
Finally 11
oc.Close() 12
End Try 13
End Sub
We already have PilotNew class so we can go on with renaming:
1public static void ChangeClass() 2
{ 3
Db4oFactory.Configure().ObjectClass(typeof(Pilot)).Rename("Db4objects.Db4odoc.Refactoring.PilotNew, db4o-reference-chapters"); 4
Db4oFactory.Configure().ObjectClass(typeof(PilotNew)).ObjectField("_name").Rename("_identity"); 5
IObjectContainer oc = Db4oFactory.OpenFile(YapFileName); 6
oc.Close(); 7
}
1Public Shared Sub ChangeClass() 2
Db4oFactory.Configure().ObjectClass(GetType(Pilot)).Rename("Db4objects.Db4odoc.Refactoring.PilotNew, Db4objects.Db4odoc") 3
Db4oFactory.Configure().ObjectClass(GetType(PilotNew)).ObjectField("_name").Rename("_identity") 4
Dim oc As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 5
oc.Close() 6
End Sub
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:
01public static void SetNewObjects() 02
{ 03
IObjectContainer oc = Db4oFactory.OpenFile(YapFileName); 04
try 05
{ 06
PilotNew pilot = new PilotNew("Rubens Barrichello",99); 07
oc.Set(pilot); 08
pilot = new PilotNew("Michael Schumacher",100); 09
oc.Set(pilot); 10
} 11
finally 12
{ 13
oc.Close(); 14
} 15
}
01Public Shared Sub SetNewObjects() 02
Dim oc As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03
Try 04
Dim pilot As PilotNew = New PilotNew("Rubens Barrichello", 99) 05
oc.Set(pilot) 06
pilot = New PilotNew("Michael Schumacher", 100) 07
oc.Set(pilot) 08
Finally 09
oc.Close() 10
End Try 11
End Sub
We can check what is stored in the database now:
01public static void RetrievePilotNew() 02
{ 03
IObjectContainer oc = Db4oFactory.OpenFile(YapFileName); 04
try 05
{ 06
IQuery q = oc.Query(); 07
q.Constrain(typeof(PilotNew)); 08
IObjectSet result = q.Execute(); 09
for (int i=0; i< result.Size();i++) 10
{ 11
PilotNew pilot = (PilotNew)result[i]; 12
System.Console.WriteLine("Pilot="+ pilot); 13
} 14
} 15
finally 16
{ 17
oc.Close(); 18
} 19
}
01Public Shared Sub RetrievePilotNew() 02
Dim oc As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03
Try 04
Dim q As IQuery = oc.Query() 05
q.Constrain(GetType(PilotNew)) 06
Dim result As IObjectSet = q.Execute() 07
Dim i As Integer 08
For i = 0 To result.Size() - 1 Step i + 1 09
Dim pilot As PilotNew = CType(result(i), PilotNew) 10
System.Console.WriteLine("Pilot=" + pilot.ToString()) 11
Next 12
Finally 13
oc.Close() 14
End Try 15
End Sub
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.