Pluggable IO Concept

Db4o input/output implementation comes as a pluggable module. It means that you can write your own IO system based on IoAdapter class.

Pluggable IO Adapter has control over the following:

Some of the popular implementations of IoAdapter:

You can look at the db4o source to see some of these implementations (search for classes inheriting from IoAdapter).

By default db4o uses RandomAccessFileAdapter. You can install another IoAdapter with a single call:

c#: Db4o.Configure().Io(new SpecificIoAdapter())

VB: Db4o.Configure().Io(new SpecificIoAdapter())

Please, note: this call should be issued before opening of a database file. IoAdapter can be changed only while the database is closed.

For a test, let's try to create debugging IoAdapter, which will log all the information about its actions to the output stream:

LoggingAdapter.cs
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02using System.IO; 03 04namespace Db4objects.Db4odoc.IOs 05{ 06 public class LoggingAdapter : Db4objects.Db4o.IO.IoAdapter { 07 private Sharpen.IO.RandomAccessFile _delegate; 08 09 public LoggingAdapter() 10 { 11 } 12 13 protected internal LoggingAdapter(string path, bool lockFile, long initialLength, bool readOnly) 14 { 15 string mode = readOnly ? "r" : "rw";; 16 _delegate = new Sharpen.IO.RandomAccessFile(path, mode); 17 if (initialLength > 0) 18 { 19 _delegate.Seek(initialLength - 1); 20 _delegate.Write(new byte[] { 0 }); 21 } 22 } 23 24 public void SetOut(TextWriter outs) 25 { 26 System.Console.SetOut(outs); 27 } 28 29 public override void Close() 30 { 31 System.Console.WriteLine("Closing file"); 32 _delegate.Close(); 33 } 34 35 public override void Delete(string path) 36 { 37 System.Console.WriteLine("Deleting file " + path); 38 new Sharpen.IO.File(path).Delete(); 39 } 40 41 public override bool Exists(string path) 42 { 43 Sharpen.IO.File existingFile = new Sharpen.IO.File(path); 44 return existingFile.Exists() && existingFile.Length() > 0; 45 } 46 47 public override long GetLength() 48 { 49 System.Console.WriteLine("File length:" + _delegate.Length()); 50 return _delegate.Length(); 51 } 52 53 public override Db4objects.Db4o .IO.IoAdapter Open(string path, bool lockFile, long initialLength, bool readOnly) 54 { 55 System.Console.WriteLine("Opening file " + path); 56 return new LoggingAdapter(path, lockFile, initialLength, readOnly); 57 } 58 59 public override int Read(byte[] bytes, int length) 60 { 61 System.Console.WriteLine("Reading " + length + " bytes"); 62 return _delegate.Read(bytes, 0, length); 63 } 64 65 public override void Seek(long pos) 66 { 67 System.Console.WriteLine("Setting pointer position to " + pos); 68 _delegate.Seek(pos); 69 } 70 71 public override void Sync() 72 { 73 System.Console.WriteLine("Synchronizing"); 74 _delegate.GetFD().Sync(); 75 } 76 77 public override void Write(byte[] buffer, int length) 78 { 79 System.Console.WriteLine("Writing " + length + " bytes"); 80 _delegate.Write(buffer, 0, length); 81 } 82 } 83}
LoggingAdapter.vb
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02 03Imports System.IO 04Imports Db4objects.Db4o.IO 05 06Namespace Db4objects.Db4odoc.IOs 07 Public Class LoggingAdapter 08 Inherits IoAdapter 09 Private _delegate As Sharpen.IO.RandomAccessFile 10 11 Public Sub New() 12 End Sub 13 14 Protected Friend Sub New(ByVal path As String, ByVal lockFile As Boolean, ByVal initialLength As Long, ByVal rOnly As Boolean) 15 Dim mode As String 16 If rOnly = True Then 17 mode = "r" 18 Else 19 mode = "rw" 20 End If 21 _delegate = New Sharpen.IO.RandomAccessFile(path, mode) 22 If initialLength > 0 Then 23 _delegate.Seek(initialLength - 1) 24 Dim b As Byte() = New Byte() {0} 25 _delegate.Write(b) 26 End If 27 End Sub 28 29 30 Public Sub SetOut(ByVal outs As TextWriter) 31 System.Console.SetOut(outs) 32 End Sub 33 34 Public Overrides Sub Close() 35 System.Console.WriteLine("Closing file") 36 _delegate.Close() 37 End Sub 38 39 Public Overrides Sub Delete(ByVal path As String) 40 System.Console.WriteLine("Deleting file " + path) 41 File.Delete(path) 42 End Sub 43 44 Public Overrides Function Exists(ByVal path As String) As Boolean 45 Dim existingFile As Sharpen.IO.File = New Sharpen.IO.File(path) 46 Return existingFile.Exists() And existingFile.Length() > 0 47 End Function 48 49 Public Overrides Function GetLength() As Long 50 System.Console.WriteLine("File length:" + _delegate.Length().ToString()) 51 Return _delegate.Length() 52 End Function 53 54 Public Overrides Function Open(ByVal path As String, ByVal lockFile As Boolean, ByVal initialLength As Long, ByVal rOnly As Boolean) As IoAdapter 55 System.Console.WriteLine("Opening file " + path) 56 Return New LoggingAdapter(path, lockFile, initialLength, rOnly) 57 End Function 58 59 Public Overrides Function Read(ByVal bytes() As Byte, ByVal length As Integer) As Integer 60 System.Console.WriteLine("Reading " + length.ToString() + " bytes") 61 Return _delegate.Read(bytes, 0, length) 62 End Function 63 64 Public Overrides Sub Seek(ByVal pos As Long) 65 System.Console.WriteLine("Setting pointer position to " + pos.ToString()) 66 _delegate.Seek(pos) 67 End Sub 68 69 Public Overrides Sub Sync() 70 System.Console.WriteLine("Synchronizing") 71 _delegate.GetFD().Sync() 72 End Sub 73 74 Public Overrides Sub Write(ByVal buffer() As Byte, ByVal length As Integer) 75 System.Console.WriteLine("Writing " + length.ToString() + " bytes") 76 _delegate.Write(buffer, 0, length) 77 End Sub 78 End Class 79End Namespace

Now let's test how it works:

IOExample.cs: TestLoggingAdapter
01private static void TestLoggingAdapter() 02 { 03 IConfiguration configuration = Db4oFactory.NewConfiguration(); 04 configuration.Io(new LoggingAdapter()); 05 IObjectContainer db = Db4oFactory.OpenFile(configuration, Db4oFileName); 06 try 07 { 08 Pilot pilot = new Pilot("Michael Schumacher"); 09 db.Set(pilot); 10 System.Console.WriteLine("New pilot added"); 11 } 12 finally 13 { 14 db.Close(); 15 } 16 17 db = Db4oFactory.OpenFile(configuration, Db4oFileName); 18 try 19 { 20 IObjectSet result=db.Get(typeof(Pilot)); 21 ListResult(result); 22 } 23 finally 24 { 25 db.Close(); 26 } 27 }

IOExample.vb: TestLoggingAdapter
01Private Shared Sub TestLoggingAdapter() 02 Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 03 configuration.Io(New LoggingAdapter()) 04 Dim db As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 05 Try 06 Dim pilot As Pilot = New Pilot("Michael Schumacher") 07 db.Set(pilot) 08 System.Console.WriteLine("New pilot added") 09 Finally 10 db.Close() 11 End Try 12 13 db = Db4oFactory.OpenFile(Db4oFileName) 14 Try 15 Dim result As IObjectSet = db.Get(GetType(Pilot)) 16 ListResult(result) 17 Finally 18 db.Close() 19 End Try 20 End Sub

The output can be used for debugging purposes.