160 * XXX: this is not actually called yet, no retry logic implemented. |
168 * XXX: this is not actually called yet, no retry logic implemented. |
161 */ |
169 */ |
162 typedef void (*evsql_error_cb)(struct evsql *evsql, void *arg); |
170 typedef void (*evsql_error_cb)(struct evsql *evsql, void *arg); |
163 |
171 |
164 /* |
172 /* |
165 * Callback for handling transaction-level errors. |
173 * Callback for handling transaction-level errors. This may be called at any time during a transaction's lifetime, |
|
174 * including from within the evsql_query_* functions. |
166 * |
175 * |
167 * The transaction is not useable anymore. |
176 * The transaction is not useable anymore. |
168 */ |
177 */ |
169 typedef void (*evsql_trans_error_cb)(struct evsql_trans *trans, void *arg); |
178 typedef void (*evsql_trans_error_cb)(struct evsql_trans *trans, void *arg); |
170 |
179 |
171 /* |
180 /* |
172 * The transaction is ready for use. |
181 * Callback for handling evsql_trans/evsql_query_abort completion. The transaction is ready for use with evsql_query_*. |
173 */ |
182 */ |
174 typedef void (*evsql_trans_ready_cb)(struct evsql_trans *trans, void *arg); |
183 typedef void (*evsql_trans_ready_cb)(struct evsql_trans *trans, void *arg); |
175 |
184 |
176 /* |
185 /* |
177 * The transaction was commited, and should not be used anymore. |
186 * Callback for handling evsql_trans_commit completion. The transaction was commited, and should not be used anymore. |
178 */ |
187 */ |
179 typedef void (*evsql_trans_done_cb)(struct evsql_trans *trans, void *arg); |
188 typedef void (*evsql_trans_done_cb)(struct evsql_trans *trans, void *arg); |
180 |
189 |
181 /* |
190 /* |
182 * Create a new PostgreSQL/libpq(evpq) -based evsql using the given conninfo. |
191 * Create a new PostgreSQL/libpq(evpq) -based evsql using the given conninfo. |
183 * |
192 * |
184 * The given conninfo must stay valid for the duration of the evsql's lifetime. |
193 * The given conninfo must stay valid for the duration of the evsql's lifetime. |
185 */ |
194 */ |
186 struct evsql *evsql_new_pq (struct event_base *ev_base, const char *pq_conninfo, evsql_error_cb error_fn, void *cb_arg); |
195 struct evsql *evsql_new_pq (struct event_base *ev_base, const char *pq_conninfo, |
|
196 evsql_error_cb error_fn, |
|
197 void *cb_arg |
|
198 ); |
187 |
199 |
188 /* |
200 /* |
189 * Create a new transaction. |
201 * Create a new transaction. |
190 * |
202 * |
191 * Transactions are separate connections that provide transaction-isolation. |
203 * A transaction will be allocated its own connection, and the "BEGIN TRANSACTION ..." query will be sent (use the |
192 * |
204 * evsql_trans_type argument to specify this). |
193 * Once the transaction is ready for use, ready_fn will be called. If the transaction fails, any pending query will be |
205 * |
194 * forgotten, and error_fn called. This also includes some (but not all) cases where evsql_query returns nonzero. |
206 * Once the transaction has been opened, the given evsql_trans_ready_cb will be triggered, and the transaction can then |
195 * |
207 * be used (see evsql_query_*). |
196 */ |
208 * |
197 struct evsql_trans *evsql_trans (struct evsql *evsql, enum evsql_trans_type type, evsql_trans_error_cb error_fn, evsql_trans_ready_cb ready_fn, evsql_trans_done_cb done_fn, void *cb_arg); |
209 * If, at any point, the transaction-connection fails, and pending query will be forgotten (i.e. the query callback |
|
210 * will NOT be called), and the given evsql_trans_error_cb will be called. Note that this includes some, but not all, |
|
211 * cases where evsql_query_* returns an error. |
|
212 * |
|
213 * Once you are done with the transaction, call either evsql_trans_commit or evsql_trans_abort. |
|
214 */ |
|
215 struct evsql_trans *evsql_trans (struct evsql *evsql, enum evsql_trans_type type, |
|
216 evsql_trans_error_cb error_fn, |
|
217 evsql_trans_ready_cb ready_fn, |
|
218 evsql_trans_done_cb done_fn, |
|
219 void *cb_arg |
|
220 ); |
198 |
221 |
199 /* |
222 /* |
200 * Queue the given query for execution. |
223 * Queue the given query for execution. |
201 * |
224 * |
202 * If trans is specified (not NULL), then the transaction must be idle, and the query will be executed in that |
225 * If trans is specified (not NULL), then the transaction must be idle, and the query will be executed in that |
203 * transaction's context. Otherwise, the query will be executed without a transaction, andmay be executed immediately, |
226 * transaction's context. Otherwise, the query will be executed without a transaction using an idle connection, or |
204 * or if other similar queries are running, it will be queued for later execution. |
227 * enqueued for later execution. |
205 * |
228 * |
206 * Once the query is complete (got a result, got an error, the connection failed), then the query_cb will be triggered. |
229 * Once the query is complete (got a result, got an error, the connection failed), then the query_cb will be called. |
|
230 * The callback can used the evsql_result_* functions to manipulate it. |
|
231 * |
|
232 * The returned evsql_query handle can be passed to evsql_query_abort at any point before query_fn being called. |
|
233 * |
207 */ |
234 */ |
208 struct evsql_query *evsql_query (struct evsql *evsql, struct evsql_trans *trans, const char *command, evsql_query_cb query_fn, void *cb_arg); |
235 struct evsql_query *evsql_query (struct evsql *evsql, struct evsql_trans *trans, const char *command, evsql_query_cb query_fn, void *cb_arg); |
209 |
236 |
210 /* |
237 /* |
211 * Same as evsql_query, but uses the SQL-level support for binding parameters. |
238 * Execute the given SQL query using the list of parameter types/values given via evsql_query_params. |
|
239 * |
|
240 * See evsql_query for more info about behaviour. |
212 */ |
241 */ |
213 struct evsql_query *evsql_query_params (struct evsql *evsql, struct evsql_trans *trans, |
242 struct evsql_query *evsql_query_params (struct evsql *evsql, struct evsql_trans *trans, |
214 const char *command, const struct evsql_query_params *params, |
243 const char *command, const struct evsql_query_params *params, |
215 evsql_query_cb query_fn, void *cb_arg |
244 evsql_query_cb query_fn, void *cb_arg |
216 ); |
245 ); |
217 |
246 |
218 /* |
247 /* |
219 * Execute the given query_info, using the parameter list in query_info to resolve the given variable arugments |
248 * Execute the given query_info's SQL query using the values given as variable arguments, using the evsql_query_info to |
|
249 * resolve the types. |
|
250 * |
|
251 * See evsql_query for more info about behaviour. |
220 */ |
252 */ |
221 struct evsql_query *evsql_query_exec (struct evsql *evsql, struct evsql_trans *trans, |
253 struct evsql_query *evsql_query_exec (struct evsql *evsql, struct evsql_trans *trans, |
222 const struct evsql_query_info *query_info, |
254 const struct evsql_query_info *query_info, |
223 evsql_query_cb query_fn, void *cb_arg, |
255 evsql_query_cb query_fn, void *cb_arg, |
224 ... |
256 ... |
225 ); |
257 ); |
226 |
258 |
227 /* |
259 /* |
228 * Abort a query, the query callback will not be called, the query and any possible results will be discarded. |
260 * Abort a query returned by evsql_query_* that has not yet completed (query_fn has not been called yet). |
229 * |
261 * |
230 * This does not garuntee that the query will not execute, simply that you won't get the results. |
262 * The actual query itself may or may not be aborted (and hence may or may not be executed on the server), but query_fn |
|
263 * will not be called anymore, and the query will dispose of itself and any results returned. |
231 * |
264 * |
232 * If the query is part of a transaction, then trans must be given, and the query must be the query that is currently |
265 * If the query is part of a transaction, then trans must be given, and the query must be the query that is currently |
233 * executing on that trans. The transaction's ready_fn will be called once the query has been aborted. |
266 * executing on that trans. The transaction's ready_fn will be called once the query has been aborted and the |
|
267 * transaction is now idle again. |
234 */ |
268 */ |
235 void evsql_query_abort (struct evsql_trans *trans, struct evsql_query *query); |
269 void evsql_query_abort (struct evsql_trans *trans, struct evsql_query *query); |
236 |
270 |
237 /* |
271 /* |
238 * Commit a transaction, calling done_fn if it was succesfull (error_fn otherwise). |
272 * Commit a transaction using "COMMIT TRANSACTION". |
239 * |
273 * |
240 * trans must be idle, just like for evsql_query. |
274 * The transaction must be idle, just like for evsql_query. Once the transaction has been commited, the transaction's |
241 * |
275 * done_fn will be called, after which the transaction must not be used. |
242 * done_fn will never be called directly, always via the event loop. |
|
243 * |
276 * |
244 * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is a FATAL error. |
277 * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is a FATAL error. |
|
278 * |
|
279 * Note that done_fn will never be called directly, always indirectly via the event loop. |
245 */ |
280 */ |
246 int evsql_trans_commit (struct evsql_trans *trans); |
281 int evsql_trans_commit (struct evsql_trans *trans); |
247 |
282 |
248 /* |
283 /* |
249 * Abort a transaction, rolling it back. No callbacks will be called. |
284 * Abort a transaction, using "ROLLBACK TRANSACTION". |
|
285 * |
|
286 * No more transaction callbacks will be called, if there was a query running, it will be aborted, and the transaction |
|
287 * then rollback'd. |
250 * |
288 * |
251 * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is a FATAL error. |
289 * You cannot abort a COMMIT, calling trans_abort on trans after a succesful trans_commit is a FATAL error. |
|
290 * |
|
291 * Do not call evsql_trans_abort from within evsql_trans_error_cb! |
252 */ |
292 */ |
253 void evsql_trans_abort (struct evsql_trans *trans); |
293 void evsql_trans_abort (struct evsql_trans *trans); |
254 |
294 |
255 /* |
295 /* |
256 * Transaction-handling functions |
296 * Transaction-handling functions |
278 |
318 |
279 /* |
319 /* |
280 * Result-handling functions |
320 * Result-handling functions |
281 */ |
321 */ |
282 |
322 |
|
323 /* |
|
324 * Check the result for errors. Intended for use with non-data queries, i.e. CREATE, etc. |
|
325 * |
|
326 * Returns zero if the query was OK, err otherwise. EIO indicates an SQL error, the error message can be retrived |
|
327 * using evsql_result_error. |
|
328 */ |
|
329 err_t evsql_result_check (struct evsql_result *res); |
|
330 |
|
331 /* |
|
332 * The iterator-based interface results interface. |
|
333 * |
|
334 * Define an evsql_result_info struct that describes the columns returned by the query, and call evsql_result_begin on |
|
335 * the evsql_result. This verifies the query result, and then prepares it for iteration using evsql_result_next. |
|
336 * |
|
337 * Call evsql_result_end once you've stopped iteration. |
|
338 * |
|
339 * Returns zero if the evsql_result is ready for iteration, err otherwise. EIO indicates an SQL error, the error |
|
340 * message can be retreived using evsql_result_error. |
|
341 * |
|
342 * Note: currently the iterator state is simply stored in evsql_result, so only one iterator at a time per evsql_result. |
|
343 */ |
|
344 err_t evsql_result_begin (struct evsql_result_info *info, struct evsql_result *res); |
|
345 |
|
346 /* |
|
347 * Reads the next result row, storing the field values into the pointer arguments given. The types are resolved using |
|
348 * the evsql_result_info given to evsql_result_begin. |
|
349 * |
|
350 * Returns >0 when a row was read, 0 when there are no more rows, and -err if there was an error. |
|
351 */ |
|
352 int evsql_result_next (struct evsql_result *res, ...); |
|
353 |
|
354 /* |
|
355 * Ends the result iteration, releasing any associated resources and the result itself. |
|
356 * |
|
357 * The result should not be iterated or accessed anymore. |
|
358 * |
|
359 * Note: this does the same thing as evsql_result_free, and works regardless of evsql_result_begin returning |
|
360 * succesfully or not. |
|
361 */ |
|
362 void evsql_result_end (struct evsql_result *res); |
|
363 |
|
364 |
283 // get error message associated with function |
365 // get error message associated with function |
284 const char *evsql_result_error (const struct evsql_result *res); |
366 const char *evsql_result_error (const struct evsql_result *res); |
285 |
|
286 /* |
|
287 * Iterator-based interface. |
|
288 * |
|
289 * Call result_begin to check for errors, then result_next to fetch rows, and finally result_end to release. |
|
290 */ |
|
291 err_t evsql_result_begin (struct evsql_result_info *info, struct evsql_result *res); |
|
292 int evsql_result_next (struct evsql_result *res, ...); |
|
293 void evsql_result_end (struct evsql_result *res); |
|
294 |
367 |
295 // number of rows in the result |
368 // number of rows in the result |
296 size_t evsql_result_rows (const struct evsql_result *res); |
369 size_t evsql_result_rows (const struct evsql_result *res); |
297 |
370 |
298 // number of columns in the result |
371 // number of columns in the result |