db_gen.h

00001 /* 
00002  * $Id$ 
00003  *
00004  * Copyright (C) 2001-2003 FhG FOKUS
00005  * Copyright (C) 2006-2007 iptelorg GmbH
00006  *
00007  * This file is part of ser, a free SIP server.
00008  *
00009  * ser is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * For a license to use the ser software under conditions
00015  * other than those described here, or to purchase support for this
00016  * software, please contact iptel.org by e-mail at the following addresses:
00017  *    info@iptel.org
00018  *
00019  * ser is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU General Public License 
00025  * along with this program; if not, write to the Free Software 
00026  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  */
00028 
00029 #ifndef _DB_GEN_H
00030 #define _DB_GEN_H  1
00031 
00036 #include "db_drv.h"
00037 #include "../../str.h"
00038 #include "../../list.h"
00039 
00040 
00041 #ifdef __cplusplus
00042 extern "C" {
00043 #endif /* __cplusplus */
00044 
00045 /*
00046  * Declare a list of DB API structures with given structure
00047  * name
00048  */
00049 #define DBLIST_HEAD(name) \
00050         STAILQ_HEAD(name, db_gen)
00051 
00052 /*
00053  * All structures that ought to be members of the DB API
00054  * linked lists must have this element as the _first_
00055  * element in the structure
00056  */
00057 #define DBLIST_ENTRY \
00058         STAILQ_ENTRY(db_gen) next
00059 
00060 
00061 /*
00062  * Initialize the static head of linked lists of DB API
00063  * structures
00064  */
00065 #define DBLIST_INITIALIZER(head) \
00066         STAILQ_HEAD_INITIALIZER(head)
00067 
00068 /*
00069  * Initialize the head of the list
00070  */
00071 #define DBLIST_INIT(head) \
00072         STAILQ_INIT(head)
00073 
00074 #define DBLIST_FIRST(head) SLIST_FIRST(head)
00075 
00076 /*
00077  * Insert a new DB API structure at the beginning of the
00078  * linked list
00079  */
00080 #define DBLIST_INSERT_HEAD(head, elem) \
00081         STAILQ_INSERT_HEAD((head), (struct db_gen*)(elem), next)
00082 
00083 /*
00084  * Add an element at the tail of the list
00085  */
00086 #define DBLIST_INSERT_TAIL(head, elem) \
00087         STAILQ_INSERT_TAIL((head), ((struct db_gen*)(elem)), next)
00088 
00089 /*
00090  * Remove a given structure from a linked list of DB API
00091  * structures
00092  */
00093 #define DBLIST_REMOVE(head, elem) \
00094         STAILQ_REMOVE(head, (struct db_gen*)(elem), db_gen, next)
00095 
00096 /*
00097  * Remove a given structure from a linked list of DB API
00098  * structures
00099  */
00100 #define DBLIST_REMOVE_HEAD(head) \
00101         STAILQ_REMOVE_HEAD(head, next)
00102 
00103 /*
00104  * Iterate through the elements of the list, store
00105  * the pointer to the current element in var variable
00106  */
00107 
00108 /*
00109  * FIXME: We should find some other way of doing this than just copying
00110  * and pasting the code from STAILQ_FOREACH
00111  */
00112 #define DBLIST_FOREACH(var, head)                                \
00113         for((var) = (void*)STAILQ_FIRST((head));         \
00114                 (var);                                                               \
00115                 (var) = (void*)STAILQ_NEXT(((struct db_gen*)(var)), next))
00116 
00117 /*
00118  * Iterate through the elements of the list, the pointer
00119  * to the current element is stored in var variable, this
00120  * is the safe version of the macro which allows you to
00121  * remove the element from the list. tvar is a temporary
00122  * variable for internal use by the macro
00123  */
00124 
00125 /*
00126  * FIXME: We should find some other way of doing this than just copying
00127  * and pasting the code from STAILQ_FOREACH_SAFE
00128  */
00129 #define DBLIST_FOREACH_SAFE(var, head, tvar)                                     \
00130         for ((var) = (void*)STAILQ_FIRST((head));                                        \
00131                  (var) && ((tvar) = (void*)STAILQ_NEXT(((struct db_gen*)(var)), next), 1); \
00132                  (var) = (tvar))
00133 
00134 /*
00135  * Maximum number of payload structures that can be attached to
00136  * any DB API structure at a time.
00137  */
00138 #define DB_PAYLOAD_MAX 16
00139 
00140 struct db_drv;
00141 
00142 /*
00143  * Template for generic data structures defined in the
00144  * DB API. Drivers can cast structure pointers to this to
00145  * obtain the pointer to driver specific data
00146  *
00147  * All variables and attributes to be shared across all DB API
00148  * structures should be put into this structure. This structure
00149  * is at the beginnning of each DB API structure to ensure that
00150  * all DB API structures share some common variables.
00151  */
00152 typedef struct db_gen {
00153         DBLIST_ENTRY;
00154 
00155         /* Array of pointers to driver-specific data. The database API
00156          * supports access to multiple databases at the same time and each
00157          * database driver may want to append some data to generic DB structures,
00158          * hence an array. The current position in the array is stored 
00159          * in db_data_idx
00160          */
00161         struct db_drv* data[DB_PAYLOAD_MAX];
00162 } db_gen_t;
00163 
00164 /*
00165  * Global variable holding the current index of the payload of the driver that
00166  * is being executed. DB API is responsible for setting this vaiable before 
00167  * calling functions of DB drivers.
00168  */
00169 extern int db_payload_idx;
00170 
00171 
00172 /*
00173  * Macros to set/get variable (DB driver specific)
00174  * payload to/from generic DB API structures
00175  */
00176 
00177 
00178 /*
00179  * Attach a driver specific data structure to a generic 
00180  * DB API structure
00181  */
00182 #define DB_SET_PAYLOAD(db_struct, drv_data) do { \
00183     ((struct db_gen*)(db_struct))->data[db_payload_idx] = (struct db_drv*)(drv_data); \
00184 } while(0)
00185 
00186 
00187 /*
00188  * Return a driver specific data structure
00189  */
00190 #define DB_GET_PAYLOAD(db_struct) \
00191     ((void*)(((struct db_gen*)(db_struct))->data[db_payload_idx]))
00192 
00193 
00194 /*
00195  * Initialize a db_gen structure and make space for the data
00196  * from n database drivers
00197  */
00198 int db_gen_init(struct db_gen* gen);
00199 
00200 
00201 /*
00202  * Free all memory allocated by a db_gen structure
00203  */
00204 void db_gen_free(struct db_gen* gen);
00205 
00206 
00207 #ifdef __cplusplus
00208 }
00209 #endif /* __cplusplus */
00210 
00213 #endif /* _DB_GEN_H */