1 #ifndef EVSQL_H |
1 #ifndef EVSQL_H |
2 #define EVSQL_H |
2 #define EVSQL_H |
3 |
3 |
4 /** |
4 /** |
|
5 * @file src/evsql.h |
|
6 * |
5 * A SQL library designed for use with libevent and PostgreSQL's libpq. Provides support for queueing non-transactional |
7 * A SQL library designed for use with libevent and PostgreSQL's libpq. Provides support for queueing non-transactional |
6 * requests, transaction support, parametrized queries and result iteration. |
8 * requests, transaction support, parametrized queries and result iteration. |
7 * |
9 * |
8 * Currently, the API does not expose the underlying libpq data structures, but since it is currently the only |
10 * Currently, the API does not expose the underlying libpq data structures, but since it is currently the only |
9 * underlying implementation, there is no garuntee that the same API will actually work with other databases' interface |
11 * underlying implementation, there is no guarantee that the same API will actually work with other databases' interface |
10 * libraries... |
12 * libraries... |
11 */ |
13 * |
12 |
14 * The order of function calls and callbacks goes something like this: |
|
15 * |
|
16 * - evsql_new_pq |
|
17 * |
|
18 * - evsql_trans |
|
19 * - evsql_trans_abort |
|
20 * - evsql_trans_error_cb |
|
21 * - evsql_trans_ready_cb |
|
22 * |
|
23 * - evsql_query, evsql_params_* + evsql_query_params, evsql_query_exec |
|
24 * - evsql_query_abort |
|
25 * - evsql_query_cb |
|
26 * - evsql_result_* |
|
27 * - evsql_result_free |
|
28 * |
|
29 * - evsql_trans_commit |
|
30 * - evsql_trans_done_cb |
|
31 * |
|
32 */ |
|
33 |
|
34 /** |
|
35 * System includes |
|
36 */ |
13 #include <stdint.h> |
37 #include <stdint.h> |
14 #include <stdbool.h> |
38 #include <stdbool.h> |
15 #include <event2/event.h> |
39 #include <event2/event.h> |
16 |
40 |
17 /** |
41 /** |
313 evsql_error_cb error_fn, |
359 evsql_error_cb error_fn, |
314 void *cb_arg |
360 void *cb_arg |
315 ); |
361 ); |
316 |
362 |
317 /** |
363 /** |
|
364 * Query API |
|
365 * |
|
366 * @name evsql_query_* |
|
367 * @{ |
|
368 */ |
|
369 |
|
370 /** |
|
371 * Queue the given query for execution. |
|
372 * |
|
373 * If a trans is given (i.e. not NULL), then the transaction must be idle, and the query will be executed in that |
|
374 * transaction's context. Otherwise, the query will be executed without a transaction using an idle connection, or |
|
375 * enqueued for later execution. |
|
376 * |
|
377 * Once the query is complete (got a result, got an error, the connection failed), then the query_cb will be called. |
|
378 * The callback can use the evsql_result_* functions to manipulate it. |
|
379 * |
|
380 * The returned evsql_query handle can be passed to evsql_query_abort at any point before query_fn being called. |
|
381 * |
|
382 * @param evsql the context handle from evsql_new_* |
|
383 * @param trans the optional transaction handle from evsql_trans |
|
384 * @param command the raw SQL command itself |
|
385 * @param query_fn the query_cb to call once the query is complete |
|
386 * @param cb_arg the void* passed to the above |
|
387 * @return the evsql_query handle that can be used to abort the query |
|
388 */ |
|
389 struct evsql_query *evsql_query (struct evsql *evsql, struct evsql_trans *trans, const char *command, evsql_query_cb query_fn, void *cb_arg); |
|
390 |
|
391 /** |
|
392 * Execute the given SQL query using the list of parameter types/values given via evsql_query_params. |
|
393 * |
|
394 * Use the EVSQL_PARAMS macros to declare the struct, and the evsql_param_* functions to populate the values. |
|
395 * |
|
396 * See evsql_query for more info about behaviour. |
|
397 * |
|
398 * XXX: explain SQL param syntax... |
|
399 * |
|
400 * @param evsql the context handle from evsql_new_* |
|
401 * @param trans the optional transaction handle from evsql_trans |
|
402 * @param command the SQL command to bind the parameters to |
|
403 * @param params the parameter types and values |
|
404 * @param query_fn the query_cb to call once the query is complete |
|
405 * @param cb_arg the void* passed to the above |
|
406 * @see evsql_query |
|
407 */ |
|
408 struct evsql_query *evsql_query_params (struct evsql *evsql, struct evsql_trans *trans, |
|
409 const char *command, const struct evsql_query_params *params, |
|
410 evsql_query_cb query_fn, void *cb_arg |
|
411 ); |
|
412 |
|
413 /** |
|
414 * Execute the given query_info's SQL query with the values given as variable arguments, using the evsql_query_info to |
|
415 * resolve the types. |
|
416 * |
|
417 * See evsql_query for more info about behaviour. |
|
418 * |
|
419 * @param evsql the context handle from evsql_new_* |
|
420 * @param trans the optional transaction handle from evsql_trans |
|
421 * @param query_info the SQL query information |
|
422 * @param query_fn the query_cb to call once the query is complete |
|
423 * @param cb_arg the void* passed to the above |
|
424 * @see evsql_query |
|
425 */ |
|
426 struct evsql_query *evsql_query_exec (struct evsql *evsql, struct evsql_trans *trans, |
|
427 const struct evsql_query_info *query_info, |
|
428 evsql_query_cb query_fn, void *cb_arg, |
|
429 ... |
|
430 ); |
|
431 |
|
432 /** |
|
433 * Abort a query returned by evsql_query_* that has not yet completed (query_fn has not been called yet). |
|
434 * |
|
435 * The actual query itself may or may not be aborted (and hence may or may not be executed on the server), but query_fn |
|
436 * will not be called anymore, and the query will dispose of itself and any results returned. |
|
437 * |
|
438 * If the query is part of a transaction, then trans must be given, and the query must be the query that is currently |
|
439 * executing on that trans. The transaction's ready_fn will be called once the query has been aborted and the |
|
440 * transaction is now idle again. |
|
441 * |
|
442 * @param trans if the query is part of a transaction, then it MUST be given here |
|
443 * @param query the in-progress query to abort |
|
444 */ |
|
445 void evsql_query_abort (struct evsql_trans *trans, struct evsql_query *query); |
|
446 |
|
447 /** |
|
448 * Print out a textual dump of the given query and parameters using DEBUG |
|
449 * |
|
450 * @param sql the SQL query command |
|
451 * @param params the list of parameter types and values |
|
452 */ |
|
453 void evsql_query_debug (const char *sql, const struct evsql_query_params *params); |
|
454 |
|
455 // @} |
|
456 |
|
457 /** |
|
458 * Transaction API |
|
459 * |
|
460 * @name evsql_trans_* |
|
461 * @{ |
|
462 */ |
|
463 |
|
464 /** |
318 * Create a new transaction. |
465 * Create a new transaction. |
319 * |
466 * |
320 * A transaction will be allocated its own connection, and the "BEGIN TRANSACTION ..." query will be sent (use the |
467 * A transaction will be allocated its own connection, and the "BEGIN TRANSACTION ..." query will be sent (use the |
321 * trans_type argument to specify this). |
468 * trans_type argument to specify this). |
322 * |
469 * |
327 * will NOT be called), and the given trans_error_cb will be called. Note that this includes some, but not all, |
474 * will NOT be called), and the given trans_error_cb will be called. Note that this includes some, but not all, |
328 * cases where evsql_query_* returns an error. |
475 * cases where evsql_query_* returns an error. |
329 * |
476 * |
330 * Once you are done with the transaction, call either evsql_trans_commit or evsql_trans_abort. |
477 * Once you are done with the transaction, call either evsql_trans_commit or evsql_trans_abort. |
331 * |
478 * |
|
479 * @ingroup evsql_trans_* |
332 * @param evsql the context handle from evsql_new_* |
480 * @param evsql the context handle from evsql_new_* |
333 * @param type the type of transaction to create |
481 * @param type the type of transaction to create |
334 * @param error_fn the trans_error_cb to call if this transaction fails |
482 * @param error_fn the trans_error_cb to call if this transaction fails |
335 * @param ready_fn the trans_ready_cb to call once this transaction is ready for use |
483 * @param ready_fn the trans_ready_cb to call once this transaction is ready for use |
336 * @param done_fn the trans_done_cb to call once this transaction has been commmited |
484 * @param done_fn the trans_done_cb to call once this transaction has been commmited |
343 evsql_trans_done_cb done_fn, |
491 evsql_trans_done_cb done_fn, |
344 void *cb_arg |
492 void *cb_arg |
345 ); |
493 ); |
346 |
494 |
347 /** |
495 /** |
348 * Queue the given query for execution. |
|
349 * |
|
350 * If a trans is given (i.e. not NULL), then the transaction must be idle, and the query will be executed in that |
|
351 * transaction's context. Otherwise, the query will be executed without a transaction using an idle connection, or |
|
352 * enqueued for later execution. |
|
353 * |
|
354 * Once the query is complete (got a result, got an error, the connection failed), then the query_cb will be called. |
|
355 * The callback can use the evsql_result_* functions to manipulate it. |
|
356 * |
|
357 * The returned evsql_query handle can be passed to evsql_query_abort at any point before query_fn being called. |
|
358 * |
|
359 * @param evsql the context handle from evsql_new_* |
|
360 * @param trans the optional transaction handle from evsql_trans |
|
361 * @param command the raw SQL command itself |
|
362 * @param query_fn the query_cb to call once the query is complete |
|
363 * @param cb_arg the void* passed to the above |
|
364 * @return the evsql_query handle that can be used to abort the query |
|
365 */ |
|
366 struct evsql_query *evsql_query (struct evsql *evsql, struct evsql_trans *trans, const char *command, evsql_query_cb query_fn, void *cb_arg); |
|
367 |
|
368 /** |
|
369 * Execute the given SQL query using the list of parameter types/values given via evsql_query_params. |
|
370 * |
|
371 * Use the EVSQL_PARAMS macros to declare the struct, and the evsql_param_* functions to populate the values. |
|
372 * |
|
373 * See evsql_query for more info about behaviour. |
|
374 * |
|
375 * XXX: explain SQL param syntax... |
|
376 * |
|
377 * @param command the SQL command to bind the parameters to |
|
378 * @param params the parameter types and values |
|
379 * @see evsql_query |
|
380 */ |
|
381 struct evsql_query *evsql_query_params (struct evsql *evsql, struct evsql_trans *trans, |
|
382 const char *command, const struct evsql_query_params *params, |
|
383 evsql_query_cb query_fn, void *cb_arg |
|
384 ); |
|
385 |
|
386 /** |
|
387 * Execute the given query_info's SQL query with the values given as variable arguments, using the evsql_query_info to |
|
388 * resolve the types. |
|
389 * |
|
390 * See evsql_query for more info about behaviour. |
|
391 * |
|
392 * @param query_info the SQL query information |
|
393 * @see evsql_query |
|
394 */ |
|
395 struct evsql_query *evsql_query_exec (struct evsql *evsql, struct evsql_trans *trans, |
|
396 const struct evsql_query_info *query_info, |
|
397 evsql_query_cb query_fn, void *cb_arg, |
|
398 ... |
|
399 ); |
|
400 |
|
401 /** |
|
402 * Abort a query returned by evsql_query_* that has not yet completed (query_fn has not been called yet). |
|
403 * |
|
404 * The actual query itself may or may not be aborted (and hence may or may not be executed on the server), but query_fn |
|
405 * will not be called anymore, and the query will dispose of itself and any results returned. |
|
406 * |
|
407 * If the query is part of a transaction, then trans must be given, and the query must be the query that is currently |
|
408 * executing on that trans. The transaction's ready_fn will be called once the query has been aborted and the |
|
409 * transaction is now idle again. |
|
410 * |
|
411 * @param trans if the query is part of a transaction, then it MUST be given here |
|
412 * @param query the in-progress query to abort |
|
413 */ |
|
414 void evsql_query_abort (struct evsql_trans *trans, struct evsql_query *query); |
|
415 |
|
416 /** |
|
417 * Commit a transaction using "COMMIT TRANSACTION". |
496 * Commit a transaction using "COMMIT TRANSACTION". |
418 * |
497 * |
419 * The transaction must be idle, just like for evsql_query. Once the transaction has been commited, the transaction's |
498 * The transaction must be idle, just like for evsql_query. Once the transaction has been commited, the transaction's |
420 * done_fn will be called, after which the transaction must not be used anymore. |
499 * done_fn will be called, after which the transaction must not be used anymore. |
421 * |
500 * |
441 * @param trans the transaction from evsql_trans to abort |
520 * @param trans the transaction from evsql_trans to abort |
442 * @see evsql_trans |
521 * @see evsql_trans |
443 */ |
522 */ |
444 void evsql_trans_abort (struct evsql_trans *trans); |
523 void evsql_trans_abort (struct evsql_trans *trans); |
445 |
524 |
446 // @{ |
|
447 /** |
|
448 * Transaction-handling functions |
|
449 */ |
|
450 |
|
451 /** |
525 /** |
452 * Retrieve the transaction-specific error message from the underlying engine. |
526 * Retrieve the transaction-specific error message from the underlying engine. |
453 * |
527 * |
454 * Intended to be called from trans_error_cb |
528 * Intended to be called from trans_error_cb |
455 */ |
529 */ |
456 const char *evsql_trans_error (struct evsql_trans *trans); |
530 const char *evsql_trans_error (struct evsql_trans *trans); |
457 |
531 |
458 // @} |
532 // @} |
459 |
533 |
460 // @{ |
|
461 /** |
534 /** |
462 * Parameter-building functions. |
535 * Parameter-building functions. |
463 * |
536 * |
464 * These manipulate the value of the given parameter index. |
537 * These manipulate the value of the given parameter index. |
|
538 * |
|
539 * @name evsql_param_* |
|
540 * @{ |
465 */ |
541 */ |
466 int evsql_param_binary (struct evsql_query_params *params, size_t param, const char *ptr, size_t len); |
542 int evsql_param_binary (struct evsql_query_params *params, size_t param, const char *ptr, size_t len); |
467 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr); |
543 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr); |
468 int evsql_param_uint16 (struct evsql_query_params *params, size_t param, uint16_t uval); |
544 int evsql_param_uint16 (struct evsql_query_params *params, size_t param, uint16_t uval); |
469 int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval); |
545 int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval); |
470 int evsql_param_null (struct evsql_query_params *params, size_t param); |
546 int evsql_param_null (struct evsql_query_params *params, size_t param); |
471 int evsql_params_clear (struct evsql_query_params *params); |
547 int evsql_params_clear (struct evsql_query_params *params); |
472 |
548 |
473 // @} |
549 // @} |
474 |
550 |
475 // @{ |
|
476 /** |
|
477 * Query-handling functions |
|
478 */ |
|
479 |
|
480 /** |
|
481 * Print out a textual dump of the given query and parameters using DEBUG |
|
482 */ |
|
483 void evsql_query_debug (const char *sql, const struct evsql_query_params *params); |
|
484 |
|
485 // @} |
|
486 |
|
487 // @{ |
|
488 /** |
551 /** |
489 * Result-handling functions |
552 * Result-handling functions |
|
553 * |
|
554 * @name evsql_result_* |
|
555 * @{ |
490 */ |
556 */ |
491 |
557 |
492 /** |
558 /** |
493 * Check the result for errors. Intended for use with non-data queries, i.e. CREATE, etc. |
559 * Check the result for errors. Intended for use with non-data queries, i.e. CREATE, etc. |
494 * |
560 * |
606 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error |
672 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error |
607 * @return zero on success, <0 on error |
673 * @return zero on success, <0 on error |
608 */ |
674 */ |
609 int evsql_result_string (const struct evsql_result *res, size_t row, size_t col, const char **ptr, int nullok); |
675 int evsql_result_string (const struct evsql_result *res, size_t row, size_t col, const char **ptr, int nullok); |
610 |
676 |
611 // @{ |
|
612 /** |
677 /** |
613 * Use evsql_result_binary to read a binary field value, and then convert it using ntoh[slq], storing the value in |
678 * Use evsql_result_binary to read a binary field value, and then convert it using ntoh[slq], storing the value in |
614 * *val. |
679 * *val. |
615 * |
680 * |
616 * The given row/col must be within bounds as returned by evsql_result_rows/cols. |
681 * The given row/col must be within bounds as returned by evsql_result_rows/cols. |
617 * |
682 * |
618 * @param res the result handle passed to query_cb |
683 * @param res the result handle passed to query_cb |
619 * @param row the row index to access |
684 * @param row the row index to access |
620 * @param col the column index to access |
685 * @param col the column index to access |
621 * @param val where to store the decoded value |
686 * @param uval where to store the decoded value |
622 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error |
687 * @param nullok when true and the field value is NULL, *ptr and *size are not modified, otherwise NULL means an error |
623 * @return zero on success, <0 on error |
688 * @return zero on success, <0 on error |
624 */ |
689 */ |
625 int evsql_result_uint16 (const struct evsql_result *res, size_t row, size_t col, uint16_t *uval, int nullok); |
690 int evsql_result_uint16 (const struct evsql_result *res, size_t row, size_t col, uint16_t *uval, int nullok); |
626 int evsql_result_uint32 (const struct evsql_result *res, size_t row, size_t col, uint32_t *uval, int nullok); |
691 int evsql_result_uint32 (const struct evsql_result *res, size_t row, size_t col, uint32_t *uval, int nullok); |
627 int evsql_result_uint64 (const struct evsql_result *res, size_t row, size_t col, uint64_t *uval, int nullok); |
692 int evsql_result_uint64 (const struct evsql_result *res, size_t row, size_t col, uint64_t *uval, int nullok); |
628 |
693 |
|
694 /** |
|
695 * Every result handle passed to query_cb MUST be released by the user, using this function. |
|
696 * |
|
697 * @param res the result handle passed to query_cb |
|
698 */ |
|
699 void evsql_result_free (struct evsql_result *res); |
|
700 |
629 // @} |
701 // @} |
630 |
702 |
631 /** |
703 /** |
632 * Every result handle passed to query_cb MUST be released by the user, using this function. |
|
633 * |
|
634 * @param res the result handle passed to query_cb |
|
635 */ |
|
636 void evsql_result_free (struct evsql_result *res); |
|
637 |
|
638 // @} |
|
639 |
|
640 /** |
|
641 * Close a connection. Callbacks for waiting queries will not be run. |
704 * Close a connection. Callbacks for waiting queries will not be run. |
642 * |
705 * |
643 * XXX: not implemented yet. |
706 * XXX: not implemented yet. |
644 * |
707 * |
|
708 * @ingroup evsql_* |
645 * @param evsql the context handle from evsql_new_* |
709 * @param evsql the context handle from evsql_new_* |
646 */ |
710 */ |
647 void evsql_close (struct evsql *evsql); |
711 void evsql_close (struct evsql *evsql); |
648 |
712 |
649 #endif /* EVSQL_H */ |
713 #endif /* EVSQL_H */ |