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_result_h
31 #define __db_result_h
32 
33 struct db_result;
34 struct db_result_list;
35 typedef struct db_result db_result_t;
36 typedef struct db_result_list db_result_list_t;
37 
38 /**
39  * Function pointer for walking a db_result_list. The backend handle specific
40  * data is supplied in `data` and setting `finish` to non-zero tells the backend
41  * that we are finished with the db_result_list.
42  * \param[in] data a void pointer for the backend specific data.
43  * \param[in] finish an integer that if non-zero will tell the backend that we
44  * are finished with the result list.
45  * \return A pointer to the next db_result_t or NULL on error.
46  */
47 typedef db_result_t* (*db_result_list_next_t)(void* data, int finish);
48 
49 #include "db_value.h"
50 #include "db_backend.h"
51 
52 /**
53  * A container for a database result, the data in the result is represented by
54  * a fixed size db_value_set_t.
55  */
56 struct db_result {
57     db_result_t* next;
58     db_value_set_t* value_set;
59 };
60 
61 /**
62  * Create a new database result.
63  * \return a db_result_t pointer or NULL on error.
64  */
65 extern db_result_t* db_result_new(void);
66 
67 /**
68  * Create a new database result that is a copy of another.
69  * \param[in] from_result a db_result_t pointer.
70  * \return a db_result_t pointer or NULL on error.
71  */
72 extern db_result_t* db_result_new_copy(const db_result_t* from_result);
73 
74 /**
75  * Delete a database result and the backend meta data list if set.
76  * \param[in] result a db_result_t pointer.
77  */
78 extern void db_result_free(db_result_t* result);
79 
80 /**
81  * Copy the content of another database result.
82  * \param[in] result a db_result_t pointer.
83  * \param[in] from_result a db_result_t pointer.
84  * \return DB_ERROR_* on failure, otherwise DB_OK.
85  */
86 extern int db_result_copy(db_result_t* result, const db_result_t* from_result);
87 
88 /**
89  * Get the value set of a database result.
90  * \param[in] result a db_result_t pointer.
91  * \return a db_value_set_t pointer or NULL on error or if no value set has
92  * been set.
93  */
94 extern const db_value_set_t* db_result_value_set(const db_result_t* result);
95 
96 /**
97  * Set the value set of a database result.
98  * \param[in] result a db_result_t pointer.
99  * \param[in] value_set a db_value_set_t pointer.
100  * \return DB_ERROR_* on failure, otherwise DB_OK.
101  */
102 extern int db_result_set_value_set(db_result_t* result, db_value_set_t* value_set);
103 
104 /**
105  * Check if a database result is not empty.
106  * \param[in] result a db_result_t pointer.
107  * \return DB_ERROR_* if empty, otherwise DB_OK.
108  */
109 extern int db_result_not_empty(const db_result_t* result);
110 
111 /**
112  * A list of database results.
113  */
114 struct db_result_list {
115     db_result_t* begin;
116     db_result_t* end;
117     db_result_t* current;
118     db_result_list_next_t next_function;
119     void* next_data;
120     size_t size;
121     int begun;
122 };
123 
124 /**
125  * Create a new database result list.
126  * \return a db_result_list_t pointer or NULL on error.
127  */
128 extern db_result_list_t* db_result_list_new(void);
129 
130 /**
131  * Create a new database result list that is a copy of another.
132  * \param[in] from_result_list a db_result_list_t pointer.
133  * \return a db_result_list_t pointer or NULL on error.
134  */
135 extern db_result_list_t* db_result_list_new_copy(const db_result_list_t* from_result_list);
136 
137 /**
138  * Delete a database result list and all database results within the list.
139  * \param[in] result_list a db_result_list_t pointer.
140  */
141 extern void db_result_list_free(db_result_list_t* result_list);
142 
143 /**
144  * free global allocator.
145  * db_result_list_free MUST be called for all its contents.
146  */
147 /**
148  * Copy the content of another database result list.
149  * \param[in] result_list a db_result_list_t pointer.
150  * \return DB_ERROR_* on failure, otherwise DB_OK.
151  */
152 extern int db_result_list_copy(db_result_list_t* result_list, const db_result_list_t* from_result_list);
153 
154 /**
155  * Set the function pointer for fetching the next database result for a database
156  * result list. The backend handle specific data is supplied in `next_data`
157  * along with the total size of the result list in `size`.
158  * \param[in] result_list a db_result_list_t pointer.
159  * \param[in] next_function a db_result_list_next_t function pointer.
160  * \param[in] next_data a void pointer.
161  * \param[in] size a size_t.
162  * \return DB_ERROR_* on failure, otherwise DB_OK.
163  */
164 extern int db_result_list_set_next(db_result_list_t* result_list, db_result_list_next_t next_function, void* next_data, size_t size);
165 
166 /**
167  * Add a database result to a database result list, this will takes over the
168  * ownership of the database result.
169  * \param[in] result_list a db_result_list_t pointer.
170  * \param[in] result a db_result_t pointer.
171  * \return DB_ERROR_* on failure, otherwise DB_OK.
172  */
173 extern int db_result_list_add(db_result_list_t* result_list, db_result_t* result);
174 
175 /**
176  * Return the first database result in a database result list and reset the
177  * position of the list.
178  * \param[in] result_list a db_result_list_t pointer.
179  * \return a db_result_t pointer or NULL on error or if the list is empty.
180  */
181 extern const db_result_t* db_result_list_begin(db_result_list_t* result_list);
182 
183 /**
184  * Return the next database result in a database result list.
185  * \param[in] result_list a db_result_list_t pointer.
186  * \return a db_result_t pointer or NULL on error or if the end of the list has
187  * been reached.
188  */
189 extern const db_result_t* db_result_list_next(db_result_list_t* result_list);
190 
191 /**
192  * Return the size of the database result list.
193  * \param[in] result_list a db_result_list_t pointer.
194  * \return a size_t with the size of the database result list or zero on error
195  * , if the database result list is empty or if the backend does not support
196  * returning the size.
197  */
198 extern size_t db_result_list_size(const db_result_list_t* result_list);
199 
200 /**
201  * Make sure that all objects in this database result list is loaded into memory
202  * so that db_result_list_begin() can be used to iterate over the list multiple
203  * times.
204  * \param[in] result_list a db_result_list_t pointer.
205  * \return DB_ERROR_* on failure, otherwise DB_OK.
206  */
207 extern int db_result_list_fetch_all(db_result_list_t* result_list);
208 
209 #endif
210