Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > fd266f45b6388e5c491c527d7b988093 > files > 8

ocaml-orm-sqlite-0.2-1mdv2010.0.i586.rpm

The Sql_orm package provides an "Object-Relational Mapper" interface
between a Sqlite3 database and OCaml.

DESCRIPTION
-----------

You provide a schema of the type of objects you want to store in
the database, and an OCaml source file is generated with modules
that:

 * initialize the database with the right schema
 * retrieve objects from the database by searching from keys
 * modify fields and save them back to the database.

The schema provides the following types:

 * text: a standard text field
 * blob: binary data
 * date: date stored as seconds since 1970
 * integer: int64
 * real: floating point number
 * foreign: map another object reference
 * foreign_many: list of other object references

You can also specify flags for each field:

 * `Optional: the field can be NULL in the database and is
    represented as an OCaml option type.
 * `Index: generate an index on the key's table for faster
    lookups.
 * `Unique: enforce a uniqueness constraint on the field.

For every table, you can also specify global table options:
 * A list of field names which specify unique constraints for
   groups of fields.  This is represented as a UNIQUE INDEX in
   the SQL backend.

The OCaml module which is generated contains a generic retrieval
function which can be used for most queries.  However, if you know
in advance that you only need certain fields retrieved, or a single
filtering criteria, you can request additional functions to be
generated by the ORM layer.

For example, consider the schema in examples/addressbook/schema.ml:
"name": text (unique)
"age": integer (optional)
"email": text

When the schema generator is executed, it creates an OCaml module
and signature.  In our example, we create My_db which is in
examples/addressbook/my_db.ml(i).

The default OCaml generated retrieval function has signature:

val get :
    ?id:int64 option ->
    ?name:string option ->
    ?age:int64 option ->
    ?email:string option ->
    ?custom_where:string * Sqlite3.Data.t list -> Init.t -> t list

All the search fields default to None, which means simply calling
Person.get will result in all the records in the database being
retrieved.  If you specify a value for a field, it is included as
a WHERE constraint in the database query.  The "custom_where" is
an advanced option to include more complex SQL constraints such as
LIKE clauses.

Now, suppose you are only interested in looking up people's names
of a certain age?  You could specify a generic query:

let qs = Person.get ~age:(Some 30L) db in
List.map (fun q -> q#name) qs

Instead of going through this step, when generating the schema you
can specify additional static query functions:

[  ["name"] , ["age"]  ]

The first element in the tuple is the list of fields to retrieve,
and the second element represents the constraint fields.  This would
generate a function:

val get_name_by_age :
    age:int64 option ->
    ?custom_where:string * Sqlite3.Data.t list -> Init.t ->
    string list

This signature is much simpler; you just pass in the single field
you want to filter on (age), and instead of a full (Person.t list)
you get back a list of name strings instead.  The SQL query is also
correspondingly more efficient since it doesnt have to SELECT
unnecessary fields as well.

INSTALLATION
------------

To get started, compile and install the Sql_orm module with:

$ make && sudo make install

It uses Findlib to locate your OCaml installation.  You will also
need the OCaml-SQLite3 bindings by Markus Mottl, available from:

 * http://www.ocaml.info/home/ocaml_sources.html

USAGE
-----

Once the library is installed, take a look inside the examples/ and
tests/ directory for how to use it.

The test_schema.ml file defines a simple address book schema and
calls into the Sql_orm generator to output OCaml code.  If you
execute run_tests.sh in that directory, it will generate the code
into ormtest.ml (and ormtest.mli), and execute some test cases
defined in test.ml.

Once the tests have (hopefully successfully) run, you can examine
the database schema in test.db to see how it maps from the schema
you defined to SQLite3.

In the generated file, each schema object you define has its own
module, with a 't' function to instantiate a new one, and 'get' to
retrieve a list of objects from the database.

Labelled arguments corresponding to the fields are used with native
OCaml types, and are mapped to the correct SQLite types.

BUGS
----

Please send bug reports or patches to:

* Anil Madhavapeddy <anil@recoil.org>