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) 14 { 15 _delegate = new Sharpen.IO.RandomAccessFile(path, "rw"); 16 if (initialLength > 0) 17 { 18 _delegate.Seek(initialLength - 1); 19 _delegate.Write(new byte[] { 0 }); 20 } 21 } 22 23 public void SetOut(TextWriter outs) 24 { 25 System.Console.SetOut(outs); 26 } 27 28 public override void Close() 29 { 30 System.Console.WriteLine("Closing file"); 31 _delegate.Close(); 32 } 33 34 public override void Delete(string path) 35 { 36 System.Console.WriteLine("Deleting file " + path); 37 new Sharpen.IO.File(path).Delete(); 38 } 39 40 public override bool Exists(string path) 41 { 42 Sharpen.IO.File existingFile = new Sharpen.IO.File(path); 43 return existingFile.Exists() && existingFile.Length() > 0; 44 } 45 46 public override long GetLength() 47 { 48 System.Console.WriteLine("File length:" + _delegate.Length()); 49 return _delegate.Length(); 50 } 51 52 public override Db4objects.Db4o .IO.IoAdapter Open(string path, bool lockFile, long initialLength) 53 { 54 System.Console.WriteLine("Opening file " + path); 55 return new LoggingAdapter(path, lockFile, initialLength); 56 } 57 58 public override int Read(byte[] bytes, int length) 59 { 60 System.Console.WriteLine("Reading " + length + " bytes"); 61 return _delegate.Read(bytes, 0, length); 62 } 63 64 public override void Seek(long pos) 65 { 66 System.Console.WriteLine("Setting pointer position to " + pos); 67 _delegate.Seek(pos); 68 } 69 70 public override void Sync() 71 { 72 System.Console.WriteLine("Synchronizing"); 73 _delegate.GetFD().Sync(); 74 } 75 76 public override void Write(byte[] buffer, int length) 77 { 78 System.Console.WriteLine("Writing " + length + " bytes"); 79 _delegate.Write(buffer, 0, length); 80 } 81 } 82}

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) 15 _delegate = New Sharpen.IO.RandomAccessFile(path, "rw") 16 If initialLength > 0 Then 17 _delegate.Seek(initialLength - 1) 18 Dim b As Byte() = New Byte() {0} 19 _delegate.Write(b) 20 End If 21 End Sub 22 23 Public Sub SetOut(ByVal outs As TextWriter) 24 System.Console.SetOut(outs) 25 End Sub 26 27 Public Overrides Sub Close() 28 System.Console.WriteLine("Closing file") 29 _delegate.Close() 30 End Sub 31 32 Public Overrides Sub Delete(ByVal path As String) 33 System.Console.WriteLine("Deleting file " + path) 34 File.Delete(path) 35 End Sub 36 37 Public Overrides Function Exists(ByVal path As String) As Boolean 38 Dim existingFile As Sharpen.IO.File = New Sharpen.IO.File(path) 39 Return existingFile.Exists() And existingFile.Length() > 0 40 End Function 41 42 Public Overrides Function GetLength() As Long 43 System.Console.WriteLine("File length:" + _delegate.Length().ToString()) 44 Return _delegate.Length() 45 End Function 46 47 Public Overrides Function Open(ByVal path As String, ByVal lockFile As Boolean, ByVal initialLength As Long) As IoAdapter 48 System.Console.WriteLine("Opening file " + path) 49 Return New LoggingAdapter(path, lockFile, initialLength) 50 End Function 51 52 Public Overrides Function Read(ByVal bytes() As Byte, ByVal length As Integer) As Integer 53 System.Console.WriteLine("Reading " + length.ToString() + " bytes") 54 Return _delegate.Read(bytes, 0, length) 55 End Function 56 57 Public Overrides Sub Seek(ByVal pos As Long) 58 System.Console.WriteLine("Setting pointer position to " + pos.ToString()) 59 _delegate.Seek(pos) 60 End Sub 61 62 Public Overrides Sub Sync() 63 System.Console.WriteLine("Synchronizing") 64 _delegate.GetFD().Sync() 65 End Sub 66 67 Public Overrides Sub Write(ByVal buffer() As Byte, ByVal length As Integer) 68 System.Console.WriteLine("Writing " + length.ToString() + " bytes") 69 _delegate.Write(buffer, 0, length) 70 End Sub 71 End Class 72End 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.