📄 sqlite.c
字号:
GNUNET_GE_BULK, "sq_prepare"); return GNUNET_SYSERR; } sqlite3_bind_int64 (stmt, 1, rid); if (SQLITE_DONE != sqlite3_step (stmt)) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); sqlite3_finalize (stmt); return GNUNET_SYSERR; } sqlite3_finalize (stmt); return GNUNET_OK;}/** * Given a full row from gn080 table (size,type,priority,anonLevel,expire,GNUNET_hash,value), * assemble it into a GNUNET_DatastoreValue representation. */static GNUNET_DatastoreValue *assembleDatum (sqliteHandle * handle, sqlite3_stmt * stmt, GNUNET_HashCode * key, unsigned long long *rowid){ GNUNET_DatastoreValue *value; int contentSize; sqlite3 *dbh; unsigned int type; sqlite3_stmt *stmtd; *rowid = sqlite3_column_int64 (stmt, 7); type = sqlite3_column_int (stmt, 1); contentSize = sqlite3_column_int (stmt, 0) - sizeof (GNUNET_DatastoreValue); dbh = handle->dbh; if (contentSize < 0) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _ ("Invalid data in %s. Trying to fix (by deletion).\n"), _("sqlite datastore")); if (SQLITE_OK != sqlite3_reset (stmt)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_reset"); if (sq_prepare (dbh, "DELETE FROM gn080 WHERE size < ?", &stmtd) != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sq_prepare"); return NULL; } if (SQLITE_OK != sqlite3_bind_int (stmtd, 1, sizeof (GNUNET_DatastoreValue))) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_bind_int"); if (SQLITE_DONE != sqlite3_step (stmtd)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); if (SQLITE_OK != sqlite3_finalize (stmtd)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_finalize"); return NULL; /* error */ } if (sqlite3_column_bytes (stmt, 5) != sizeof (GNUNET_HashCode) || sqlite3_column_bytes (stmt, 6) != contentSize) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _("Invalid data in %s. Trying to fix (by deletion).\n"), _("sqlite datastore")); if (SQLITE_OK != sqlite3_reset (stmt)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_reset"); if (sq_prepare (dbh, "DELETE FROM gn080 WHERE NOT ((LENGTH(hash) = ?) AND (size = LENGTH(value) + ?))", &stmtd) != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sq_prepare"); return NULL; } if (SQLITE_OK != sqlite3_bind_int (stmtd, 1, sizeof (GNUNET_HashCode))) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_bind_int"); if (SQLITE_OK != sqlite3_bind_int (stmtd, 2, sizeof (GNUNET_DatastoreValue))) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_bind_int"); if (SQLITE_DONE != sqlite3_step (stmtd)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); if (SQLITE_OK != sqlite3_finalize (stmtd)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_finalize"); return NULL; } value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + contentSize); value->size = htonl (contentSize + sizeof (GNUNET_DatastoreValue)); value->type = htonl (type); value->priority = htonl (sqlite3_column_int (stmt, 2)); value->anonymity_level = htonl (sqlite3_column_int (stmt, 3)); value->expiration_time = GNUNET_htonll (sqlite3_column_int64 (stmt, 4)); memcpy (key, sqlite3_column_blob (stmt, 5), sizeof (GNUNET_HashCode)); memcpy (&value[1], sqlite3_column_blob (stmt, 6), contentSize); return value;}/** * @brief Get database statistics * @param key kind of stat to retrieve * @return GNUNET_SYSERR on error, the value otherwise */static unsigned long longgetStat (sqliteHandle * handle, const char *key){ int i; sqlite3_stmt *stmt; unsigned long long ret = GNUNET_SYSERR; i = sq_prepare (handle->dbh, "SELECT value FROM gn071 WHERE key = ?", &stmt); if (i == SQLITE_OK) { sqlite3_bind_text (stmt, 1, key, strlen (key), SQLITE_STATIC); i = sqlite3_step (stmt); if (i == SQLITE_DONE) { ret = 0; i = SQLITE_OK; } else if (i == SQLITE_ROW) { ret = sqlite3_column_int64 (stmt, 0); i = SQLITE_OK; } sqlite3_finalize (stmt); } if (i == SQLITE_BUSY) return GNUNET_SYSERR; if (i != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite_getStat"); return GNUNET_SYSERR; } return ret;}/** * @brief set database statistics * @param key statistic to set * @param val value to set * @return GNUNET_SYSERR on error, GNUNET_OK otherwise */static intsetStat (sqliteHandle * handle, const char *key, unsigned long long val){ sqlite3_stmt *stmt; sqlite3 *dbh; dbh = handle->dbh; if (sq_prepare (dbh, "DELETE FROM gn071 where key = ?", &stmt) == SQLITE_OK) { sqlite3_bind_text (stmt, 1, key, strlen (key), SQLITE_STATIC); if (SQLITE_DONE != sqlite3_step (stmt)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); sqlite3_finalize (stmt); } if (sq_prepare (dbh, "INSERT INTO gn071(key, value) VALUES (?, ?)", &stmt) != SQLITE_OK) return GNUNET_SYSERR; if ((SQLITE_OK != sqlite3_bind_text (stmt, 1, key, strlen (key), SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, val))) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_bind_xxx"); sqlite3_finalize (stmt); return GNUNET_SYSERR; } if (sqlite3_step (stmt) != SQLITE_DONE) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); sqlite3_finalize (stmt); return GNUNET_SYSERR; } sqlite3_finalize (stmt); return GNUNET_OK;}/** * @brief write all statistics to the db */static voidsyncStats (sqliteHandle * handle){ setStat (handle, "PAYLOAD", payload); lastSync = 0;}/** * Call a method for each key in the database and * call the callback method on it. * * @param type entries of which type should be considered? * @param iter maybe NULL (to just count); iter * should return GNUNET_SYSERR to abort the * iteration, GNUNET_NO to delete the entry and * continue and GNUNET_OK to continue iterating * @return the number of results processed, * GNUNET_SYSERR on error */static intsqlite_iterate (unsigned int type, int is_asc, int is_prio, int is_migr, int limit_nonanonymous, const char *stmt_str_1, const char *stmt_str_2, GNUNET_DatastoreValueIterator iter, void *closure){ sqlite3_stmt *stmt_1; sqlite3_stmt *stmt_2; int count; GNUNET_DatastoreValue *datum_1; GNUNET_DatastoreValue *datum_2; GNUNET_DatastoreValue *last_datum_2; GNUNET_DatastoreValue *datum; unsigned int lastPrio; unsigned long long lastExp; GNUNET_HashCode key_1; GNUNET_HashCode key_2; GNUNET_HashCode key; sqlite3 *dbh; sqliteHandle *handle; int ret; GNUNET_CronTime now; unsigned long long rowid; unsigned long long rowid_1; unsigned long long rowid_2; GNUNET_mutex_lock (lock); handle = getDBHandle (); dbh = handle->dbh; if (sq_prepare (dbh, stmt_str_1, &stmt_1) != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_prepare"); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } if (sq_prepare (dbh, stmt_str_2, &stmt_2) != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_prepare"); sqlite3_finalize (stmt_1); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } count = 0; if (is_asc) { lastPrio = 0; lastExp = 0; memset (&key, 0, sizeof (GNUNET_HashCode)); } else { lastPrio = 0x7FFFFFFF; lastExp = 0x7FFFFFFFFFFFFFFFLL; memset (&key, 255, sizeof (GNUNET_HashCode)); } last_datum_2 = NULL; while (1) { if (is_prio) { sqlite3_bind_int (stmt_1, 1, lastPrio); sqlite3_bind_int (stmt_2, 1, lastPrio); } else { sqlite3_bind_int64 (stmt_1, 1, lastExp); sqlite3_bind_int64 (stmt_2, 1, lastExp); } sqlite3_bind_blob (stmt_1, 2, &key, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT); now = GNUNET_get_time (); datum_1 = NULL; datum_2 = last_datum_2; last_datum_2 = NULL; if ((ret = sqlite3_step (stmt_1)) == SQLITE_ROW) { if (is_migr && sqlite3_column_int64 (stmt_1, 4) < now) datum_1 = NULL; else datum_1 = assembleDatum (handle, stmt_1, &key_1, &rowid_1); if (SQLITE_OK != sqlite3_reset (stmt_1)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_reset"); } else { if (ret != SQLITE_DONE) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); sqlite3_finalize (stmt_1); sqlite3_finalize (stmt_2); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } sqlite3_reset (stmt_1); } if (datum_2 == NULL) { if ((ret = sqlite3_step (stmt_2)) == SQLITE_ROW) { if (is_migr && sqlite3_column_int64 (stmt_2, 4) < now) datum_2 = NULL; else datum_2 = assembleDatum (handle, stmt_2, &key_2, &rowid_2); if (SQLITE_OK != sqlite3_reset (stmt_2)) LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_reset"); } else { if (ret != SQLITE_DONE) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite3_step"); sqlite3_finalize (stmt_1); sqlite3_finalize (stmt_2); GNUNET_mutex_unlock (lock); GNUNET_free_non_null (datum_1); return GNUNET_SYSERR; } sqlite3_reset (stmt_2); } } datum = NULL; if (datum_1 == NULL) { datum = datum_2; rowid = rowid_2; key = key_2; } else if (datum_2 == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -