Explorar o código

further cleanups in core database API
- move use_table and close function for SQL DBs to core
- move query, raw_query, insert, update, delete functions for SQL DBs to core
- all this functions were almost identical implemented in the three DB,
this functions uses now a function pointer based interface to do the work
- the use_table functions from dbtext and db_berkeley uses also now the core API
- move result management function from db_col to db_res to the other result
management functions, they are not useful alone
- change postgres module to match more the structure of mysql and unixodbc,
remove the 'PARANOID' #define, the other modules don't have this and prefix
all functions with db_postgres, make this more consistent to mysql module
- prefix all functions in unixodbc module with db_unixodbc, make this consistent
to the other modules, cleanup the namespace
- prefix val2str function in mysql with db_mysql too
- move the SQL_BUF_LENGTH to core API, all modules need this
- remove the static SQL char buffer from postgres and unixodbc, uses the one
provided from the core API
- move documentation from db/doc to API files in doxygen format
- improve and extend documentation for the whole API
- make database API const correct, to guard against implementation errors and
allow better compiler optimizations
- change interface free_connection function in SQL DBs to connection structure
to allow the usage of core API do_close
- fix indention for postgres driver and make logging messages consistent
- remove now unneeded system header includes for SQL DBs
- remove transaction related code from postgres driver, this is not used at all
and according to Klaus also brings no performance benefit if used.
- probably some other smaller cleanups

Tested with the testcases, so basic functionality should work.. Please test! :-)


git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@3506 689a6050-402a-0410-94f2-e92a70836424

Henning Westerholt %!s(int64=17) %!d(string=hai) anos
pai
achega
bc4bf2658a

+ 109 - 54
lib/srdb1/db.c

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  * 
  * 
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -26,6 +27,21 @@
   *  2006-10-10  Added support for retrieving the last inserted ID (Carsten Bock, BASIS AudioNet GmbH)
   *  2006-10-10  Added support for retrieving the last inserted ID (Carsten Bock, BASIS AudioNet GmbH)
   */
   */
 
 
+/**
+ * \file db/db.c
+ * \brief Generic Database Interface
+ *
+ * This is a generic database interface for modules that need to utilize a
+ * database. The interface should be used by all modules that access database.
+ * The interface will be independent of the underlying database server.
+ * Notes:
+ * If possible, use the predefined macros if you need to access any structure
+ * attributes.
+ * For additional description, see the comments in the sources of mysql module.
+ *
+ * If you want to see more complicated examples of how the API could be used,
+ * take a look at the sources of the usrloc or auth modules.
+ */
 
 
 #include "../dprint.h"
 #include "../dprint.h"
 #include "../sr_module.h"
 #include "../sr_module.h"
@@ -38,7 +54,6 @@
 #include "db.h"
 #include "db.h"
 
 
 
 
-
 /* fills mydbf with the corresponding db module callbacks
 /* fills mydbf with the corresponding db module callbacks
  * returns 0 on success, -1 on error
  * returns 0 on success, -1 on error
  * on error mydbf will contain only 0s */
  * on error mydbf will contain only 0s */
@@ -164,6 +179,92 @@ int bind_dbmod(char* mod, db_func_t* mydbf)
 }
 }
 
 
 
 
+/*
+ * Initialize database module
+ * No function should be called before this
+ */
+db_con_t* db_do_init(const char* url, void* (*new_connection)())
+{
+	struct db_id* id;
+	void* con;
+	db_con_t* res;
+
+	int con_size = sizeof(db_con_t) + sizeof(void *);
+	id = 0;
+	res = 0;
+
+	if (!url || !new_connection) {
+		LM_ERR("invalid parameter value\n");
+		return 0;
+	}
+	if (strlen(url) > 255)
+	{
+		LM_ERR("SQL URL too long\n");
+		return 0;
+	}
+	
+	/* this is the root memory for this database connection. */
+	res = (db_con_t*)pkg_malloc(con_size);
+	if (!res) {
+		LM_ERR("no private memory left\n");
+		return 0;
+	}
+	memset(res, 0, con_size);
+
+	id = new_db_id(url);
+	if (!id) {
+		LM_ERR("cannot parse URL '%s'\n", url);
+		goto err;
+	}
+
+	/* Find the connection in the pool */
+	con = pool_get(id);
+	if (!con) {
+		LM_DBG("connection %p not found in pool\n", id);
+		/* Not in the pool yet */
+		con = new_connection(id);
+		if (!con) {
+			LM_ERR("could not add connection to the pool");
+			goto err;
+		}
+		pool_insert((struct pool_con*)con);
+	} else {
+		LM_DBG("connection %p found in pool\n", id);
+	}
+
+	res->tail = (unsigned long)con;
+	return res;
+
+ err:
+	if (id) free_db_id(id);
+	if (res) pkg_free(res);
+	return 0;
+}
+
+
+/*
+ * Shut down database module
+ * No function should be called after this
+ */
+void db_do_close(db_con_t* _h, void (*free_connection)())
+{
+	struct pool_con* con;
+
+	if (!_h) {
+		LM_ERR("invalid parameter value\n");
+		return;
+	}
+
+	con = (struct pool_con*)_h->tail;
+	if (pool_remove(con) == 1) {
+		free_connection(con);
+	}
+
+	pkg_free(_h);
+}
+
+
+
 /*
 /*
  * Get version of a table
  * Get version of a table
  * If there is no row for the given table, return version 0
  * If there is no row for the given table, return version 0
@@ -226,64 +327,18 @@ int table_version(db_func_t* dbf, db_con_t* connection, const str* table)
 	return ret;
 	return ret;
 }
 }
 
 
+
 /*
 /*
- * Initialize database module
- * No function should be called before this
+ * Store name of table that will be used by
+ * subsequent database functions
  */
  */
-db_con_t* db_do_init(const char* url, void* (*new_connection)())
+int db_use_table(db_con_t* _h, const char* _t)
 {
 {
-	struct db_id* id;
-	void* con;
-	db_con_t* res;
-
-	int con_size = sizeof(db_con_t) + sizeof(void *);
-	id = 0;
-	res = 0;
-
-	if (!url) {
+	if ((!_h) || (!_t)) {
 		LM_ERR("invalid parameter value\n");
 		LM_ERR("invalid parameter value\n");
-		return 0;
-	}
-	if (strlen(url) > 255)
-	{
-		LM_ERR("SQL URL too long\n");
-		return 0;
-	}
-	
-	/* this is the root memory for this database connection. */
-	res = (db_con_t*)pkg_malloc(con_size);
-	if (!res) {
-		LM_ERR("no private memory left\n");
-		return 0;
-	}
-	memset(res, 0, con_size);
-
-	id = new_db_id(url);
-	if (!id) {
-		LM_ERR("cannot parse URL '%s'\n", url);
-		goto err;
-	}
-
-	/* Find the connection in the pool */
-	con = pool_get(id);
-	if (!con) {
-		LM_DBG("connection %p not found in pool\n", id);
-		/* Not in the pool yet */
-		con = new_connection(id);
-		if (!con) {
-			LM_ERR("could not add connection to the pool");
-			goto err;
-		}
-		pool_insert((struct pool_con*)con);
-	} else {
-		LM_DBG("connection %p found in pool\n", id);
+		return -1;
 	}
 	}
 
 
-	res->tail = (unsigned long)con;
-	return res;
-
- err:
-	if (id) free_db_id(id);
-	if (res) pkg_free(res);
+	CON_TABLE(_h) = _t;
 	return 0;
 	return 0;
 }
 }

+ 46 - 21
lib/srdb1/db.h

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of ser, a free SIP server.
  * This file is part of ser, a free SIP server.
  *
  *
@@ -32,7 +33,7 @@
  */
  */
 
 
 /**
 /**
- * \file db.h
+ * \file db/db.h
  * \brief Generic Database Interface
  * \brief Generic Database Interface
  *
  *
  * This is a generic database interface for modules that need to utilize a
  * This is a generic database interface for modules that need to utilize a
@@ -45,7 +46,7 @@
  *
  *
  * If you want to see more complicated examples of how the API could be used,
  * If you want to see more complicated examples of how the API could be used,
  * take a look at the sources of the usrloc or auth modules.
  * take a look at the sources of the usrloc or auth modules.
-*/
+ */
 
 
 #ifndef DB_H
 #ifndef DB_H
 #define DB_H
 #define DB_H
@@ -57,6 +58,7 @@
 #include "db_row.h"
 #include "db_row.h"
 #include "db_res.h"
 #include "db_res.h"
 #include "db_cap.h"
 #include "db_cap.h"
+#include "db_con.h"
 
 
 
 
 /**
 /**
@@ -67,7 +69,7 @@
  * that table.
  * that table.
  * \param _h database connection handle
  * \param _h database connection handle
  * \param _t table name
  * \param _t table name
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_use_table_f)(db_con_t* _h, const char* _t);
 typedef int (*db_use_table_f)(db_con_t* _h, const char* _t);
 
 
@@ -92,7 +94,7 @@ typedef int (*db_use_table_f)(db_con_t* _h, const char* _t);
  * \see bind_dbmod
  * \see bind_dbmod
  * \param _sqlurl database connection URL
  * \param _sqlurl database connection URL
  * \return returns a pointer to the db_con_t representing the connection if it was
  * \return returns a pointer to the db_con_t representing the connection if it was
-  successful, otherwise 0 is returned.
+ * successful, otherwise 0 is returned
  */
  */
 typedef db_con_t* (*db_init_f) (const char* _sqlurl);
 typedef db_con_t* (*db_init_f) (const char* _sqlurl);
 
 
@@ -134,7 +136,7 @@ typedef void (*db_close_f) (db_con_t* _h);
  * \param _nc number of columns in _c parameter
  * \param _nc number of columns in _c parameter
  * \param _o order by statement for query
  * \param _o order by statement for query
  * \param _r address of variable where pointer to the result will be stored
  * \param _r address of variable where pointer to the result will be stored
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_query_f) (db_con_t* _h, db_key_t* _k,
 typedef int (*db_query_f) (db_con_t* _h, db_key_t* _k,
 			   db_op_t* _op, db_val_t* _v, db_key_t* _c,
 			   db_op_t* _op, db_val_t* _v, db_key_t* _c,
@@ -149,7 +151,7 @@ typedef int (*db_query_f) (db_con_t* _h, db_key_t* _k,
  * \param _h structure representing database connection
  * \param _h structure representing database connection
  * \param _r structure for the result
  * \param _r structure for the result
  * \param _n the number of rows that should be fetched
  * \param _n the number of rows that should be fetched
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_fetch_result_f) (db_con_t* _h, db_res_t** _r, int _n);
 typedef int (*db_fetch_result_f) (db_con_t* _h, db_res_t** _r, int _n);
 
 
@@ -167,7 +169,7 @@ typedef int (*db_fetch_result_f) (db_con_t* _h, db_res_t** _r, int _n);
  * \param _h structure representing database connection
  * \param _h structure representing database connection
  * \param _s the SQL query
  * \param _s the SQL query
  * \param _r structure for the result
  * \param _r structure for the result
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_raw_query_f) (db_con_t* _h, char* _s, db_res_t** _r);
 typedef int (*db_raw_query_f) (db_con_t* _h, char* _s, db_res_t** _r);
 
 
@@ -180,7 +182,7 @@ typedef int (*db_raw_query_f) (db_con_t* _h, char* _s, db_res_t** _r);
  * structure anymore. You must call this function before you call db_query again!
  * structure anymore. You must call this function before you call db_query again!
  * \param _h database connection handle
  * \param _h database connection handle
  * \param _r pointer to db_res_t structure to destroy
  * \param _r pointer to db_res_t structure to destroy
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_free_result_f) (db_con_t* _h, db_res_t* _r);
 typedef int (*db_free_result_f) (db_con_t* _h, db_res_t* _r);
 
 
@@ -194,7 +196,7 @@ typedef int (*db_free_result_f) (db_con_t* _h, db_res_t* _r);
  * \param _k array of keys (column names) 
  * \param _k array of keys (column names) 
  * \param _v array of values for keys specified in _k parameter
  * \param _v array of values for keys specified in _k parameter
  * \param _n number of keys-value pairs int _k and _v parameters
  * \param _n number of keys-value pairs int _k and _v parameters
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_insert_f) (db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n);
 typedef int (*db_insert_f) (db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n);
 
 
@@ -213,7 +215,7 @@ typedef int (*db_insert_f) (db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n);
  * \param _o array of operators to be used with key-value pairs
  * \param _o array of operators to be used with key-value pairs
  * \param _v array of values that the row must match to be deleted
  * \param _v array of values that the row must match to be deleted
  * \param _n number of keys-value parameters in _k and _v parameters
  * \param _n number of keys-value parameters in _k and _v parameters
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_delete_f) (db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n);
 typedef int (*db_delete_f) (db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n);
 
 
@@ -247,7 +249,7 @@ typedef int (*db_update_f) (db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _
  * \param _k key names
  * \param _k key names
  * \param _v values of the keys
  * \param _v values of the keys
  * \param _n number of key=value pairs
  * \param _n number of key=value pairs
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
 */
 */
 typedef int (*db_replace_f) (db_con_t* handle, db_key_t* keys, db_val_t* vals, int n);
 typedef int (*db_replace_f) (db_con_t* handle, db_key_t* keys, db_val_t* vals, int n);
 
 
@@ -276,7 +278,7 @@ typedef int (*db_last_inserted_id_f) (db_con_t* _h);
  * \param _k key names
  * \param _k key names
  * \param _v values of the keys
  * \param _v values of the keys
  * \param _n number of key=value pairs
  * \param _n number of key=value pairs
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 typedef int (*db_insert_update_f) (db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n);
 typedef int (*db_insert_update_f) (db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n);
 
 
@@ -323,11 +325,33 @@ typedef struct db_func {
  * \see db_func_t
  * \see db_func_t
  * \param mod database connection URL or a database module name
  * \param mod database connection URL or a database module name
  * \param dbf database module callbacks
  * \param dbf database module callbacks
- * \return returns 0 if everything is OK, otherwise returns value < 0.
+ * \return returns 0 if everything is OK, otherwise returns value < 0
  */
  */
 int bind_dbmod(char* mod, db_func_t* dbf);
 int bind_dbmod(char* mod, db_func_t* dbf);
 
 
 
 
+/**
+ * \brief Helper for db_init function.
+ *
+ * This helper method do the actual work for the database specific db_init
+ * functions.
+ * \param url database connection URL
+ * \param (*new_connection)() Pointer to the db specific connection creation method
+ * \return returns a pointer to the db_con_t representing the connection if it was
+   successful, otherwise 0 is returned.
+ */
+db_con_t* db_do_init(const char* url, void* (*new_connection)());
+
+/**
+ * \brief Helper for db_close function.
+ *
+ * This helper method does some work for the closing of a database 
+ * connection. No function should be called after this
+ * \param _h database connection handle
+ * \param (*free_connection) Pointer to the db specifc free_connection method
+ */
+void db_do_close(db_con_t* _h, void (*free_connection)());
+
 /**
 /**
  * \brief Get the version of a table.
  * \brief Get the version of a table.
  *
  *
@@ -339,16 +363,17 @@ int bind_dbmod(char* mod, db_func_t* dbf);
  */
  */
 int table_version(db_func_t* dbf, db_con_t* con, const str* table);
 int table_version(db_func_t* dbf, db_con_t* con, const str* table);
 
 
+
 /**
 /**
- * \brief Helper for db_init function.
+ * \brief Stores the name of table
  *
  *
- * This helper method do the actual work for the database specific db_init
- * functions.
- * \param url database connection URL
- * \param (*new_connection)() Pointer to the db specific connection creation method
- * \return returns a pointer to the db_con_t representing the connection if it was
-   successful, otherwise 0 is returned.
+ * Stores the name of the table that will be used by subsequent database
+ * functions calls in a db_con_t structure.
+ * \param _h database connection handle
+ * \param _t stored name
+ * \return 0 if everything is ok, otherwise returns value < 0
  */
  */
-db_con_t* db_do_init(const char* url, void* (*new_connection)());
+int db_use_table(db_con_t* _h, const char* _t);
+
 
 
 #endif /* DB_H */
 #endif /* DB_H */

+ 24 - 14
lib/srdb1/db_cap.h

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2004 FhG Fokus
  * Copyright (C) 2001-2004 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,36 +21,45 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db_cap.h
+ * \brief Data structures that represents capabilities in the database.
+ *
+ * This file defines data structures that represents certain database
+ * capabilities. It also provides some macros for convenient access to this
+ * values.
+ */
+
 #ifndef DB_CAP_H
 #ifndef DB_CAP_H
 #define DB_CAP_H
 #define DB_CAP_H
 
 
 
 
-/*
- * Database capabilities
+/**
+ * Represents the capabilities that a database driver supports.
  */
  */
 typedef enum db_cap {
 typedef enum db_cap {
-	DB_CAP_QUERY =     1 << 0,  /* Database driver can query database */
-	DB_CAP_RAW_QUERY = 1 << 1,  /* Database driver can perform raw queries */
-	DB_CAP_INSERT =    1 << 2,  /* Database driver can insert data into database */
-	DB_CAP_DELETE =    1 << 3,  /* Database driver can delete data from database */
-	DB_CAP_UPDATE =    1 << 4,  /* Database driver can update data in the database */
-	DB_CAP_REPLACE =   1 << 5,  /* Replace (also known as INSERT OR UPDATE) support */
-	DB_CAP_FETCH   =   1 << 6,  /* Fetch result support */
-	DB_CAP_LAST_INSERTED_ID = 1 << 7,  /* ID of the last insert */
- 	DB_CAP_INSERT_UPDATE = 1 << 8 /* Database driver can insert data into database and update on duplicate */
+	DB_CAP_QUERY =     1 << 0,  /**< driver can perform queries                                     */
+	DB_CAP_RAW_QUERY = 1 << 1,  /**< driver can perform raw queries                                 */
+	DB_CAP_INSERT =    1 << 2,  /**< driver can insert data                                         */
+	DB_CAP_DELETE =    1 << 3,  /**< driver can delete data                                         */
+	DB_CAP_UPDATE =    1 << 4,  /**< driver can update data                                         */
+	DB_CAP_REPLACE =   1 << 5,  /**< driver can replace (also known as INSERT OR UPDATE) data       */
+	DB_CAP_FETCH   =   1 << 6,  /**< driver supports fetch result queries                           */
+	DB_CAP_LAST_INSERTED_ID = 1 << 7,  /**< driver can return the ID of the last insert operation   */
+ 	DB_CAP_INSERT_UPDATE = 1 << 8 /**< driver can insert data into database and update on duplicate */
 
 
 } db_cap_t;
 } db_cap_t;
 
 
 
 
-/*
+/**
  * All database capabilities except raw_query, replace, insert_update and 
  * All database capabilities except raw_query, replace, insert_update and 
  * last_inserted_id which should be checked separately when needed
  * last_inserted_id which should be checked separately when needed
  */
  */
 #define DB_CAP_ALL (DB_CAP_QUERY | DB_CAP_INSERT | DB_CAP_DELETE | DB_CAP_UPDATE)
 #define DB_CAP_ALL (DB_CAP_QUERY | DB_CAP_INSERT | DB_CAP_DELETE | DB_CAP_UPDATE)
 
 
 
 
-/*
- * True if all the capabilities in cpv are supported by module
+/**
+ * Returns true if all the capabilities in cpv are supported by module
  * represented by dbf, false otherwise
  * represented by dbf, false otherwise
  */
  */
 #define DB_CAPABILITY(dbf, cpv) (((dbf).cap & (cpv)) == (cpv))
 #define DB_CAPABILITY(dbf, cpv) (((dbf).cap & (cpv)) == (cpv))

+ 0 - 42
lib/srdb1/db_col.c

@@ -1,42 +0,0 @@
-/* 
- * $Id$ 
- *
- * Copyright (C) 2001-2003 FhG Fokus
- * Copyright (C) 2007 1und1 Internet AG
- *
- * This file is part of openser, a free SIP server.
- *
- * openser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * openser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "db_col.h"
-
-#include "../dprint.h"
-#include "../mem/mem.h"
-
-/*
- * Release memory used by columns
- */
-inline int db_free_columns(db_res_t* _r)
-{
-	if (!_r) {
-		LM_ERR("invalid parameter\n");
-		return -1;
-	}
-
-	if (RES_NAMES(_r)) pkg_free(RES_NAMES(_r));
-	if (RES_TYPES(_r)) pkg_free(RES_TYPES(_r));
-	return 0;
-}

+ 0 - 36
lib/srdb1/db_col.h

@@ -1,36 +0,0 @@
-/* 
- * $Id$ 
- *
- * Copyright (C) 2001-2003 FhG Fokus
- *
- * This file is part of openser, a free SIP server.
- *
- * openser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * openser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef DB_COL_H
-#define DB_COL_H
-
-
-#include "db_res.h"
-
-
-/*
- * Release memory used by columns
- */
-int db_free_columns(db_res_t* _r);
-
-#endif /* DB_COL_H */

+ 12 - 8
lib/srdb1/db_con.h

@@ -2,6 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,25 +21,28 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
-
+/**
+ * \file db/db_con.h
+ * \brief Type that represents a database connection
+ */
 
 
 #ifndef DB_CON_H
 #ifndef DB_CON_H
 #define DB_CON_H
 #define DB_CON_H
 
 
 
 
-/*
- * This structure represents a database connection
- * and pointer to this structure is used as a connection
- * handle
+/**
+ * This structure represents a database connection, pointer to this structure
+ * are used as a connection handle from modules uses the db API.
  */
  */
 typedef struct {
 typedef struct {
-	const char* table;     /* Default table to use */
-	unsigned long tail;    /* Variable length tail
-				* database module specific */    
+	const char* table;     /**< Default table that should be used              */
+	unsigned long tail;    /**< Variable length tail, database module specific */
 } db_con_t;
 } db_con_t;
 
 
 
 
+/** Return the table of the connection handle */
 #define CON_TABLE(cn)      ((cn)->table)
 #define CON_TABLE(cn)      ((cn)->table)
+/** Return the tail of the connection handle */
 #define CON_TAIL(cn)       ((cn)->tail)
 #define CON_TAIL(cn)       ((cn)->tail)
 
 
 
 

+ 7 - 1
lib/srdb1/db_id.c

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2005 iptel.org
  * Copyright (C) 2001-2005 iptel.org
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,6 +21,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_id.c
+ * \brief Functions for parsing a database URL and work with db identifier.
+ */
+
 #include "db_id.h"
 #include "db_id.h"
 #include "../dprint.h"
 #include "../dprint.h"
 #include "../mem/mem.h"
 #include "../mem/mem.h"
@@ -239,7 +245,7 @@ struct db_id* new_db_id(const char* url)
 /*
 /*
  * Compare two connection identifiers
  * Compare two connection identifiers
  */
  */
-unsigned char cmp_db_id(struct db_id* id1, struct db_id* id2)
+unsigned char cmp_db_id(const struct db_id* id1, const struct db_id* id2)
 {
 {
 	if (!id1 || !id2) return 0;
 	if (!id1 || !id2) return 0;
 	if (id1->port != id2->port) return 0;
 	if (id1->port != id2->port) return 0;

+ 23 - 11
lib/srdb1/db_id.h

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2005 iptel.org
  * Copyright (C) 2001-2005 iptel.org
+ * Copyright (C) 2007-2008 1&1 Internet AG
  * 
  * 
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,36 +21,47 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_id.c
+ * \brief Functions for parsing a database URL and works with db identifier.
+ */
+
 #ifndef _DB_ID_H
 #ifndef _DB_ID_H
 #define _DB_ID_H
 #define _DB_ID_H
 
 
 #include "../str.h"
 #include "../str.h"
 
 
-
+/** Structure representing a database ID */
 struct db_id {
 struct db_id {
-	char* scheme;        /* URL scheme */
-	char* username;      /* Username, case sensitive */
-	char* password;      /* Password, case sensitive */
-	char* host;          /* Host or IP, case insensitive */
-	unsigned short port; /* Port number */
-	char* database;      /* Database, case sensitive */
+	char* scheme;        /**< URL scheme */
+	char* username;      /**< Username, case sensitive */
+	char* password;      /**< Password, case sensitive */
+	char* host;          /**< Host or IP, case insensitive */
+	unsigned short port; /**< Port number */
+	char* database;      /**< Database, case sensitive */
 };
 };
 
 
 
 
-/*
+/**
  * Create a new connection identifier
  * Create a new connection identifier
+ * \param url database URL
+ * \return new allocated db_id structure, NULL on failure
  */
  */
 struct db_id* new_db_id(const char* url);
 struct db_id* new_db_id(const char* url);
 
 
 
 
-/*
+/**
  * Compare two connection identifiers
  * Compare two connection identifiers
+ * \param id1 first identifier
+ * \param id2 second identifier
+ * \return 1 if both identifier are equal, 0 if there not equal
  */
  */
-unsigned char cmp_db_id(struct db_id* id1, struct db_id* id2);
+unsigned char cmp_db_id(const struct db_id* id1, const struct db_id* id2);
 
 
 
 
-/*
+/**
  * Free a connection identifier
  * Free a connection identifier
+ * \param id the identifier that should released
  */
  */
 void free_db_id(struct db_id* id);
 void free_db_id(struct db_id* id);
 
 

+ 8 - 2
lib/srdb1/db_key.h

@@ -2,6 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,13 +21,18 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_key.h
+ * \brief Type that represents a database key.
+ */
 
 
 #ifndef DB_KEY_H
 #ifndef DB_KEY_H
 #define DB_KEY_H
 #define DB_KEY_H
 
 
 
 
-/*
- * Type of a database key (column)
+/**
+ * This type represents a database key (column).
+ * Every time you need to specify a key value, this type should be used.
  */
  */
 typedef const char* db_key_t;
 typedef const char* db_key_t;
 
 

+ 13 - 2
lib/srdb1/db_op.h

@@ -2,6 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,20 +21,30 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_op.h
+ * \brief Type that represents a expression operator.
+ */
 
 
 #ifndef DB_OP_H
 #ifndef DB_OP_H
 #define DB_OP_H
 #define DB_OP_H
 
 
+/** operator less than */
 #define OP_LT  "<"
 #define OP_LT  "<"
+/** operator greater than */
 #define OP_GT  ">"
 #define OP_GT  ">"
+/** operator equal */
 #define OP_EQ  "="
 #define OP_EQ  "="
+/** operator less than equal */
 #define OP_LEQ "<="
 #define OP_LEQ "<="
+/** operator greater than equal */
 #define OP_GEQ ">="
 #define OP_GEQ ">="
+/** operator negation */
 #define OP_NEQ "!="
 #define OP_NEQ "!="
 
 
 
 
-/*
- * Type of a operator
+/**
+ * This type represents an expression operator uses for SQL queries.
  */
  */
 typedef const char* db_op_t;
 typedef const char* db_op_t;
 
 

+ 7 - 1
lib/srdb1/db_pool.c

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2005 iptel.org
  * Copyright (C) 2001-2005 iptel.org
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,6 +21,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_pool.c
+ * \brief Functions for managing a pool of database connections.
+ */
+
 #include "../dprint.h"
 #include "../dprint.h"
 #include "db_pool.h"
 #include "db_pool.h"
 
 
@@ -33,7 +39,7 @@ static struct pool_con* db_pool = 0;
  * the identifier equal to id, NULL is returned
  * the identifier equal to id, NULL is returned
  * when no connection is found
  * when no connection is found
  */
  */
-struct pool_con* pool_get(struct db_id* id)
+struct pool_con* pool_get(const struct db_id* id)
 {
 {
 	struct pool_con* ptr;
 	struct pool_con* ptr;
 
 

+ 23 - 13
lib/srdb1/db_pool.h

@@ -2,6 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2005 iptel.org
  * Copyright (C) 2001-2005 iptel.org
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,6 +21,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_pool.h
+ * \brief Functions for managing a pool of database connections.
+ */
+
 #ifndef _DB_POOL_H
 #ifndef _DB_POOL_H
 #define _DB_POOL_H
 #define _DB_POOL_H
 
 
@@ -27,7 +33,7 @@
 #include "db_con.h"
 #include "db_con.h"
 
 
 
 
-/*
+/**
  * This is a stub that contains all attributes
  * This is a stub that contains all attributes
  * that pool members must have, it is not really
  * that pool members must have, it is not really
  * used, real connection structures are created
  * used, real connection structures are created
@@ -36,28 +42,30 @@
  * attributes.
  * attributes.
  */
  */
 struct pool_con {
 struct pool_con {
-	struct db_id* id;        /* Connection identifier */
-	unsigned int ref;        /* Reference count */
-	struct pool_con* next;   /* Next element in the pool */
+	struct db_id* id;        /**< Connection identifier */
+	unsigned int ref;        /**< Reference count */
+	struct pool_con* next;   /**< Next element in the pool */
 };
 };
 
 
 
 
-/*
- * Search the pool for a connection with
- * the identifier equal to id, NULL is returned
- * when no connection is found
+/**
+ * Search the pool for a connection with the identifier equal to
+ * the id.
+ * \param id searched id
+ * \return the connection if it could be found, NULL otherwise
  */
  */
-struct pool_con* pool_get(struct db_id* id);
+struct pool_con* pool_get(const struct db_id* id);
 
 
 
 
-/*
- * Insert a new connection into the pool
+/**
+ * Insert a new connection into the pool.
+ * \param con the inserted connection 
  */
  */
 void pool_insert(struct pool_con* con);
 void pool_insert(struct pool_con* con);
 
 
 
 
-/*
- * Release connection from the pool, the function
+/**
+ * Release a connection from the pool, the function
  * would return 1 when if the connection is not
  * would return 1 when if the connection is not
  * referenced anymore and thus can be closed and
  * referenced anymore and thus can be closed and
  * deleted by the backend. The function returns
  * deleted by the backend. The function returns
@@ -65,6 +73,8 @@ void pool_insert(struct pool_con* con);
  * because some other module is still using it.
  * because some other module is still using it.
  * The function returns -1 if the connection is
  * The function returns -1 if the connection is
  * not in the pool.
  * not in the pool.
+ * \param con connection that should be removed
+ * \return 1 if the connection can be freed, 0 if it can't be freed, -1 if not found
  */
  */
 int pool_remove(struct pool_con* con);
 int pool_remove(struct pool_con* con);
 
 

+ 300 - 0
lib/srdb1/db_query.c

@@ -0,0 +1,300 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2007-2008 1&1 Internet AG
+ *
+ * This file is part of openser, a free SIP server.
+ *
+ * openser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * openser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/**
+ * \file db/db_query.c
+ * \brief Query helper for database drivers
+ *
+ * This helper methods for database queries are used from the database
+ * SQL driver to do the actual work. Each function uses some functions from
+ * the actual driver with function pointers to the concrete, specific
+ * implementation.
+*/
+
+#include <stdio.h>
+#include "../dprint.h"
+#include "db_ut.h"
+#include "db_query.h"
+
+static char sql_buf[SQL_BUF_LEN];
+
+int db_do_query( const db_con_t* _h, const db_key_t* _k, const db_op_t* _op,
+	const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
+	const db_key_t _o, db_res_t** _r, int (*val2str) (const db_con_t*,
+	const db_val_t*, char*, int* _len), int (*submit_query)(const db_con_t*,
+	const char*), int (*store_result)(const db_con_t*, db_res_t**))
+{
+	int off, ret;
+
+	if (!_h || !val2str || !submit_query || !store_result) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	if (!_c) {
+		ret = snprintf(sql_buf, SQL_BUF_LEN, "select * from %s ", CON_TABLE(_h));
+		if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+		off = ret;
+	} else {
+		ret = snprintf(sql_buf, SQL_BUF_LEN, "select ");
+		if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+		off = ret;
+
+		ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _c, _nc);
+		if (ret < 0) return -1;
+		off += ret;
+
+		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "from %s ", CON_TABLE(_h));
+		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		off += ret;
+	}
+	if (_n) {
+		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "where ");
+		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		off += ret;
+
+		ret = db_print_where(_h, sql_buf + off,
+				SQL_BUF_LEN - off, _k, _op, _v, _n, val2str);
+		if (ret < 0) return -1;;
+		off += ret;
+	}
+	if (_o) {
+		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " order by %s", _o);
+		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		off += ret;
+	}
+	
+	*(sql_buf + off) = '\0';
+	if (submit_query(_h, sql_buf) < 0) {
+		LM_ERR("error while submitting query\n");
+		return -2;
+	}
+
+	if(_r) {
+		int tmp = store_result(_h, _r);
+		if (tmp < 0) {
+			LM_ERR("error while storing result");
+			return tmp;
+		}
+	}
+
+	return 0;
+
+error:
+	LM_ERR("error while preparing query\n");
+	return -1;
+}
+
+
+int db_do_raw_query(const db_con_t* _h, const char* _s, db_res_t** _r, 
+	int (*submit_query)(const db_con_t* _h, const char* _c),
+	int (*store_result)(const db_con_t* _h, db_res_t** _r))
+{
+	if (!_h || !_s || !submit_query || !store_result) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	if (submit_query(_h, _s) < 0) {
+		LM_ERR("error while submitting query\n");
+		return -2;
+	}
+
+	if(_r) {
+		int tmp = store_result(_h, _r);
+		if (tmp < 0) {
+			LM_ERR("error while storing result");
+			return tmp;
+		}
+	}
+	return 0;
+}
+
+
+int db_do_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
+	const int _n, int (*val2str) (const db_con_t*, const db_val_t*, char*, int*), 
+	int (*submit_query)(const db_con_t* _h, const char* _c))
+{
+	int off, ret;
+
+	if (!_h || !_k || !_v || !_n || !val2str || !submit_query) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	ret = snprintf(sql_buf, SQL_BUF_LEN, "insert into %s (", CON_TABLE(_h));
+	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	off = ret;
+
+	ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
+	if (ret < 0) return -1;
+	off += ret;
+
+	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
+	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+	off += ret;
+
+	ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n, val2str);
+	if (ret < 0) return -1;
+	off += ret;
+
+	*(sql_buf + off++) = ')';
+	*(sql_buf + off) = '\0';
+
+	if (submit_query(_h, sql_buf) < 0) {
+	        LM_ERR("error while submitting query\n");
+		return -2;
+	}
+	return 0;
+
+error:
+	LM_ERR("error while preparing insert operation\n");
+	return -1;
+}
+
+
+int db_do_delete(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
+	const db_val_t* _v, const int _n, int (*val2str) (const db_con_t*,
+	const db_val_t*, char*, int*), int (*submit_query)(const db_con_t* _h,
+	const char* _c))
+{
+	int off, ret;
+
+	if (!_h || !val2str || !submit_query) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	ret = snprintf(sql_buf, SQL_BUF_LEN, "delete from %s", CON_TABLE(_h));
+	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	off = ret;
+
+	if (_n) {
+		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");
+		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		off += ret;
+
+		ret = db_print_where(_h, sql_buf + off,
+				SQL_BUF_LEN - off, _k, _o, _v, _n, val2str);
+		if (ret < 0) return -1;
+		off += ret;
+	}
+
+	*(sql_buf + off) = '\0';
+	if (submit_query(_h, sql_buf) < 0) {
+		LM_ERR("error while submitting query\n");
+		return -2;
+	}
+	return 0;
+
+error:
+	LM_ERR("error while preparing delete operation\n");
+	return -1;
+}
+
+
+int db_do_update(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
+	const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n,
+	const int _un, int (*val2str) (const db_con_t*, const db_val_t*, char*, int*),
+	int (*submit_query)(const db_con_t* _h, const char* _c))
+{
+	int off, ret;
+
+	if (!_h || !_uk || !_uv || !_un || !val2str || !submit_query) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	ret = snprintf(sql_buf, SQL_BUF_LEN, "update %s set ", CON_TABLE(_h));
+	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	off = ret;
+
+	ret = db_print_set(_h, sql_buf + off, SQL_BUF_LEN - off, _uk, _uv, _un, val2str);
+	if (ret < 0) return -1;
+	off += ret;
+
+	if (_n) {
+		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");
+		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+		off += ret;
+
+		ret = db_print_where(_h, sql_buf + off, SQL_BUF_LEN - off, _k, _o, _v, _n, val2str);
+		if (ret < 0) return -1;
+		off += ret;
+
+		*(sql_buf + off) = '\0';
+	}
+
+	if (submit_query(_h, sql_buf) < 0) {
+		LM_ERR("error while submitting query\n");
+		return -2;
+	}
+	return 0;
+
+error:
+	LM_ERR("error while preparing update operation\n");
+	return -1;
+}
+
+
+int db_do_replace(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
+	const int _n, int (*val2str) (const db_con_t*, const db_val_t*, char*,
+	int*), int (*submit_query)(const db_con_t* _h, const char* _c))
+{
+	int off, ret;
+
+	if (!_h || !_k || !_v || !val2str|| !submit_query) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	ret = snprintf(sql_buf, SQL_BUF_LEN, "replace %s (", CON_TABLE(_h));
+	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
+	off = ret;
+
+	ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
+	if (ret < 0) return -1;
+	off += ret;
+
+	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
+	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
+	off += ret;
+
+	ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n,
+	val2str);
+	if (ret < 0) return -1;
+	off += ret;
+
+	*(sql_buf + off++) = ')';
+	*(sql_buf + off) = '\0';
+
+	if (submit_query(_h, sql_buf) < 0) {
+	        LM_ERR("error while submitting query\n");
+		return -2;
+	}
+	return 0;
+
+ error:
+	LM_ERR("error while preparing replace operation\n");
+	return -1;
+}

+ 188 - 0
lib/srdb1/db_query.h

@@ -0,0 +1,188 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2007-2008 1&1 Internet AG
+ *
+ * This file is part of openser, a free SIP server.
+ *
+ * openser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * openser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/**
+ * \file db/db_query.h
+ * \brief Query helper for database drivers
+ *
+ * This helper methods for database queries are used from the database
+ * SQL driver to do the actual work. Each function uses some functions from
+ * the actual driver with function pointers to the concrete, specific
+ * implementation.
+*/
+
+#ifndef DB_QUERY_H
+#define DB_QUERY_H
+
+#include "db_key.h"
+#include "db_op.h"
+#include "db_val.h"
+#include "db_con.h"
+#include "db_row.h"
+#include "db_res.h"
+#include "db_cap.h"
+
+
+/**
+ * \brief Helper function for db queries
+ *
+ * This method evaluates the actual arguments for the database query and
+ * setups the string that is used for the query in the db module.
+ * Then its submit the query and stores the result if necessary. It uses for
+ * its work the implementation in the concrete database module.
+ *
+ * \param _h structure representing database connection
+ * \param _k key names, if not present the whole table will be returned
+ * \param _op operators
+ * \param _v values of the keys that must match
+ * \param _c column names that should be returned
+ * \param _n number of key/value pairs that are compared, if zero then no comparison is done
+ * \param _nc number of colums that should be returned
+ * \param _o order by the specificied column, optional
+ * \param _r the result that is returned
+ * \param (*val2str) function pointer to the db specific val conversion function
+ * \param (*submit_query) function pointer to the db specific query submit function
+ * \param (*store_result) function pointer to the db specific store result function
+ * \return zero on success, negative on errors
+ */
+int db_do_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op,
+	const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
+	const db_key_t _o, db_res_t** _r, int (*val2str) (const db_con_t*,
+	const db_val_t*, char*, int*), int (*submit_query)(const db_con_t* _h,
+	const char* _c), int (*store_result)(const db_con_t* _h, db_res_t** _r));
+
+
+/**
+ * \brief Helper function for raw db queries
+ *
+ * This method evaluates the actual arguments for the database raw query
+ * and setups the string that is used for the query in the db module.
+ * Then its submit the query and stores the result if necessary.
+ * It uses for its work the implementation in the concrete database module.
+ *
+ * \param _h structure representing database connection
+ * \param _s char holding the raw query
+ * \param _r the result that is returned
+ * \param (*val2str) function pointer to the db specific val conversion function
+ * \param (*submit_query) function pointer to the db specific query submit function
+ * \param (*store_result) function pointer to the db specific store result function
+ * \return zero on success, negative on errors
+ */
+int db_do_raw_query(const db_con_t* _h, const char* _s, db_res_t** _r,
+	int (*submit_query)(const db_con_t* _h, const char* _c),
+	int (*store_result)(const db_con_t* _h, db_res_t** _r));
+
+
+/**
+ * \brief Helper function for db insert operations
+ *
+ * This method evaluates the actual arguments for the database operation
+ * and setups the string that is used for the insert operation in the db
+ * module. Then its submit the query for the operation. It uses for its work
+ * the implementation in the concrete database module.
+ *
+ * \param _h structure representing database connection
+ * \param _k key names
+ * \param _v values of the keys
+ * \param _n number of key/value pairs 
+ * \param (*val2str) function pointer to the db specific val conversion function
+ * \param (*submit_query) function pointer to the db specific query submit function
+ * \return zero on success, negative on errors
+ */
+int db_do_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
+	const int _n, int (*val2str) (const db_con_t*, const db_val_t*, char*, int*),
+	int (*submit_query)(const db_con_t* _h, const char* _c));
+
+
+/**
+ * \brief Helper function for db delete operations
+ *
+ * This method evaluates the actual arguments for the database operation
+ * and setups the string that is used for the delete operation in the db
+ * module. Then its submit the query for the operation. It uses for its work
+ * the implementation in the concrete database module.
+ *
+ * \param _h structure representing database connection
+ * \param _k key names
+ * \param _o operators
+ * \param _v values of the keys that must match
+ * \param _n number of key/value pairs that are compared, if zero then the whole table is deleted
+ * \param (*val2str) function pointer to the db specific val conversion function
+ * \param (*submit_query) function pointer to the db specific query submit function
+ * \return zero on success, negative on errors
+ */
+int db_do_delete(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
+	const db_val_t* _v, const int _n, int (*val2str) (const db_con_t*,
+	const db_val_t*, char*, int*), int (*submit_query)(const db_con_t* _h,
+	const char* _c));
+
+
+/**
+ * \brief Helper function for db update operations
+ *
+ * This method evaluates the actual arguments for the database operation
+ * and setups the string that is used for the update operation in the db
+ * module. Then its submit the query for the operation. It uses for its work
+ * the implementation in the concrete database module.
+ *
+ * \param _h structure representing database connection
+ * \param _k key names, if not present the whole table will be returned
+ * \param _o operators
+ * \param _v values of the keys that must match
+ * \param _uk: updated columns
+ * \param _uv: updated values of the columns
+ * \param _n number of key/value pairs that are compared, if zero then no comparison is done
+ * \param _un: number of columns that should be updated
+ * \param (*val2str) function pointer to the db specific val conversion function
+ * \param (*submit_query) function pointer to the db specific query submit function
+ * \return zero on success, negative on errors
+ */
+int db_do_update(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
+	const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n,
+	const int _un, int (*val2str) (const db_con_t*, const db_val_t*, char*, int*),
+	int (*submit_query)(const db_con_t* _h, const char* _c));
+
+
+/**
+ * \brief Helper function for db delete operations
+ *
+ * This helper method evaluates the actual arguments for the database operation
+ * and setups the string that is used for the replace operation in the db
+ * module. Then its submit the query for the operation. It uses for its work the
+ * implementation in the concrete database module.
+ *
+ * \param _h structure representing database connection
+ * \param _k key names, if not present the whole table will be returned
+ * \param _v values of the keys that must match
+ * \param _n number of key/value pairs that are compared, if zero then no comparison is done
+ * \param _un: number of columns that should be updated
+ * \param (*val2str) function pointer to the db specific val conversion function
+ * \param (*submit_query) function pointer to the db specific query submit function
+ * \return zero on success, negative on errors
+ */
+int db_do_replace(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
+	const int _n, int (*val2str) (const db_con_t*, const db_val_t*, char*,
+	int*), int (*submit_query)(const db_con_t* _h, const char* _c));
+
+
+#endif

+ 25 - 1
lib/srdb1/db_res.c

@@ -2,7 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
- * Copyright (C) 2007 1und1 Internet AG
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -21,6 +21,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_res.c
+ * \brief Functions to manage result structures
+ *
+ * Provides some convenience macros and some memory management
+ * functions for result structures.
+ */
+
 #include "db_res.h"
 #include "db_res.h"
 
 
 #include "db_row.h"
 #include "db_row.h"
@@ -57,6 +65,22 @@ inline int db_free_rows(db_res_t* _r)
 }
 }
 
 
 
 
+/*
+ * Release memory used by columns
+ */
+inline int db_free_columns(db_res_t* _r)
+{
+	if (!_r) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	if (RES_NAMES(_r)) pkg_free(RES_NAMES(_r));
+	if (RES_TYPES(_r)) pkg_free(RES_TYPES(_r));
+	return 0;
+}
+
+
 /*
 /*
  * Create a new result structure and initialize it
  * Create a new result structure and initialize it
  */
  */

+ 50 - 10
lib/srdb1/db_res.h

@@ -2,6 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,6 +21,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_res.h
+ * \brief Data structure that represents a result from a query.
+ *
+ * Data structure that represents a result from a database query,
+ * it also provides some convenience macros and some memory management
+ * functions for result structures.
+ */
 
 
 #ifndef DB_RES_H
 #ifndef DB_RES_H
 #define DB_RES_H
 #define DB_RES_H
@@ -30,34 +39,65 @@
 #include "db_val.h"
 #include "db_val.h"
 
 
 
 
+/**
+ * This type represents a result returned by db_query function (see below). The 
+ * result can consist of zero or more rows (see db_row_t description).
+ * 
+ * Note: A variable of type db_res_t returned by db_query function uses dynamicaly
+ * allocated memory, don't forget to call db_free_result if you don't need the
+ * variable anymore. You will encounter memory leaks if you fail to do this!
+ *
+ * In addition to zero or more rows, each db_res_t object contains also an array
+ * of db_key_t objects. The objects represent keys (names of columns).
+ */
 typedef struct db_res {
 typedef struct db_res {
 	struct {
 	struct {
-		db_key_t* names;   /* Column names */
-		db_type_t* types;  /* Column types */
-		int n;             /* Number of columns */
+		db_key_t* names;   /**< Column names                    */
+		db_type_t* types;  /**< Column types                    */
+		int n;             /**< Number of columns               */
 	} col;
 	} col;
-	struct db_row* rows;       /* Rows */
-	int n;                     /* Number of rows in current fetch */
-	int res_rows;              /* Number of total rows in query */
-	int last_row;              /* Last row */
+	struct db_row* rows;   /**< Rows                            */
+	int n;                 /**< Number of rows in current fetch */
+	int res_rows;          /**< Number of total rows in query   */
+	int last_row;          /**< Last row                        */
 } db_res_t;
 } db_res_t;
 
 
 
 
+/** Return the column names */
 #define RES_NAMES(re) ((re)->col.names)
 #define RES_NAMES(re) ((re)->col.names)
+/** Return the column types */
 #define RES_TYPES(re) ((re)->col.types)
 #define RES_TYPES(re) ((re)->col.types)
+/** Return the number of columns */
 #define RES_COL_N(re) ((re)->col.n)
 #define RES_COL_N(re) ((re)->col.n)
+/** Return the result rows */
 #define RES_ROWS(re)  ((re)->rows)
 #define RES_ROWS(re)  ((re)->rows)
+/** Return the number of current result rows */
 #define RES_ROW_N(re) ((re)->n)
 #define RES_ROW_N(re) ((re)->n)
+/** Return the last row of the result */
 #define RES_LAST_ROW(re)  ((re)->last_row)
 #define RES_LAST_ROW(re)  ((re)->last_row)
+/** Return the number of total result rows */
 #define RES_NUM_ROWS(re) ((re)->res_rows)
 #define RES_NUM_ROWS(re) ((re)->res_rows)
 
 
-/*
+
+/**
  * Release memory used by rows in a result structure
  * Release memory used by rows in a result structure
+ * \param _r the result that should be released
+ * \return zero on success, negative on errors
  */
  */
-int db_free_rows(db_res_t* _r);
+inline int db_free_rows(db_res_t* _r);
+
+
+/**
+ * Release memory used by columns
+ * \param _r the result that should be released
+ * \return zero on success, negative on errors
+ */
+int db_free_columns(db_res_t* _r);
+
 
 
-/*
+/**
  * Create a new result structure and initialize it
  * Create a new result structure and initialize it
+ * \return a pointer to the new result on success, NULL on errors
  */
  */
 inline db_res_t* db_new_result(void);
 inline db_res_t* db_new_result(void);
 
 

+ 9 - 1
lib/srdb1/db_row.c

@@ -2,7 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
- * Copyright (C) 2007 1und1 Internet AG
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -21,6 +21,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_row.c
+ * \brief Type that represents a row in a database.
+ *
+ * This file holds a type that represents a row in a database, some convenience
+ * macros and a function for memory managements.
+ */
+
 #include "db_row.h"
 #include "db_row.h"
 
 
 #include "../dprint.h"
 #include "../dprint.h"

+ 21 - 6
lib/srdb1/db_row.h

@@ -2,6 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,6 +21,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_row.h
+ * \brief Type that represents a row in a database.
+ *
+ * This file holds a type that represents a row in a database, some convenience
+ * macros and a function for memory managements.
+ */
+
 
 
 #ifndef DB_ROW_H
 #ifndef DB_ROW_H
 #define DB_ROW_H
 #define DB_ROW_H
@@ -27,20 +36,26 @@
 #include "db_val.h"
 #include "db_val.h"
 
 
 
 
-/*
- * Structure holding result of query_table function (ie. table row)
+/**
+ * Structure holding the result of a query table function.
+ * It represents one row in a database table. In other words, the row is an
+ * array of db_val_t variables, where each db_val_t variable represents exactly
+ * one cell in the table.
  */
  */
 typedef struct db_row {
 typedef struct db_row {
-	db_val_t* values;  /* Columns in the row */
-	int n;             /* Number of columns in the row */
+	db_val_t* values;  /**< Columns in the row */
+	int n;             /**< Number of columns in the row */
 } db_row_t;
 } db_row_t;
 
 
-
+/** Return the columns in the row */
 #define ROW_VALUES(rw) ((rw)->values)
 #define ROW_VALUES(rw) ((rw)->values)
+/** Return the number of rows */
 #define ROW_N(rw)      ((rw)->n)
 #define ROW_N(rw)      ((rw)->n)
 
 
-/*
+/**
  * Release memory used by row
  * Release memory used by row
+ * \param _r the row that should be released
+ * \return zero on success, negative on error
  */
  */
 int db_free_row(db_row_t* _r);
 int db_free_row(db_row_t* _r);
 
 

+ 28 - 49
lib/srdb1/db_ut.c

@@ -2,7 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
- * Copyright (C) 2007 1und1 Internet AG
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -21,33 +21,25 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_ut.c
+ * \brief Utility functions for database drivers.
+ *
+ * This utility methods are used from the database SQL driver to convert
+ * values and print SQL queries from the internal API representation.
+ */
 
 
 #include "db_ut.h"
 #include "db_ut.h"
-#include "db.h"
 
 
+#include "../mem/mem.h"
 #include "../dprint.h"
 #include "../dprint.h"
 #include <limits.h>
 #include <limits.h>
 #include <errno.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
-#include <strings.h>
-
-/**
- * \file db_ut.c
- * \brief Utility functions that are needed from database drivers.
- *
- * Contains methods for datatype conversation in both directions 
- * and some SQL print functions.
- */
 
 
 
 
-/**
- * Convert a string to integer
- * \param _s source string
- * \param _v target value
- * \return -1 on error, 0 on success
- */
 inline int db_str2int(const char* _s, int* _v)
 inline int db_str2int(const char* _s, int* _v)
 {
 {
 	long tmp;
 	long tmp;
@@ -163,16 +155,6 @@ inline int db_str2time(const char* _s, time_t* _v)
 }
 }
 
 
 
 
-/**
- * Convert a time_t value to string
- * \param _v source value
- * \param _s target string
- * \param _l available length and target length
- * \return -1 on error, 0 on success
- * \todo This functions add quotes to the time value. This
- * should be done in the val2str function, as some databases
- * like db_berkeley don't need or like this at all.
- */
 inline int db_time2str(time_t _v, char* _s, int* _l)
 inline int db_time2str(time_t _v, char* _s, int* _l)
 {
 {
 	struct tm* t;
 	struct tm* t;
@@ -207,10 +189,9 @@ inline int db_time2str(time_t _v, char* _s, int* _l)
 /*
 /*
  * Print list of columns separated by comma
  * Print list of columns separated by comma
  */
  */
-inline int db_print_columns(char* _b, int _l, db_key_t* _c, int _n)
+inline int db_print_columns(char* _b, const int _l, const db_key_t* _c, const int _n)
 {
 {
-	int i, ret;
-	int len = 0;
+	int i, ret, len = 0;
 
 
 	if ((!_c) || (!_n) || (!_b) || (!_l)) {
 	if ((!_c) || (!_n) || (!_b) || (!_l)) {
 		LM_ERR("Invalid parameter value\n");
 		LM_ERR("Invalid parameter value\n");
@@ -239,10 +220,10 @@ inline int db_print_columns(char* _b, int _l, db_key_t* _c, int _n)
 /*
 /*
  * Print values of SQL statement
  * Print values of SQL statement
  */
  */
-int db_print_values(db_con_t* _c, char* _b, int _l, db_val_t* _v, int _n,
-		int (*val2str)() )
+int db_print_values(const db_con_t* _c, char* _b, const int _l, const db_val_t* _v,
+	const int _n, int (*val2str)(const db_con_t*, const db_val_t*, char*, int*))
 {
 {
-	int i, res = 0, l;  
+	int i, l, len = 0;
 
 
 	if (!_c || !_b || !_l || !_v || !_n) {
 	if (!_c || !_b || !_l || !_v || !_n) {
 		LM_ERR("Invalid parameter value\n");
 		LM_ERR("Invalid parameter value\n");
@@ -250,30 +231,29 @@ int db_print_values(db_con_t* _c, char* _b, int _l, db_val_t* _v, int _n,
 	}
 	}
 
 
 	for(i = 0; i < _n; i++) {
 	for(i = 0; i < _n; i++) {
-		l = _l - res;
-		if ( (*val2str)(_c, _v + i, _b + res, &l) < 0) {
+		l = _l - len;
+		if ( (*val2str)(_c, _v + i, _b + len, &l) < 0) {
 			LM_ERR("Error while converting value to string\n");
 			LM_ERR("Error while converting value to string\n");
 			return -1;
 			return -1;
 		}
 		}
-		res += l;
+		len += l;
 		if (i != (_n - 1)) {
 		if (i != (_n - 1)) {
-			*(_b + res) = ',';
-			res++;
+			*(_b + len) = ',';
+			len++;
 		}
 		}
 	}
 	}
-	return res;
+	return len;
 }
 }
 
 
 
 
 /*
 /*
  * Print where clause of SQL statement
  * Print where clause of SQL statement
  */
  */
-int db_print_where(db_con_t* _c, char* _b, int _l, db_key_t* _k, db_op_t* _o,
-		db_val_t* _v, int _n, int (*val2str)() )
+int db_print_where(const db_con_t* _c, char* _b, const int _l, const db_key_t* _k,
+	const db_op_t* _o, const db_val_t* _v, const int _n, int (*val2str)
+	(const 	db_con_t*, const db_val_t*, char*, int*))
 {
 {
-	int i;
-	int len = 0, ret;
-	int l;
+	int i, l, ret, len = 0;
 
 
 	if (!_c || !_b || !_l || !_k || !_v || !_n) {
 	if (!_c || !_b || !_l || !_k || !_v || !_n) {
 		LM_ERR("Invalid parameter value\n");
 		LM_ERR("Invalid parameter value\n");
@@ -310,12 +290,11 @@ int db_print_where(db_con_t* _c, char* _b, int _l, db_key_t* _k, db_op_t* _o,
 /*
 /*
  * Print set clause of update SQL statement
  * Print set clause of update SQL statement
  */
  */
-int db_print_set(db_con_t* _c, char* _b, int _l, db_key_t* _k, db_val_t* _v,
-		int _n, int (*val2str)() )
+int db_print_set(const db_con_t* _c, char* _b, const int _l, const db_key_t* _k,
+	const db_val_t* _v, const int _n, int (*val2str)(const db_con_t*,
+	const db_val_t*,char*, int*))
 {
 {
-	int i;
-	int len = 0, ret;
-	int l;
+	int i, l, ret, len = 0;
 
 
 	if (!_c || !_b || !_l || !_k || !_v || !_n) {
 	if (!_c || !_b || !_l || !_k || !_v || !_n) {
 		LM_ERR("Invalid parameter value\n");
 		LM_ERR("Invalid parameter value\n");

+ 130 - 6
lib/srdb1/db_ut.h

@@ -2,7 +2,7 @@
  * $Id$
  * $Id$
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
- * Copyright (C) 2007 1und1 Internet AG
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -21,12 +21,26 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_ut.h
+ * \brief Utility functions for database drivers.
+ *
+ * This utility methods are used from the database SQL driver to convert
+ * values and print SQL queries from the internal API representation.
+*/
 
 
 #ifndef DB_UT_H
 #ifndef DB_UT_H
 #define DB_UT_H
 #define DB_UT_H
 
 
+/**
+ * maximal SQL buffer length for database drivers
+ */
+#define SQL_BUF_LEN 65536
 
 
-/* for strptime, use 600 for 'Single UNIX Specification, Version 3' */
+/**
+ * make strptime available
+ * use 600 for 'Single UNIX Specification, Version 3'
+ */
 #define _XOPEN_SOURCE 600          /* glibc2 on linux, bsd */
 #define _XOPEN_SOURCE 600          /* glibc2 on linux, bsd */
 #define _XOPEN_SOURCE_EXTENDED 1   /* solaris */
 #define _XOPEN_SOURCE_EXTENDED 1   /* solaris */
 
 
@@ -38,22 +52,132 @@
 #include "db_key.h"
 #include "db_key.h"
 #include "db.h"
 #include "db.h"
 
 
+
+/**
+ * Converts a char into an integer value.
+ *
+ * \param _s source value
+ * \param _v target value
+ * \return zero on sucess, negative on conversion errors
+ */
 int db_str2int(const char* _s, int* _v);
 int db_str2int(const char* _s, int* _v);
 
 
+
+/**
+ * Converts a char into a double value.
+ *
+ * \param _s source value
+ * \param _v target value
+ * \return zero on sucess, negative on conversion errors
+ */
 int db_str2double(const char* _s, double* _v);
 int db_str2double(const char* _s, double* _v);
 
 
+
+/**
+ * Converts a integer value in a char pointer.
+ *
+ * \param _v source value
+ * \param _s target value
+ * \param _l available length and target length
+ * \return zero on sucess, negative on conversion errors
+ */
 int db_int2str(int _v, char* _s, int* _l);
 int db_int2str(int _v, char* _s, int* _l);
 
 
+
+/**
+ * Converts a double value into a char pointer.
+ *
+ * \param _v source value
+ * \param _s target value
+ * \param _l available length and target length
+ * \return zero on sucess, negative on conversion errors
+ */
 int db_double2str(double _v, char* _s, int* _l);
 int db_double2str(double _v, char* _s, int* _l);
 
 
+
+/**
+ * Convert a time_t value to string.
+ *
+ * \param _v source value
+ * \param _s target value
+ * \param _l available length and target length
+ * \return zero on sucess, negative on conversion errors
+ * \todo This functions add quotes to the time value. This
+ * should be done in the val2str function, as some databases
+ * like db_berkeley don't need or like this at all.
+ */
 int db_time2str(time_t _v, char* _s, int* _l);
 int db_time2str(time_t _v, char* _s, int* _l);
 
 
+
+/**
+ * Converts a char into a time_t value.
+ *
+ * \param _s source value
+ * \param _v target value
+ * \return zero on sucess, negative on conversion errors
+ */
 int db_str2time(const char* _s, time_t* _v);
 int db_str2time(const char* _s, time_t* _v);
 
 
-int db_print_columns(char* _b, int _l, db_key_t* _c, int _n);
 
 
-int db_print_values(db_con_t* _c, char* _b, int _l, db_val_t* _v, int _n, int (*val2str)() );
-int db_print_where(db_con_t* _c, char* _b, int _l, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n, int (*val2str)() );
-int db_print_set(db_con_t* _c, char* _b, int _l, db_key_t* _k, db_val_t* _v, int _n, int (*val2str)() );
+/**
+ * Print columns for a SQL statement, separated by commas.
+ *
+ * \param _b target char
+ * \param _l length of the target
+ * \param _c keys that should be printed
+ * \param _n number of keys
+ * \return the length of the printed result on success, negative on errors
+ */
+int db_print_columns(char* _b, const int _l, const db_key_t* _c, const int _n);
+
+
+/**
+ * Print values for a SQL statement.
+ *
+ * \param _c structure representing database connection
+ * \param _b target char
+ * \param _l length of the target
+ * \param _v values that should be printed
+ * \param _n number of values
+ * \param  (*val2str) function pointer to a db specific conversion function
+ * \return the length of the printed result on success, negative on errors
+ */
+int db_print_values(const db_con_t* _c, char* _b, const int _l, const db_val_t* _v,
+	const int _n, int (*val2str)(const db_con_t*, const db_val_t*, char*, int*));
+
+
+/**
+ * Print where clause for a SQL statement.
+ *
+ * \param _c structure representing database connection
+ * \param _b target char
+ * \param _l length of the target
+ * \param _k keys that should be printed
+ * \param _o optional operators
+ * \param _v values that should be printed
+ * \param _n number of key/value pairs
+ * \param  (*val2str) function pointer to a db specific conversion function
+ * \return the length of the printed result on success, negative on errors
+ */
+int db_print_where(const db_con_t* _c, char* _b, const int _l, const db_key_t* _k,
+	const db_op_t* _o, const db_val_t* _v, const int _n, int (*val2str)
+	(const 	db_con_t*, const db_val_t*, char*, int*));
+
+
+/**
+ * Print set clause for a SQL statement.
+ *
+ * \param _c structure representing database connection
+ * \param _b target char
+ * \param _l length of the target
+ * \param _k keys that should be printed
+ * \param _v vals that should be printed
+ * \param _n number of key/value pairs
+ * \param  (*val2str) function pointer to a db specific conversion function
+ * \return the length of the printed result on success, negative on errors
+ */
+int db_print_set(const db_con_t* _c, char* _b, const int _l,
+	const db_key_t* _k, const db_val_t* _v, const int _n, int (*val2str)
+	(const db_con_t*, const db_val_t*, char*, int*));
 
 
 #endif
 #endif

+ 88 - 25
lib/srdb1/db_val.h

@@ -2,6 +2,7 @@
  * $Id$ 
  * $Id$ 
  *
  *
  * Copyright (C) 2001-2003 FhG Fokus
  * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2007-2008 1&1 Internet AG
  *
  *
  * This file is part of openser, a free SIP server.
  * This file is part of openser, a free SIP server.
  *
  *
@@ -20,6 +21,16 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+/**
+ * \file db/db_val.h
+ * \brief Data structures that represents values in the database.
+ *
+ * This file defines data structures that represents values in the database.
+ * Several datatypes are recognized and converted by the database API.
+ * Available types: DB_INT, DB_DOUBLE, DB_STRING, DB_STR, DB_DATETIME, DB_BLOB and DB_BITMAP
+ * It also provides some macros for convenient access to this values.
+ */
+
 
 
 #ifndef DB_VAL_H
 #ifndef DB_VAL_H
 #define DB_VAL_H
 #define DB_VAL_H
@@ -28,51 +39,103 @@
 #include "../str.h"
 #include "../str.h"
 
 
 
 
-/*
- * Accepted value types
+/**
+ * Each cell in a database table can be of a different type. To distinguish
+ * among these types, the db_type_t enumeration is used. Every value of the
+ * enumeration represents one datatype that is recognized by the database
+ * API.
  */
  */
 typedef enum {
 typedef enum {
-	DB_INT,        /* 32-bit integer */
-	DB_DOUBLE,     /* double data type */
-	DB_STRING,     /* Zero-terminated string */
-	DB_STR,        /* str structure */
-	DB_DATETIME,   /* Date and time */
-	DB_BLOB,       /* Large binary object */
-	DB_BITMAP      /* Bitmap of flags */
+	DB_INT,        /**< represents an 32 bit integer number */
+	DB_DOUBLE,     /**< represents a floating point number  */
+	DB_STRING,     /**< represents a zero terminated string */
+	DB_STR,        /**< represents a string of 'str' type   */
+	DB_DATETIME,   /**< represents date and time            */
+	DB_BLOB,       /**< represents a large binary object    */
+	DB_BITMAP      /**< an one-dimensional array of flags   */
 } db_type_t;
 } db_type_t;
 
 
 
 
-/*
- * Column value structure
+/**
+ * This structure represents a value in the database. Several datatypes are
+ * recognized and converted by the database API. These datatypes are automaticaly
+ * recognized, converted from internal database representation and stored in the
+ * variable of corresponding type.
  */
  */
 typedef struct {
 typedef struct {
-	db_type_t type;                /* Type of the value */
-	int nul;                       /* Means that the column in database
-					* has no value 
-					*/
+	db_type_t type; /** Type of the value                              */
+	int nul;        /** Means that the column in database has no value */
+	/** Column value structure that holds the actual data in a union.  */
 	union {
 	union {
-		int           int_val;    /* integer value */
-		double        double_val; /* double value */
-		time_t        time_val;   /* unix time value */
-		const char*   string_val; /* NULL terminated string */
-		str           str_val;    /* str string value */
-		str           blob_val;   /* Blob data */
-		unsigned int  bitmap_val; /* Bitmap data type, 32 flags, should be enough */ 
-	} val;                            /* union of all possible types */
+		int           int_val;    /**< integer value              */
+		double        double_val; /**< double value               */
+		time_t        time_val;   /**< unix time_t value          */
+		const char*   string_val; /**< zero terminated string     */
+		str           str_val;    /**< str string value           */
+		str           blob_val;   /**< binary object data         */
+		unsigned int  bitmap_val; /**< Bitmap data type, 32 flags */
+	} val;
 } db_val_t;
 } db_val_t;
 
 
 
 
-/*
- * Useful macros for accessing attributes of db_val structure
+/**
+ * Useful macros for accessing attributes of db_val structure.
+ * All macros expect a reference to a db_val_t variable as parameter.
+ */
+
+/**
+ * Use this macro if you need to set/get the type of the value.
  */
  */
 #define VAL_TYPE(dv)   ((dv)->type)
 #define VAL_TYPE(dv)   ((dv)->type)
+
+
+/**
+ * Use this macro if you need to set/get the null flag. A non-zero flag means that
+ * the corresponding cell in the database contains no data (a NULL value in MySQL
+ * terminology).
+ */
 #define VAL_NULL(dv)   ((dv)->nul)
 #define VAL_NULL(dv)   ((dv)->nul)
+
+
+/**
+ * Use this macro if you need to access the integer value in the db_val_t structure.
+ */
 #define VAL_INT(dv)    ((dv)->val.int_val)
 #define VAL_INT(dv)    ((dv)->val.int_val)
+
+
+/**
+ * Use this macro if you need to access the double value in the db_val_t structure.
+ */
 #define VAL_DOUBLE(dv) ((dv)->val.double_val)
 #define VAL_DOUBLE(dv) ((dv)->val.double_val)
+
+
+/**
+ * Use this macro if you need to access the time_t value in the db_val_t structure.
+ */
 #define VAL_TIME(dv)   ((dv)->val.time_val)
 #define VAL_TIME(dv)   ((dv)->val.time_val)
+
+
+/**
+ * Use this macro if you need to access the string value in the db_val_t structure.
+ */
 #define VAL_STRING(dv) ((dv)->val.string_val)
 #define VAL_STRING(dv) ((dv)->val.string_val)
+
+
+/**
+ * Use this macro if you need to access the str structure in the db_val_t structure.
+ */
 #define VAL_STR(dv)    ((dv)->val.str_val)
 #define VAL_STR(dv)    ((dv)->val.str_val)
+
+
+/**
+ * Use this macro if you need to access the blob value in the db_val_t structure.
+ */
 #define VAL_BLOB(dv)   ((dv)->val.blob_val)
 #define VAL_BLOB(dv)   ((dv)->val.blob_val)
+
+
+/**
+ * Use this macro if you need to access the bitmap value in the db_val_t structure.
+ */
 #define VAL_BITMAP(dv) ((dv)->val.bitmap_val)
 #define VAL_BITMAP(dv) ((dv)->val.bitmap_val)