====== db4objects ======
===== Estructura =====
==== Con .NET ====
Una vez instalado en ''C:\Archivos de programa\Db4objects\db4o-7.8\bin'' tendremos localizadas las distintas librerías, por ejemplo, la necesaria para utilizar db4o en programas de escritorio es ''C:\Archivos de programa\Db4objects\db4o-7.8\bin\net-3.5\Db4objects.Db4o.dll''. \\ \\
En Ubuntu puedes conseguir ''db4o'' desde el repositorio oficial.
===== First glance =====
Primero deberemos incluir la referencia a ''Db4objects.Db4o'' y los namespaces necesarios para acceder a las clases que utilizaremos:
using Db4objects.Db4o;
==== Abrir base de datos ====
Para abrir una base de datos deberemos llamar al método estático ''OpenFile'' de la clase ''Db4oFactory'' pasandole la ruta del archivo de DB con el que vayamos a trabajar. Esto devolverá un ''IObjectContainer'' que representará a la base de datos. \\
El método ''Close'' del ''IObjectContainer'' cerrará la DB.
IObjectContainer db = Db4oFactory.OpenFile(@"c:\prueba.db");
try {
// Operaciones con la base de datos
}
finally {
db.Close();
}
===== Versión 6.0 en Mono =====
La versión 6.0 es una versión accesible con las versiones actuales de Mono (21 de febrero de 2010), sobre ella puede utilizarse LINQ y es perfectamente usable. Aún así __no utilices un ObjectManager de una versión superior__ sobre una DB de esta versión porque la corromperá.
* [[http://developer.db4o.com/Documentation/Reference/db4o-6.0/mono/api/|API]]
* [[http://developer.db4o.com/Documentation/Reference/db4o-6.0/mono/reference/|Reference]]
* [[http://developer.db4o.com/Documentation/Reference/db4o-6.0/mono/tutorial/|Tutorial]]
* {{db:db4o:db4o-6.0.rar|Binarios}}
* {{db:db4o:objectmanager-_6.4-java.zip|ObjectManager}}
==== Queries ====
=== Recoger todos los elementos de un tipo ===
Para ello lo haremos con el método ''Get'' del ''IObjectContainer'', pudiendo hacerlo de dos formas:
- Pasándole el tipo del que queremos todos los elementos mediante el ''typeof''.
- Pasándole un objeto vacío del tipo que buscamos.
// Forma 1:
IObjectSet result = db.Get(typeof(Car));
foreach (var b in result)
Console.WriteLine(((Car)b).marca);
// Forma 2:
IObjectSet result = db.Get(new Car () { marca = null });
=== Filtrar elementos ===
Para lanzar la consulta simplemente llamaríamos al ''Get'' sólo asignando la propiedad por la que queremos buscar:
IObjectSet result = db.Get(new Pilot () { Name = "Pedro" });
=== Utilizando el método Query (Native Query) ===
Podemos utilizar el método ''Query'' que requiere de un delegado que reciba por parámetro el tipo de elemento consultado y que devuelva un bool, de esa forma internamente se va llamando a este por cada elemento y se comprueba lo deseado.
public IList GetThePilot (Pilot templatePilot)
{
IList pilots = db.Query (
delegate(Pilot match)
{
return ((match.name == templatePilot.name) && (match.id == templatePilot.id))
} );
return pilots;
}
=== Queries con LINQ ===
Aunque las versiones anteriores de Mono tienen un uso bastante precario de LINQ este sí que puede ser aprovechado para las consultas a una base de datos db4o. \\
La siguiente query busca el nombre de los pilotos con un mini ordenando el resultado por el número de coches que estos tienen:
var result = from p in db.Query()
from c in p.lCars
where (c.marca == "MINI")
orderby p.lCars.Count
select p;
foreach (var r in result)
System.Console.WriteLine(r.name);
=== Notas ===
* Para tipar el resultado:
var template = new Car () { marca = null };
var result = db.Get(template).Cast();
var first = result.FirstOrDefault();
var list = result.ToList();
==== Acciones básicas ====
class Pilot
{
public int id {get; set; }
public string name {get; set;}
public List lCars = new List();
}
class Car
{
public string marca;
}
=== Insertar ===
Para insertar un elemento llamaremos al método ''Set'':
db.Set(new Pilot () { id = 1, name = "Juan" });
Si un objeto insertado tiene otros objetos internamente (como por ejemplo la clase ''Pilot'' que tiene una lista de la ''Car'') aparecerá en la base de datos otra "tabla" con los objetos, por ejemplo objetos ''Car'' de los ''Pilot'' que se van insertando. \\
Si en el código se ha asignado un mismo ''Car'' a varios ''Pilot'' no se duplicará en la tabla de la clase ''Car''. \\
Al eliminar objetos ''Pilot'' no se eliminarán los ''Car'' en la tabla.
=== Actualizar ===
Para actualizar un elemento símplemente tenemos que recoger lo que queramos actualizar, cambiarlo y volver a colocarlo en la DB llamando al método ''Set''. \\
La siguiente consulta recoge todos los pilotos con un coche "mini" y actualiza sus nombres agregandoles "minimalistas".
IObjectContainer db = Db4oFactory.OpenFile("prueba.db");
var result = from p in db.Query()
from c in p.lCars
where (c.marca == "MINI")
select p;
foreach (var r in result)
{
r.name = r.name + " - Minimalistas";
db.Set(r);
}
db.Close();
=== Eliminar ===
Eliminar funciona igual que actualizar, únicamente cambia la llamada al método de la DB, esta vez el método es ''Delete''. \\
El siguiente código elimina todos los pilotos que tengan un mini:
var result = from p in db.Query()
from c in p.lCars
where c.marca == "MINI"
select p;
foreach (var r in result)
db.Delete(r);
==== Acciones avanzadas ====
=== Generación de IDs ===
''db4o'' por defecto genera un identificador ''long'' para cada objeto insertado en la DB. \\
Para coger la id de un objeto haremos: ''db.Ext().GetID(object);'' \\
Para coger un objeto a partir de su id haremos: ''db.Ext().GetByID(id);'' \\ \\
Opcionalmente también se pueden generar los UUID (//Unique Universal IDs//), que son identificadores universales para que elementos que se compartan entre diferentes DB.
=== Indexar un campo ===
Para crear un índice deberemos de poner la siguiente línia **antes de abrir la base de datos**:
Db4oFactory.Configure().ObjectClass(typeof(NombreClase)).ObjectField("NombreCampo").Indexed(true);
El campo que queramos indexar **no puede ser un campo autoimplementado**, es decir, que sea así:
int id { get; set; }
Sería algo así:
class Program
{
public int id;
public int name;
static void Main(string[] args)
{
Db4oFactory.Configure().ObjectClass(typeof(Program)).ObjectField("id").Indexed(true);
var db = Db4oFactory.OpenFile("c:\\prueba.db");
...
==== Creación de servidor ====
=== Embedded ===
Para usar accesos concurrentes desde un mismo ejecutable:
IObjectServer server = Db4oFactory.OpenServer(dbPath, 0);
IObjectContainer client1 = server.OpenClient();
IObjectContainer client2 = server.OpenClient();
// ...
client1.Close();
client2.Close();
server.Close();
=== En red ===
Para que funcione en red, el servidor:
public void Start()
{
lock (this)
{
IObjectServer server = Db4oFactory.OpenServer("c:\\db.db4o", 1258);
server.GrantAccess(USER, PASSWORD);
Monitor.Wait(this);
}
}
Y el cliente:
IObjectContainer db = Db4oFactory.OpenClient(SERVER_HOST, 1258, USER, PASSWORD);