Use sqlite user schema version to remember state

This commit is contained in:
Jeremy Lakeman 2013-01-06 13:04:49 +10:30
parent 2b480c1d1a
commit c7cf80b352
3 changed files with 52 additions and 26 deletions

View File

@ -204,23 +204,37 @@ int rhizome_opendb()
if (config.debug.rhizome) {
DEBUGF("Rhizome will use %lluB of storage for its database.", (unsigned long long) config.rhizome.database_size);
}
/* Create tables as required */
sqlite_exec_void_loglevel(loglevel, "PRAGMA auto_vacuum=2;");
if ( sqlite_exec_void("CREATE TABLE IF NOT EXISTS GROUPLIST(id text not null primary key, closed integer,ciphered integer,priority integer);") == -1
|| sqlite_exec_void("CREATE TABLE IF NOT EXISTS MANIFESTS(id text not null primary key, version integer,inserttime integer, filesize integer, filehash text, author text, bar blob, manifest blob);") == -1
|| sqlite_exec_void("CREATE TABLE IF NOT EXISTS FILES(id text not null primary key, length integer, highestpriority integer, datavalid integer, inserttime integer);") == -1
|| sqlite_exec_void("CREATE TABLE IF NOT EXISTS FILEBLOBS(id text not null primary key, data blob);") == -1
|| sqlite_exec_void("DROP TABLE IF EXISTS FILEMANIFESTS;") == -1
|| sqlite_exec_void("CREATE TABLE IF NOT EXISTS GROUPMEMBERSHIPS(manifestid text not null, groupid text not null);") == -1
|| sqlite_exec_void("CREATE TABLE IF NOT EXISTS VERIFICATIONS(sid text not null, did text, name text, starttime integer, endtime integer, signature blob);") == -1
) {
RETURN(WHY("Failed to create schema"));
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
long long version;
if (sqlite_exec_int64_retry(&retry, &version, "PRAGMA user_version;")<0)
RETURN(WHY("Failed to check schema version"));
if (version<1){
/* Create tables as required */
sqlite_exec_void_loglevel(loglevel, "PRAGMA auto_vacuum=2;");
if ( sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS GROUPLIST(id text not null primary key, closed integer,ciphered integer,priority integer);") == -1
|| sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS MANIFESTS(id text not null primary key, version integer,inserttime integer, filesize integer, filehash text, author text, bar blob, manifest blob);") == -1
|| sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS FILES(id text not null primary key, length integer, highestpriority integer, datavalid integer, inserttime integer);") == -1
|| sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS FILEBLOBS(id text not null primary key, data blob);") == -1
|| sqlite_exec_void_retry(&retry, "DROP TABLE IF EXISTS FILEMANIFESTS;") == -1
|| sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS GROUPMEMBERSHIPS(manifestid text not null, groupid text not null);") == -1
|| sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS VERIFICATIONS(sid text not null, did text, name text, starttime integer, endtime integer, signature blob);") == -1
) {
RETURN(WHY("Failed to create schema"));
}
/* Create indexes if they don't already exist */
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS bundlesizeindex ON manifests (filesize);");
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFESTS_HASH ON MANIFESTS(filehash);");
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=1;");
}
/* Create indexes if they don't already exist */
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS bundlesizeindex ON manifests (filesize);");
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFESTS_HASH ON MANIFESTS(filehash);");
/* Future schema updates should be performed here.
The above schema can be assumed to exist.
All changes should attempt to preserve any existing data */
// We can't delete a file that is being transferred in another process at this very moment...
// TODO don't cleanup before every command line operation...
rhizome_cleanup();
@ -403,7 +417,7 @@ int _sqlite_step_retry(struct __sourceloc __whence, int log_level, sqlite_retry_
}
// fall through...
default:
LOGF(log_level, "query failed, %s: %s", sqlite3_errmsg(rhizome_db), sqlite3_sql(statement));
LOGF(log_level, "query failed (%d), %s: %s", stepcode, sqlite3_errmsg(rhizome_db), sqlite3_sql(statement));
ret = -1;
statement = NULL;
break;

View File

@ -59,7 +59,6 @@ int rhizome_open_write(struct rhizome_write *write, char *expectedFileHash, int6
/* Bind appropriate sized zero-filled blob to data field */
if (sqlite3_bind_zeroblob(statement, 1, file_length) != SQLITE_OK) {
WHYF("sqlite3_bind_zeroblob() failed: %s: %s", sqlite3_errmsg(rhizome_db), sqlite3_sql(statement));
sqlite3_finalize(statement);
goto insert_row_fail;
}
@ -71,18 +70,26 @@ int rhizome_open_write(struct rhizome_write *write, char *expectedFileHash, int6
if (rowcount)
WARNF("void query unexpectedly returned %d row%s", rowcount, rowcount == 1 ? "" : "s");
sqlite3_finalize(statement);
if (!sqlite_code_ok(stepcode)){
insert_row_fail:
WHYF("Failed to insert row for fileid=%s", write->id);
if (statement) sqlite3_finalize(statement);
sqlite_exec_void_retry(&retry, "ROLLBACK;");
return -1;
}
sqlite3_finalize(statement);
statement=NULL;
/* Get rowid for inserted row, so that we can modify the blob */
write->blob_rowid = sqlite3_last_insert_rowid(rhizome_db);
DEBUGF("Got rowid %lld for %s", write->blob_rowid, write->id);
if (sqlite_exec_void_retry(&retry, "COMMIT;")!=SQLITE_OK){
return WHYF("Failed to commit transaction: %s", sqlite3_errmsg(rhizome_db));
}
write->file_length = file_length;
write->file_offset = 0;
SHA512_Init(&write->sha512_context);
@ -93,9 +100,6 @@ int rhizome_open_write(struct rhizome_write *write, char *expectedFileHash, int6
write->buffer_size=RHIZOME_BUFFER_MAXIMUM_SIZE;
write->buffer=malloc(write->buffer_size);
if (sqlite_exec_void_retry(&retry, "COMMIT;")!=SQLITE_OK){
return WHYF("Failed to commit transaction: %s", sqlite3_errmsg(rhizome_db));
}
return 0;
}
@ -147,7 +151,6 @@ int rhizome_flush(struct rhizome_write *write){
break;
WHYF("sqlite3_blob_close() failed: %s", sqlite3_errmsg(rhizome_db));
if (blob) sqlite3_blob_close(blob);
return -1;
again:
@ -297,7 +300,12 @@ int rhizome_import_file(rhizome_manifest *m, const char *filepath)
return -1;
}
return rhizome_finish_write(&write);
if (rhizome_finish_write(&write)){
rhizome_fail_write(&write);
return -1;
}
return 0;
}
int rhizome_stat_file(rhizome_manifest *m, const char *filepath)
@ -348,8 +356,10 @@ int rhizome_add_file(rhizome_manifest *m, const char *filepath)
return -1;
}
if (rhizome_finish_write(&write))
if (rhizome_finish_write(&write)){
rhizome_fail_write(&write);
return -1;
}
strlcpy(m->fileHexHash, write.id, SHA512_DIGEST_STRING_LENGTH);
rhizome_manifest_set(m, "filehash", m->fileHexHash);
@ -446,8 +456,10 @@ int rhizome_read(struct rhizome_read *read, unsigned char *buffer, int buffer_le
}
if (read->crypt){
if(rhizome_crypt_xor_block(buffer, count, read->offset, read->key, read->nonce))
if(rhizome_crypt_xor_block(buffer, count, read->offset, read->key, read->nonce)){
sqlite3_blob_close(blob);
return -1;
}
}
read->offset+=count;

0
tests/rhizomeops Normal file → Executable file
View File