📄 sqlite.c
字号:
{ datum = datum_1; rowid = rowid_1; key = key_1; } else { /* have to pick between 1 and 2 */ if (is_prio) { if ((ntohl (datum_1->priority) < ntohl (datum_2->priority)) == is_asc) { datum = datum_1; rowid = rowid_1; key = key_1; last_datum_2 = datum_2; } else { datum = datum_2; rowid = rowid_2; key = key_2; GNUNET_free (datum_1); } } else { if ((GNUNET_ntohll (datum_1->expiration_time) < GNUNET_ntohll (datum_2->expiration_time)) == is_asc) { datum = datum_1; rowid = rowid_1; key = key_1; last_datum_2 = datum_2; } else { datum = datum_2; rowid = rowid_2; key = key_2; GNUNET_free (datum_1); } } } if (datum == NULL) break;#if 0 printf ("FOUND %4u prio %4u exp %20llu old: %4u, %20llu\n", (ntohl (datum->size) - sizeof (GNUNET_DatastoreValue)), ntohl (datum->priority), GNUNET_ntohll (datum->expiration_time), lastPrio, lastExp);#endif if (((GNUNET_NO == limit_nonanonymous) || (ntohl (datum->anonymity_level) == 0)) && ((type == GNUNET_ECRS_BLOCKTYPE_ANY) || (type == ntohl (datum->type)))) { count++; if (iter != NULL) { GNUNET_mutex_unlock (lock); ret = iter (&key, datum, closure, rowid); GNUNET_mutex_lock (lock); if (ret == GNUNET_SYSERR) { GNUNET_free (datum); break; } if (ret == GNUNET_NO) { payload -= getContentDatastoreSize (datum); delete_by_rowid (handle, rowid); } } } lastPrio = ntohl (datum->priority); lastExp = GNUNET_ntohll (datum->expiration_time); GNUNET_free (datum); } sqlite3_finalize (stmt_1); sqlite3_finalize (stmt_2); GNUNET_free_non_null (last_datum_2); GNUNET_mutex_unlock (lock); return count;}/** * Call a method for each key in the database and * call the callback method on it. * * @param type limit the iteration to entries of this * type. 0 for all entries. * @param iter the callback method * @param closure argument to all callback calls * @return the number of results, GNUNET_SYSERR on error */static intiterateLowPriority (unsigned int type, GNUNET_DatastoreValueIterator iter, void *closure){ return sqlite_iterate (type, GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_NO, SELECT_IT_LOW_PRIORITY_1, SELECT_IT_LOW_PRIORITY_2, iter, closure);}/** * Call a method on content with zero anonymity. * * @param type limit the iteration to entries of this * type. 0 for all entries. * @param iter the callback method * @param closure argument to all callback calls * @return the number of results, GNUNET_SYSERR on error */static intiterateNonAnonymous (unsigned int type, GNUNET_DatastoreValueIterator iter, void *closure){ return sqlite_iterate (type, GNUNET_NO, GNUNET_YES, GNUNET_NO, GNUNET_YES, SELECT_IT_NON_ANONYMOUS_1, SELECT_IT_NON_ANONYMOUS_2, iter, closure);}/** * Call a method for each key in the database and * call the callback method on it. * * @param handle the database * @param callback the callback method * @param data second argument to all callback calls * @return the number of items stored in the content database */static intiterateExpirationTime (unsigned int type, GNUNET_DatastoreValueIterator iter, void *closure){ return sqlite_iterate (type, GNUNET_YES, GNUNET_NO, GNUNET_NO, GNUNET_NO, SELECT_IT_EXPIRATION_TIME_1, SELECT_IT_EXPIRATION_TIME_2, iter, closure);}/** * Iterate over the items in the datastore in migration * order. * * @param iter never NULL * @return the number of results, GNUNET_SYSERR on error */static intiterateMigrationOrder (GNUNET_DatastoreValueIterator iter, void *closure){ return sqlite_iterate (0, GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO, SELECT_IT_MIGRATION_ORDER_1, SELECT_IT_MIGRATION_ORDER_2, iter, closure);}/** * Call a method for each key in the database and * do so quickly in any order (can lock the * database until iteration is complete). * * @param callback the callback method * @param data second argument to all callback calls * @return the number of items stored in the content database */static intiterateAllNow (GNUNET_DatastoreValueIterator iter, void *closure){ sqlite3_stmt *stmt; int count; GNUNET_DatastoreValue *datum; sqlite3 *dbh; sqliteHandle *handle; int ret; unsigned long long newpayload; unsigned long long rowid; unsigned long long last_rowid; GNUNET_HashCode key; newpayload = 0; GNUNET_mutex_lock (lock); handle = getDBHandle (); dbh = handle->dbh; /* For the rowid trick see http://permalink.gmane.org/gmane.network.gnunet.devel/1363 */ if (sq_prepare (dbh, "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_" " FROM gn080 WHERE _ROWID_ > :1 ORDER BY _ROWID_ ASC LIMIT 1", &stmt) != 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; } count = 0; last_rowid = 0; while (1) { ret = sqlite3_bind_int64 (stmt, 1, last_rowid); if (ret != SQLITE_OK) break; if (sqlite3_step (stmt) != SQLITE_ROW) break; datum = assembleDatum (handle, stmt, &key, &rowid);#if 0 printf ("IA-FOUND %4u prio %4u exp %20llu RID %llu old-RID: %llu\n", (ntohl (datum->size) - sizeof (GNUNET_DatastoreValue)), ntohl (datum->priority), GNUNET_ntohll (datum->expiration_time), rowid, last_rowid);#endif last_rowid = rowid; sqlite3_reset (stmt); if (datum == NULL) continue; newpayload += getContentDatastoreSize (datum); count++; if (iter != NULL) { GNUNET_mutex_unlock (lock); ret = iter (&key, datum, closure, rowid); GNUNET_mutex_lock (lock); } else ret = GNUNET_OK; if (ret == GNUNET_SYSERR) { GNUNET_free (datum); break; } if (ret == GNUNET_NO) { newpayload -= getContentDatastoreSize (datum); delete_by_rowid (handle, rowid); } GNUNET_free (datum); } sqlite3_reset (stmt); sqlite3_finalize (stmt); if (count != GNUNET_SYSERR) { /* re-computed payload! */ GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_IMMEDIATE | GNUNET_GE_USER | GNUNET_GE_ADMIN, "SQLite database size recomputed. New estimate is %llu, old estimate was %llu\n", newpayload, payload); payload = newpayload; syncStats (handle); } GNUNET_mutex_unlock (lock); return count;}static voidsqlite_shutdown (){ unsigned int idx; if (fn == NULL) return; /* already down */#if DEBUG_SQLITE GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "SQLite: closing database\n");#endif syncStats (getDBHandle ()); for (idx = 0; idx < handle_count; idx++) { sqliteHandle *h = handles[idx]; GNUNET_thread_release_self (h->tid); sqlite3_finalize (h->updPrio); sqlite3_finalize (h->insertContent); if (sqlite3_close (h->dbh) != SQLITE_OK) LOG_SQLITE (h, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite_close"); GNUNET_free (h); } GNUNET_free (handles); handles = NULL; handle_count = 0; GNUNET_free (fn); fn = NULL;}/** * Delete the database. The next operation is * guaranteed to be unloading of the module. */static voiddrop (){ char *n = GNUNET_strdup (fn); sqlite_shutdown (); UNLINK (n); GNUNET_free (n);}/** * Iterate over all entries matching a particular key and * type. * * @param key maybe NULL (to match all entries) * @param vhash hash of the value; maybe NULL (to match all entries) * @param type entries of which type are relevant? * Use 0 for any type. * @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 intget (const GNUNET_HashCode * key, const GNUNET_HashCode * vhash, unsigned int type, GNUNET_DatastoreValueIterator iter, void *closure){ int ret; int count; int total; int off; int limit_off; sqlite3_stmt *stmt; char scratch[256]; GNUNET_DatastoreValue *datum; sqlite3 *dbh; sqliteHandle *handle; GNUNET_HashCode rkey; unsigned long long last_rowid; unsigned long long rowid; int sqoff; if (key == NULL) return iterateLowPriority (type, iter, closure); GNUNET_mutex_lock (lock); handle = getDBHandle (); dbh = handle->dbh; GNUNET_snprintf (scratch, 256, "SELECT count(*) FROM gn080 WHERE hash=:1%s%s", vhash == NULL ? "" : " AND vhash=:2", type == 0 ? "" : (vhash == NULL) ? " AND type=:2" : " AND type=:3"); if (sq_prepare (dbh, scratch, &stmt) != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite_prepare"); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } sqoff = 1; ret = sqlite3_bind_blob (stmt, sqoff++, key, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT); if ((vhash != NULL) && (ret == SQLITE_OK)) ret = sqlite3_bind_blob (stmt, sqoff++, vhash, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT); if ((type != 0) && (ret == SQLITE_OK)) ret = sqlite3_bind_int (stmt, sqoff++, type); if (ret != SQLITE_OK) { LOG_SQLITE (handle, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite_bind"); sqlite3_reset (stmt); sqlite3_finalize (stmt); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } ret = sqlite3_step (stmt); if (ret != SQLITE_ROW)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -