Coverage Report

Created: 2025-07-11 06:28

/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 */