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 - 2007 db4objects Inc. http://www.db4o.com */ 02
namespace Db4objects.Db4odoc.Refactoring 03
{ 04
public class Pilot 05
{ 06
private string _name; 07
08
public Pilot(string name) 09
{ 10
this._name=name; 11
} 12
13
public string Name 14
{ 15
get 16
{ 17
return _name; 18
} 19
set 20
{ 21
_name = value; 22
} 23
} 24
override public string ToString() 25
{ 26
return _name; 27
} 28
} 29
}
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02
Namespace Db4objects.Db4odoc.Refactoring 03
Public Class Pilot 04
Private _name As String 05
06
Public Sub New(ByVal name As String) 07
Me._name = name 08
End Sub 09
10
Public Property Name() As String 11
Get 12
Return _name 13
End Get 14
Set(ByVal Value As String) 15
_name = Value 16
End Set 17
End Property 18
Public Overrides Function ToString() As String 19
Return _name 20
End Function 21
End Class 22
End Namespace
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
namespace Db4objects.Db4odoc.Refactoring 03
{ 04
public class PilotNew 05
{ 06
private string _identity; 07
private int _points; 08
09
public PilotNew(string name, int points) 10
{ 11
_identity = name; 12
_points = points; 13
} 14
15
public string Identity 16
{ 17
get 18
{ 19
return _identity; 20
} 21
} 22
23
override public string ToString() 24
{ 25
return string.Format("{0}/{1}",_identity,_points); 26
} 27
} 28
}
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02
Namespace Db4objects.Db4odoc.Refactoring 03
Public Class PilotNew 04
Private _identity As String 05
Private _points As Integer 06
07
Public Sub New(ByVal name As String, ByVal points As Integer) 08
_identity = name 09
_points = points 10
End Sub 11
12
Public ReadOnly Property Identity() As String 13
Get 14
Return _identity 15
End Get 16
End Property 17
18
Public Overrides Function ToString() As String 19
Return String.Format("{0}/{1}", _identity, _points) 20
End Function 21
End Class 22
End Namespace
First let's create a database and fill it with some values:
01private static void SetObjects() 02
{ 03
File.Delete(Db4oFileName); 04
IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 05
try 06
{ 07
Pilot pilot = new Pilot("Rubens Barrichello"); 08
container.Set(pilot); 09
pilot = new Pilot("Michael Schumacher"); 10
container.Set(pilot); 11
} 12
finally 13
{ 14
container.Close(); 15
} 16
}
01Private Shared Sub SetObjects() 02
File.Delete(Db4oFileName) 03
Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04
Try 05
Dim pilot As 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
End Try 12
End Sub
01private static void CheckDB() 02
{ 03
IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04
try 05
{ 06
IObjectSet result = container.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
container.Close(); 16
} 17
}
01Private Shared Sub CheckDB() 02
Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03
Try 04
Dim result As IObjectSet = container.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
container.Close() 12
End Try 13
End Sub
We already have PilotNew class so we can go on with renaming:
1private static void ChangeClass() 2
{ 3
IConfiguration configuration = Db4oFactory.NewConfiguration(); 4
configuration.ObjectClass(typeof(Pilot)).Rename("Db4objects.Db4odoc.Refactoring.PilotNew, Db4objects.Db4odoc"); 5
configuration.ObjectClass(typeof(PilotNew)).ObjectField("_name").Rename("_identity"); 6
IObjectContainer container = Db4oFactory.OpenFile(configuration, Db4oFileName); 7
container.Close(); 8
}
1Private Shared Sub ChangeClass() 2
Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 3
configuration.ObjectClass(GetType(Pilot)).Rename("Db4objects.Db4odoc.Refactoring.PilotNew, Db4objects.Db4odoc") 4
configuration.ObjectClass(GetType(PilotNew)).ObjectField("_name").Rename("_identity") 5
Dim container As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 6
container.Close() 7
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:
01private static void SetNewObjects() 02
{ 03
IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04
try 05
{ 06
PilotNew pilot = new PilotNew("Rubens Barrichello",99); 07
container.Set(pilot); 08
pilot = new PilotNew("Michael Schumacher",100); 09
container.Set(pilot); 10
} 11
finally 12
{ 13
container.Close(); 14
} 15
}
01Private Shared Sub SetNewObjects() 02
Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03
Try 04
Dim pilot As PilotNew = 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
End Try 11
End Sub
We can check what is stored in the database now:
01private static void RetrievePilotNew() 02
{ 03
IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04
try 05
{ 06
IQuery q = container.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
container.Close(); 18
} 19
}
01Private Shared Sub RetrievePilotNew() 02
Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03
Try 04
Dim q As IQuery = container.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
container.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.