From 9370b1d2fa46ef2b7a2a6ab265102d3c1f69099d Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Sat, 14 Jul 2018 17:47:51 -0400 Subject: [PATCH] switching most columns from blob to text --- torba/basedatabase.py | 138 ++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 71 deletions(-) diff --git a/torba/basedatabase.py b/torba/basedatabase.py index 92efd97b9..d8c4b12c0 100644 --- a/torba/basedatabase.py +++ b/torba/basedatabase.py @@ -108,32 +108,32 @@ class SQLiteMixin(object): class BaseDatabase(SQLiteMixin): + CREATE_PUBKEY_ADDRESS_TABLE = """ + create table if not exists pubkey_address ( + address text primary key, + account text not null, + chain integer not null, + position integer not null, + pubkey text not null, + history text, + used_times integer not null default 0 + ); + """ + CREATE_TX_TABLE = """ create table if not exists tx ( - txhash blob primary key, + txid text primary key, raw blob not null, height integer not null, is_verified boolean not null default 0 ); """ - CREATE_PUBKEY_ADDRESS_TABLE = """ - create table if not exists pubkey_address ( - address blob primary key, - account blob not null, - chain integer not null, - position integer not null, - pubkey blob not null, - history text, - used_times integer not null default 0 - ); - """ - CREATE_TXO_TABLE = """ create table if not exists txo ( - txoid integer primary key, - txhash blob references tx, - address blob references pubkey_address, + txoid text primary key, + txid text references tx, + address text references pubkey_address, position integer not null, amount integer not null, script blob not null, @@ -143,9 +143,9 @@ class BaseDatabase(SQLiteMixin): CREATE_TXI_TABLE = """ create table if not exists txi ( - txhash blob references tx, - address blob references pubkey_address, - txoid integer references txo + txid text references tx, + txoid text references txo, + address text references pubkey_address ); """ @@ -158,9 +158,9 @@ class BaseDatabase(SQLiteMixin): def txo_to_row(self, tx, address, txo): return { - 'txhash': sqlite3.Binary(tx.hash), + 'txid': sqlite3.Binary(tx.hash), 'address': sqlite3.Binary(address), - 'position': txo.index, + 'position': txo.position, 'amount': txo.amount, 'script': sqlite3.Binary(txo.script.source) } @@ -245,17 +245,26 @@ class BaseDatabase(SQLiteMixin): def get_balance_for_account(self, account, **constraints): extra_sql = "" if constraints: - extra_sql = ' AND ' + ' AND '.join( - '{} = :{}'.format(c, c) for c in constraints.keys() - ) + extras = [] + for key in constraints.keys(): + col, op = key, '=' + if key.endswith('__not'): + col, op = key[:-len('__not')], '!=' + elif key.endswith('__lte'): + col, op = key[:-len('__lte')], '<=' + extras.append('{} {} :{}'.format(col, op, key)) + extra_sql = ' AND ' + ' AND '.join(extras) values = {'account': sqlite3.Binary(account.public_key.address)} values.update(constraints) result = yield self.db.runQuery( """ - SELECT SUM(amount) FROM txo - JOIN pubkey_address ON pubkey_address.address=txo.address - WHERE account=:account AND - txoid NOT IN (SELECT txoid FROM txi) + SELECT SUM(amount) + FROM txo + JOIN tx ON tx.txhash=txo.txhash + JOIN pubkey_address ON pubkey_address.address=txo.address + WHERE + pubkey_address.account=:account AND + txoid NOT IN (SELECT txoid FROM txi) """+extra_sql, values ) if result: @@ -305,38 +314,6 @@ class BaseDatabase(SQLiteMixin): values.append(sqlite3.Binary(pubkey.pubkey_bytes)) return self.db.runOperation(sql, values) - def get_addresses(self, account, chain, limit=None, details=False): - sql = ["SELECT {} FROM pubkey_address WHERE account = :account"] - params = {'account': sqlite3.Binary(account.public_key.address)} - if chain is not None: - sql.append("AND chain = :chain") - params['chain'] = chain - sql.append("ORDER BY position DESC") - if limit is not None: - sql.append("LIMIT {}".format(limit)) - if details: - return self.query_dict_value_list(' '.join(sql), ('address', 'position', 'used_times'), params) - else: - return self.query_one_value_list(' '.join(sql).format('address'), params) - - def _used_address_sql(self, account, chain, comparison_op, used_times, limit=None): - sql = [ - "SELECT address FROM pubkey_address", - "WHERE account = :account AND" - ] - params = { - 'account': sqlite3.Binary(account.public_key.address), - 'used_times': used_times - } - if chain is not None: - sql.append("chain = :chain AND") - params['chain'] = chain - sql.append("used_times {} :used_times".format(comparison_op)) - sql.append("ORDER BY used_times ASC") - if limit is not None: - sql.append('LIMIT {}'.format(limit)) - return ' '.join(sql), params - @staticmethod def _set_address_history(t, address, history): t.execute( @@ -347,20 +324,39 @@ class BaseDatabase(SQLiteMixin): def set_address_history(self, address, history): return self.db.runInteraction(lambda t: self._set_address_history(t, address, history)) - def get_unused_addresses(self, account, chain): - # type: (torba.baseaccount.BaseAccount, Union[int,None]) -> defer.Deferred[List[str]] - return self.query_one_value_list(*self._used_address_sql( - account, chain, '=', 0 - )) + def get_addresses(self, account, chain, limit=None, max_used_times=None, order_by=None): + columns = ['account', 'chain', 'position', 'address', 'used_times'] + sql = ["SELECT {} FROM pubkey_address"] - def get_usable_addresses(self, account, chain, max_used_times, limit): - return self.query_one_value_list(*self._used_address_sql( - account, chain, '<=', max_used_times, limit - )) + where = [] + params = {} + if account is not None: + params["account"] = account.public_key.address + where.append("account = :account") + columns.remove("account") + if chain is not None: + params["chain"] = chain + where.append("chain = :chain") + columns.remove("chain") + if max_used_times is not None: + params["used_times"] = max_used_times + where.append("used_times <= :used_times") + + if where: + sql.append("WHERE") + sql.append(" AND ".join(where)) + + if order_by: + sql.append("ORDER BY {}".format(order_by)) + + if limit is not None: + sql.append("LIMIT {}".format(limit)) + + return self.query_dict_value_list(" ".join(sql), columns, params) def get_address(self, address): return self.query_dict_value( - "SELECT {} FROM pubkey_address WHERE address= :address", + "SELECT {} FROM pubkey_address WHERE address = :address", ('address', 'account', 'chain', 'position', 'pubkey', 'history', 'used_times'), - {'address': sqlite3.Binary(address)} + {'address': address} )