db4o's default policy is to never do any damage to stored data. When you change the type of a field, db4o will not update the data in this field. Instead db4o internally creates a new field of the same name, but with the new type. For existing object, the values of the old typed field are still present, but hidden. Of course you can access the old data. When you want to convert the content from the old field type to the new field type, you have to do it yourself.
You can use the stored-class API to retrieve the data of the old typed field. An example: We decide that we want to refactor the id-field from a simple int to a special identity-class. First we change the field-type:
public Identity id = Identity.NewId(); // was an int previously: // public int id = new Random().nextInt();
Public m_id As Identity = Identity.NewId() ' was an int previously: ' public int id = new Random().nextInt();
After than read the old value from the old field-type and convert it to the new type:
using (IObjectContainer container = Db4oEmbedded.OpenFile("database.db4o"))
{
// first get all objects which should be updated
IList<Person> persons = container.Query<Person>();
foreach (Person person in persons)
{
// get the database-meta data about this object-type
IStoredClass dbClass = container.Ext().StoredClass(person);
// get the old field which was an int-type
IStoredField oldField = dbClass.StoredField("id", typeof (int));
if(null!=oldField)
{
// Access the old data and copy it to the new field!
Object oldValue = oldField.Get(person);
if (null != oldValue)
{
person.id = new Identity((int)oldValue);
container.Store(person);
}
}
}
}
Using container As IObjectContainer = Db4oEmbedded.OpenFile("database.db4o")
' first get all objects which should be updated
Dim persons As IList(Of Person) = container.Query(Of Person)()
For Each person As Person In persons
' get the database-meta data about this object-type
Dim dbClass As IStoredClass = container.Ext().StoredClass(person)
' get the old field which was an int-type
Dim oldField As IStoredField = dbClass.StoredField("id", GetType(Integer))
If oldField IsNot Nothing Then
' Access the old data and copy it to the new field!
Dim oldValue As [Object] = oldField.[Get](person)
If oldValue IsNot Nothing Then
person.id = New Identity(CInt(oldValue))
container.Store(person)
End If
End If
Next
End Using
db4o's approach gives you the maximum flexibility for refactoring field types. You can handle the convertion with regular code, which means it can be as complex as needed. Furthermore you can decide when you convert the values. You can update all objects in one operation, you can dynamically update and covert when you access a object or even decide not to convert the old values.