diff options
Diffstat (limited to 'src/util/db.c')
-rw-r--r-- | src/util/db.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/src/util/db.c b/src/util/db.c index a0b234a06..c048a30ff 100644 --- a/src/util/db.c +++ b/src/util/db.c | |||
@@ -13,15 +13,13 @@ | |||
13 | You should have received a copy of the GNU General Public License along with | 13 | You should have received a copy of the GNU General Public License along with |
14 | TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | 14 | TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> |
15 | */ | 15 | */ |
16 | |||
17 | |||
18 | /** | 16 | /** |
19 | * @file util/db.c | 17 | * @file util/db.c |
20 | * @brief helper functions for DB interactions | 18 | * @brief helper functions for DB interactions |
21 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | 19 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> |
22 | * @author Florian Dold | 20 | * @author Florian Dold |
21 | * @author Christian Grothoff | ||
23 | */ | 22 | */ |
24 | |||
25 | #include "platform.h" | 23 | #include "platform.h" |
26 | #include <gnunet/gnunet_util_lib.h> | 24 | #include <gnunet/gnunet_util_lib.h> |
27 | #include "taler_db_lib.h" | 25 | #include "taler_db_lib.h" |
@@ -39,12 +37,11 @@ TALER_DB_exec_prepared (PGconn *db_conn, | |||
39 | unsigned i; | 37 | unsigned i; |
40 | 38 | ||
41 | /* count the number of parameters */ | 39 | /* count the number of parameters */ |
42 | |||
43 | { | 40 | { |
44 | const struct TALER_DB_QueryParam *x; | 41 | const struct TALER_DB_QueryParam *x; |
45 | for (len = 0, x = params; | 42 | for (len = 0, x = params; |
46 | x->more; | 43 | x->more; |
47 | len +=1, x += 1); | 44 | len++, x++); |
48 | } | 45 | } |
49 | 46 | ||
50 | /* new scope to allow stack allocation without alloca */ | 47 | /* new scope to allow stack allocation without alloca */ |
@@ -61,20 +58,22 @@ TALER_DB_exec_prepared (PGconn *db_conn, | |||
61 | param_formats[i] = 1; | 58 | param_formats[i] = 1; |
62 | } | 59 | } |
63 | return PQexecPrepared (db_conn, name, len, | 60 | return PQexecPrepared (db_conn, name, len, |
64 | (const char **) param_values, param_lengths, param_formats, 1); | 61 | (const char **) param_values, |
62 | param_lengths, | ||
63 | param_formats, 1); | ||
65 | } | 64 | } |
66 | } | 65 | } |
67 | 66 | ||
68 | 67 | ||
69 | /** | 68 | /** |
70 | * Extract results from a query result according to the given specification. | 69 | * Extract results from a query result according to the given specification. |
71 | * If colums are NULL, the destination is not modified, and GNUNET_NO | 70 | * If colums are NULL, the destination is not modified, and #GNUNET_NO |
72 | * is returned. | 71 | * is returned. |
73 | * | 72 | * |
74 | * @return | 73 | * @return |
75 | * GNUNET_YES if all results could be extracted | 74 | * #GNUNET_YES if all results could be extracted |
76 | * GNUNET_NO if at least one result was NULL | 75 | * #GNUNET_NO if at least one result was NULL |
77 | * GNUNET_SYSERR if a result was invalid (non-existing field) | 76 | * #GNUNET_SYSERR if a result was invalid (non-existing field) |
78 | */ | 77 | */ |
79 | int | 78 | int |
80 | TALER_DB_extract_result (PGresult *result, | 79 | TALER_DB_extract_result (PGresult *result, |
@@ -82,35 +81,56 @@ TALER_DB_extract_result (PGresult *result, | |||
82 | int row) | 81 | int row) |
83 | { | 82 | { |
84 | int had_null = GNUNET_NO; | 83 | int had_null = GNUNET_NO; |
84 | size_t len; | ||
85 | unsigned int i; | ||
86 | unsigned int j; | ||
85 | 87 | ||
86 | for (; NULL != rs->fname; rs += 1) | 88 | for (i=0; NULL != rs[i].fname; i++) |
87 | { | 89 | { |
88 | int fnum; | 90 | int fnum; |
89 | fnum = PQfnumber (result, rs->fname); | 91 | |
92 | fnum = PQfnumber (result, rs[i].fname); | ||
90 | if (fnum < 0) | 93 | if (fnum < 0) |
91 | { | 94 | { |
92 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "field '%s' does not exist in result\n", rs->fname); | 95 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
96 | "field '%s' does not exist in result\n", | ||
97 | rs->fname); | ||
93 | return GNUNET_SYSERR; | 98 | return GNUNET_SYSERR; |
94 | } | 99 | } |
95 | 100 | ||
96 | /* if a field is null, continue but | 101 | /* if a field is null, continue but |
97 | * remember that we now return a different result */ | 102 | * remember that we now return a different result */ |
98 | |||
99 | if (PQgetisnull (result, row, fnum)) | 103 | if (PQgetisnull (result, row, fnum)) |
100 | { | 104 | { |
101 | had_null = GNUNET_YES; | 105 | had_null = GNUNET_YES; |
102 | continue; | 106 | continue; |
103 | } | 107 | } |
104 | const char *res; | 108 | const char *res; |
105 | if (rs->dst_size != PQgetlength (result, row, fnum)) | 109 | len = PQgetlength (result, row, fnum); |
110 | if ( (0 != rs[i].dst_size) && | ||
111 | (rs[i].dst_size != len) ) | ||
106 | { | 112 | { |
107 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "field '%s' has wrong size (got %u, expected %u)\n", | 113 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
108 | rs->fname, (int) PQgetlength (result, row, fnum), (int) rs->dst_size); | 114 | "field '%s' has wrong size (got %d, expected %d)\n", |
115 | rs[i].fname, | ||
116 | (int) len, | ||
117 | (int) rs->dst_size); | ||
118 | for (j=0;j<i;j++) | ||
119 | if (0 == rs[i].dst_size) | ||
120 | { | ||
121 | GNUNET_free (rs[i].dst); | ||
122 | rs[i].dst = NULL; | ||
123 | *rs[i].result_size = 0; | ||
124 | } | ||
109 | return GNUNET_SYSERR; | 125 | return GNUNET_SYSERR; |
110 | } | 126 | } |
111 | res = PQgetvalue (result, row, fnum); | 127 | res = PQgetvalue (result, row, fnum); |
112 | GNUNET_assert (NULL != res); | 128 | GNUNET_assert (NULL != res); |
113 | memcpy (rs->dst, res, rs->dst_size); | 129 | if (0 == rs->dst_size) |
130 | *(void**) rs->dst = GNUNET_malloc (*rs->result_size = len); | ||
131 | memcpy (rs->dst, | ||
132 | res, | ||
133 | len); | ||
114 | } | 134 | } |
115 | if (GNUNET_YES == had_null) | 135 | if (GNUNET_YES == had_null) |
116 | return GNUNET_NO; | 136 | return GNUNET_NO; |
@@ -124,6 +144,7 @@ TALER_DB_field_isnull (PGresult *result, | |||
124 | const char *fname) | 144 | const char *fname) |
125 | { | 145 | { |
126 | int fnum; | 146 | int fnum; |
147 | |||
127 | fnum = PQfnumber (result, fname); | 148 | fnum = PQfnumber (result, fname); |
128 | GNUNET_assert (fnum >= 0); | 149 | GNUNET_assert (fnum >= 0); |
129 | if (PQgetisnull (result, row, fnum)) | 150 | if (PQgetisnull (result, row, fnum)) |