Field type change

The reviewed refactoring types are fairly easy. It gets more difficult when you need to change a field's type.

If you modify a field's type, db4o internally creates a new field of the same name, but with the new type. The values of the old typed field are still present, but hidden. If you will change the type back to the old type the old values will still be there.

You can access the values of the previous field data using StoredField API.

c#:

IStoredClass#StoredField(name, type)

VB:

IStoredClass#StoredField(name, type)

gives you access to the field, which type was changed.

c#:

IStoredField#Get(Object)

VB:

IStoredField#Get(Object)

allows you to get the old field value for the specified object.

To see how it works on example, let's change Pilot's field name from type string to type Identity:

Identity.cs
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02namespace Db4objects.Db4odoc.Refactoring.NewClasses 03{ 04 public class Identity 05 { 06 private string _name; 07 private string _id; 08 09 public Identity(string name, string id) 10 { 11 _name = name; 12 _id = id; 13 } 14 15 public string Name 16 { 17 get 18 { 19 return _name; 20 } 21 set 22 { 23 _name=value; 24 } 25 } 26 27 28 public override string ToString() 29 { 30 return string.Format("{0}[{1}]", _name, _id); 31 } 32 } 33}
Identity.vb
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02Imports System 03 04Namespace Db4objects.Db4odoc.Refactoring.Newclasses 05 Public Class Identity 06 Private _name As String 07 Private _id As String 08 09 Public Sub New(ByVal name As String, ByVal id As String) 10 _name = name 11 _id = id 12 End Sub 13 14 Public Property Name() As String 15 Get 16 Return _name 17 End Get 18 Set(ByVal Value As String) 19 _name = Value 20 End Set 21 End Property 22 23 24 Public Overloads Overrides Function ToString() As String 25 Return String.Format("{0}[{1}]", _name, _id) 26 End Function 27 End Class 28End Namespace

Now to access old "name" values and transfer them to the new "name" we can use the following procedure:

RefactoringExample.cs: TransferValues
01private static void TransferValues() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 04 try 05 { 06 IStoredClass sc = container.Ext().StoredClass(typeof(Pilot)); 07 System.Console.WriteLine("Stored class: "+ sc.ToString()); 08 IStoredField sfOld = sc.StoredField("_name",typeof(string)); 09 System.Console.WriteLine("Old field: "+ sfOld.ToString()+";"+sfOld.GetStoredType()); 10 IQuery q = container.Query(); 11 q.Constrain(typeof(Pilot)); 12 IObjectSet result = q.Execute(); 13 foreach (object obj in result) 14 { 15 Pilot pilot = (Pilot)obj; 16 pilot.Name = new Identity(sfOld.Get(pilot).ToString(),""); 17 System.Console.WriteLine("Pilot="+ pilot); 18 container.Set(pilot); 19 } 20 } 21 finally 22 { 23 container.Close(); 24 } 25 }

RefactoringExample.vb: TransferValues
01Private Shared Sub TransferValues() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03 Try 04 Dim sc As IStoredClass = container.Ext().StoredClass(GetType(Pilot)) 05 System.Console.WriteLine("Stored class: " + sc.GetName()) 06 Dim sfOld As IStoredField = sc.StoredField("_name", GetType(String)) 07 System.Console.WriteLine("Old field: " + sfOld.GetName() + ";" + sfOld.GetStoredType().GetName()) 08 Dim q As IQuery = container.Query() 09 q.Constrain(GetType(Pilot)) 10 Dim result As IObjectSet = q.Execute() 11 Dim obj As Object 12 For Each obj In result 13 Dim pilot As Pilot = CType(obj, Pilot) 14 pilot.Name = New Identity(sfOld.Get(pilot).ToString(), "") 15 System.Console.WriteLine("Pilot=" + pilot.ToString()) 16 container.Set(pilot) 17 Next 18 Finally 19 container.Close() 20 End Try 21 End Sub

These are the basic refactoring types, which can help with any changes you will need to make.