/** * Delete the entry with the lowest expiration value * from the datacache right now. * * @param cls closure (our `struct Plugin`) * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int postgres_plugin_del (void *cls) { struct Plugin *plugin = cls; uint32_t size; uint32_t oid; struct GNUNET_HashCode key; PGresult *res; res = PQexecPrepared (plugin->dbh, "getm", 0, NULL, NULL, NULL, 1); if (GNUNET_OK != GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "getm")) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (postgres error)\n"); return 0; } if (0 == PQntuples (res)) { /* no result */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (no more results)\n"); PQclear (res); return GNUNET_SYSERR; } if ((3 != PQnfields (res)) || (sizeof (size) != PQfsize (res, 0)) || (sizeof (oid) != PQfsize (res, 1)) || (sizeof (struct GNUNET_HashCode) != PQgetlength (res, 0, 2))) { GNUNET_break (0); PQclear (res); return 0; } size = ntohl (*(uint32_t *) PQgetvalue (res, 0, 0)); oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); memcpy (&key, PQgetvalue (res, 0, 2), sizeof (struct GNUNET_HashCode)); PQclear (res); if (GNUNET_OK != GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", oid)) return GNUNET_SYSERR; plugin->num_items--; plugin->env->delete_notify (plugin->env->cls, &key, size + OVERHEAD); return GNUNET_OK; }
/** * Function invoked to process the result and call the processor. * * @param plugin global plugin data * @param proc function to call the value (once only). * @param proc_cls closure for proc * @param res result from exec * @param filename filename for error messages * @param line line number for error messages */ static void process_result (struct Plugin *plugin, PluginDatumProcessor proc, void *proc_cls, PGresult * res, const char *filename, int line) { int iret; uint32_t rowid; uint32_t utype; uint32_t anonymity; uint32_t priority; size_t size; void *data; struct GNUNET_TIME_Absolute expiration_time; struct GNUNET_HashCode key; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint32 ("type", &utype), GNUNET_PQ_result_spec_uint32 ("prio", &priority), GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity), GNUNET_PQ_result_spec_uint32 ("oid", &rowid), GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time), GNUNET_PQ_result_spec_auto_from_type ("hash", &key), GNUNET_PQ_result_spec_variable_size ("value", &data, &size), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != GNUNET_POSTGRES_check_result_ (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "select", filename, line)) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Ending iteration (postgres error)\n"); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } if (0 == PQntuples (res)) { /* no result */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Ending iteration (no more results)\n"); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); PQclear (res); return; } if (1 != PQntuples (res)) { GNUNET_break (0); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); PQclear (res); return; } if (GNUNET_OK != GNUNET_PQ_extract_result (res, rs, 0)) { GNUNET_break (0); PQclear (res); GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", rowid); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Found result of size %u bytes and type %u in database\n", (unsigned int) size, (unsigned int) utype); iret = proc (proc_cls, &key, size, data, (enum GNUNET_BLOCK_Type) utype, priority, anonymity, expiration_time, rowid); PQclear (res); if (iret == GNUNET_NO) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processor asked for item %u to be removed.\n", (unsigned int) rowid); if (GNUNET_OK == GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", rowid)) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Deleting %u bytes from database\n", (unsigned int) size); plugin->env->duc (plugin->env->cls, - (size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Deleted %u bytes from database\n", (unsigned int) size); } } }