This commit is contained in:
Lex Berezhny 2020-04-12 11:06:05 -04:00
parent 74e3471bd9
commit 10c262a095
4 changed files with 72 additions and 51 deletions

View file

@ -39,6 +39,16 @@ jobs:
db:
- postgres
- sqlite
services:
postgres:
image: postgres:12
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1

View file

@ -21,7 +21,13 @@ from lbry.wallet import PubKey
from lbry.wallet.transaction import Transaction, Output, OutputScript, TXRefImmutable
from lbry.wallet.constants import TXO_TYPES, CLAIM_TYPES
from .tables import metadata, Version, TX, TXI, TXO, PubkeyAddress, AccountAddress
from .tables import (
metadata, Version,
PubkeyAddress, AccountAddress,
TX,
TXO, txo_join_account,
TXI, txi_join_account,
)
log = logging.getLogger(__name__)
@ -229,8 +235,8 @@ class Database:
def sync_create(self, name):
engine = sqlalchemy.create_engine(self.url)
db = engine.connect()
db.execute('commit')
db.execute(f'create database {name}')
db.execute(text('commit'))
db.execute(text(f'create database {name}'))
async def create(self, name):
await asyncio.get_event_loop().run_in_executor(
@ -240,8 +246,8 @@ class Database:
def sync_drop(self, name):
engine = sqlalchemy.create_engine(self.url)
db = engine.connect()
db.execute('commit')
db.execute(f'drop database if exists {name}')
db.execute(text('commit'))
db.execute(text(f'drop database if exists {name}'))
async def drop(self, name):
await asyncio.get_event_loop().run_in_executor(
@ -366,8 +372,8 @@ class Database:
assert accounts, "'accounts' argument required when no 'tx_hash' constraint is present"
where = in_account(accounts)
tx_hashes = union(
select(TXO.c.tx_hash).select_from(TXO.join(AccountAddress)).where(where),
select(TXI.c.tx_hash).select_from(TXI.join(AccountAddress)).where(where)
select(TXO.c.tx_hash).select_from(txo_join_account).where(where),
select(TXI.c.tx_hash).select_from(txi_join_account).where(where)
)
s = s.where(TX.c.tx_hash.in_(tx_hashes))
return await self.execute_fetchall(query2([TX], s, **constraints))
@ -753,7 +759,7 @@ class Database:
if not {'purchased_claim_hash', 'purchased_claim_hash__in'}.intersection(constraints):
constraints['purchased_claim_hash__is_not_null'] = True
constraints['tx_hash__in'] = (
select(TXI.c.tx_hash).select_from(TXI.join(AccountAddress)).where(in_account(accounts))
select(TXI.c.tx_hash).select_from(txi_join_account).where(in_account(accounts))
)
async def get_purchases(self, **constraints):

View file

@ -2,7 +2,7 @@
from sqlalchemy import (
MetaData, Table, Column, ForeignKey,
BINARY, TEXT, SMALLINT, INTEGER, BOOLEAN
LargeBinary, Text, SmallInteger, Integer, Boolean
)
@ -11,74 +11,78 @@ metadata = MetaData()
Version = Table(
'version', metadata,
Column('version', TEXT, primary_key=True),
Column('version', Text, primary_key=True),
)
PubkeyAddress = Table(
'pubkey_address', metadata,
Column('address', TEXT, primary_key=True),
Column('history', TEXT, nullable=True),
Column('used_times', INTEGER, server_default='0'),
Column('address', Text, primary_key=True),
Column('history', Text, nullable=True),
Column('used_times', Integer, server_default='0'),
)
AccountAddress = Table(
'account_address', metadata,
Column('account', TEXT, primary_key=True),
Column('address', TEXT, ForeignKey(PubkeyAddress.columns.address), primary_key=True),
Column('chain', INTEGER),
Column('pubkey', BINARY),
Column('chain_code', BINARY),
Column('n', INTEGER),
Column('depth', INTEGER),
Column('account', Text, primary_key=True),
Column('address', Text, ForeignKey(PubkeyAddress.columns.address), primary_key=True),
Column('chain', Integer),
Column('pubkey', LargeBinary),
Column('chain_code', LargeBinary),
Column('n', Integer),
Column('depth', Integer),
)
Block = Table(
'block', metadata,
Column('block_hash', BINARY, primary_key=True),
Column('previous_hash', BINARY),
Column('file_number', SMALLINT),
Column('height', INTEGER),
Column('block_hash', LargeBinary, primary_key=True),
Column('previous_hash', LargeBinary),
Column('file_number', SmallInteger),
Column('height', Integer),
)
TX = Table(
'tx', metadata,
Column('block_hash', BINARY, nullable=True),
Column('tx_hash', BINARY, primary_key=True),
Column('raw', BINARY),
Column('height', INTEGER),
Column('position', SMALLINT),
Column('is_verified', BOOLEAN, server_default='FALSE'),
Column('purchased_claim_hash', BINARY, nullable=True),
Column('day', INTEGER, nullable=True),
Column('block_hash', LargeBinary, nullable=True),
Column('tx_hash', LargeBinary, primary_key=True),
Column('raw', LargeBinary),
Column('height', Integer),
Column('position', SmallInteger),
Column('is_verified', Boolean, server_default='FALSE'),
Column('purchased_claim_hash', LargeBinary, nullable=True),
Column('day', Integer, nullable=True),
)
TXO = Table(
'txo', metadata,
Column('tx_hash', BINARY, ForeignKey(TX.columns.tx_hash)),
Column('txo_hash', BINARY, primary_key=True),
Column('address', TEXT, ForeignKey(AccountAddress.columns.address)),
Column('position', INTEGER),
Column('amount', INTEGER),
Column('script', BINARY),
Column('is_reserved', BOOLEAN, server_default='0'),
Column('txo_type', INTEGER, server_default='0'),
Column('claim_id', TEXT, nullable=True),
Column('claim_hash', BINARY, nullable=True),
Column('claim_name', TEXT, nullable=True),
Column('channel_hash', BINARY, nullable=True),
Column('reposted_claim_hash', BINARY, nullable=True),
Column('tx_hash', LargeBinary, ForeignKey(TX.columns.tx_hash)),
Column('txo_hash', LargeBinary, primary_key=True),
Column('address', Text),
Column('position', Integer),
Column('amount', Integer),
Column('script', LargeBinary),
Column('is_reserved', Boolean, server_default='0'),
Column('txo_type', Integer, server_default='0'),
Column('claim_id', Text, nullable=True),
Column('claim_hash', LargeBinary, nullable=True),
Column('claim_name', Text, nullable=True),
Column('channel_hash', LargeBinary, nullable=True),
Column('reposted_claim_hash', LargeBinary, nullable=True),
)
txo_join_account = TXO.join(AccountAddress, TXO.columns.address == AccountAddress.columns.address)
TXI = Table(
'txi', metadata,
Column('tx_hash', BINARY, ForeignKey(TX.columns.tx_hash)),
Column('txo_hash', BINARY, ForeignKey(TXO.columns.txo_hash), primary_key=True),
Column('address', TEXT, ForeignKey(AccountAddress.columns.address)),
Column('position', INTEGER),
Column('tx_hash', LargeBinary, ForeignKey(TX.columns.tx_hash)),
Column('txo_hash', LargeBinary, ForeignKey(TXO.columns.txo_hash), primary_key=True),
Column('address', Text),
Column('position', Integer),
)
txi_join_account = TXI.join(AccountAddress, TXI.columns.address == AccountAddress.columns.address)

View file

@ -130,11 +130,12 @@ class WalletNode:
if db_driver == 'sqlite':
db = 'sqlite:///'+os.path.join(self.data_path, self.ledger_class.get_id(), 'blockchain.db')
elif db_driver == 'postgres':
db_connection = 'postgres:postgres@localhost:5432'
db_name = f'lbry_test_{self.port}'
meta_db = Database(f'postgresql+psycopg2:///postgres')
meta_db = Database(f'postgresql+psycopg2://{db_connection}/postgres')
await meta_db.drop(db_name)
await meta_db.create(db_name)
db = f'postgresql+psycopg2:///{db_name}'
db = f'postgresql+psycopg2://{db_connection}/{db_name}'
else:
raise RuntimeError(f"Unsupported database driver: {db_driver}")
self.manager = self.manager_class.from_config({