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(x) GNUNET_SQ_query_param_fixed_size ((x), sizeof (*(x)))
  96. /**
  97. * Generate query parameter for an RSA public key. The
  98. * database must contain a BLOB type in the respective position.
  99. *
  100. * @param x the query parameter to pass.
  101. */
  102. struct GNUNET_SQ_QueryParam
  103. GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x);
  104. /**
  105. * Generate query parameter for an RSA signature. The
  106. * database must contain a BLOB type in the respective position.
  107. *
  108. * @param x the query parameter to pass
  109. */
  110. struct GNUNET_SQ_QueryParam
  111. GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x);
  112. /**
  113. * Generate query parameter for an absolute time value.
  114. * The database must store a 64-bit integer.
  115. *
  116. * @param x pointer to the query parameter to pass
  117. */
  118. struct GNUNET_SQ_QueryParam
  119. GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
  120. /**
  121. * Generate query parameter for an absolute time value.
  122. * The database must store a 64-bit integer.
  123. *
  124. * @param x pointer to the query parameter to pass
  125. */
  126. struct GNUNET_SQ_QueryParam
  127. GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x);
  128. /**
  129. * Generate query parameter for an uint16_t in host byte order.
  130. *
  131. * @param x pointer to the query parameter to pass
  132. */
  133. struct GNUNET_SQ_QueryParam
  134. GNUNET_SQ_query_param_uint16 (const uint16_t *x);
  135. /**
  136. * Generate query parameter for an uint32_t in host byte order.
  137. *
  138. * @param x pointer to the query parameter to pass
  139. */
  140. struct GNUNET_SQ_QueryParam
  141. GNUNET_SQ_query_param_uint32 (const uint32_t *x);
  142. /**
  143. * Generate query parameter for an uint16_t in host byte order.
  144. *
  145. * @param x pointer to the query parameter to pass
  146. */
  147. struct GNUNET_SQ_QueryParam
  148. GNUNET_SQ_query_param_uint64 (const uint64_t *x);
  149. /**
  150. * Execute binding operations for a prepared statement.
  151. *
  152. * @param db_conn database connection
  153. * @param params parameters to the statement
  154. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  155. */
  156. int
  157. GNUNET_SQ_bind (sqlite3_stmt *stmt,
  158. const struct GNUNET_SQ_QueryParam *params);
  159. /**
  160. * Reset @a stmt and log error.
  161. *
  162. * @param dbh database handle
  163. * @param stmt statement to reset
  164. */
  165. void
  166. GNUNET_SQ_reset (sqlite3 *dbh,
  167. sqlite3_stmt *stmt);
  168. /**
  169. * Extract data from a Postgres database @a result at row @a row.
  170. *
  171. * @param cls closure
  172. * @param result where to extract data from
  173. * @param column column to extract data from
  174. * @param[in,out] dst_size where to store size of result, may be NULL
  175. * @param[out] dst where to store the result
  176. * @return
  177. * #GNUNET_YES if all results could be extracted
  178. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  179. */
  180. typedef int
  181. (*GNUNET_SQ_ResultConverter)(void *cls,
  182. sqlite3_stmt *result,
  183. unsigned int column,
  184. size_t *dst_size,
  185. void *dst);
  186. /**
  187. * @brief Description of a DB result cell.
  188. */
  189. struct GNUNET_SQ_ResultSpec;
  190. /**
  191. * Function called to clean up memory allocated
  192. * by a #GNUNET_SQ_ResultConverter.
  193. *
  194. * @param cls closure
  195. */
  196. typedef void
  197. (*GNUNET_SQ_ResultCleanup)(void *cls);
  198. /**
  199. * @brief Description of a DB result cell.
  200. */
  201. struct GNUNET_SQ_ResultSpec
  202. {
  203. /**
  204. * What is the format of the result?
  205. */
  206. GNUNET_SQ_ResultConverter conv;
  207. /**
  208. * Function to clean up result data, NULL if cleanup is
  209. * not necessary.
  210. */
  211. GNUNET_SQ_ResultCleanup cleaner;
  212. /**
  213. * Closure for @e conv and @e cleaner.
  214. */
  215. void *cls;
  216. /**
  217. * Destination for the data.
  218. */
  219. void *dst;
  220. /**
  221. * Allowed size for the data, 0 for variable-size
  222. * (in this case, the type of @e dst is a `void **`
  223. * and we need to allocate a buffer of the right size).
  224. */
  225. size_t dst_size;
  226. /**
  227. * Where to store actual size of the result. If left at
  228. * NULL, will be made to point to @e dst_size before
  229. * @a conv is called.
  230. */
  231. size_t *result_size;
  232. /**
  233. * Number of parameters (columns) eaten by this operation.
  234. */
  235. unsigned int num_params;
  236. };
  237. /**
  238. * End of result parameter specification.
  239. *
  240. * @return array last entry for the result specification to use
  241. */
  242. #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, 0 }
  243. /**
  244. * Variable-size result expected.
  245. *
  246. * @param[out] dst where to store the result, allocated
  247. * @param[out] sptr where to store the size of @a dst
  248. * @return array entry for the result specification to use
  249. */
  250. struct GNUNET_SQ_ResultSpec
  251. GNUNET_SQ_result_spec_variable_size (void **dst,
  252. size_t *sptr);
  253. /**
  254. * Fixed-size result expected.
  255. *
  256. * @param[out] dst where to store the result
  257. * @param dst_size number of bytes in @a dst
  258. * @return array entry for the result specification to use
  259. */
  260. struct GNUNET_SQ_ResultSpec
  261. GNUNET_SQ_result_spec_fixed_size (void *dst,
  262. size_t dst_size);
  263. /**
  264. * We expect a fixed-size result, with size determined by the type of `* dst`
  265. *
  266. * @param dst point to where to store the result, type fits expected result size
  267. * @return array entry for the result specification to use
  268. */
  269. #define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof (*(dst)))
  270. /**
  271. * Variable-size result expected.
  272. *
  273. * @param[out] dst where to store the result, allocated
  274. * @param[out] sptr where to store the size of @a dst
  275. * @return array entry for the result specification to use
  276. */
  277. struct GNUNET_SQ_ResultSpec
  278. GNUNET_SQ_result_spec_variable_size (void **dst,
  279. size_t *sptr);
  280. /**
  281. * 0-terminated string expected.
  282. *
  283. * @param[out] dst where to store the result, allocated
  284. * @return array entry for the result specification to use
  285. */
  286. struct GNUNET_SQ_ResultSpec
  287. GNUNET_SQ_result_spec_string (char **dst);
  288. /**
  289. * RSA public key expected.
  290. *
  291. * @param[out] rsa where to store the result
  292. * @return array entry for the result specification to use
  293. */
  294. struct GNUNET_SQ_ResultSpec
  295. GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa);
  296. /**
  297. * RSA signature expected.
  298. *
  299. * @param[out] sig where to store the result;
  300. * @return array entry for the result specification to use
  301. */
  302. struct GNUNET_SQ_ResultSpec
  303. GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig);
  304. /**
  305. * Absolute time expected.
  306. *
  307. * @param[out] at where to store the result
  308. * @return array entry for the result specification to use
  309. */
  310. struct GNUNET_SQ_ResultSpec
  311. GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at);
  312. /**
  313. * Absolute time expected.
  314. *
  315. * @param[out] at where to store the result
  316. * @return array entry for the result specification to use
  317. */
  318. struct GNUNET_SQ_ResultSpec
  319. GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at);
  320. /**
  321. * uint16_t expected.
  322. *
  323. * @param[out] u16 where to store the result
  324. * @return array entry for the result specification to use
  325. */
  326. struct GNUNET_SQ_ResultSpec
  327. GNUNET_SQ_result_spec_uint16 (uint16_t *u16);
  328. /**
  329. * uint32_t expected.
  330. *
  331. * @param[out] u32 where to store the result
  332. * @return array entry for the result specification to use
  333. */
  334. struct GNUNET_SQ_ResultSpec
  335. GNUNET_SQ_result_spec_uint32 (uint32_t *u32);
  336. /**
  337. * uint64_t expected.
  338. *
  339. * @param[out] u64 where to store the result
  340. * @return array entry for the result specification to use
  341. */
  342. struct GNUNET_SQ_ResultSpec
  343. GNUNET_SQ_result_spec_uint64 (uint64_t *u64);
  344. /**
  345. * Extract results from a query result according to the given specification.
  346. *
  347. * @param result result to process
  348. * @param[in,out] rs result specification to extract for
  349. * @return
  350. * #GNUNET_OK if all results could be extracted
  351. * #GNUNET_SYSERR if a result was invalid (non-existing field)
  352. */
  353. int
  354. GNUNET_SQ_extract_result (sqlite3_stmt *result,
  355. struct GNUNET_SQ_ResultSpec *rs);
  356. /**
  357. * Free all memory that was allocated in @a rs during
  358. * #GNUNET_SQ_extract_result().
  359. *
  360. * @param rs reult specification to clean up
  361. */
  362. void
  363. GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs);
  364. /* ******************** sq_prepare.c functions ************** */
  365. /**
  366. * Information needed to run a list of SQL statements using
  367. * #GNUNET_SQ_exec_statements().
  368. */
  369. struct GNUNET_SQ_PrepareStatement {
  370. /**
  371. * Actual SQL statement.
  372. */
  373. const char *sql;
  374. /**
  375. * Where to store handle?
  376. */
  377. sqlite3_stmt **pstmt;
  378. };
  379. /**
  380. * Terminator for executable statement list.
  381. */
  382. #define GNUNET_SQ_PREPARE_END { NULL, NULL }
  383. /**
  384. * Create a `struct GNUNET_SQ_PrepareStatement`
  385. *
  386. * @param sql actual SQL statement
  387. * @param pstmt where to store the handle
  388. * @return initialized struct
  389. */
  390. struct GNUNET_SQ_PrepareStatement
  391. GNUNET_SQ_make_prepare (const char *sql,
  392. sqlite3_stmt **pstmt);
  393. /**
  394. * Prepare all statements given in the (NULL,NULL)-terminated
  395. * array at @a ps
  396. *
  397. * @param dbh database handle
  398. * @param ps array of statements to prepare
  399. * @return #GNUNET_OK on success
  400. */
  401. int
  402. GNUNET_SQ_prepare (sqlite3 *dbh,
  403. const struct GNUNET_SQ_PrepareStatement *ps);
  404. /* ******************** sq_exec.c functions ************** */
  405. /**
  406. * Information needed to run a list of SQL statements using
  407. * #GNUNET_SQ_exec_statements().
  408. */
  409. struct GNUNET_SQ_ExecuteStatement {
  410. /**
  411. * Actual SQL statement.
  412. */
  413. const char *sql;
  414. /**
  415. * Should we ignore errors?
  416. */
  417. int ignore_errors;
  418. };
  419. /**
  420. * Terminator for executable statement list.
  421. */
  422. #define GNUNET_SQ_EXECUTE_STATEMENT_END { NULL, GNUNET_SYSERR }
  423. /**
  424. * Create a `struct GNUNET_SQ_ExecuteStatement` where errors are fatal.
  425. *
  426. * @param sql actual SQL statement
  427. * @return initialized struct
  428. */
  429. struct GNUNET_SQ_ExecuteStatement
  430. GNUNET_SQ_make_execute (const char *sql);
  431. /**
  432. * Create a `struct GNUNET_SQ_ExecuteStatement` where errors should
  433. * be tolerated.
  434. *
  435. * @param sql actual SQL statement
  436. * @return initialized struct
  437. */
  438. struct GNUNET_SQ_ExecuteStatement
  439. GNUNET_SQ_make_try_execute (const char *sql);
  440. /**
  441. * Request execution of an array of statements @a es from Postgres.
  442. *
  443. * @param dbh database to execute the statements over
  444. * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
  445. * statements.
  446. * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
  447. * #GNUNET_SYSERR on error
  448. */
  449. int
  450. GNUNET_SQ_exec_statements (sqlite3 *dbh,
  451. const struct GNUNET_SQ_ExecuteStatement *es);
  452. #endif /* GNUNET_SQ_LIB_H_ */
  453. /* end of include/gnunet_sq_lib.h */