1 /* 2 * Copyright (C) 2001-2003 FhG FOKUS 3 * Copyright (C) 2006-2007 iptelorg GmbH 4 * 5 * This file is part of Kamailio, a free SIP server. 6 * 7 * Kamailio is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version 11 * 12 * Kamailio is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 #ifndef _DB_GEN_H 23 #define _DB_GEN_H 1 24 25 /** \ingroup DB_API 26 * @{ 27 */ 28 29 #include "db_drv.h" 30 #include "../../core/str.h" 31 #include "../../core/list.h" 32 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif /* __cplusplus */ 37 38 /* 39 * Declare a list of DB API structures with given structure 40 * name 41 */ 42 #define DBLIST_HEAD(name) \ 43 STAILQ_HEAD(name, db_gen) 44 45 /* 46 * All structures that ought to be members of the DB API 47 * linked lists must have this element as the _first_ 48 * element in the structure 49 */ 50 #define DBLIST_ENTRY \ 51 STAILQ_ENTRY(db_gen) next 52 53 54 /* 55 * Initialize the static head of linked lists of DB API 56 * structures 57 */ 58 #define DBLIST_INITIALIZER(head) \ 59 STAILQ_HEAD_INITIALIZER(head) 60 61 /* 62 * Initialize the head of the list 63 */ 64 #define DBLIST_INIT(head) \ 65 STAILQ_INIT(head) 66 67 #define DBLIST_FIRST(head) SLIST_FIRST(head) 68 69 /* 70 * Insert a new DB API structure at the beginning of the 71 * linked list 72 */ 73 #define DBLIST_INSERT_HEAD(head, elem) \ 74 STAILQ_INSERT_HEAD((head), (struct db_gen*)(elem), next) 75 76 /* 77 * Add an element at the tail of the list 78 */ 79 #define DBLIST_INSERT_TAIL(head, elem) \ 80 STAILQ_INSERT_TAIL((head), ((struct db_gen*)(elem)), next) 81 82 /* 83 * Remove a given structure from a linked list of DB API 84 * structures 85 */ 86 #define DBLIST_REMOVE(head, elem) \ 87 STAILQ_REMOVE(head, (struct db_gen*)(elem), db_gen, next) 88 89 /* 90 * Remove a given structure from a linked list of DB API 91 * structures 92 */ 93 #define DBLIST_REMOVE_HEAD(head) \ 94 STAILQ_REMOVE_HEAD(head, next) 95 96 /* 97 * Iterate through the elements of the list, store 98 * the pointer to the current element in var variable 99 */ 100 101 /* 102 * FIXME: We should find some other way of doing this than just copying 103 * and pasting the code from STAILQ_FOREACH 104 */ 105 #define DBLIST_FOREACH(var, head) \ 106 for((var) = (void*)STAILQ_FIRST((head)); \ 107 (var); \ 108 (var) = (void*)STAILQ_NEXT(((struct db_gen*)(var)), next)) 109 110 /* 111 * Iterate through the elements of the list, the pointer 112 * to the current element is stored in var variable, this 113 * is the safe version of the macro which allows you to 114 * remove the element from the list. tvar is a temporary 115 * variable for internal use by the macro 116 */ 117 118 /* 119 * FIXME: We should find some other way of doing this than just copying 120 * and pasting the code from STAILQ_FOREACH_SAFE 121 */ 122 #define DBLIST_FOREACH_SAFE(var, head, tvar) \ 123 for ((var) = (void*)STAILQ_FIRST((head)); \ 124 (var) && ((tvar) = (void*)STAILQ_NEXT(((struct db_gen*)(var)), next), 1); \ 125 (var) = (tvar)) 126 127 /* 128 * Maximum number of payload structures that can be attached to 129 * any DB API structure at a time. 130 */ 131 #define DB_PAYLOAD_MAX 16 132 133 struct db_drv; 134 135 /* 136 * Template for generic data structures defined in the 137 * DB API. Drivers can cast structure pointers to this to 138 * obtain the pointer to driver specific data 139 * 140 * All variables and attributes to be shared across all DB API 141 * structures should be put into this structure. This structure 142 * is at the beginnning of each DB API structure to ensure that 143 * all DB API structures share some common variables. 144 */ 145 typedef struct db_gen { 146 DBLIST_ENTRY; 147 148 /* Array of pointers to driver-specific data. The database API 149 * supports access to multiple databases at the same time and each 150 * database driver may want to append some data to generic DB structures, 151 * hence an array. The current position in the array is stored 152 * in db_data_idx 153 */ 154 struct db_drv* data[DB_PAYLOAD_MAX]; 155 } db_gen_t; 156 157 /* 158 * Global variable holding the current index of the payload of the driver that 159 * is being executed. DB API is responsible for setting this vaiable before 160 * calling functions of DB drivers. 161 */ 162 extern int db_payload_idx; 163 164 165 /* 166 * Macros to set/get variable (DB driver specific) 167 * payload to/from generic DB API structures 168 */ 169 170 171 /* 172 * Attach a driver specific data structure to a generic 173 * DB API structure 174 */ 175 #define DB_SET_PAYLOAD(db_struct, drv_data) do { \ 176 ((struct db_gen*)(db_struct))->data[db_payload_idx] = (struct db_drv*)(drv_data); \ 177 } while(0) 178 179 180 /* 181 * Return a driver specific data structure 182 */ 183 #define DB_GET_PAYLOAD(db_struct) \ 184 ((void*)(((struct db_gen*)(db_struct))->data[db_payload_idx])) 185 186 187 /* 188 * Initialize a db_gen structure and make space for the data 189 * from n database drivers 190 */ 191 int db_gen_init(struct db_gen* gen); 192 193 194 /* 195 * Free all memory allocated by a db_gen structure 196 */ 197 void db_gen_free(struct db_gen* gen); 198 199 200 #ifdef __cplusplus 201 } 202 #endif /* __cplusplus */ 203 204 /** @} */ 205 206 #endif /* _DB_GEN_H */ 207