\input texinfo  @c -*-texinfo-*-

@c Copyright (C) 2004, 2005, 2008, 2010 Free Software Foundation, Inc.

@c %**start of header
@setfilename guile-dbi.info
@settitle Guile DBI manual

@ifinfo
@dircategory The Algorithmic Language Scheme
@direntry
* Guile DBI: (guile-dbi).       Guile database abstraction layer
@end direntry

Guile DBI Manual
Copyright (C) 2004,2005 Maurizio Boriani@*
Copyright (C) 2008,2010 Linas Vepstas@*

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.

@end ifinfo
@c %**end of header

@include version.texi

@titlepage
@title Guile DBI Manual
@subtitle For use with Guile DBI @value{VERSION}

@author Maurizio Boriani
@author @email{baux@@member.fsf.org}

@author Linas Vepstas
@author @email{linasvepstasx@@gmail.com}

@c The following two commands start the copyright page.
@page
@vskip 0pt plus 1filll
@vskip 0pt plus 1filll
Copyright @copyright{} 2004,2005 Maurizio Boriani
Copyright @copyright{} 2008,2010 Linas Vepstas

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by Free Software Foundation.

@page
@end titlepage
@page

@ifnottex
@node Top, Introduction, (dir), (dir)
@top Guile DBI Manual

This reference manual documents Guile DBI, Guile Data Base Interface.
It describes how to use Guile DBI and how to write new dbd database
drivers.

This Info file contains edition @value{VERSION} of the reference
manual, corresponding to Guile DBI version @value{VERSION}.

@end ifnottex

@menu
* Introduction::
* Tutorial::
* Reference::
* Internals and Database Drivers::
@end menu

@node Introduction, Tutorial, Top, Top
@chapter Introduction

guile-dbi provides a simple, generic, easy-to-use scheme/guile interface
to SQL databases, such as Postgres, MySQL or SQLite.

The system is split into two parts: the DBI (database independent)
part, which provides the scheme interfaces, and the DBD (database
dependent) plugins, which connect to the actual SQL server. Currently,
there are DBD backends for Postgres, MySQL and SQLite3.

@section History

In 2004, Maurizio Boriani wrote:
<<I was looking around for a generic database library for guile scheme
implementation and found some projects. But them, actually, wasn't
really 'dynamic', simply compiled with different backend; I was
looking for something which permit me to link database driver at
runtime (like dbi systems for perl or php, tcl and so on), but
not found it. So I write it.>>

In 2008, Linas Vepstas wrote:
<<I was looking for a generic SQL database interface for guile, and
this was the only one that was documented, and held any promise of
working. After a few bug fixes, it worked to my satisfaction, and
I now use it in one of my projects (the OpenCog NLP subsystem).>>

@section Getting Guile DBI

You can find the latest version of Guile DBI at its project page,
@url{http://www.gna.org/projects/guile-dbi/}.

@*
In the file download area, there are dbi and driver tarballs.

@node Tutorial, Reference, Introduction, Top
@chapter Tutorial

The Scheme interface is very simple.
There are only 5 functions: @code{dbi-open},
@code{dbi-close}, @code{dbi-query}, @code{dbi-get_status}
and @code{dbi-get_row}.

@*
Guile DBI supports any database for which a dbd backend is written.
Currently, these are MySQL, Postgres and SQLite.

Here's an example usage, using SQLite3:
@example
(use-modules (dbi dbi))

;; Log into the database.
(define db-obj (dbi-open "sqlite3" "my-example-db"))

;; Create a table.
(dbi-query db-obj "create table hellotable(id int, name varchar(15))")

;; Look at the return status of the last SQL command
(display db-obj) (newline)

;; Populate the table with values.
(dbi-query db-obj "insert into hellotable ('id', 'name') values('33', 'ola')")
(dbi-query db-obj "insert into hellotable ('id', 'name') values('34', 'dzien dobre')")
(dbi-query db-obj "insert into hellotable ('id', 'name') values('44', 'annyong haseyo')")
(display db-obj) (newline)

;; Display each of the rows of the table, in turn.
(dbi-query db-obj "select * from hellotable")
(display db-obj) (newline)
(write (dbi-get_row db-obj)) (newline)
(write (dbi-get_row db-obj)) (newline)
(write (dbi-get_row db-obj)) (newline)
(write (dbi-get_row db-obj)) (newline)

;; Close the database.
(dbi-close db-obj)
(display db-obj) (newline)

@end example

Here's another example, using the MySQL database. This example assumes
that the MySQL server is running, and that a table named "pippo" has
already been created and populated with data:

@example
#!/usr/bin/guile -e main -s
!#

(use-modules (dbi dbi))

(define ciccio (dbi-open "mysql" "user:pass:pluto:tcp:localhost:3306"))
(define ret #f)
;; (define ciccio (dbi-open "mysql" "user:pass:pluto:socket:/tmp/mysql.sock"))

(define main
  (lambda (args)
    (display "HERE")(newline)
    (display ciccio)(newline)
    (dbi-query ciccio "select * from pippo")
    (display ciccio)(newline)
    (set! ret (dbi-get_row ciccio))
    (while (not (equal? ret #f))
	   (display ret)(newline)
	   (set! ret (dbi-get_row ciccio))
	   )
    (display ret)(newline)

))
@end example

Login credentials for PostgreSQL work similarly:
@example
#!/usr/bin/guile -e main -s
!#

(use-modules (dbi dbi))

(define conxion (dbi-open "postgresql" "user:pass:pluto:tcp:localhost:5432"))
(define conxion (dbi-open "postgresql" "user:pass:pluto:socket:/var/run/posgresql"))
@end example


@node Reference, Internals and Database Drivers, Tutorial, Top
@chapter Reference

@section Functions

@deffn Primitive dbi-open backend connString

Attempt to load driver @var{backend}, and connect to database passing
@var{connString} (which is connection string) to driver connect function.

If successful, it returns a @code{db-handle} object which is to be
used to reference the newly opened database connection. This object also
contains result status.

Every dbd implemention requires its own connection string format which
should be explained in its README file.

For example, to connect to postgres, using TCP sockets, to the
localhost, at the standard, default postgres port 5432:
@example
(dbi-open "postgresql" "user:pass:database:tcp:localhost:5432")
@end example

@end deffn


@deffn Primitive dbi-query db-handle query

Execute a query using @var{db-handle} and store status.

Example:
@example
(dbi-query db "select * from table")
@end example
@end deffn


@deffn Primitive dbi-get_status db-handle

Return a pair whose car is the status numeric code and cdr is a
status string message. @var{db-handle} should be a valid database
handle object.

@end deffn


@deffn Primitive dbi-get_row db-handle

This function, called after dbi-query, returns @code{#f} if there isn't
a next row to retrive; otherwise it returns a pair. The car of the
pair contains the field name and cdr is it's value.

Example:
@example
(dbi-get_row db)
@end example
@end deffn


@deffn Primitive dbi-close db-handle

This function closes @var{db-handle} and dereferences the loaded database
driver. When driver's reference count is 0, it is freed.

Example:
@example
(dbi-close db-handle)
@end example
@end deffn


@node Internals and Database Drivers, ,Reference, Top
@chapter Internals and Database Drivers

@menu
* Internal structures::
* Internal functions::
* How plugins are loaded::
* How to write plugins::
@end menu

@node Internal structures, Internal functions, Internals and Database Drivers, Internals and Database Drivers
@section Internal structures

The main data structure used to store lib needed data is:

@example
typedef struct g_db_handle
@{
  SCM bcknd;
  SCM constr;
  SCM status;  /* pair: car = error numeric code, cdr = status message */
  SCM closed;  /* boolean, TRUE if closed otherwise FALSE */
  lt_dlhandle handle;
  void* db_info;
  int in_free; /* boolean, used to avoid alloc during garbage collection */
@} gdbi_db_handle_t;
@end example

@itemize @bullet
@item @code{bcknd} stores backend name (e.g. mysql, postgresql, sqlite, ...).
@item @code{constr} string, stores the backend connection string. This
is not touched by guile-dbi, but is passed ``as is'' to the databse plugin.
@item @code{status} this is a pair which is used to return information from
backend to the dbi interface library. Its car is returns a status code number,
cdr is a status return message.
@item @code{closed} boolean, @code{#t} if the connection is closed, and
@code{#f} otherwise.
@item @code{handle} is a lt_dlhandle used to point to dynamically
loaded back-end library, filled by dbi-open @code{__gdbi_dbd_wrap}.
Set to ``NULL'' at connection close.
@item @code{db_info} is a void pointer used by the backends as a data
hook.  Set to ``NULL'' at connection close.
@item @code{in_free} Boolean flag, used to avoid alloc during garbage
collection.
@end itemize


@node Internal functions, How plugins are loaded, Internal structures, Internals and Database Drivers
@section Internal functions

@defun void __gdbi_dbd_wrap (gdbi_db_handle_t* dbh, char* function_name, void** function_pointer)
@end defun

This function is used to search for, and return, in the function
pointer, the back-end functions in order to shadow them from main dbi
library. It uses a handle (which points to the back-end dynamically
loaded library) to search for a function named
``__bcknd_function_name''. In dbi interfaces functions (like open, close,
query...) the function_name is filled by C ``__FUNCTION__'' macro.
Status code and message are returned by status field in dbh.

@defun void init_db_handle_type(void)
@end defun

Used to register static functions used to manage dbh SMOB.

@defun void init_dbi(void)
@end defun

Used to expose guile-dbi symbols so, scheme can call them.

@node How plugins are loaded, How to write plugins, Internal functions, Internals and Database Drivers
@section How plugins are loaded

Everything starts at @code{s_make_db_handle}. This function uses
libltdl to load a shared library named ``libguile-dbd-bcknd'' with the
extension of ``.la'', ``.so'', etc. It's searched in the value of
environment variable @code{GUILE_DBD_PATH} first, then libltdl's
search patch and system library search path. bcknd is the first param
of dbi-open.

@*
If the shared library is successfully loaded, the dbh's field ``handle''
is filled with the pointer returned by ``lt_dlopen'' and dbh->status is
set.  Otherwise the status is set to an error code in the car location,
while cdr is filled with an error message returned by @code{strerror}.

@*
Once ``lt_dlopen'' is ok, @code{__gdbi_dbd_wrap} is used to call the backend
plugin connect function passing it the connection string. If this
step also succeeds, then the db should be connected.
@sp 1
In every other dbi interface function, after type check,
@code{__gdbi_dbd_wrap} is used to call dbd function. When close is
called, after dbd close return, the reference to linked dbd is
decremented until is 0.

@node How to write plugins, , How plugins are loaded, Internals and Database Drivers
@section How to write plugins

Writing a plugin is fairly easy (have a look at the mysql, postgres or
sqlite dbd source code). You will need to supply a few functions with
appropriiately chosen names.

@*
These are the functions and return types you should supply for
a well written dbd:
@sp 1

@defun void __bcknd_make_g_db_handle(gdbi_db_handle_t* dbh)
@end defun

The ``bcknd'' is the name used by the open function.
This function should parse the connection string
and use params to connect to backend dbd database. Status should be
set in dbh in order to return useful informations. Don't forget
to set dbh field ``closed'' to false if connection is correctly established.
@sp 1

@defun void __mysql_close_g_db_handle(gdbi_db_handle_t* dbh)
@end defun

Close the connection and perform any needed cleanup.
Don't forget do set field ``closed'' to true if the connection
was correctly closed.

@defun void __mysql_query_g_db_handle(gdbi_db_handle_t* dbh, char* query)
@end defun

This should run the query and set the status, but should not return
any rows.  To return rows, the getrow function must be implemented.
@sp 1

@defun SCM __mysql_getrow_g_db_handle(gdbi_db_handle_t* dbh)
@end defun

This function should return a single row from a previously executed
query. It will typically be called more than once. When no more row
are available a @code{#f} must be returned.

A returned row must be an association list, that is, a list of pairs
whose car is the field name and cdr is it's value (if possible, the
value should use the closest possible guile/scheme type).

@sp 1
@*
That's all, for any other questions see the source code :)
@contents
@bye
