Пример #1
0
int db_schema_verify(DB_txn *const txn) {
	char const magic[] = "DBDB schema layer v1";
	size_t const len = sizeof(magic)-1;

	DB_val key[1];
	DB_VAL_STORAGE(key, DB_VARINT_MAX*2);
	db_bind_uint64(key, DBSchema);
	db_bind_uint64(key, 0);
	DB_val val[1];

	DB_cursor *cur;
	int rc = db_txn_cursor(txn, &cur);
	if(rc < 0) return rc;
	rc = db_cursor_first(cur, NULL, NULL, +1);
	if(rc < 0 && DB_NOTFOUND != rc) return rc;

	// If the database is completely empty
	// we can assume it's ours to play with
	if(DB_NOTFOUND == rc) {
		*val = (DB_val){ len, (char *)magic };
		rc = db_put(txn, key, val, 0);
		if(rc < 0) return rc;
		return 0;
	}

	rc = db_get(txn, key, val);
	if(DB_NOTFOUND == rc) return DB_VERSION_MISMATCH;
	if(rc < 0) return rc;
	if(len != val->size) return DB_VERSION_MISMATCH;
	if(0 != memcmp(val->data, magic, len)) return DB_VERSION_MISMATCH;
	return 0;
}
Пример #2
0
uint64_t db_next_id(dbid_t const table, DB_txn *const txn) {
	DB_cursor *cur = NULL;
	if(db_txn_cursor(txn, &cur) < 0) return 0;
	DB_range range[1];
	DB_RANGE_STORAGE(range, DB_VARINT_MAX);
	db_bind_uint64(range->min, table+0);
	db_bind_uint64(range->max, table+1);
	DB_val prev[1];
	int rc = db_cursor_firstr(cur, range, prev, NULL, -1);
	if(DB_NOTFOUND == rc) return 1;
	if(rc < 0) return 0;
	uint64_t const t = db_read_uint64(prev);
	assert(table == t);
	return db_read_uint64(prev)+1;
}
Пример #3
0
int SLNSessionCopyLastSubmissionURIs(SLNSessionRef const session, str_t *const outFileURI, str_t *const outMetaURI) {
	DB_env *db = NULL;
	DB_txn *txn = NULL;
	int rc = SLNSessionDBOpen(session, SLN_RDWR, &db);
	if(rc < 0) goto cleanup;
	rc = db_txn_begin(db, NULL, DB_RDONLY, &txn);
	if(rc < 0) goto cleanup;

	if(outFileURI) {
		DB_val key[1], val[1];
		DB_VAL_STORAGE(key, DB_VARINT_MAX*2);
		db_bind_uint64(key, SLNLastFileURIBySessionID);
		db_bind_uint64(key, session->sessionID);
		DB_VAL_STORAGE_VERIFY(key);
		rc = db_get(txn, key, val);
		if(rc >= 0) {
			strarg_t const URI = db_read_string(val, txn);
			strlcpy(outFileURI, URI, SLN_URI_MAX);
		} else if(DB_NOTFOUND == rc) {
			outFileURI[0] = '\0';
			rc = 0;
		} else {
			goto cleanup;
		}
	}
	if(outMetaURI) {
		DB_val key[1], val[1];
		DB_VAL_STORAGE(key, DB_VARINT_MAX*2);
		db_bind_uint64(key, SLNLastMetaURIBySessionID);
		db_bind_uint64(key, session->sessionID);
		DB_VAL_STORAGE_VERIFY(key);
		rc = db_get(txn, key, val);
		if(rc >= 0) {
			strarg_t const URI = db_read_string(val, txn);
			strlcpy(outMetaURI, URI, SLN_URI_MAX);
		} else if(DB_NOTFOUND == rc) {
			outMetaURI[0] = '\0';
			rc = 0;
		} else {
			goto cleanup;
		}
	}

cleanup:
	db_txn_abort(txn); txn = NULL;
	SLNSessionDBClose(session, &db);
	return rc;
}