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