Static fields API

By default db4o does not persist static fields. Normally this is not necessary as static values are set for a class, not for an object. However you can set up db4o to store static fields if you need to implement constant or enumeration:

c#: Db4oFactory.Configure().ObjectClass(typeof(Foo)).PersistStaticFieldValues()

VB: Db4oFactory.Configure().ObjectClass(GetType(Foo)).PersistStaticFieldValues()

Do not use this option unnecessarily, as it will slow down the process of opening database files and the stored objects will occupy space in the database file.

This option does not have any eaffect on primitive types (int, boolean, etc). Use their object alternatives instead (Integer, Boolean, etc).

When this setting is on for a specific class, all non-primitive-typed static field values of this class are stored the first time an object of the class is stored, and restored, every time a database file is opened afterwards, after class meta information is loaded for this class (when the class objects are retrieved with a query, for example).

A good example of non-primitive constant type is type-safe enumeration implementation:

PilotCategories.cs
01using System; 02 03namespace Db4objects.Db4odoc.StaticFields 04{ 05 public class PilotCategories 06 { 07 private string _qualification = null; 08 public static PilotCategories WINNER=new PilotCategories("WINNER"); 09 public static PilotCategories TALENTED=new PilotCategories("TALENTED"); 10 public static PilotCategories AVERAGE=new PilotCategories("AVERAGE"); 11 public static PilotCategories DISQUALIFIED=new PilotCategories("DISQUALIFIED"); 12 13 private PilotCategories(String qualification) 14 { 15 this._qualification = qualification; 16 } 17 18 public PilotCategories() 19 { 20 21 } 22 23 public void TestChange(String qualification) 24 { 25 this._qualification = qualification; 26 } 27 28 override public string ToString() 29 { 30 return _qualification; 31 } 32 } 33}

PilotCategories.vb
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com 02Imports System 03 04Namespace Db4objects.Db4odoc.StaticFields 05 Public Class PilotCategories 06 Private _qualification As String = Nothing 07 Public Shared WINNER As PilotCategories = New PilotCategories("WINNER") 08 Public Shared TALENTED As PilotCategories = New PilotCategories("TALENTED") 09 Public Shared AVERAGE As PilotCategories = New PilotCategories("AVERAGE") 10 Public Shared DISQUALIFIED As PilotCategories = New PilotCategories("DISQUALIFIED") 11 12 Private Sub New(ByVal qualification As String) 13 Me._qualification = qualification 14 End Sub 15 16 Public Sub New() 17 18 End Sub 19 20 Public Sub TestChange(ByVal qualification As String) 21 Me._qualification = qualification 22 End Sub 23 24 Public Overrides Function ToString() As String 25 Return _qualification 26 End Function 27 End Class 28End Namespace

Let's use it with

Pilot.cs
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02using System; 03 04namespace Db4objects.Db4odoc.StaticFields 05{ 06 public class Pilot 07 { 08 private String _name; 09 private PilotCategories _category; 10 11 public Pilot(String name,PilotCategories category) 12 { 13 this._name=name; 14 this._category=category; 15 } 16 17 public PilotCategories Category 18 { 19 get 20 { 21 return _category; 22 } 23 } 24 25 public String Name 26 { 27 get 28 { 29 return _name; 30 } 31 } 32 33 override public string ToString() 34 { 35 return string.Format("{0}/{1}", _name, _category); 36 } 37 } 38}

Pilot.vb
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com 02Imports System 03 04Namespace Db4objects.Db4odoc.StaticFields 05 Public Class Pilot 06 Private _name As String 07 Private _category As PilotCategories 08 09 Public Sub New(ByVal name As String, ByVal Category As PilotCategories) 10 Me._name = name 11 Me._category = Category 12 End Sub 13 14 Public ReadOnly Property Category() As PilotCategories 15 Get 16 Return _category 17 End Get 18 End Property 19 20 Public ReadOnly Property Name() As String 21 Get 22 Return _name 23 End Get 24 End Property 25 26 Public Overrides Function ToString() As String 27 Return String.Format("{0}/{1}", _name, _category) 28 End Function 29 End Class 30End Namespace

StaticFieldExample.cs: SetPilotsSimple
01public static void SetPilotsSimple() 02 { 03 Console.WriteLine("In the default setting, static constants are not continously stored and updated."); 04 File.Delete(YapFileName); 05 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 06 try 07 { 08 db.Set(new Pilot("Michael Schumacher",PilotCategories.WINNER)); 09 db.Set(new Pilot("Rubens Barrichello",PilotCategories.TALENTED)); 10 } 11 finally 12 { 13 db.Close(); 14 } 15 }

StaticFieldExample.vb: SetPilotsSimple
01Public Shared Sub SetPilotsSimple() 02 Console.WriteLine("In the default setting, static constants are not continously stored and updated.") 03 File.Delete(YapFileName) 04 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 05 Try 06 db.Set(New Pilot("Michael Schumacher", PilotCategories.WINNER)) 07 db.Set(New Pilot("Rubens Barrichello", PilotCategories.TALENTED)) 08 Finally 09 db.Close() 10 End Try 11 End Sub

We can try to save pilots with the default db4o settings:

StaticFieldExample.cs: CheckPilots
01public static void CheckPilots() 02 { 03 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 04 try 05 { 06 IObjectSet result = db.Get(typeof(Pilot)); 07 for(int x = 0; x < result.Count; x++) 08 { 09 Pilot pilot = (Pilot )result[x]; 10 if (pilot.Category == PilotCategories.WINNER) 11 { 12 Console.WriteLine("Winner pilot: " + pilot); 13 } 14 else if (pilot.Category == PilotCategories.TALENTED) 15 { 16 Console.WriteLine("Talented pilot: " + pilot); 17 } 18 else 19 { 20 Console.WriteLine("Uncategorized pilot: " + pilot); 21 } 22 } 23 } 24 finally 25 { 26 db.Close(); 27 } 28 }

StaticFieldExample.vb: CheckPilots
01Public Shared Sub CheckPilots() 02 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03 Try 04 Dim result As IObjectSet = db.Get(GetType(Pilot)) 05 Dim x As Integer 06 For x = 0 To result.Count - 1 Step x + 1 07 Dim pilot As Pilot = CType(result(x), Pilot) 08 If pilot.Category Is PilotCategories.WINNER Then 09 Console.WriteLine("Winner pilot: " + pilot.ToString()) 10 ElseIf pilot.Category Is PilotCategories.TALENTED Then 11 Console.WriteLine("Talented pilot: " + pilot.ToString()) 12 Else 13 Console.WriteLine("Uncategorized pilot: " + pilot.ToString()) 14 End If 15 Next 16 Finally 17 db.Close() 18 End Try 19 End Sub

That does not work however. We will have to explicitly point out, which class's static fields we want to save:

StaticFieldExample.cs: SetPilotsStatic
01public static void SetPilotsStatic() 02 { 03 Console.WriteLine("The feature can be turned on for individual classes."); 04 Db4oFactory.Configure().ObjectClass(typeof(PilotCategories)).PersistStaticFieldValues(); 05 File.Delete(YapFileName); 06 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 07 try 08 { 09 db.Set(new Pilot("Michael Schumacher",PilotCategories.WINNER)); 10 db.Set(new Pilot("Rubens Barrichello",PilotCategories.TALENTED)); 11 } 12 finally 13 { 14 db.Close(); 15 } 16 }

StaticFieldExample.vb: SetPilotsStatic
01Public Shared Sub SetPilotsStatic() 02 Console.WriteLine("The feature can be turned on for individual classes.") 03 Db4oFactory.Configure().ObjectClass(GetType(PilotCategories)).PersistStaticFieldValues() 04 File.Delete(YapFileName) 05 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 06 Try 07 db.Set(New Pilot("Michael Schumacher", PilotCategories.WINNER)) 08 db.Set(New Pilot("Rubens Barrichello", PilotCategories.TALENTED)) 09 Finally 10 db.Close() 11 End Try 12 End Sub

StaticFieldExample.cs: CheckPilots
01public static void CheckPilots() 02 { 03 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 04 try 05 { 06 IObjectSet result = db.Get(typeof(Pilot)); 07 for(int x = 0; x < result.Count; x++) 08 { 09 Pilot pilot = (Pilot )result[x]; 10 if (pilot.Category == PilotCategories.WINNER) 11 { 12 Console.WriteLine("Winner pilot: " + pilot); 13 } 14 else if (pilot.Category == PilotCategories.TALENTED) 15 { 16 Console.WriteLine("Talented pilot: " + pilot); 17 } 18 else 19 { 20 Console.WriteLine("Uncategorized pilot: " + pilot); 21 } 22 } 23 } 24 finally 25 { 26 db.Close(); 27 } 28 }

StaticFieldExample.vb: CheckPilots
01Public Shared Sub CheckPilots() 02 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03 Try 04 Dim result As IObjectSet = db.Get(GetType(Pilot)) 05 Dim x As Integer 06 For x = 0 To result.Count - 1 Step x + 1 07 Dim pilot As Pilot = CType(result(x), Pilot) 08 If pilot.Category Is PilotCategories.WINNER Then 09 Console.WriteLine("Winner pilot: " + pilot.ToString()) 10 ElseIf pilot.Category Is PilotCategories.TALENTED Then 11 Console.WriteLine("Talented pilot: " + pilot.ToString()) 12 Else 13 Console.WriteLine("Uncategorized pilot: " + pilot.ToString()) 14 End If 15 Next 16 Finally 17 db.Close() 18 End Try 19 End Sub

As it was mentioned before, it is important to keep static values in one place and do not allow different objects to modify them. If we try to change static value from the referencing object:

StaticFieldExample.cs: UpdatePilots
01public static void UpdatePilots() 02 { 03 Console.WriteLine("Updating PilotCategory in pilot reference:"); 04 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 05 try 06 { 07 IObjectSet result = db.Get(typeof(Pilot)); 08 for(int x = 0; x < result.Count; x++) 09 { 10 Pilot pilot = (Pilot )result[x]; 11 if (pilot.Category == PilotCategories.WINNER) 12 { 13 Console.WriteLine("Winner pilot: " + pilot); 14 PilotCategories pc = pilot.Category; 15 pc.TestChange("WINNER2006"); 16 db.Set(pilot); 17 } 18 } 19 } 20 finally 21 { 22 db.Close(); 23 } 24 PrintCategories(); 25 }

StaticFieldExample.vb: UpdatePilots
01Public Shared Sub UpdatePilots() 02 Console.WriteLine("Updating PilotCategory in pilot reference:") 03 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 04 Try 05 Dim result As IObjectSet = db.Get(GetType(Pilot)) 06 Dim x As Integer 07 For x = 0 To result.Count - 1 Step x + 1 08 Dim pilot As Pilot = CType(result(x), Pilot) 09 If pilot.Category Is PilotCategories.WINNER Then 10 Console.WriteLine("Winner pilot: " + pilot.ToString()) 11 Dim pc As PilotCategories = pilot.Category 12 pc.TestChange("WINNER2006") 13 db.Set(pilot) 14 End If 15 Next 16 Finally 17 db.Close() 18 End Try 19 PrintCategories() 20 End Sub

the value just does not change.

In order to update static field we will have to do that explicitly:

StaticFieldExample.cs: UpdatePilotCategories
01public static void UpdatePilotCategories() 02 { 03 Console.WriteLine("Updating PilotCategories explicitly:"); 04 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 05 try 06 { 07 IObjectSet result = db.Get(typeof(PilotCategories)); 08 for(int x = 0; x < result.Count; x++) 09 { 10 PilotCategories pc = (PilotCategories)result[x]; 11 if (pc == PilotCategories.WINNER) 12 { 13 pc.TestChange("WINNER2006"); 14 db.Set(pc); 15 } 16 } 17 } 18 finally 19 { 20 db.Close(); 21 } 22 PrintCategories(); 23 }

StaticFieldExample.vb: UpdatePilotCategories
01Public Shared Sub UpdatePilotCategories() 02 Console.WriteLine("Updating PilotCategories explicitly:") 03 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 04 Try 05 Dim result As IObjectSet = db.Get(GetType(PilotCategories)) 06 Dim x As Integer 07 For x = 0 To result.Count - 1 Step x + 1 08 Dim pc As PilotCategories = CType(result(x), PilotCategories) 09 If pc Is PilotCategories.WINNER Then 10 pc.TestChange("WINNER2006") 11 db.Set(pc) 12 End If 13 Next 14 Finally 15 db.Close() 16 End Try 17 PrintCategories() 18 End Sub

StaticFieldExample.cs: CheckPilots
01public static void CheckPilots() 02 { 03 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 04 try 05 { 06 IObjectSet result = db.Get(typeof(Pilot)); 07 for(int x = 0; x < result.Count; x++) 08 { 09 Pilot pilot = (Pilot )result[x]; 10 if (pilot.Category == PilotCategories.WINNER) 11 { 12 Console.WriteLine("Winner pilot: " + pilot); 13 } 14 else if (pilot.Category == PilotCategories.TALENTED) 15 { 16 Console.WriteLine("Talented pilot: " + pilot); 17 } 18 else 19 { 20 Console.WriteLine("Uncategorized pilot: " + pilot); 21 } 22 } 23 } 24 finally 25 { 26 db.Close(); 27 } 28 }

StaticFieldExample.vb: CheckPilots
01Public Shared Sub CheckPilots() 02 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03 Try 04 Dim result As IObjectSet = db.Get(GetType(Pilot)) 05 Dim x As Integer 06 For x = 0 To result.Count - 1 Step x + 1 07 Dim pilot As Pilot = CType(result(x), Pilot) 08 If pilot.Category Is PilotCategories.WINNER Then 09 Console.WriteLine("Winner pilot: " + pilot.ToString()) 10 ElseIf pilot.Category Is PilotCategories.TALENTED Then 11 Console.WriteLine("Talented pilot: " + pilot.ToString()) 12 Else 13 Console.WriteLine("Uncategorized pilot: " + pilot.ToString()) 14 End If 15 Next 16 Finally 17 db.Close() 18 End Try 19 End Sub

We can see that the reference has changed correctly.

What about deletion? Nothing is new here. We can delete static fields from the referenced object, or directly from the database:

StaticFieldExample.cs: DeleteTest
01public static void DeleteTest() 02 { 03 IObjectContainer db=Db4oFactory.OpenFile(YapFileName); 04 db.Ext().Configure().ObjectClass(typeof(Pilot)).CascadeOnDelete(true); 05 try 06 { 07 Console.WriteLine("Deleting Pilots :"); 08 IObjectSet result = db.Get(typeof(Pilot)); 09 for(int x = 0; x < result.Count; x++) 10 { 11 Pilot pilot = (Pilot )result[x]; 12 db.Delete(pilot); 13 } 14 PrintCategories(); 15 Console.WriteLine("Deleting PilotCategories :"); 16 result = db.Get(typeof(PilotCategories)); 17 for(int x = 0; x < result.Count; x++) 18 { 19 db.Delete(result[x]); 20 } 21 PrintCategories(); 22 } 23 finally 24 { 25 db.Close(); 26 } 27 }

StaticFieldExample.vb: DeleteTest
01Public Shared Sub DeleteTest() 02 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03 db.Ext().Configure().ObjectClass(GetType(Pilot)).CascadeOnDelete(True) 04 Try 05 Console.WriteLine("Deleting Pilots :") 06 Dim result As IObjectSet = db.Get(GetType(Pilot)) 07 Dim x As Integer 08 For x = 0 To result.Count - 1 Step x + 1 09 Dim pilot As Pilot = CType(result(x), Pilot) 10 db.Delete(pilot) 11 Next 12 PrintCategories() 13 Console.WriteLine("Deleting PilotCategories :") 14 result = db.Get(GetType(PilotCategories)) 15 For x = 0 To result.Count - 1 Step x + 1 16 db.Delete(result(x)) 17 Next 18 PrintCategories() 19 Finally 20 db.Close() 21 End Try 22 End Sub