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.