Db4o does not deliver a field autoincrement feature, which is common in RDBMS. If your application logic requires this feature you can implement it using External Callbacks. One of the possible solutions is presented below.
We will need an object to store the last generated ID and to return a new ID on request:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
/* 03
* Singleton class used to keep auotincrement information 04
* and give the next available ID on request 05
*/ 06
using System; 07
using Db4objects.Db4o; 08
09
namespace Db4objects.Db4odoc.Callbacks 10
{ 11
class IncrementedId 12
{ 13
private int _no; 14
private static IncrementedId _ref; 15
16
private IncrementedId() 17
{ 18
_no = 0; 19
} 20
// end IncrementedId 21
22
public int GetNextID(IObjectContainer db) 23
{ 24
_no++; 25
db.Set(this); 26
return _no; 27
} 28
// end increment 29
30
public static IncrementedId GetIdObject(IObjectContainer db) 31
{ 32
// if _ref is not assigned yet: 33
if (_ref == null) 34
{ 35
// check if there is a stored instance from the previous 36
// session in the database 37
IObjectSet os = db.Get(typeof(IncrementedId)); 38
if (os.Size() > 0) 39
_ref = (IncrementedId)os.Next(); 40
} 41
42
if (_ref == null) 43
{ 44
// create new instance and store it 45
Console.WriteLine("Id object is created"); 46
_ref = new IncrementedId(); 47
db.Set(_ref); 48
} 49
return _ref; 50
} 51
// end getIdObject 52
} 53
}
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
03
' Singleton class used to keep auotincrement information 04
' and give the next available ID on request 05
06
Imports System 07
Imports Db4objects.Db4o 08
Namespace Db4objects.Db4odoc.Callbacks 09
10
Class IncrementedId 11
Private _no As Integer 12
Private Shared _ref As IncrementedId 13
14
Private Sub New() 15
_no = 0 16
End Sub 17
' end New 18
19
Public Function GetNextID(ByVal db As IObjectContainer) As Integer 20
System.Math.Min(System.Threading.Interlocked.Increment(_no), _no - 1) 21
db.Set(Me) 22
Return _no 23
End Function 24
' end GetNextID 25
26
Public Shared Function GetIdObject(ByVal db As IObjectContainer) As IncrementedId 27
' if _ref is not assigned yet: 28
If _ref Is Nothing Then 29
' check if there is a stored instance from the previous 30
' session in the database 31
Dim os As IObjectSet = db.Get(GetType(IncrementedId)) 32
If os.Size > 0 Then 33
_ref = CType(os.Next, IncrementedId) 34
End If 35
End If 36
If _ref Is Nothing Then 37
' create new instance and store it 38
Console.WriteLine("Id object is created") 39
_ref = New IncrementedId 40
db.Set(_ref) 41
End If 42
Return _ref 43
End Function 44
' end GetIdObject 45
46
End Class 47
End Namespace
This object generates the simplest ID, which is an autoincremented integer value. You can add your own algorithm to generate more sophisticated ID sequences, like ABC0001DEF.
When you use external callbacks you are not limited to a single object: a callback can apply to any group of objects Thus you can create a sequence of classes sharing the same autoincrement. To distinguish the objects, which will have an autoincremented field, we will use an abstract (MustInherit in VB) class:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
/* 03
* This class is used to mark classes that need to get an autoincremented ID 04
*/ 05
namespace Db4objects.Db4odoc.Callbacks 06
{ 07
abstract class CountedObject 08
{ 09
protected int _id; 10
11
public int Id 12
{ 13
get 14
{ 15
return _id; 16
} 17
set 18
{ 19
_id = value; 20
} 21
} 22
} 23
}
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
'This class is used to mark classes that need to get an autoincremented ID 03
Namespace Db4objects.Db4odoc.Callbacks 04
05
MustInherit Class CountedObject 06
Protected _id As Integer 07
08
Public Property Id() As Integer 09
Get 10
Return _id 11
End Get 12
Set(ByVal value As Integer) 13
_id = value 14
End Set 15
End Property 16
End Class 17
End Namespace
Each object extending CountedObject will get an autoincremented ID. For example:
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02
namespace Db4objects.Db4odoc.Callbacks 03
{ 04
class TestObject: CountedObject 05
{ 06
string _name; 07
08
public TestObject(string name) { 09
_name = name; 10
} 11
12
public override string ToString() { 13
return _name+"/"+_id; 14
} 15
} 16
}
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com 02
Namespace Db4objects.Db4odoc.Callbacks 03
04
Class TestObject 05
Inherits CountedObject 06
Private _name As String 07
08
Public Sub New(ByVal name As String) 09
_name = name 10
End Sub 11
12
Public Overloads Overrides Function ToString() As String 13
Return _name + "/" + _id.ToString() 14
End Function 15
End Class 16
End Namespace
It is only left to register the callback with the creating() event:
1public static void RegisterCallback() 2
{ 3
IObjectContainer db = OpenContainer(); 4
IEventRegistry registry = EventRegistryFactory.ForObjectContainer(db); 5
// register an event handler, which will assign autoincremented IDs to any 6
// object extending CountedObject, when the object is created 7
registry.Creating += new CancellableObjectEventHandler(OnCreating); 8
}
01private static void OnCreating(object sender, CancellableObjectEventArgs args) 02
{ 03
IObjectContainer db = OpenContainer(); 04
object obj = args.Object; 05
// only for the objects extending the CountedObject 06
if (obj is CountedObject) 07
{ 08
((CountedObject)obj).Id = GetNextId(db); 09
} 10
}
01private static int GetNextId(IObjectContainer db) 02
{ 03
// this function retrieves the next available ID from 04
// the IncrementedId object 05
IncrementedId r = IncrementedId.GetIdObject(db); 06
int nRoll; 07
nRoll = r.GetNextID(db); 08
09
return nRoll; 10
}
1Public Shared Sub RegisterCallback() 2
Dim db As IObjectContainer = OpenContainer() 3
' register an event handler, which will assign autoincremented IDs to any 4
' object extending CountedObject, when the object is created 5
Dim registry As IEventRegistry = EventRegistryFactory.ForObjectContainer(db) 6
AddHandler registry.Creating, AddressOf OnCreating 7
End Sub
1Private Shared Sub OnCreating(ByVal sender As Object, ByVal args As CancellableObjectEventArgs) 2
Dim db As IObjectContainer = OpenContainer 3
Dim obj As Object = args.Object 4
' only for the objects extending the CountedObject 5
If TypeOf obj Is CountedObject Then 6
CType(obj, CountedObject).Id = GetNextId(db) 7
End If 8
End Sub
1Private Shared Function GetNextId(ByVal db As IObjectContainer) As Integer 2
' this function retrieves the next available ID from 3
' the IncrementedId object 4
Dim r As IncrementedId = IncrementedId.GetIdObject(db) 5
Dim nRoll As Integer 6
nRoll = r.GetNextID(db) 7
Return nRoll 8
End Function
You can test the results with the following code:
01public static void StoreObjects() 02
{ 03
IObjectContainer db = OpenContainer(); 04
TestObject test; 05
test = new TestObject("FirstObject"); 06
db.Set(test); 07
test = new TestObject("SecondObject"); 08
db.Set(test); 09
test = new TestObject("ThirdObject"); 10
db.Set(test); 11
}
1public static void RetrieveObjects() 2
{ 3
IObjectContainer db = OpenContainer(); 4
IObjectSet result = db.Get(new TestObject(null)); 5
ListResult(result); 6
}
01Public Shared Sub StoreObjects() 02
Dim db As IObjectContainer = OpenContainer 03
Dim test As TestObject 04
test = New TestObject("FirstObject") 05
db.Set(test) 06
test = New TestObject("SecondObject") 07
db.Set(test) 08
test = New TestObject("ThirdObject") 09
db.Set(test) 10
End Sub
1Public Shared Sub RetrieveObjects() 2
Dim db As IObjectContainer = OpenContainer 3
Dim result As IObjectSet = db.Get(New TestObject(Nothing)) 4
ListResult(result) 5
End Sub