@ -324,7 +324,7 @@ static void db_cascade_from(struct DB_SYNC_INSTANCE* si, uint32_t from_pos)
sqlite3_stmt * sel , * upd ;
sqlite3_stmt * sel , * upd ;
if ( si_prep ( si , & sel ,
if ( si_prep ( si , & sel ,
" SELECT id,timestamp,author ,author_signature FROM \" %s \" "
" SELECT id,timestamp,node_id ,author_signature FROM \" %s \" "
" ORDER BY timestamp, author_signature "
" ORDER BY timestamp, author_signature "
" LIMIT -1 OFFSET ? " ) ! = SQLITE_OK )
" LIMIT -1 OFFSET ? " ) ! = SQLITE_OK )
{ sqlite3_exec ( db , " ROLLBACK " , NULL , NULL , NULL ) ; return ; }
{ sqlite3_exec ( db , " ROLLBACK " , NULL , NULL , NULL ) ; return ; }
@ -445,7 +445,7 @@ static int db_record_insert(struct DB_SYNC_INSTANCE* si,
// Insert new record
// Insert new record
if ( si_prep ( si , & stmt ,
if ( si_prep ( si , & stmt ,
" INSERT INTO \" %s \" "
" INSERT INTO \" %s \" "
" (timestamp,author ,id,chain_hash,flags,data, "
" (timestamp,node_id ,id,chain_hash,flags,data, "
" author_signature,delivered_peers,delivery_chain) "
" author_signature,delivered_peers,delivery_chain) "
" VALUES (?,?,?,?,0,?,?,0,'') " ) ! = SQLITE_OK )
" VALUES (?,?,?,?,0,?,?,0,'') " ) ! = SQLITE_OK )
{ sqlite3_exec ( db , " ROLLBACK " , NULL , NULL , NULL ) ; return - 1 ; }
{ sqlite3_exec ( db , " ROLLBACK " , NULL , NULL , NULL ) ; return - 1 ; }
@ -464,7 +464,7 @@ static int db_record_insert(struct DB_SYNC_INSTANCE* si,
if ( do_cascade ) {
if ( do_cascade ) {
sqlite3_stmt * sel ;
sqlite3_stmt * sel ;
if ( si_prep ( si , & sel ,
if ( si_prep ( si , & sel ,
" SELECT timestamp,id,author ,author_signature FROM \" %s \" "
" SELECT timestamp,id,node_id ,author_signature FROM \" %s \" "
" WHERE timestamp>?1 "
" WHERE timestamp>?1 "
" OR (timestamp=?1 AND author_signature>?2) "
" OR (timestamp=?1 AND author_signature>?2) "
" ORDER BY timestamp, author_signature " ) ! = SQLITE_OK )
" ORDER BY timestamp, author_signature " ) ! = SQLITE_OK )
@ -551,7 +551,7 @@ static void si_delivery_update(struct DB_SYNC_INSTANCE* si, uint64_t ts, uint64_
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
if ( si_prep ( si , & stmt ,
if ( si_prep ( si , & stmt ,
" SELECT delivery_chain FROM \" %s \" "
" SELECT delivery_chain FROM \" %s \" "
" WHERE timestamp=? AND author =? " ) = = SQLITE_OK )
" WHERE timestamp=? AND node_id =? " ) = = SQLITE_OK )
{
{
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) ts ) ;
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) ts ) ;
sqlite3_bind_int64 ( stmt , 2 , ( sqlite3_int64 ) author ) ;
sqlite3_bind_int64 ( stmt , 2 , ( sqlite3_int64 ) author ) ;
@ -661,7 +661,7 @@ static void db_handle_init_resp(struct DB_SYNC_INSTANCE* si, uint64_t src, const
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
si_prep ( si , & stmt ,
si_prep ( si , & stmt ,
" SELECT id,timestamp,author ,data,author_signature "
" SELECT id,timestamp,node_id ,data,author_signature "
" FROM \" %s \" ORDER BY timestamp, author_signature "
" FROM \" %s \" ORDER BY timestamp, author_signature "
" LIMIT ? OFFSET ? " ) ;
" LIMIT ? OFFSET ? " ) ;
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) b ) ;
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) b ) ;
@ -713,7 +713,7 @@ static void db_handle_init_resp(struct DB_SYNC_INSTANCE* si, uint64_t src, const
uint16_t * rcp = ( uint16_t * ) ( sdbuf + off ) ; off + = 2 ;
uint16_t * rcp = ( uint16_t * ) ( sdbuf + off ) ; off + = 2 ;
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
si_prep ( si , & stmt ,
si_prep ( si , & stmt ,
" SELECT id,timestamp,author ,data,author_signature "
" SELECT id,timestamp,node_id ,data,author_signature "
" FROM \" %s \" ORDER BY timestamp, author_signature "
" FROM \" %s \" ORDER BY timestamp, author_signature "
" LIMIT ? OFFSET ? " ) ;
" LIMIT ? OFFSET ? " ) ;
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) b ) ;
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) b ) ;
@ -996,8 +996,8 @@ static void db_handle_ack_push(struct DB_SYNC_INSTANCE* si, uint64_t src, const
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
if ( si_prep ( si , & stmt ,
if ( si_prep ( si , & stmt ,
" UPDATE \" %s \" SET flags = flags | 1 "
" UPDATE \" %s \" SET flags = flags | 1 "
" WHERE timestamp=? AND author =? "
" WHERE timestamp=? AND node_id =? "
" AND author =? AND (flags & 1) = 0 " ) = = SQLITE_OK )
" AND node_id =? AND (flags & 1) = 0 " ) = = SQLITE_OK )
{
{
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) ts ) ;
sqlite3_bind_int64 ( stmt , 1 , ( sqlite3_int64 ) ts ) ;
sqlite3_bind_int64 ( stmt , 2 , ( sqlite3_int64 ) author ) ;
sqlite3_bind_int64 ( stmt , 2 , ( sqlite3_int64 ) author ) ;
@ -1188,7 +1188,7 @@ static void db_verify_chain(struct DB_SYNC_INSTANCE* si)
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
if ( si_prep ( si , & stmt ,
if ( si_prep ( si , & stmt ,
" SELECT id,timestamp,author ,author_signature,chain_hash FROM \" %s \" "
" SELECT id,timestamp,node_id ,author_signature,chain_hash FROM \" %s \" "
" ORDER BY timestamp, author_signature " ) ! = SQLITE_OK )
" ORDER BY timestamp, author_signature " ) ! = SQLITE_OK )
return ;
return ;
for ( uint32_t pos = 0 ; sqlite3_step ( stmt ) = = SQLITE_ROW ; pos + + ) {
for ( uint32_t pos = 0 ; sqlite3_step ( stmt ) = = SQLITE_ROW ; pos + + ) {
@ -1305,7 +1305,7 @@ static void db_sync_instance_ttl_cb(void* arg)
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
if ( si_prep ( si , & stmt ,
if ( si_prep ( si , & stmt ,
" DELETE FROM \" %s \" "
" DELETE FROM \" %s \" "
" WHERE author =? AND (flags & 1) = 0 "
" WHERE node_id =? AND (flags & 1) = 0 "
" AND timestamp<? " ) ! = SQLITE_OK )
" AND timestamp<? " ) ! = SQLITE_OK )
{
{
si - > ttl_timer = uasync_set_timeout ( si - > db_sync - > inst - > ua , interval , si , db_sync_instance_ttl_cb , " db_sync_ttl " ) ;
si - > ttl_timer = uasync_set_timeout ( si - > db_sync - > inst - > ua , interval , si , db_sync_instance_ttl_cb , " db_sync_ttl " ) ;
@ -1346,7 +1346,7 @@ int db_sync_init(struct UTUN_INSTANCE* inst)
const char * dp = inst - > config - > global . db_path ;
const char * dp = inst - > config - > global . db_path ;
char sp [ 512 ] ;
char sp [ 512 ] ;
if ( dp [ 0 ] ) snprintf ( sp , sizeof ( sp ) , " %s/syn c " , dp ) ;
if ( dp [ 0 ] ) snprintf ( sp , sizeof ( sp ) , " %s/chats.db " , dp ) ;
else snprintf ( sp , sizeof ( sp ) , " /tmp/utun_db_sync " ) ;
else snprintf ( sp , sizeof ( sp ) , " /tmp/utun_db_sync " ) ;
if ( db_sqlite_open ( db , sp ) ! = 0 ) {
if ( db_sqlite_open ( db , sp ) ! = 0 ) {
@ -1412,31 +1412,28 @@ void db_sync_destroy(struct UTUN_INSTANCE* inst)
DEBUG_INFO ( DEBUG_CATEGORY_DB_SYNC , " db_sync: destroyed " ) ;
DEBUG_INFO ( DEBUG_CATEGORY_DB_SYNC , " db_sync: destroyed " ) ;
}
}
struct DB_SYNC_INSTANCE * db_sync_instance_add ( struct UTUN_INSTANCE * inst , const char * name , uint64_t id )
struct DB_SYNC_INSTANCE * db_sync_instance_add ( struct UTUN_INSTANCE * inst , const char * table_ name, uint64_t hash )
{
{
if ( ! inst | | ! inst - > db_sync | | ! name | | ! name [ 0 ] ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " instance_add invalid args " ) ; return NULL ; }
if ( ! inst | | ! inst - > db_sync | | ! table_ name | | ! table_ name[ 0 ] ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " instance_add invalid args " ) ; return NULL ; }
DEBUG_TRACE ( DEBUG_CATEGORY_DB_SYNC , " name=%s id =%016llx" , name , ( unsigned long long ) id ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_DB_SYNC , " table=%s hash =%016llx" , table_ name, ( unsigned long long ) hash ) ;
struct DB_SYNC * db = inst - > db_sync ;
struct DB_SYNC * db = inst - > db_sync ;
if ( ! db - > enabled | | ! db - > db ) return NULL ;
if ( ! db - > enabled | | ! db - > db ) return NULL ;
if ( ! si_name_valid ( name ) ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " invalid instance name '%s' " , name ) ; return NULL ; }
uint64_t hash = db_instance_hash_compute ( name , id ) ;
struct DB_SYNC_INSTANCE * si = db_instance_find ( db , hash ) ;
struct DB_SYNC_INSTANCE * si = db_instance_find ( db , hash ) ;
if ( si ) { DEBUG_INFO ( DEBUG_CATEGORY_DB_SYNC , " instance already exists hash=%016llx " , ( unsigned long long ) hash ) ; return si ; }
if ( si ) { DEBUG_INFO ( DEBUG_CATEGORY_DB_SYNC , " instance already exists hash=%016llx " , ( unsigned long long ) hash ) ; return si ; }
si = db_instance_alloc ( db ) ;
si = db_instance_alloc ( db ) ;
if ( ! si ) return NULL ;
if ( ! si ) return NULL ;
si - > hash = hash ;
si - > hash = hash ;
snprintf ( si - > table_name , sizeof ( si - > table_name ) , " db_sync_ %s_%llx " , name , ( unsigned long long ) id ) ;
snprintf ( si - > table_name , sizeof ( si - > table_name ) , " %s " , table_name ) ;
// Create table — PK is (timestamp, author ), author_signature NOT NULL
// Create table — PK is (timestamp, node_id ), author_signature NOT NULL
{
{
char sql [ 512 ] ;
char sql [ 512 ] ;
snprintf ( sql , sizeof ( sql ) ,
snprintf ( sql , sizeof ( sql ) ,
" CREATE TABLE IF NOT EXISTS \" %s \" ( "
" CREATE TABLE IF NOT EXISTS \" %s \" ( "
" timestamp INTEGER NOT NULL, "
" timestamp INTEGER NOT NULL, "
" author INTEGER NOT NULL, "
" node_id INTEGER NOT NULL, "
" id INTEGER NOT NULL, "
" id INTEGER NOT NULL, "
" chain_hash BLOB NOT NULL, "
" chain_hash BLOB NOT NULL, "
" flags INTEGER NOT NULL DEFAULT 0, "
" flags INTEGER NOT NULL DEFAULT 0, "
@ -1450,7 +1447,7 @@ struct DB_SYNC_INSTANCE* db_sync_instance_add(struct UTUN_INSTANCE* inst, const
if ( rc ! = SQLITE_OK ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " CREATE TABLE %s: %s " , si - > table_name , sqlite3_errmsg ( db - > db ) ) ; si - > enabled = 0 ; return si ; }
if ( rc ! = SQLITE_OK ) { DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " CREATE TABLE %s: %s " , si - > table_name , sqlite3_errmsg ( db - > db ) ) ; si - > enabled = 0 ; return si ; }
snprintf ( sql , sizeof ( sql ) ,
snprintf ( sql , sizeof ( sql ) ,
" CREATE INDEX IF NOT EXISTS \" idx_%s_ttl \" "
" CREATE INDEX IF NOT EXISTS \" idx_%s_ttl \" "
" ON \" %s \" (author , timestamp) " ,
" ON \" %s \" (node_id , timestamp) " ,
si - > table_name , si - > table_name ) ;
si - > table_name , si - > table_name ) ;
rc = sqlite3_exec ( db - > db , sql , NULL , NULL , NULL ) ;
rc = sqlite3_exec ( db - > db , sql , NULL , NULL , NULL ) ;
if ( rc ! = SQLITE_OK ) DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " CREATE INDEX %s: %s " , si - > table_name , sqlite3_errmsg ( db - > db ) ) ;
if ( rc ! = SQLITE_OK ) DEBUG_ERROR ( DEBUG_CATEGORY_DB_SYNC , " CREATE INDEX %s: %s " , si - > table_name , sqlite3_errmsg ( db - > db ) ) ;
@ -1469,6 +1466,8 @@ struct DB_SYNC_INSTANCE* db_sync_instance_add(struct UTUN_INSTANCE* inst, const
db_verify_chain ( si ) ;
db_verify_chain ( si ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_DEBUG , " instance_add: tbl=%s mc=%u next_id=%llu hash=%016llx " , SI_TBL ( si ) , db_count ( si ) , ( unsigned long long ) si - > next_id , ( unsigned long long ) si - > hash ) ;
si - > ttl_timer = uasync_set_timeout ( inst - > ua , DB_SYNC_TTL_INTERVAL * 10000u , si , db_sync_instance_ttl_cb , " db_sync_ttl " ) ;
si - > ttl_timer = uasync_set_timeout ( inst - > ua , DB_SYNC_TTL_INTERVAL * 10000u , si , db_sync_instance_ttl_cb , " db_sync_ttl " ) ;
int peers_found = 0 , peers_synced = 0 ;
int peers_found = 0 , peers_synced = 0 ;
@ -1487,8 +1486,8 @@ struct DB_SYNC_INSTANCE* db_sync_instance_add(struct UTUN_INSTANCE* inst, const
}
}
DEBUG_INFO ( DEBUG_CATEGORY_DB_SYNC ,
DEBUG_INFO ( DEBUG_CATEGORY_DB_SYNC ,
" instance added name=%s id=%llx tbl=%s hash=%016llx next_id=%llu peers_found=%d peers_synced=%d mc=%u " ,
" instance added table=%s tbl=%s hash=%016llx next_id=%llu peers_found=%d peers_synced=%d mc=%u " ,
name , ( unsigned long long ) id , si - > table_name , ( unsigned long long ) hash ,
table_name , si - > table_name , ( unsigned long long ) hash ,
( unsigned long long ) si - > next_id , peers_found , peers_synced , db_count ( si ) ) ;
( unsigned long long ) si - > next_id , peers_found , peers_synced , db_count ( si ) ) ;
return si ;
return si ;
}
}
@ -1592,7 +1591,7 @@ int db_sync_select(struct DB_SYNC_INSTANCE* si, uint32_t offset, uint32_t limit,
sqlite3_stmt * stmt ;
sqlite3_stmt * stmt ;
if ( si_prep ( si , & stmt ,
if ( si_prep ( si , & stmt ,
" SELECT id,timestamp,author ,data, "
" SELECT id,timestamp,node_id ,data, "
" author_signature,delivered_peers,delivery_chain "
" author_signature,delivered_peers,delivery_chain "
" FROM \" %s \" ORDER BY timestamp, author_signature "
" FROM \" %s \" ORDER BY timestamp, author_signature "
" LIMIT ? OFFSET ? " ) ! = SQLITE_OK )
" LIMIT ? OFFSET ? " ) ! = SQLITE_OK )