1 /*
2  * Copyright (c) 2014 Jerry Lundström <lundstrom.jerry@gmail.com>
3  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
4  * Copyright (c) 2014 OpenDNSSEC AB (svb)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #ifndef __db_value_h
31 #define __db_value_h
32 
33 struct db_value;
34 struct db_value_set;
35 typedef struct db_value db_value_t;
36 typedef struct db_value_set db_value_set_t;
37 
38 #include "config.h"
39 
40 #include "db_type.h"
41 #include "db_enum.h"
42 
43 #include <stdlib.h>
44 
45 /**
46  * A container for a database value.
47  */
48 struct db_value {
49     db_type_t type;
50     int primary_key;
51     char* text;
52     db_type_int32_t int32;
53     db_type_uint32_t uint32;
54     db_type_int64_t int64;
55     db_type_uint64_t uint64;
56     int enum_value;
57     const char* enum_text;
58 };
59 
60 #define DB_VALUE_EMPTY { DB_TYPE_EMPTY, 0, NULL, 0, 0, 0, 0, 0, NULL }
61 
62 /**
63  * Create a new database value.
64  * \return a db_value_t pointer or NULL on error.
65  */
66 extern db_value_t* db_value_new(void);
67 
68 /**
69  * Delete a database value.
70  * \param[in] value a db_value_t pointer.
71  */
72 extern void db_value_free(db_value_t* value);
73 
74 /**
75  * Reset a database value, releasing all interal resources and marking it empty.
76  * \param[in] value a db_value_t pointer.
77  */
78 extern void db_value_reset(db_value_t* value);
79 
80 /**
81  * Copy the contant from one database value into another.
82  * \param[in] value a db_value_t pointer to copy to.
83  * \param[in] from_value a db_value_t pointer to copy from.
84  * \return DB_ERROR_* on failure, otherwise DB_OK.
85  */
86 extern int db_value_copy(db_value_t* value, const db_value_t* from_value);
87 
88 /**
89  * Compare two database values A and B. Sets `result` with less than, equal to,
90  * or greater than zero if A is found, respectively, to be less than, to match,
91  * or be greater than B.
92  * \param[in] value_a a db_value_t pointer.
93  * \param[in] value_b a db_value_t pointer.
94  * \param[out] result an integer pointer.
95  * \return DB_ERROR_* on failure, otherwise DB_OK.
96  */
97 extern int db_value_cmp(const db_value_t* value_a, const db_value_t* value_b, int* result);
98 
99 /**
100  * Get the type of a database value.
101  * \param[in] value a db_value_t pointer.
102  * \return a db_type_t.
103  */
104 extern db_type_t db_value_type(const db_value_t* value);
105 
106 /**
107  * Get a pointer for the 32bit integer in a database value.
108  * \param[in] value a db_value_t pointer.
109  * \return a db_type_int32_t pointer or NULL on error, if empty or not a 32bit
110  * integer value.
111  * TODO: unit test
112  */
113 extern const db_type_int32_t* db_value_int32(const db_value_t* value);
114 
115 /**
116  * Get a pointer for the unsigned 32bit integer in a database value.
117  * \param[in] value a db_value_t pointer.
118  * \return a db_type_uint32_t pointer or NULL on error, if empty or not an
119  * unsigned 32bit integer value.
120  * TODO: unit test
121  */
122 extern const db_type_uint32_t* db_value_uint32(const db_value_t* value);
123 
124 /**
125  * Get a pointer for the 64bit integer in a database value.
126  * \param[in] value a db_value_t pointer.
127  * \return a db_type_int64_t pointer or NULL on error, if empty or not a 64bit
128  * integer value.
129  * TODO: unit test
130  */
131 extern const db_type_int64_t* db_value_int64(const db_value_t* value);
132 
133 /**
134  * Get a pointer for the unsigned 64bit integer in a database value.
135  * \param[in] value a db_value_t pointer.
136  * \return a db_type_uint64_t pointer or NULL on error, if empty or not an
137  * unsigned 64bit integer value.
138  * TODO: unit test
139  */
140 extern const db_type_uint64_t* db_value_uint64(const db_value_t* value);
141 
142 /**
143  * Get a character pointer for the text in a database value.
144  * \param[in] value a db_value_t pointer.
145  * \return a character pointer or NULL on error, if empty or not a text value.
146  */
147 extern const char* db_value_text(const db_value_t* value);
148 
149 /**
150  * Sets `enum_value` with the integer value of an enumeration database value.
151  * \param[in] value a db_value_t pointer.
152  * \param[out] enum_value an integer pointer.
153  * \return DB_ERROR_* on failure, otherwise DB_OK.
154  */
155 extern int db_value_enum_value(const db_value_t* value, int* enum_value);
156 
157 /**
158  * Check if a database value is not empty.
159  * \param[in] value a db_value_t pointer.
160  * \return DB_ERROR_* if empty, otherwise DB_OK.
161  */
162 extern int db_value_not_empty(const db_value_t* value);
163 
164 /**
165  * Get the 32bit integer representation of the database value.
166  * \param[in] value a db_value_t pointer.
167  * \param[out] to_int32 a db_type_int32_t pointer.
168  * \return DB_ERROR_* on failure, otherwise DB_OK.
169  */
170 extern int db_value_to_int32(const db_value_t* value, db_type_int32_t* to_int32);
171 
172 /**
173  * Get the unsigned 32bit integer representation of the database value.
174  * \param[in] value a db_value_t pointer.
175  * \param[out] to_uint32 a db_type_uint32_t pointer.
176  * \return DB_ERROR_* on failure, otherwise DB_OK.
177  */
178 extern int db_value_to_uint32(const db_value_t* value, db_type_uint32_t* to_uint32);
179 
180 /**
181  * Get the 64bit integer representation of the database value.
182  * \param[in] value a db_value_t pointer.
183  * \param[out] to_int64 a db_type_int64_t pointer.
184  * \return DB_ERROR_* on failure, otherwise DB_OK.
185  */
186 extern int db_value_to_int64(const db_value_t* value, db_type_int64_t* to_int64);
187 
188 /**
189  * Get the unsigned 64bit integer representation of the database value.
190  * \param[in] value a db_value_t pointer.
191  * \param[out] to_uint64 a db_type_uint64_t pointer.
192  * \return DB_ERROR_* on failure, otherwise DB_OK.
193  */
194 extern int db_value_to_uint64(const db_value_t* value, db_type_uint64_t* to_uint64);
195 
196 /**
197  * Get the character representation of the database value.
198  * \param[in] value a db_value_t pointer.
199  * \param[out] to_text a character pointer pointer.
200  * \return DB_ERROR_* on failure, otherwise DB_OK.
201  */
202 extern int db_value_to_text(const db_value_t* value, char** to_text);
203 
204 /**
205  * Get the integer enumeration representation of the database value.
206  * \param[in] value a db_value_t pointer.
207  * \param[out] to_int an integer pointer.
208  * \param[in] enum_set a db_enum_t array that MUST end with NULL.
209  * \return DB_ERROR_* on failure, otherwise DB_OK.
210  */
211 extern int db_value_to_enum_value(const db_value_t* value, int* to_int, const db_enum_t* enum_set);
212 
213 /**
214  * Set the database value to a 32bit integer value.
215  * \param[in] value a db_value_t pointer.
216  * \param[in] from_int32 a db_type_int32_t pointer.
217  * \return DB_ERROR_* on failure, otherwise DB_OK.
218  */
219 extern int db_value_from_int32(db_value_t* value, db_type_int32_t from_int32);
220 
221 /**
222  * Set the database value to an unsigned 32bit integer value.
223  * \param[in] value a db_value_t pointer.
224  * \param[in] from_uint32 a db_type_uint32_t pointer.
225  * \return DB_ERROR_* on failure, otherwise DB_OK.
226  */
227 extern int db_value_from_uint32(db_value_t* value, db_type_uint32_t from_uint32);
228 
229 /**
230  * Set the database value to a 64bit integer value.
231  * \param[in] value a db_value_t pointer.
232  * \param[in] from_int64 a db_type_int64_t pointer.
233  * \return DB_ERROR_* on failure, otherwise DB_OK.
234  */
235 extern int db_value_from_int64(db_value_t* value, db_type_int64_t from_int64);
236 
237 /**
238  * Set the database value to an unsigned 64bit integer value.
239  * \param[in] value a db_value_t pointer.
240  * \param[in] from_uint64 a db_type_uint64_t pointer.
241  * \return DB_ERROR_* on failure, otherwise DB_OK.
242  */
243 extern int db_value_from_uint64(db_value_t* value, db_type_uint64_t from_uint64);
244 
245 /**
246  * Set the database value to a text value.
247  * \param[in] value a db_value_t pointer.
248  * \param[in] from_text a character pointer.
249  * \return DB_ERROR_* on failure, otherwise DB_OK.
250  */
251 extern int db_value_from_text(db_value_t* value, const char* from_text);
252 
253 /**
254  * Set the database value to a text value.
255  * \param[in] value a db_value_t pointer.
256  * \param[in] from_text a character pointer.
257  * \param[in] size a size_t.
258  * \return DB_ERROR_* on failure, otherwise DB_OK.
259  */
260 extern int db_value_from_text2(db_value_t* value, const char* from_text, size_t size);
261 
262 /**
263  * Set the database value to an enumeration value based on an integer value.
264  * \param[in] value a db_value_t pointer.
265  * \param[in] enum_value an integer pointer.
266  * \param[in] enum_set a db_enum_t array that MUST end with NULL.
267  * \return DB_ERROR_* on failure, otherwise DB_OK.
268  */
269 extern int db_value_from_enum_value(db_value_t* value, int enum_value, const db_enum_t* enum_set);
270 
271 /**
272  * Mark the database as a primary key.
273  * \param[in] value a db_value_t pointer.
274  * \return DB_ERROR_* on failure, otherwise DB_OK.
275  */
276 extern int db_value_set_primary_key(db_value_t* value);
277 
278 /**
279  * A container for a fixed set of database values.
280  */
281 struct db_value_set {
282     db_value_t* values;
283     size_t size;
284 };
285 
286 /**
287  * Create a new set of database value.
288  * \param[in] size a size_t.
289  * \return a db_value_set_t pointer or NULL on error.
290  */
291 extern db_value_set_t* db_value_set_new(size_t size);
292 
293 /**
294  * Create a new set of database value that is a copy of another.
295  * \param[in] from_value_set a db_value_set_t pointer.
296  * \return a db_value_set_t pointer or NULL on error.
297  */
298 extern db_value_set_t* db_value_set_new_copy(const db_value_set_t* from_value_set);
299 
300 /**
301  * Delete a database value set and all values within the set.
302  * \param[in] value_set a db_value_set_t pointer.
303  */
304 extern void db_value_set_free(db_value_set_t* value_set);
305 
306 /**
307  * Get the size of database value set.
308  * \param[in] value_set a db_value_set_t pointer.
309  * \return a size_t.
310  */
311 extern size_t db_value_set_size(const db_value_set_t* value_set);
312 
313 /**
314  * Get a read only database value at a position in a database value set.
315  * \param[in] value_set a db_value_set_t pointer.
316  * \param[in] at a size_t.
317  * \return a db_value_t pointer or NULL on error.
318  */
319 extern const db_value_t* db_value_set_at(const db_value_set_t* value_set, size_t at);
320 
321 /**
322  * Get a writable database value at a position in a database value set.
323  * \param[in] value_set a db_value_set_t pointer.
324  * \param[in] at a size_t.
325  * \return a db_value_t pointer or NULL on error.
326  */
327 extern db_value_t* db_value_set_get(db_value_set_t* value_set, size_t at);
328 
329 #endif
330