+ * The given 'sqlite' statement has been prepared to be run.
+ * It will return a record which should be given to the iterator.
+ * Runs the statement and parses the returned record.
+ *
+ * @param plugin plugin context
+ * @param stmt to run (and then clean up)
+ * @param zone_key private key of the zone
+ * @param iter iterator to call with the result
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
+ */
+static int
+get_record_and_call_iterator (struct Plugin *plugin,
+ sqlite3_stmt *stmt,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
+ GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
+{
+ unsigned int record_count;
+ size_t data_size;
+ const char *data;
+ const char *label;
+ int ret;
+ int sret;
+
+ ret = GNUNET_NO;
+ if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
+ {
+ record_count = sqlite3_column_int (stmt, 0);
+ data_size = sqlite3_column_bytes (stmt, 1);
+ data = sqlite3_column_blob (stmt, 1);
+ label = (const char*) sqlite3_column_text (stmt, 2);
+ if (NULL == zone_key)
+ {
+ /* must be "iterate_all_zones", got one extra return value */
+ if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) !=
+ sqlite3_column_bytes (stmt, 3))
+ {
+ GNUNET_break (0);
+ ret = GNUNET_SYSERR;
+ }
+ else
+ {
+ zone_key = sqlite3_column_blob (stmt, 3);
+ }
+ }
+ if (record_count > 64 * 1024)
+ {
+ /* sanity check, don't stack allocate far too much just
+ because database might contain a large value here */
+ GNUNET_break (0);
+ ret = GNUNET_SYSERR;
+ }
+ else
+ {
+ struct GNUNET_GNSRECORD_Data rd[record_count];
+
+ if (GNUNET_OK !=
+ GNUNET_GNSRECORD_records_deserialize (data_size, data,
+ record_count, rd))
+ {
+ GNUNET_break (0);
+ ret = GNUNET_SYSERR;
+ }
+ else if (NULL != zone_key)
+ {
+ if (NULL != iter)
+ iter (iter_cls, zone_key, label, record_count, rd);
+ ret = GNUNET_YES;
+ }
+ }
+ }
+ else
+ {
+ if (SQLITE_DONE != sret)
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
+ }
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ LOG_SQLITE (plugin,
+ GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "sqlite3_reset");
+ return ret;
+}
+
+/**
+ * Lookup records in the datastore for which we are the authority.