mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Add random UUID to Rhizome database
This commit is contained in:
parent
50bbb722d0
commit
64db53a092
@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "sha2.h"
|
#include "sha2.h"
|
||||||
|
#include "uuid.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "http_server.h"
|
#include "http_server.h"
|
||||||
@ -405,6 +406,7 @@ int create_rhizome_datastore_dir();
|
|||||||
#define FORM_RHIZOME_IMPORT_PATH(buf,fmt,...) (form_rhizome_import_path((buf), sizeof(buf), (fmt), ##__VA_ARGS__))
|
#define FORM_RHIZOME_IMPORT_PATH(buf,fmt,...) (form_rhizome_import_path((buf), sizeof(buf), (fmt), ##__VA_ARGS__))
|
||||||
|
|
||||||
extern sqlite3 *rhizome_db;
|
extern sqlite3 *rhizome_db;
|
||||||
|
uuid_t rhizome_db_uuid;
|
||||||
|
|
||||||
int rhizome_opendb();
|
int rhizome_opendb();
|
||||||
int rhizome_close_db();
|
int rhizome_close_db();
|
||||||
@ -517,6 +519,7 @@ enum sqlbind_type {
|
|||||||
TOHEX, // const unsigned char *binary, unsigned bytes
|
TOHEX, // const unsigned char *binary, unsigned bytes
|
||||||
TEXT_TOUPPER, // const char *text,
|
TEXT_TOUPPER, // const char *text,
|
||||||
TEXT_LEN_TOUPPER, // const char *text, unsigned bytes
|
TEXT_LEN_TOUPPER, // const char *text, unsigned bytes
|
||||||
|
UUID_T, // const uuid_t *uuidp
|
||||||
NUL = 1 << 15, // NUL (no arg) ; NUL|INT, ...
|
NUL = 1 << 15, // NUL (no arg) ; NUL|INT, ...
|
||||||
INDEX = 0xfade0000, // INDEX|INT, int index, ...
|
INDEX = 0xfade0000, // INDEX|INT, int index, ...
|
||||||
NAMED = 0xdead0000 // NAMED|INT, const char *label, ...
|
NAMED = 0xdead0000 // NAMED|INT, const char *label, ...
|
||||||
|
@ -75,7 +75,8 @@ int create_rhizome_datastore_dir()
|
|||||||
return emkdirs(rhizome_datastore_path(), 0700);
|
return emkdirs(rhizome_datastore_path(), 0700);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3 *rhizome_db=NULL;
|
sqlite3 *rhizome_db = NULL;
|
||||||
|
uuid_t rhizome_db_uuid;
|
||||||
|
|
||||||
/* XXX Requires a messy join that might be slow. */
|
/* XXX Requires a messy join that might be slow. */
|
||||||
int rhizome_manifest_priority(sqlite_retry_state *retry, const rhizome_bid_t *bidp)
|
int rhizome_manifest_priority(sqlite_retry_state *retry, const rhizome_bid_t *bidp)
|
||||||
@ -207,7 +208,10 @@ void verify_bundles(){
|
|||||||
|
|
||||||
int rhizome_opendb()
|
int rhizome_opendb()
|
||||||
{
|
{
|
||||||
if (rhizome_db) return 0;
|
if (rhizome_db) {
|
||||||
|
assert(uuid_is_valid(&rhizome_db_uuid));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
IN();
|
IN();
|
||||||
|
|
||||||
@ -257,11 +261,9 @@ int rhizome_opendb()
|
|||||||
) {
|
) {
|
||||||
RETURN(WHY("Failed to create schema"));
|
RETURN(WHY("Failed to create schema"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create indexes if they don't already exist */
|
/* Create indexes if they don't already exist */
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS bundlesizeindex ON manifests (filesize);", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS bundlesizeindex ON manifests (filesize);", END);
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFESTS_HASH ON MANIFESTS(filehash);", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFESTS_HASH ON MANIFESTS(filehash);", END);
|
||||||
|
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=1;", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=1;", END);
|
||||||
}
|
}
|
||||||
if (version<2){
|
if (version<2){
|
||||||
@ -273,26 +275,52 @@ int rhizome_opendb()
|
|||||||
verify_bundles();
|
verify_bundles();
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=2;", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=2;", END);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version<3){
|
if (version<3){
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFESTS_ID_VERSION ON MANIFESTS(id, version);", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFESTS_ID_VERSION ON MANIFESTS(id, version);", END);
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=3;", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=3;", END);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version<4){
|
if (version<4){
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN tail integer;", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN tail integer;", END);
|
||||||
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=4;", END);
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=4;", END);
|
||||||
}
|
}
|
||||||
|
if (version<5){
|
||||||
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE TABLE IF NOT EXISTS IDENTITY(uuid text not null); ", END);
|
||||||
|
sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=5;", END);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[UUID_STRLEN + 1];
|
||||||
|
int r = sqlite_exec_strbuf_retry(&retry, strbuf_local(buf, sizeof buf), "SELECT uuid from IDENTITY LIMIT 1;", END);
|
||||||
|
if (r == -1)
|
||||||
|
RETURN(-1);
|
||||||
|
if (r) {
|
||||||
|
if (!str_to_uuid(buf, &rhizome_db_uuid, NULL)) {
|
||||||
|
WHYF("IDENTITY table contains malformed UUID %s -- overwriting", alloca_str_toprint(buf));
|
||||||
|
if (uuid_generate_random(&rhizome_db_uuid) == -1)
|
||||||
|
RETURN(WHY("Cannot generate new UUID for Rhizome database"));
|
||||||
|
if (sqlite_exec_void_retry(&retry, "UPDATE IDENTITY SET uuid = ? LIMIT 1;", UUID_T, &rhizome_db_uuid, END) == -1)
|
||||||
|
RETURN(WHY("Failed to update new UUID in Rhizome database"));
|
||||||
|
if (config.debug.rhizome)
|
||||||
|
DEBUGF("Updated Rhizome database UUID to %s", alloca_uuid_str(rhizome_db_uuid));
|
||||||
|
}
|
||||||
|
} else if (r == 0) {
|
||||||
|
if (uuid_generate_random(&rhizome_db_uuid) == -1)
|
||||||
|
RETURN(WHY("Cannot generate UUID for Rhizome database"));
|
||||||
|
if (sqlite_exec_void_retry(&retry, "INSERT INTO IDENTITY (uuid) VALUES (?);", UUID_T, &rhizome_db_uuid, END) == -1)
|
||||||
|
RETURN(WHY("Failed to insert UUID into Rhizome database"));
|
||||||
|
if (config.debug.rhizome)
|
||||||
|
DEBUGF("Set Rhizome database UUID to %s", alloca_uuid_str(rhizome_db_uuid));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO recreate tables with collate nocase on hex columns
|
// TODO recreate tables with collate nocase on hex columns
|
||||||
|
|
||||||
/* Future schema updates should be performed here.
|
/* Future schema updates should be performed here.
|
||||||
The above schema can be assumed to exist.
|
The above schema can be assumed to exist.
|
||||||
All changes should attempt to preserve any existing data */
|
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...
|
// We can't delete a file that is being transferred in another process at this very moment...
|
||||||
if (config.rhizome.clean_on_open)
|
if (config.rhizome.clean_on_open)
|
||||||
rhizome_cleanup(NULL);
|
rhizome_cleanup(NULL);
|
||||||
|
INFOF("Opened Rhizome database %s, UUID=%s", dbpath, alloca_uuid_str(rhizome_db_uuid));
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
OUT();
|
OUT();
|
||||||
}
|
}
|
||||||
@ -740,6 +768,19 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case UUID_T: {
|
||||||
|
const uuid_t *uuidp = va_arg(ap, const uuid_t *);
|
||||||
|
++argnum;
|
||||||
|
if (uuidp == NULL) {
|
||||||
|
BIND_NULL(UUID_T);
|
||||||
|
} else {
|
||||||
|
char uuid_str[UUID_STRLEN + 1];
|
||||||
|
uuid_to_str(uuidp, uuid_str);
|
||||||
|
BIND_DEBUG(UUID_T, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", uuid_str, UUID_STRLEN);
|
||||||
|
BIND_RETRY(sqlite3_bind_text, uuid_str, UUID_STRLEN, SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
#undef BIND_RETRY
|
#undef BIND_RETRY
|
||||||
default:
|
default:
|
||||||
FATALF("at bind arg %u, unsupported bind code typ=0x%08x: %s", argnum, typ, sqlite3_sql(statement));
|
FATALF("at bind arg %u, unsupported bind code typ=0x%08x: %s", argnum, typ, sqlite3_sql(statement));
|
||||||
|
17
uuid.c
17
uuid.c
@ -66,23 +66,26 @@ int uuid_generate_random(uuid_t *uuid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uuid_to_str(const uuid_t *uuid, char *dst)
|
char *uuid_to_str(const uuid_t *uuid, char *const dst)
|
||||||
{
|
{
|
||||||
|
char *p = dst;
|
||||||
assert(uuid_is_valid(uuid));
|
assert(uuid_is_valid(uuid));
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i != sizeof uuid->u.binary; ++i) {
|
for (i = 0; i != sizeof uuid->u.binary; ++i) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 4: case 6: case 8: case 10:
|
case 4: case 6: case 8: case 10:
|
||||||
*dst++ = '-';
|
*p++ = '-';
|
||||||
default:
|
default:
|
||||||
*dst++ = hexdigit[uuid->u.binary[i] >> 4];
|
*p++ = hexdigit[uuid->u.binary[i] >> 4];
|
||||||
*dst++ = hexdigit[uuid->u.binary[i] & 0xf];
|
*p++ = hexdigit[uuid->u.binary[i] & 0xf];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*dst = '\0';
|
*p = '\0';
|
||||||
|
assert(p == dst + UUID_STRLEN);
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
int str_to_uuid(const char *str, uuid_t *uuid, const char **afterp)
|
int str_to_uuid(const char *const str, uuid_t *uuid, const char **afterp)
|
||||||
{
|
{
|
||||||
const char *end = str;
|
const char *end = str;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -96,7 +99,7 @@ int str_to_uuid(const char *str, uuid_t *uuid, const char **afterp)
|
|||||||
&& *end == '-'
|
&& *end == '-'
|
||||||
&& strn_fromhex(uuid->u.binary + 10, 6, end + 1, &end) == 6
|
&& strn_fromhex(uuid->u.binary + 10, 6, end + 1, &end) == 6
|
||||||
) {
|
) {
|
||||||
assert(end == str + 36);
|
assert(end == str + UUID_STRLEN);
|
||||||
ret = uuid_is_valid(uuid);
|
ret = uuid_is_valid(uuid);
|
||||||
}
|
}
|
||||||
if (afterp)
|
if (afterp)
|
||||||
|
7
uuid.h
7
uuid.h
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#define __SERVALDNA_UUID_H
|
#define __SERVALDNA_UUID_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
#ifndef __SERVALDNA_UUID_H_INLINE
|
#ifndef __SERVALDNA_UUID_H_INLINE
|
||||||
# if __GNUC__ && !__GNUC_STDC_INLINE__
|
# if __GNUC__ && !__GNUC_STDC_INLINE__
|
||||||
@ -93,9 +94,13 @@ int uuid_generate_random(uuid_t *dest_uuid);
|
|||||||
* are filled with the representation shown above, and the 37th byte dst[36] is
|
* are filled with the representation shown above, and the 37th byte dst[36] is
|
||||||
* set to NUL '\0'.
|
* set to NUL '\0'.
|
||||||
*
|
*
|
||||||
|
* Returns the 'dst' argument.
|
||||||
|
*
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
void uuid_to_str(const uuid_t *valid_uuid, char *dst);
|
char *uuid_to_str(const uuid_t *valid_uuid, char *dst);
|
||||||
|
#define UUID_STRLEN 36
|
||||||
|
#define alloca_uuid_str(uuid) uuid_to_str(&(uuid), alloca(UUID_STRLEN + 1))
|
||||||
|
|
||||||
/* Parse a canonical UUID string (as generated by uuid_to_str()) into a valid
|
/* Parse a canonical UUID string (as generated by uuid_to_str()) into a valid
|
||||||
* UUID, which may or not be supported.
|
* UUID, which may or not be supported.
|
||||||
|
Loading…
Reference in New Issue
Block a user