gnunet_sq_lib.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2017 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file include/gnunet_sq_lib.h
  18. * @brief helper functions for Sqlite3 DB interactions
  19. * @author Christian Grothoff
  20. */
  21. #ifndef GNUNET_SQ_LIB_H
  22. #define GNUNET_SQ_LIB_H
  23. #include <sqlite3.h>
  24. #include "gnunet_util_lib.h"
  25. /**
  26. * Function called to convert input argument into SQL parameters.
  27. *
  28. * @param cls closure
  29. * @param data pointer to input argument
  30. * @param data_len number of bytes in @a data (if applicable)
  31. * @param stmt sqlite statement to bind parameters for
  32. * @param off offset of the argument to bind in @a stmt, numbered from 1,
  33. * so immediately suitable for passing to `sqlite3_bind`-functions.
  34. * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
  35. */
  36. typedef int
  37. (*GNUNET_SQ_QueryConverter)(void *cls,
  38. const void *data,
  39. size_t data_len,
  40. sqlite3_stmt *stmt,
  41. unsigned int off);
  42. /**
  43. * @brief Description of a DB query parameter.
  44. */
  45. struct GNUNET_SQ_QueryParam
  46. {
  47. /**
  48. * Function for how to handle this type of entry.
  49. */
  50. GNUNET_SQ_QueryConverter conv;
  51. /**
  52. * Closure for @e conv.
  53. */
  54. void *conv_cls;
  55. /**
  56. * Data or NULL.
  57. */
  58. const void *data;
  59. /**
  60. * Size of @e data
  61. */
  62. size_t size;
  63. /**
  64. * Number of parameters eaten by this operation.
  65. */
  66. unsigned int num_params;
  67. };
  68. /**
  69. * End of query parameter specification.
  70. */
  71. #define GNUNET_SQ_query_param_end { NULL, NULL, NULL, 0, 0 }
  72. /**
  73. * Generate query parameter for a buffer @a ptr of
  74. * @a ptr_size bytes.
  75. *
  76. * @param ptr pointer to the query parameter to pass
  77. * @oaran ptr_size number of bytes in @a ptr
  78. */
  79. struct GNUNET_SQ_QueryParam
  80. GNUNET_SQ_query_param_fixed_size (const void *ptr,
  81. size_t ptr_size);
  82. /**
  83. * Generate query parameter for a string.
  84. *
  85. * @param ptr pointer to the string query parameter to pass
  86. */
  87. struct GNUNET_SQ_QueryParam
  88. GNUNET_SQ_query_param_string (const char *ptr);
  89. /**
  90. * Generate fixed-size query parameter with size determined
  91. * by variable type.
  92. *
  93. * @param x pointer to the query parameter to pass.
  94. */
  95. #define GNUNET_SQ_query_param_auto_from_type( \
  96. x) GNUNET_SQ_query_param_fixed_size ((x), sizeof(*(x)))
  97. /**
  98. * Generate query parameter for an RSA public key. The
  99. * database must contain a BLOB type in the respective position.
  100. *
  101. * @param x the query parameter to pass.
  102. */
  103. struct GNUNET_SQ_QueryParam
  104. GNUNET_SQ_query_param_rsa_public_key (const struct
  105. GNUNET_CRYPTO_RsaPublicKey *x);
  106. /**
  107. * Generate query parameter for an RSA signature. The
  108. * database must contain a BLOB type in the respective position.
  109. *
  110. * @param x the query parameter to pass
  111. */
  112. struct GNUNET_SQ_QueryParam
  113. GNUNET_SQ_query_param_rsa_signature (const struct
  114. GNUNET_CRYPTO_RsaSignature *x);
  115. /**
  116. * Generate query parameter for an absolute time value.
  117. * The database must store a 64-bit integer.
  118. *
  119. * @param x pointer to the query parameter to pass
  120. */
  121. struct GNUNET_SQ_QueryParam
  122. GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
  123. /**
  124. * Generate query parameter for an absolute time value.
  125. * The database must store a 64-bit integer.
  126. *
  127. * @param x pointer to the query parameter to pass
  128. */
  129. struct GNUNET_SQ_QueryParam
  130. GNUNET_SQ_query_param_absolute_time_nbo (const struct
  131. GNUNET_TIME_AbsoluteNBO *x);
  132. /**
  133. * Generate query parameter for an uint16_t in host byte order.
  134. *
  135. * @param x pointer to the query parameter to pass
  136. */
  137. struct GNUNET_SQ_QueryParam
  138. GNUNET_SQ_query_param_uint16 (const uint16_t *x);
  139. /**
  140. * Generate query parameter for an uint32_t in host byte order.
  141. *
  142. * @param x pointer to the query parameter to pass
  143. */
  144. struct GNUNET_SQ_QueryParam
  145. GNUNET_SQ_query_param_uint32 (const uint32_t *x);
  146. /**
  147. * Generate query parameter for an uint16_t in host byte order.
  148. *
  149. * @param x pointer to the query parameter to pass
  150. */
  151. struct GNUNET_SQ_QueryParam
  152. GNUNET_SQ_query_param_uint64 (const uint64_t *x);
  153. /**
  154. * Execute binding operations for a prepared statement.
  155. *
  156. * @param db_conn database connection
  157. * @param params parameters to the statement
  158. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  159. */
  160. int
  161. GNUNET_SQ_bind (sqlite3_stmt *stmt,
  162. const struct GNUNET_SQ_QueryParam *params);
  163. /**
  164. * Reset @a stmt and log error.
  165. *
  166. * @param dbh database handle
  167. * @param stmt statement to reset
  168. */
  169. void
  170. GNUNET_SQ_reset (sqlite3 *dbh,
  171. sqlite3_stmt *stmt);
  172. /**
  173. * Extract data from a Postgres database @a result at row @a row.
  174. *
  175. * @param cls closure
  176. * @param result where to extract data from
  177. * @param column column to extract data from
  178. * @param[in,out] dst_size where to store size of result, may be NULL
  179. * @param[out] dst where to store the result
  180. * @return
  181. * #GNUNET_YES if all results could be extracted
  182. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  183. */
  184. typedef int
  185. (*GNUNET_SQ_ResultConverter)(void *cls,
  186. sqlite3_stmt *result,
  187. unsigned int column,
  188. size_t *dst_size,
  189. void *dst);
  190. /**
  191. * @brief Description of a DB result cell.
  192. */
  193. struct GNUNET_SQ_ResultSpec;
  194. /**
  195. * Function called to clean up memory allocated
  196. * by a #GNUNET_SQ_ResultConverter.
  197. *
  198. * @param cls closure
  199. */
  200. typedef void
  201. (*GNUNET_SQ_ResultCleanup)(void *cls);
  202. /**
  203. * @brief Description of a DB result cell.
  204. */
  205. struct GNUNET_SQ_ResultSpec
  206. {
  207. /**
  208. * What is the format of the result?
  209. */
  210. GNUNET_SQ_ResultConverter conv;
  211. /**
  212. * Function to clean up result data, NULL if cleanup is
  213. * not necessary.
  214. */
  215. GNUNET_SQ_ResultCleanup cleaner;
  216. /**
  217. * Closure for @e conv and @e cleaner.
  218. */
  219. void *cls;
  220. /**
  221. * Destination for the data.
  222. */
  223. void *dst;
  224. /**
  225. * Allowed size for the data, 0 for variable-size
  226. * (in this case, the type of @e dst is a `void **`
  227. * and we need to allocate a buffer of the right size).
  228. */
  229. size_t dst_size;
  230. /**
  231. * Where to store actual size of the result. If left at
  232. * NULL, will be made to point to @e dst_size before
  233. * @a conv is called.
  234. */
  235. size_t *result_size;
  236. /**
  237. * Number of parameters (columns) eaten by this operation.
  238. */
  239. unsigned int num_params;
  240. };
  241. /**
  242. * End of result parameter specification.
  243. *
  244. * @return array last entry for the result specification to use
  245. */
  246. #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, 0 }
  247. /**
  248. * Variable-size result expected.
  249. *
  250. * @param[out] dst where to store the result, allocated
  251. * @param[out] sptr where to store the size of @a dst
  252. * @return array entry for the result specification to use
  253. */
  254. struct GNUNET_SQ_ResultSpec
  255. GNUNET_SQ_result_spec_variable_size (void **dst,
  256. size_t *sptr);
  257. /**
  258. * Fixed-size result expected.
  259. *
  260. * @param[out] dst where to store the result
  261. * @param dst_size number of bytes in @a dst
  262. * @return array entry for the result specification to use
  263. */
  264. struct GNUNET_SQ_ResultSpec
  265. GNUNET_SQ_result_spec_fixed_size (void *dst,
  266. size_t dst_size);
  267. /**
  268. * We expect a fixed-size result, with size determined by the type of `* dst`
  269. *
  270. * @param dst point to where to store the result, type fits expected result size
  271. * @return array entry for the result specification to use
  272. */
  273. #define GNUNET_SQ_result_spec_auto_from_type( \
  274. dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof(*(dst)))
  275. /**
  276. * Variable-size result expected.
  277. *
  278. * @param[out] dst where to store the result, allocated
  279. * @param[out] sptr where to store the size of @a dst
  280. * @return array entry for the result specification to use
  281. */
  282. struct GNUNET_SQ_ResultSpec
  283. GNUNET_SQ_result_spec_variable_size (void **dst,
  284. size_t *sptr);
  285. /**
  286. * 0-terminated string expected.
  287. *
  288. * @param[out] dst where to store the result, allocated
  289. * @return array entry for the result specification to use
  290. */
  291. struct GNUNET_SQ_ResultSpec
  292. GNUNET_SQ_result_spec_string (char **dst);
  293. /**
  294. * RSA public key expected.
  295. *
  296. * @param[out] rsa where to store the result
  297. * @return array entry for the result specification to use
  298. */
  299. struct GNUNET_SQ_ResultSpec
  300. GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa);
  301. /**
  302. * RSA signature expected.
  303. *
  304. * @param[out] sig where to store the result;
  305. * @return array entry for the result specification to use
  306. */
  307. struct GNUNET_SQ_ResultSpec
  308. GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig);
  309. /**
  310. * Absolute time expected.
  311. *
  312. * @param[out] at where to store the result
  313. * @return array entry for the result specification to use
  314. */
  315. struct GNUNET_SQ_ResultSpec
  316. GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at);
  317. /**
  318. * Absolute time expected.
  319. *
  320. * @param[out] at where to store the result
  321. * @return array entry for the result specification to use
  322. */
  323. struct GNUNET_SQ_ResultSpec
  324. GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at);
  325. /**
  326. * uint16_t expected.
  327. *
  328. * @param[out] u16 where to store the result
  329. * @return array entry for the result specification to use
  330. */
  331. struct GNUNET_SQ_ResultSpec
  332. GNUNET_SQ_result_spec_uint16 (uint16_t *u16);
  333. /**
  334. * uint32_t expected.
  335. *
  336. * @param[out] u32 where to store the result
  337. * @return array entry for the result specification to use
  338. */
  339. struct GNUNET_SQ_ResultSpec
  340. GNUNET_SQ_result_spec_uint32 (uint32_t *u32);
  341. /**
  342. * uint64_t expected.
  343. *
  344. * @param[out] u64 where to store the result
  345. * @return array entry for the result specification to use
  346. */
  347. struct GNUNET_SQ_ResultSpec
  348. GNUNET_SQ_result_spec_uint64 (uint64_t *u64);
  349. /**
  350. * Extract results from a query result according to the given specification.
  351. *
  352. * @param result result to process
  353. * @param[in,out] rs result specification to extract for
  354. * @return
  355. * #GNUNET_OK if all results could be extracted
  356. * #GNUNET_SYSERR if a result was invalid (non-existing field)
  357. */
  358. int
  359. GNUNET_SQ_extract_result (sqlite3_stmt *result,
  360. struct GNUNET_SQ_ResultSpec *rs);
  361. /**
  362. * Free all memory that was allocated in @a rs during
  363. * #GNUNET_SQ_extract_result().
  364. *
  365. * @param rs reult specification to clean up
  366. */
  367. void
  368. GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs);
  369. /* ******************** sq_prepare.c functions ************** */
  370. /**
  371. * Information needed to run a list of SQL statements using
  372. * #GNUNET_SQ_exec_statements().
  373. */
  374. struct GNUNET_SQ_PrepareStatement
  375. {
  376. /**
  377. * Actual SQL statement.
  378. */
  379. const char *sql;
  380. /**
  381. * Where to store handle?
  382. */
  383. sqlite3_stmt **pstmt;
  384. };
  385. /**
  386. * Terminator for executable statement list.
  387. */
  388. #define GNUNET_SQ_PREPARE_END { NULL, NULL }
  389. /**
  390. * Create a `struct GNUNET_SQ_PrepareStatement`
  391. *
  392. * @param sql actual SQL statement
  393. * @param pstmt where to store the handle
  394. * @return initialized struct
  395. */
  396. struct GNUNET_SQ_PrepareStatement
  397. GNUNET_SQ_make_prepare (const char *sql,
  398. sqlite3_stmt **pstmt);
  399. /**
  400. * Prepare all statements given in the (NULL,NULL)-terminated
  401. * array at @a ps
  402. *
  403. * @param dbh database handle
  404. * @param ps array of statements to prepare
  405. * @return #GNUNET_OK on success
  406. */
  407. int
  408. GNUNET_SQ_prepare (sqlite3 *dbh,
  409. const struct GNUNET_SQ_PrepareStatement *ps);
  410. /* ******************** sq_exec.c functions ************** */
  411. /**
  412. * Information needed to run a list of SQL statements using
  413. * #GNUNET_SQ_exec_statements().
  414. */
  415. struct GNUNET_SQ_ExecuteStatement
  416. {
  417. /**
  418. * Actual SQL statement.
  419. */
  420. const char *sql;
  421. /**
  422. * Should we ignore errors?
  423. */
  424. int ignore_errors;
  425. };
  426. /**
  427. * Terminator for executable statement list.
  428. */
  429. #define GNUNET_SQ_EXECUTE_STATEMENT_END { NULL, GNUNET_SYSERR }
  430. /**
  431. * Create a `struct GNUNET_SQ_ExecuteStatement` where errors are fatal.
  432. *
  433. * @param sql actual SQL statement
  434. * @return initialized struct
  435. */
  436. struct GNUNET_SQ_ExecuteStatement
  437. GNUNET_SQ_make_execute (const char *sql);
  438. /**
  439. * Create a `struct GNUNET_SQ_ExecuteStatement` where errors should
  440. * be tolerated.
  441. *
  442. * @param sql actual SQL statement
  443. * @return initialized struct
  444. */
  445. struct GNUNET_SQ_ExecuteStatement
  446. GNUNET_SQ_make_try_execute (const char *sql);
  447. /**
  448. * Request execution of an array of statements @a es from Postgres.
  449. *
  450. * @param dbh database to execute the statements over
  451. * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
  452. * statements.
  453. * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
  454. * #GNUNET_SYSERR on error
  455. */
  456. int
  457. GNUNET_SQ_exec_statements (sqlite3 *dbh,
  458. const struct GNUNET_SQ_ExecuteStatement *es);
  459. #endif /* GNUNET_SQ_LIB_H_ */
  460. /* end of include/gnunet_sq_lib.h */