<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<section id="bdb" xmlns:xi="http://www.w3.org/2001/XInclude">
    <sectioninfo>
	<authorgroup>
	    <author>
		<!--
		<firstname></firstname>
		<surname></surname>
		-->
		<affiliation><orgname>Sippy Software, Inc.</orgname></affiliation>
		<address>
		<email>devel@sippysoft.com</email>
                <otheraddr>
                <ulink url="http://www.sippysoft.com">http://www.sippysoft.com</ulink>
                </otheraddr>
		</address>
	    </author>
	</authorgroup>
	<copyright>
	    <year>2006</year>
	    <holder>Sippy Software, Inc.</holder>
	</copyright>
    </sectioninfo>

    <title>BDB Module</title>

    <section id="bdb.overview">
	<title>Overview</title>
	<para>
		The SER (SIP Express Router) supports several different persistent
		storage backends (flatfile, dbtext and several SQL servers). However, in
		certain cases those existing backends don't satisfy conditions.
		Particularly, SQL server-based backends typically provide good
		performance and scalability, but at the same time require considerable
		efforts to configure and manage and also have significant memory and
		on-disk footprint, while simpler storage backends (flatfile, dbtext) are
		lighter and simpler to setup and manage, but scale poorly and don't
		provide sufficient performance. For certain types of applications (i.e.
		embedded SIP applications, SIP load balancing farms etc), different
		solution that would combine some of the non-overlapping properties of
		those two existing classes of backends is necessary.
	</para>
	<para>
		Berkeley DB is widely regarded as industry-leading open source, embeddable
		database engine that provides developers with fast, reliable, local
		persistence with almost zero administration.
	</para>

	<section id="design">
	    <title>Design of DBD Engine</title>
	    <para>
		The dbtext database system architecture: 
		<itemizedlist>
		    <listitem>
			<para>
				A database is represented by a directory in the local file system
				where BDB environment is located.
			</para>
			<note>
			    <para>
				When using BDB driver in SER, the database URL for modules must be
				the path to the directory where the BDB environment is located,
				prefixed by "bdb://", e.g., "bdb:///var/db/ser". If there is no
				"/" after "bdb://" then "CFG_DIR/" (the OS-specific path defined
				at SER's compile time) is inserted at the beginning of the database
				path automatically. So that, either an absolute path to database
				directory, or one relative to "CFG_DIR" directory should be provided
				in the URL.
			    </para>
			</note>
		    </listitem>
		    <listitem>
			<para>
				The individual tables internaly are represented by binary files
				inside environment directory.
			</para>
			<note>
			    <para>
				The BDB driver uses BTree access method.
			    </para>
			    <para>
				On-disk storage format has been developed to be as simple as
				possible, while meeting performance requirements set forth above.
				It is not compatible with on-disk format of any other BDB-based DB
				engine (e.g. MySQL's BDB table handler). 
			    </para>
			</note>
		    </listitem>
		</itemizedlist>
	    </para>
	</section>
    </section>

    <section id="bdb.dep">
	<title>Dependencies</title>
	<section id="external_libs">
	    <title>External libraries or applications</title>
	    <para>
		The next libraries or applications must be installed before running
		SER with this module:
		<itemizedlist>
		    <listitem>
			<para>
				<ulink url="http://www.oracle.com/technology/software/products/berkeley-db/index.html">Berkeley DB 4.X</ulink>
			</para>
		    </listitem>
		</itemizedlist>
	    </para>
	</section>
    </section>

    <section id="bdb.parameters">
	<title>Exported parameters</title>
	<section id="bdb.describe_table">
	    <title><varname>describe_table</varname> (string)</title>
	    <para>
		Define the table and its structure. Each table that will be used
		by other modules has to be defined. The format of the parameter is:
		table_name:column_name_1(column_type_1)[column_name_2(column_type_2)[... column_name_N(column_type_N)]] 
	    </para>
	    <para>
		The names of table and columns must not include white spaces.
	    </para>
	    <para>
		The first column in definition is used as index.
	    </para>
	    <para>
		Between name of table and name of first column must be ":".
	    </para>
	    <para>
		Between two columns definitions must be exactly one white space.
	    </para>
	    <para>
		Type of column has to be enclosed into parentheses.
	    </para>
	    <para>
		Supported column types are:
		<itemizedlist>
		    <listitem>
			<para>
				int
			</para>
		    </listitem>
		    <listitem>
			<para>
				float
			</para>
		    </listitem>
		    <listitem>
			<para>
				double
			</para>
		    </listitem>
		    <listitem>
			<para>
				string
			</para>
		    </listitem>
		    <listitem>
			<para>
				str
			</para>
		    </listitem>
		    <listitem>
			<para>
				datetime
			</para>
		    </listitem>
		    <listitem>
			<para>
				blob
			</para>
		    </listitem>
		    <listitem>
			<para>
				bitmap
			</para>
		    </listitem>
		</itemizedlist>
	    </para>
	</section>
    </section>

    <section id="bdb.constrains">
	<title>Constrains and limitations</title>
	<para>
		Use of indexes:
		<itemizedlist>
		    <listitem>
			<para>
				Effective SELECT, UPDATE and DELETE operations on a
				structured storage that contains any more or less decent
				number of records are impossible without using some kind of
				indexing scheme. Since Berkley DB is relatively simple
				storage engine it provides only basic support for indexing,
				nearly not as rich as usually expected by an average SQL
				user. Therefore, it has been decided to limit number of
				indexes supported to one per table. This is sufficient for
				most of the uses in the SER (for example: usrloc, auth_db etc).
			</para>
		    </listitem>
		    <listitem>
			<para>
				SELECT/UPDATE/DELETE records matching criteria. Due to its
				simplicity, Berkley DB only supports exact match on indexed
				field. In order to support &lt;, &gt;, &lt;= and &gt;= operations
				mandated by the SIP DB API it is necessary to fall back to
				sequental scan of the index values, which obviously has
				significant negative impact on performance. Fortunately
				those advanced records matching criterias are not required
				neither by the usrloc module nor by auth_db module.
			</para>
		    </listitem>
		    <listitem>
			<para>
				BDB driver uses index only if key column appears in search
				clause at least once and records matching operator
				associated with it is '='.
			</para>
		    </listitem>
		    <listitem>
			<para>
				It is not allowed to set index value to NULL or an empty string.
			</para>
		    </listitem>
		    <listitem>
			<para>
				It is not allowed to update index value. The DELETE followed
				by INSERT should be used instead. 
			</para>
		    </listitem>
		</itemizedlist>
	</para>
	<para>
		BDB driver does not support db_raw_query() method.
	</para>
	<para>
		BDB driver does not support ORDER BY clause of db_query() method. 
	</para>
    </section>

    <section id="install_run">
	<title>Installation and running</title>
	<para>
	    Compile the module and load it instead of mysql or other DB
	    modules.
	</para>

	<example id="exmple1">
	    <title>Load the bdb module</title>
	    <programlisting>
...
loadmodule "/path/to/ser/modules/dbb.so"
...
modparam("module_name", "db_url", "bdb:///path/to/bdb/database")
...
	    </programlisting>
	</example>

	<example id="exmple2">
	    <title>definition of the standard version table</title>
	    <programlisting>
...
modparam("bdb", "describe_table", "version:table_name(str) table_version(int)")
...
	    </programlisting>
	</example>

	<section id="using">
	    <title>Using BDB With Basic SER Configuration</title>
	    <para>
		Here are the definitions for tables used by usrloc module as well
		as a part of basic configuration file to use BDB driver with SER.
		The table structures may change in future releases, so that some
		adjustment to example below may be necessary. That example
		corresponds to SER v0.9.4
	    </para>
	    <para>
		According to the configuration file below, the table files will be
		placed in the //var/db/ser/ directory.
	    </para>
	    <para>
		The table version should be populated manually before the SER is
		started. To do this version.dump file located in the directotry of
		BDB driver sources and db_load utility from Berkeley BD
		distribution should be used as follows:
		<example id="exmple3">
			<title>Population of version table</title>
			<programlisting>
$ db_load -h /var/db/ser -f version.dump version
			</programlisting>
		</example>
	    </para>

	    <example id="exmple4">
		<title>Configuration file</title>
		<programlisting>
# ---------- global configuration parameters ------------------------

# [skip]

# ---------- module loading -----------------------------------------

loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/bdb.so"

# ---------- module-specific configuration parameteres --------------

modparam("usrloc", "db_mode", 2)
modparam("usrloc", "timer_interval", 3)
modparam("usrloc", "db_url", "bdb:///var/db/ser")

modparam("bdb", "describe_table", "version:table_name(str) table_version(int)")

modparam("bdb", "describe_table", "location:username(str) domain(str) contact(str) i_env(int) expires(datetime) q(double) callid(str) cseq(int) method(str) flags(int) user_agent(str) received(str)")
modparam("bdb", "describe_table", "aliases:username(str) domain(str) contact(str) i_env(int) expires(datetime) q(double) callid(str) cseq(int) method(str) flags(int) user_agent(str) received(str)")

# ---------- request routing logic ----------------------------------

# [skip]

		</programlisting>
	    </example>
	</section>
    </section>

</section>
