/src/opensips/db/db_val.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2001-2003 FhG Fokus |
3 | | * Copyright (C) 2007-2008 1&1 Internet AG |
4 | | * |
5 | | * This file is part of opensips, a free SIP server. |
6 | | * |
7 | | * opensips 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 | | * opensips 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 | | /** |
23 | | * \file db/db_val.h |
24 | | * \brief Data structures that represents values in the database. |
25 | | * |
26 | | * This file defines data structures that represents values in the database. |
27 | | * Several datatypes are recognized and converted by the database API. |
28 | | * Available types: DB_INT, DB_DOUBLE, DB_STRING, DB_STR, DB_DATETIME, DB_BLOB and DB_BITMAP |
29 | | * It also provides some macros for convenient access to this values. |
30 | | */ |
31 | | |
32 | | |
33 | | #ifndef DB_VAL_H |
34 | | #define DB_VAL_H |
35 | | |
36 | | #include <time.h> |
37 | | #include <stdint.h> |
38 | | |
39 | | #include "../dprint.h" |
40 | | #include "../str.h" |
41 | | |
42 | | |
43 | | /** |
44 | | * Each cell in a database table can be of a different type. To distinguish |
45 | | * among these types, the db_type_t enumeration is used. Every value of the |
46 | | * enumeration represents one datatype that is recognized by the database |
47 | | * API. |
48 | | */ |
49 | | typedef enum { |
50 | | DB_INT, /**< represents an 32 bit integer number */ |
51 | | DB_BIGINT, /**< represents an 64 bit integer number */ |
52 | | DB_DOUBLE, /**< represents a floating point number */ |
53 | | DB_STRING, /**< represents a zero terminated const char* */ |
54 | | DB_STR, /**< represents a string of 'str' type */ |
55 | | DB_DATETIME, /**< represents date and time */ |
56 | | DB_BLOB, /**< represents a large binary object */ |
57 | | DB_BITMAP /**< an one-dimensional array of 32 flags */ |
58 | | } db_type_t; |
59 | | |
60 | | |
61 | | /** |
62 | | * This structure represents a value in the database. Several datatypes are |
63 | | * recognized and converted by the database API. These datatypes are automaticaly |
64 | | * recognized, converted from internal database representation and stored in the |
65 | | * variable of corresponding type. |
66 | | * |
67 | | * Module that want to use this values needs to copy them to another memory |
68 | | * location, because after the call to free_result there are not more available. |
69 | | * |
70 | | * If the structure holds a pointer to a string value that needs to be freed |
71 | | * because the module allocated new memory for it then the free flag must |
72 | | * be set to a non-zero value. A free flag of zero means that the string |
73 | | * data must be freed internally by the database driver. |
74 | | */ |
75 | | typedef struct { |
76 | | db_type_t type; /**< Type of the value */ |
77 | | int nul; /**< Means that the column in database has no value */ |
78 | | int free; /**< Means that the value should be freed */ |
79 | | /** Column value structure that holds the actual data in a union. */ |
80 | | union { |
81 | | int int_val; /**< integer value */ |
82 | | long long bigint_val; /**< big integer value */ |
83 | | double double_val; /**< double value */ |
84 | | time_t time_val; /**< unix time_t value */ |
85 | | const char* string_val; /**< zero terminated string */ |
86 | | str str_val; /**< str type string value */ |
87 | | str blob_val; /**< binary object data */ |
88 | | unsigned int bitmap_val; /**< Bitmap data type */ |
89 | | } val; |
90 | | } db_val_t; |
91 | | |
92 | | static inline void db_print_val(db_val_t *v) |
93 | 0 | { |
94 | 0 | switch (v->type) { |
95 | 0 | case DB_INT: |
96 | 0 | LM_GEN1(L_DBG, "\t'%d'\n", v->val.int_val); |
97 | 0 | break; |
98 | 0 | case DB_BIGINT: |
99 | 0 | LM_GEN1(L_DBG, "\t'%lld'\n", v->val.bigint_val); |
100 | 0 | break; |
101 | 0 | case DB_DOUBLE: |
102 | 0 | LM_GEN1(L_DBG, "\t'%.3lf'\n", v->val.double_val); |
103 | 0 | break; |
104 | 0 | case DB_STRING: |
105 | 0 | LM_GEN1(L_DBG, "\t'%s'\n", v->val.string_val); |
106 | 0 | break; |
107 | 0 | case DB_STR: |
108 | 0 | LM_GEN1(L_DBG, "\t'%.*s'\n", v->val.str_val.len, v->val.str_val.s); |
109 | 0 | break; |
110 | 0 | case DB_DATETIME: |
111 | 0 | LM_GEN1(L_DBG, "\t'%ld'\n", (long)v->val.time_val); |
112 | 0 | break; |
113 | 0 | case DB_BLOB: |
114 | 0 | LM_GEN1(L_DBG, "\t'%.*s'\n", v->val.blob_val.len, v->val.blob_val.s); |
115 | 0 | break; |
116 | 0 | case DB_BITMAP: |
117 | 0 | LM_GEN1(L_DBG, "\t'%u'\n", v->val.bitmap_val); |
118 | 0 | break; |
119 | 0 | } |
120 | 0 | } Unexecuted instantiation: pt.c:db_print_val Unexecuted instantiation: db_insertq.c:db_print_val Unexecuted instantiation: db.c:db_print_val Unexecuted instantiation: cfg.tab.c:db_print_val Unexecuted instantiation: shutdown.c:db_print_val Unexecuted instantiation: core_cmds.c:db_print_val Unexecuted instantiation: cachedb.c:db_print_val |
121 | | |
122 | | |
123 | | /** |
124 | | * Useful macros for accessing attributes of db_val structure. |
125 | | * All macros expect a reference to a db_val_t variable as parameter. |
126 | | */ |
127 | | |
128 | | /** |
129 | | * Use this macro if you need to set/get the type of the value. |
130 | | */ |
131 | 0 | #define VAL_TYPE(dv) ((dv)->type) |
132 | | |
133 | | |
134 | | /** |
135 | | * Use this macro if you need to set/get the null flag. A non-zero flag means that |
136 | | * the corresponding cell in the database contains no data (a NULL value in MySQL |
137 | | * terminology). |
138 | | */ |
139 | 0 | #define VAL_NULL(dv) ((dv)->nul) |
140 | | |
141 | | |
142 | | /** |
143 | | * Use this macro if you need to set/ get the free flag. A non-zero flag means that |
144 | | * the corresponding cell in the database contains data that must be freed from the |
145 | | * DB API. |
146 | | */ |
147 | | #define VAL_FREE(dv) ((dv)->free) |
148 | | |
149 | | |
150 | | /** |
151 | | * Use this macro if you need to access the integer value in the db_val_t structure. |
152 | | */ |
153 | 0 | #define VAL_INT(dv) ((dv)->val.int_val) |
154 | | |
155 | | |
156 | | /** |
157 | | * Use this macro if you need to access the big integer value in the db_val_t structure. |
158 | | */ |
159 | 0 | #define VAL_BIGINT(dv) ((dv)->val.bigint_val) |
160 | | |
161 | | |
162 | | /** |
163 | | * Use this macro if you need to access the double value in the db_val_t structure. |
164 | | */ |
165 | | #define VAL_DOUBLE(dv) ((dv)->val.double_val) |
166 | | |
167 | | |
168 | | /** |
169 | | * Use this macro if you need to access the time_t value in the db_val_t structure. |
170 | | */ |
171 | | #define VAL_TIME(dv) ((dv)->val.time_val) |
172 | | |
173 | | |
174 | | /** |
175 | | * Use this macro if you need to access the string value in the db_val_t structure. |
176 | | */ |
177 | 0 | #define VAL_STRING(dv) ((dv)->val.string_val) |
178 | | |
179 | | |
180 | | /** |
181 | | * Use this macro if you need to access the str structure in the db_val_t structure. |
182 | | */ |
183 | 0 | #define VAL_STR(dv) ((dv)->val.str_val) |
184 | | |
185 | | |
186 | | /** |
187 | | * Use this macro if you need to access the blob value in the db_val_t structure. |
188 | | */ |
189 | 0 | #define VAL_BLOB(dv) ((dv)->val.blob_val) |
190 | | |
191 | | |
192 | | /** |
193 | | * Use this macro if you need to access the bitmap value in the db_val_t structure. |
194 | | */ |
195 | | #define VAL_BITMAP(dv) ((dv)->val.bitmap_val) |
196 | | |
197 | | |
198 | | #define get_str_from_dbval( _col_name, _val, _not_null, _not_empty, _str, _error_label) \ |
199 | | do{\ |
200 | | if ((_val)->nul) { \ |
201 | | if (_not_null) { \ |
202 | | LM_ERR("value in column %s cannot be null\n", _col_name); \ |
203 | | goto _error_label;\ |
204 | | } else { \ |
205 | | _str.s = NULL; _str.len = 0; \ |
206 | | } \ |
207 | | } \ |
208 | | if ((_val)->type==DB_STRING) { \ |
209 | | if ( VAL_STRING(_val)==NULL || *(VAL_STRING(_val))==0 ) { \ |
210 | | if (_not_empty) { \ |
211 | | LM_ERR("value in column %s cannot be empty\n", _col_name); \ |
212 | | goto _error_label;\ |
213 | | } else { \ |
214 | | _str.s = (char*)VAL_STRING(_val) ; _str.len = 0; \ |
215 | | } \ |
216 | | } else { \ |
217 | | _str.s = (char*)VAL_STRING(_val) ; _str.len = strlen(_str.s); \ |
218 | | } \ |
219 | | } else if ((_val)->type==DB_STR) { \ |
220 | | if ( VAL_STR(_val).s==NULL || VAL_STR(_val).len==0 ) { \ |
221 | | if (_not_empty) { \ |
222 | | LM_ERR("value in column %s cannot be empty\n", _col_name); \ |
223 | | goto _error_label;\ |
224 | | } else { \ |
225 | | _str = VAL_STR(_val) ;\ |
226 | | } \ |
227 | | } else { \ |
228 | | _str = VAL_STR(_val); \ |
229 | | } \ |
230 | | } else if ((_val)->type==DB_BLOB) { \ |
231 | | if ( VAL_BLOB(_val).s==NULL || VAL_BLOB(_val).len==0 ) { \ |
232 | | if (_not_empty) { \ |
233 | | LM_ERR("value in column %s cannot be empty\n", _col_name); \ |
234 | | goto _error_label;\ |
235 | | } else { \ |
236 | | _str = VAL_BLOB(_val) ;\ |
237 | | } \ |
238 | | } else { \ |
239 | | _str = VAL_BLOB(_val); \ |
240 | | } \ |
241 | | } else {\ |
242 | | LM_ERR("column %s does not have a string type (found %d)\n",\ |
243 | | _col_name,(_val)->type); \ |
244 | | goto _error_label;\ |
245 | | } \ |
246 | | }while(0) |
247 | | |
248 | | |
249 | | |
250 | | |
251 | | #endif /* DB_VAL_H */ |