sq_result_helper.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  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 sq/sq_result_helper.c
  18. * @brief helper functions for queries
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_sq_lib.h"
  23. /**
  24. * Extract variable-sized binary data from a Postgres database @a result at row @a row.
  25. *
  26. * @param cls closure
  27. * @param result where to extract data from
  28. * @param column column to extract data from
  29. * @param[in,out] dst_size where to store size of result, may be NULL
  30. * @param[out] dst where to store the result (actually a `void **`)
  31. * @return
  32. * #GNUNET_YES if all results could be extracted
  33. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  34. */
  35. static int
  36. extract_var_blob (void *cls,
  37. sqlite3_stmt *result,
  38. unsigned int column,
  39. size_t *dst_size,
  40. void *dst)
  41. {
  42. int have;
  43. const void *ret;
  44. void **rdst = (void **) dst;
  45. if (SQLITE_NULL ==
  46. sqlite3_column_type (result,
  47. column))
  48. {
  49. *rdst = NULL;
  50. *dst_size = 0;
  51. return GNUNET_YES;
  52. }
  53. if (SQLITE_BLOB !=
  54. sqlite3_column_type (result,
  55. column))
  56. {
  57. GNUNET_break (0);
  58. return GNUNET_SYSERR;
  59. }
  60. /* sqlite manual says to invoke 'sqlite3_column_blob()'
  61. before calling sqlite3_column_bytes() */
  62. ret = sqlite3_column_blob (result,
  63. column);
  64. have = sqlite3_column_bytes (result,
  65. column);
  66. if (have < 0)
  67. {
  68. GNUNET_break (0);
  69. return GNUNET_SYSERR;
  70. }
  71. *dst_size = have;
  72. if (0 == have)
  73. {
  74. *rdst = NULL;
  75. return GNUNET_OK;
  76. }
  77. *rdst = GNUNET_malloc (have);
  78. GNUNET_memcpy (*rdst,
  79. ret,
  80. have);
  81. return GNUNET_OK;
  82. }
  83. /**
  84. * Cleanup memory allocated by #extract_var_blob().
  85. *
  86. * @param cls pointer to pointer of allocation
  87. */
  88. static void
  89. clean_var_blob (void *cls)
  90. {
  91. void **dptr = (void **) cls;
  92. if (NULL != *dptr)
  93. {
  94. GNUNET_free (*dptr);
  95. *dptr = NULL;
  96. }
  97. }
  98. /**
  99. * Variable-size result expected.
  100. *
  101. * @param[out] dst where to store the result, allocated
  102. * @param[out] sptr where to store the size of @a dst
  103. * @return array entry for the result specification to use
  104. */
  105. struct GNUNET_SQ_ResultSpec
  106. GNUNET_SQ_result_spec_variable_size (void **dst,
  107. size_t *sptr)
  108. {
  109. struct GNUNET_SQ_ResultSpec rs = {
  110. .conv = &extract_var_blob,
  111. .cleaner = &clean_var_blob,
  112. .dst = dst,
  113. .cls = dst,
  114. .result_size = sptr,
  115. .num_params = 1
  116. };
  117. return rs;
  118. }
  119. /**
  120. * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
  121. *
  122. * @param cls closure
  123. * @param result where to extract data from
  124. * @param column column to extract data from
  125. * @param[in,out] dst_size where to store size of result, may be NULL
  126. * @param[out] dst where to store the result
  127. * @return
  128. * #GNUNET_YES if all results could be extracted
  129. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  130. */
  131. static int
  132. extract_fixed_blob (void *cls,
  133. sqlite3_stmt *result,
  134. unsigned int column,
  135. size_t *dst_size,
  136. void *dst)
  137. {
  138. int have;
  139. const void *ret;
  140. if ( (0 == *dst_size) &&
  141. (SQLITE_NULL ==
  142. sqlite3_column_type (result,
  143. column)) )
  144. {
  145. return GNUNET_YES;
  146. }
  147. if (SQLITE_BLOB !=
  148. sqlite3_column_type (result,
  149. column))
  150. {
  151. GNUNET_break (0);
  152. return GNUNET_SYSERR;
  153. }
  154. /* sqlite manual says to invoke 'sqlite3_column_blob()'
  155. before calling sqlite3_column_bytes() */
  156. ret = sqlite3_column_blob (result,
  157. column);
  158. have = sqlite3_column_bytes (result,
  159. column);
  160. if (*dst_size != have)
  161. {
  162. GNUNET_break (0);
  163. return GNUNET_SYSERR;
  164. }
  165. GNUNET_memcpy (dst,
  166. ret,
  167. have);
  168. return GNUNET_OK;
  169. }
  170. /**
  171. * Fixed-size result expected.
  172. *
  173. * @param[out] dst where to store the result
  174. * @param dst_size number of bytes in @a dst
  175. * @return array entry for the result specification to use
  176. */
  177. struct GNUNET_SQ_ResultSpec
  178. GNUNET_SQ_result_spec_fixed_size (void *dst,
  179. size_t dst_size)
  180. {
  181. struct GNUNET_SQ_ResultSpec rs = {
  182. .conv = &extract_fixed_blob,
  183. .dst = dst,
  184. .dst_size = dst_size,
  185. .num_params = 1
  186. };
  187. return rs;
  188. }
  189. /**
  190. * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
  191. *
  192. * @param cls closure
  193. * @param result where to extract data from
  194. * @param column column to extract data from
  195. * @param[in,out] dst_size where to store size of result, may be NULL
  196. * @param[out] dst where to store the result
  197. * @return
  198. * #GNUNET_YES if all results could be extracted
  199. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  200. */
  201. static int
  202. extract_utf8_string (void *cls,
  203. sqlite3_stmt *result,
  204. unsigned int column,
  205. size_t *dst_size,
  206. void *dst)
  207. {
  208. const char *text;
  209. char **rdst = dst;
  210. if (SQLITE_NULL ==
  211. sqlite3_column_type (result,
  212. column))
  213. {
  214. *rdst = NULL;
  215. return GNUNET_OK;
  216. }
  217. if (SQLITE_TEXT !=
  218. sqlite3_column_type (result,
  219. column))
  220. {
  221. GNUNET_break (0);
  222. return GNUNET_SYSERR;
  223. }
  224. /* sqlite manual guarantees that 'sqlite3_column_text()'
  225. is 0-terminated */
  226. text = (const char *) sqlite3_column_text (result,
  227. column);
  228. if (NULL == text)
  229. {
  230. GNUNET_break (0);
  231. return GNUNET_SYSERR;
  232. }
  233. *dst_size = strlen (text) + 1;
  234. *rdst = GNUNET_strdup (text);
  235. return GNUNET_OK;
  236. }
  237. /**
  238. * Cleanup memory allocated by #extract_var_blob().
  239. *
  240. * @param cls pointer to pointer of allocation
  241. */
  242. static void
  243. clean_utf8_string (void *cls)
  244. {
  245. char **dptr = (char **) cls;
  246. if (NULL != *dptr)
  247. {
  248. GNUNET_free (*dptr);
  249. *dptr = NULL;
  250. }
  251. }
  252. /**
  253. * 0-terminated string expected.
  254. *
  255. * @param[out] dst where to store the result, allocated
  256. * @return array entry for the result specification to use
  257. */
  258. struct GNUNET_SQ_ResultSpec
  259. GNUNET_SQ_result_spec_string (char **dst)
  260. {
  261. struct GNUNET_SQ_ResultSpec rs = {
  262. .conv = &extract_utf8_string,
  263. .cleaner = &clean_utf8_string,
  264. .cls = dst,
  265. .dst = dst,
  266. .num_params = 1
  267. };
  268. return rs;
  269. }
  270. /**
  271. * Extract data from a Postgres database @a result at row @a row.
  272. *
  273. * @param cls closure
  274. * @param result where to extract data from
  275. * @param column column to extract data from
  276. * @param[in,out] dst_size where to store size of result, may be NULL
  277. * @param[out] dst where to store the result
  278. * @return
  279. * #GNUNET_YES if all results could be extracted
  280. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  281. */
  282. static int
  283. extract_rsa_pub (void *cls,
  284. sqlite3_stmt *result,
  285. unsigned int column,
  286. size_t *dst_size,
  287. void *dst)
  288. {
  289. struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
  290. int have;
  291. const void *ret;
  292. if (SQLITE_BLOB !=
  293. sqlite3_column_type (result,
  294. column))
  295. {
  296. GNUNET_break (0);
  297. return GNUNET_SYSERR;
  298. }
  299. /* sqlite manual says to invoke 'sqlite3_column_blob()'
  300. before calling sqlite3_column_bytes() */
  301. ret = sqlite3_column_blob (result,
  302. column);
  303. have = sqlite3_column_bytes (result,
  304. column);
  305. if (have < 0)
  306. {
  307. GNUNET_break (0);
  308. return GNUNET_SYSERR;
  309. }
  310. *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
  311. have);
  312. if (NULL == *pk)
  313. {
  314. GNUNET_break (0);
  315. return GNUNET_SYSERR;
  316. }
  317. return GNUNET_OK;
  318. }
  319. /**
  320. * Function called to clean up memory allocated
  321. * by a #GNUNET_PQ_ResultConverter.
  322. *
  323. * @param cls closure
  324. */
  325. static void
  326. clean_rsa_pub (void *cls)
  327. {
  328. struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
  329. if (NULL != *pk)
  330. {
  331. GNUNET_CRYPTO_rsa_public_key_free (*pk);
  332. *pk = NULL;
  333. }
  334. }
  335. /**
  336. * RSA public key expected.
  337. *
  338. * @param[out] rsa where to store the result
  339. * @return array entry for the result specification to use
  340. */
  341. struct GNUNET_SQ_ResultSpec
  342. GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
  343. {
  344. struct GNUNET_SQ_ResultSpec rs = {
  345. .conv = &extract_rsa_pub,
  346. .cleaner = &clean_rsa_pub,
  347. .dst = rsa,
  348. .cls = rsa,
  349. .num_params = 1
  350. };
  351. return rs;
  352. }
  353. /**
  354. * Extract data from a Postgres database @a result at row @a row.
  355. *
  356. * @param cls closure
  357. * @param result where to extract data from
  358. * @param column column to extract data from
  359. * @param[in,out] dst_size where to store size of result, may be NULL
  360. * @param[out] dst where to store the result
  361. * @return
  362. * #GNUNET_YES if all results could be extracted
  363. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  364. */
  365. static int
  366. extract_rsa_sig (void *cls,
  367. sqlite3_stmt *result,
  368. unsigned int column,
  369. size_t *dst_size,
  370. void *dst)
  371. {
  372. struct GNUNET_CRYPTO_RsaSignature **sig = dst;
  373. int have;
  374. const void *ret;
  375. if (SQLITE_BLOB !=
  376. sqlite3_column_type (result,
  377. column))
  378. {
  379. GNUNET_break (0);
  380. return GNUNET_SYSERR;
  381. }
  382. /* sqlite manual says to invoke 'sqlite3_column_blob()'
  383. before calling sqlite3_column_bytes() */
  384. ret = sqlite3_column_blob (result,
  385. column);
  386. have = sqlite3_column_bytes (result,
  387. column);
  388. if (have < 0)
  389. {
  390. GNUNET_break (0);
  391. return GNUNET_SYSERR;
  392. }
  393. *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
  394. have);
  395. if (NULL == *sig)
  396. {
  397. GNUNET_break (0);
  398. return GNUNET_SYSERR;
  399. }
  400. return GNUNET_OK;
  401. }
  402. /**
  403. * Function called to clean up memory allocated
  404. * by a #GNUNET_PQ_ResultConverter.
  405. *
  406. * @param cls result data to clean up
  407. */
  408. static void
  409. clean_rsa_sig (void *cls)
  410. {
  411. struct GNUNET_CRYPTO_RsaSignature **sig = cls;
  412. if (NULL != *sig)
  413. {
  414. GNUNET_CRYPTO_rsa_signature_free (*sig);
  415. *sig = NULL;
  416. }
  417. }
  418. /**
  419. * RSA signature expected.
  420. *
  421. * @param[out] sig where to store the result;
  422. * @return array entry for the result specification to use
  423. */
  424. struct GNUNET_SQ_ResultSpec
  425. GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
  426. {
  427. struct GNUNET_SQ_ResultSpec rs = {
  428. .conv = &extract_rsa_sig,
  429. .cleaner = &clean_rsa_sig,
  430. .dst = sig,
  431. .cls = sig,
  432. .num_params = 1
  433. };
  434. return rs;
  435. }
  436. /**
  437. * Extract absolute time value from a Postgres database @a result at row @a row.
  438. *
  439. * @param cls closure
  440. * @param result where to extract data from
  441. * @param column column to extract data from
  442. * @param[in,out] dst_size where to store size of result, may be NULL
  443. * @param[out] dst where to store the result
  444. * @return
  445. * #GNUNET_YES if all results could be extracted
  446. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  447. */
  448. static int
  449. extract_abs_time (void *cls,
  450. sqlite3_stmt *result,
  451. unsigned int column,
  452. size_t *dst_size,
  453. void *dst)
  454. {
  455. struct GNUNET_TIME_Absolute *u = dst;
  456. struct GNUNET_TIME_Absolute t;
  457. GNUNET_assert (sizeof (uint64_t) == *dst_size);
  458. if (SQLITE_INTEGER !=
  459. sqlite3_column_type (result,
  460. column))
  461. {
  462. GNUNET_break (0);
  463. return GNUNET_SYSERR;
  464. }
  465. t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
  466. column);
  467. if (INT64_MAX == t.abs_value_us)
  468. t = GNUNET_TIME_UNIT_FOREVER_ABS;
  469. *u = t;
  470. return GNUNET_OK;
  471. }
  472. /**
  473. * Absolute time expected.
  474. *
  475. * @param[out] at where to store the result
  476. * @return array entry for the result specification to use
  477. */
  478. struct GNUNET_SQ_ResultSpec
  479. GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
  480. {
  481. struct GNUNET_SQ_ResultSpec rs = {
  482. .conv = &extract_abs_time,
  483. .dst = at,
  484. .dst_size = sizeof (struct GNUNET_TIME_Absolute),
  485. .num_params = 1
  486. };
  487. return rs;
  488. }
  489. /**
  490. * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
  491. *
  492. * @param cls closure
  493. * @param result where to extract data from
  494. * @param column column to extract data from
  495. * @param[in,out] dst_size where to store size of result, may be NULL
  496. * @param[out] dst where to store the result
  497. * @return
  498. * #GNUNET_YES if all results could be extracted
  499. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  500. */
  501. static int
  502. extract_abs_time_nbo (void *cls,
  503. sqlite3_stmt *result,
  504. unsigned int column,
  505. size_t *dst_size,
  506. void *dst)
  507. {
  508. struct GNUNET_TIME_AbsoluteNBO *u = dst;
  509. struct GNUNET_TIME_Absolute t;
  510. GNUNET_assert (sizeof (uint64_t) == *dst_size);
  511. if (SQLITE_INTEGER !=
  512. sqlite3_column_type (result,
  513. column))
  514. {
  515. GNUNET_break (0);
  516. return GNUNET_SYSERR;
  517. }
  518. t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
  519. column);
  520. if (INT64_MAX == t.abs_value_us)
  521. t = GNUNET_TIME_UNIT_FOREVER_ABS;
  522. *u = GNUNET_TIME_absolute_hton (t);
  523. return GNUNET_OK;
  524. }
  525. /**
  526. * Absolute time expected.
  527. *
  528. * @param[out] at where to store the result
  529. * @return array entry for the result specification to use
  530. */
  531. struct GNUNET_SQ_ResultSpec
  532. GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
  533. {
  534. struct GNUNET_SQ_ResultSpec rs = {
  535. .conv = &extract_abs_time_nbo,
  536. .dst = at,
  537. .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
  538. .num_params = 1
  539. };
  540. return rs;
  541. }
  542. /**
  543. * Extract 16-bit integer from a Postgres database @a result at row @a row.
  544. *
  545. * @param cls closure
  546. * @param result where to extract data from
  547. * @param column column to extract data from
  548. * @param[in,out] dst_size where to store size of result, may be NULL
  549. * @param[out] dst where to store the result
  550. * @return
  551. * #GNUNET_YES if all results could be extracted
  552. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  553. */
  554. static int
  555. extract_uint16 (void *cls,
  556. sqlite3_stmt *result,
  557. unsigned int column,
  558. size_t *dst_size,
  559. void *dst)
  560. {
  561. uint64_t v;
  562. uint16_t *u = dst;
  563. GNUNET_assert (sizeof (uint16_t) == *dst_size);
  564. if (SQLITE_INTEGER !=
  565. sqlite3_column_type (result,
  566. column))
  567. {
  568. GNUNET_break (0);
  569. return GNUNET_SYSERR;
  570. }
  571. v = (uint64_t) sqlite3_column_int64 (result,
  572. column);
  573. if (v > UINT16_MAX)
  574. {
  575. GNUNET_break (0);
  576. return GNUNET_SYSERR;
  577. }
  578. *u = (uint16_t) v;
  579. return GNUNET_OK;
  580. }
  581. /**
  582. * uint16_t expected.
  583. *
  584. * @param[out] u16 where to store the result
  585. * @return array entry for the result specification to use
  586. */
  587. struct GNUNET_SQ_ResultSpec
  588. GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
  589. {
  590. struct GNUNET_SQ_ResultSpec rs = {
  591. .conv = &extract_uint16,
  592. .dst = u16,
  593. .dst_size = sizeof (uint16_t),
  594. .num_params = 1
  595. };
  596. return rs;
  597. }
  598. /**
  599. * Extract 32-bit integer from a Postgres database @a result at row @a row.
  600. *
  601. * @param cls closure
  602. * @param result where to extract data from
  603. * @param column column to extract data from
  604. * @param[in,out] dst_size where to store size of result, may be NULL
  605. * @param[out] dst where to store the result
  606. * @return
  607. * #GNUNET_YES if all results could be extracted
  608. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  609. */
  610. static int
  611. extract_uint32 (void *cls,
  612. sqlite3_stmt *result,
  613. unsigned int column,
  614. size_t *dst_size,
  615. void *dst)
  616. {
  617. uint64_t v;
  618. uint32_t *u = dst;
  619. GNUNET_assert (sizeof (uint32_t) == *dst_size);
  620. if (SQLITE_INTEGER !=
  621. sqlite3_column_type (result,
  622. column))
  623. {
  624. GNUNET_break (0);
  625. return GNUNET_SYSERR;
  626. }
  627. v = (uint64_t) sqlite3_column_int64 (result,
  628. column);
  629. if (v > UINT32_MAX)
  630. {
  631. GNUNET_break (0);
  632. return GNUNET_SYSERR;
  633. }
  634. *u = (uint32_t) v;
  635. return GNUNET_OK;
  636. }
  637. /**
  638. * uint32_t expected.
  639. *
  640. * @param[out] u32 where to store the result
  641. * @return array entry for the result specification to use
  642. */
  643. struct GNUNET_SQ_ResultSpec
  644. GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
  645. {
  646. struct GNUNET_SQ_ResultSpec rs = {
  647. .conv = &extract_uint32,
  648. .dst = u32,
  649. .dst_size = sizeof (uint32_t),
  650. .num_params = 1
  651. };
  652. return rs;
  653. }
  654. /**
  655. * Extract 64-bit integer from a Postgres database @a result at row @a row.
  656. *
  657. * @param cls closure
  658. * @param result where to extract data from
  659. * @param column column to extract data from
  660. * @param[in,out] dst_size where to store size of result, may be NULL
  661. * @param[out] dst where to store the result
  662. * @return
  663. * #GNUNET_YES if all results could be extracted
  664. * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
  665. */
  666. static int
  667. extract_uint64 (void *cls,
  668. sqlite3_stmt *result,
  669. unsigned int column,
  670. size_t *dst_size,
  671. void *dst)
  672. {
  673. uint64_t *u = dst;
  674. GNUNET_assert (sizeof (uint64_t) == *dst_size);
  675. if (SQLITE_INTEGER !=
  676. sqlite3_column_type (result,
  677. column))
  678. {
  679. GNUNET_break (0);
  680. return GNUNET_SYSERR;
  681. }
  682. *u = (uint64_t) sqlite3_column_int64 (result,
  683. column);
  684. return GNUNET_OK;
  685. }
  686. /**
  687. * uint64_t expected.
  688. *
  689. * @param[out] u64 where to store the result
  690. * @return array entry for the result specification to use
  691. */
  692. struct GNUNET_SQ_ResultSpec
  693. GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
  694. {
  695. struct GNUNET_SQ_ResultSpec rs = {
  696. .conv = &extract_uint64,
  697. .dst = u64,
  698. .dst_size = sizeof (uint64_t),
  699. .num_params = 1
  700. };
  701. return rs;
  702. }
  703. /* end of sq_result_helper.c */