expanding PQ APIs with cleanup function

This commit is contained in:
Christian Grothoff 2015-05-06 11:25:13 +02:00
parent 85e59ceb1a
commit f8723b9b5d
2 changed files with 61 additions and 32 deletions

View File

@ -133,7 +133,7 @@ enum TALER_PQ_ResultFormat
/** /**
* We have a currency amount. * We have a currency amount.
* Data points to a `struct TALER_AmountNBO`, size is not used. * Data points to a `struct TALER_AmountNBO`, size only used for checking.
*/ */
TALER_PQ_RF_AMOUNT_NBO TALER_PQ_RF_AMOUNT_NBO
}; };
@ -251,6 +251,16 @@ TALER_PQ_extract_result (PGresult *result,
int row); int row);
/**
* Free all memory that was allocated in @a rs during
* #TALER_PQ_extract_result().
*
* @param rs reult specification to clean up
*/
void
TALER_PQ_cleanup_result (struct TALER_PQ_ResultSpec *rs);
/** /**
* Extract a currency amount from a query result according to the * Extract a currency amount from a query result according to the
* given specification. * given specification.

View File

@ -122,6 +122,31 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
} }
/**
* Free all memory that was allocated in @a rs during
* #TALER_PQ_extract_result().
*
* @param rs reult specification to clean up
*/
void
TALER_PQ_cleanup_result (struct TALER_PQ_ResultSpec *rs)
{
unsigned int i;
for (i=0; TALER_PQ_RF_END != rs[i].format; i++)
{
if ( (0 == rs[i].dst_size) &&
(NULL != rs[i].dst) )
{
GNUNET_free (rs[i].dst);
rs[i].dst = NULL;
if (NULL != rs[i].result_size)
*rs[i].result_size = 0;
}
}
}
/** /**
* Extract results from a query result according to the given specification. * Extract results from a query result according to the given specification.
* If colums are NULL, the destination is not modified, and #GNUNET_NO * If colums are NULL, the destination is not modified, and #GNUNET_NO
@ -154,7 +179,6 @@ TALER_PQ_extract_result (PGresult *result,
case TALER_PQ_RF_VARSIZE_BLOB: case TALER_PQ_RF_VARSIZE_BLOB:
{ {
size_t len; size_t len;
unsigned int j;
const char *res; const char *res;
void *dst; void *dst;
int fnum; int fnum;
@ -181,40 +205,31 @@ TALER_PQ_extract_result (PGresult *result,
len = PQgetlength (result, len = PQgetlength (result,
row, row,
fnum); fnum);
if ( (0 != rs[i].dst_size) && if ( (0 != spec->dst_size) &&
(rs[i].dst_size != len) ) (spec->dst_size != len) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Field `%s' has wrong size (got %u, expected %u)\n", "Field `%s' has wrong size (got %u, expected %u)\n",
rs[i].fname, spec->fname,
(unsigned int) len, (unsigned int) len,
(unsigned int) rs[i].dst_size); (unsigned int) spec->dst_size);
for (j=0; j<i; j++) TALER_PQ_cleanup_result (rs);
{
if (0 == rs[j].dst_size)
{
GNUNET_free (rs[j].dst);
rs[j].dst = NULL;
if (NULL != rs[j].result_size)
*rs[j].result_size = 0;
}
}
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
res = PQgetvalue (result, res = PQgetvalue (result,
row, row,
fnum); fnum);
GNUNET_assert (NULL != res); GNUNET_assert (NULL != res);
if (0 == rs[i].dst_size) if (0 == spec->dst_size)
{ {
if (NULL != rs[i].result_size) if (NULL != spec->result_size)
*rs[i].result_size = len; *spec->result_size = len;
rs[i].dst_size = len; spec->dst_size = len;
dst = GNUNET_malloc (len); dst = GNUNET_malloc (len);
*((void **) rs[i].dst) = dst; *((void **) spec->dst) = dst;
} }
else else
dst = rs[i].dst; dst = spec->dst;
memcpy (dst, memcpy (dst,
res, res,
len); len);
@ -226,8 +241,11 @@ TALER_PQ_extract_result (PGresult *result,
char *frac_name; char *frac_name;
char *curr_name; char *curr_name;
const char *name = spec->fname; const char *name = spec->fname;
int ret;
GNUNET_assert (NULL != rs[i].dst); GNUNET_assert (NULL != spec->dst);
GNUNET_assert (sizeof (struct TALER_AmountNBO) ==
spec->dst_size);
GNUNET_asprintf (&val_name, GNUNET_asprintf (&val_name,
"%s_val", "%s_val",
name); name);
@ -237,18 +255,19 @@ TALER_PQ_extract_result (PGresult *result,
GNUNET_asprintf (&curr_name, GNUNET_asprintf (&curr_name,
"%s_curr", "%s_curr",
name); name);
ret = TALER_PQ_extract_amount_nbo (result,
if (GNUNET_YES !=
TALER_PQ_extract_amount_nbo (result,
row, row,
val_name, val_name,
frac_name, frac_name,
curr_name, curr_name,
rs[i].dst)) spec->dst);
had_null = GNUNET_YES;
GNUNET_free (val_name); GNUNET_free (val_name);
GNUNET_free (frac_name); GNUNET_free (frac_name);
GNUNET_free (curr_name); GNUNET_free (curr_name);
if (GNUNET_SYSERR == ret)
return GNUNET_SYSERR;
if (GNUNET_OK != ret)
had_null = GNUNET_YES;
break; break;
} }
default: default: