migrate to sqlalchemy-aio.

a big refactor that:

- fixes some issues that might have happened (or not) with asynchronous
    reactions to payments;
- paves the way to https://github.com/lnbits/lnbits/issues/121;
- uses more async/await notation which just looks nice; and
- makes it simple(r?) for one extension to modify stuff from other extensions.
This commit is contained in:
fiatjaf
2020-11-21 23:02:14 -03:00
parent f877dde2b0
commit d3fc52cd49
68 changed files with 971 additions and 1075 deletions
+39 -39
View File
@@ -2,11 +2,11 @@ import json
import datetime
from uuid import uuid4
from typing import List, Optional, Dict
from quart import g
from lnbits import bolt11
from lnbits.settings import DEFAULT_WALLET_NAME
from . import db
from .models import User, Wallet, Payment
@@ -14,28 +14,28 @@ from .models import User, Wallet, Payment
# --------
def create_account() -> User:
async def create_account() -> User:
user_id = uuid4().hex
g.db.execute("INSERT INTO accounts (id) VALUES (?)", (user_id,))
await db.execute("INSERT INTO accounts (id) VALUES (?)", (user_id,))
new_account = get_account(user_id=user_id)
new_account = await get_account(user_id=user_id)
assert new_account, "Newly created account couldn't be retrieved"
return new_account
def get_account(user_id: str) -> Optional[User]:
row = g.db.fetchone("SELECT id, email, pass as password FROM accounts WHERE id = ?", (user_id,))
async def get_account(user_id: str) -> Optional[User]:
row = await db.fetchone("SELECT id, email, pass as password FROM accounts WHERE id = ?", (user_id,))
return User(**row) if row else None
def get_user(user_id: str) -> Optional[User]:
user = g.db.fetchone("SELECT id, email FROM accounts WHERE id = ?", (user_id,))
async def get_user(user_id: str) -> Optional[User]:
user = await db.fetchone("SELECT id, email FROM accounts WHERE id = ?", (user_id,))
if user:
extensions = g.db.fetchall("SELECT extension FROM extensions WHERE user = ? AND active = 1", (user_id,))
wallets = g.db.fetchall(
extensions = await db.fetchall("SELECT extension FROM extensions WHERE user = ? AND active = 1", (user_id,))
wallets = await db.fetchall(
"""
SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) AS balance_msat
FROM wallets
@@ -51,8 +51,8 @@ def get_user(user_id: str) -> Optional[User]:
)
def update_user_extension(*, user_id: str, extension: str, active: int) -> None:
g.db.execute(
async def update_user_extension(*, user_id: str, extension: str, active: int) -> None:
await db.execute(
"""
INSERT OR REPLACE INTO extensions (user, extension, active)
VALUES (?, ?, ?)
@@ -65,9 +65,9 @@ def update_user_extension(*, user_id: str, extension: str, active: int) -> None:
# -------
def create_wallet(*, user_id: str, wallet_name: Optional[str] = None) -> Wallet:
async def create_wallet(*, user_id: str, wallet_name: Optional[str] = None) -> Wallet:
wallet_id = uuid4().hex
g.db.execute(
await db.execute(
"""
INSERT INTO wallets (id, name, user, adminkey, inkey)
VALUES (?, ?, ?, ?, ?)
@@ -75,14 +75,14 @@ def create_wallet(*, user_id: str, wallet_name: Optional[str] = None) -> Wallet:
(wallet_id, wallet_name or DEFAULT_WALLET_NAME, user_id, uuid4().hex, uuid4().hex),
)
new_wallet = get_wallet(wallet_id=wallet_id)
new_wallet = await get_wallet(wallet_id=wallet_id)
assert new_wallet, "Newly created wallet couldn't be retrieved"
return new_wallet
def delete_wallet(*, user_id: str, wallet_id: str) -> None:
g.db.execute(
async def delete_wallet(*, user_id: str, wallet_id: str) -> None:
await db.execute(
"""
UPDATE wallets AS w
SET
@@ -95,8 +95,8 @@ def delete_wallet(*, user_id: str, wallet_id: str) -> None:
)
def get_wallet(wallet_id: str) -> Optional[Wallet]:
row = g.db.fetchone(
async def get_wallet(wallet_id: str) -> Optional[Wallet]:
row = await db.fetchone(
"""
SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) AS balance_msat
FROM wallets
@@ -108,8 +108,8 @@ def get_wallet(wallet_id: str) -> Optional[Wallet]:
return Wallet(**row) if row else None
def get_wallet_for_key(key: str, key_type: str = "invoice") -> Optional[Wallet]:
row = g.db.fetchone(
async def get_wallet_for_key(key: str, key_type: str = "invoice") -> Optional[Wallet]:
row = await db.fetchone(
"""
SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) AS balance_msat
FROM wallets
@@ -131,8 +131,8 @@ def get_wallet_for_key(key: str, key_type: str = "invoice") -> Optional[Wallet]:
# ---------------
def get_standalone_payment(checking_id: str) -> Optional[Payment]:
row = g.db.fetchone(
async def get_standalone_payment(checking_id: str) -> Optional[Payment]:
row = await db.fetchone(
"""
SELECT *
FROM apipayments
@@ -144,8 +144,8 @@ def get_standalone_payment(checking_id: str) -> Optional[Payment]:
return Payment.from_row(row) if row else None
def get_wallet_payment(wallet_id: str, payment_hash: str) -> Optional[Payment]:
row = g.db.fetchone(
async def get_wallet_payment(wallet_id: str, payment_hash: str) -> Optional[Payment]:
row = await db.fetchone(
"""
SELECT *
FROM apipayments
@@ -157,7 +157,7 @@ def get_wallet_payment(wallet_id: str, payment_hash: str) -> Optional[Payment]:
return Payment.from_row(row) if row else None
def get_wallet_payments(
async def get_wallet_payments(
wallet_id: str,
*,
complete: bool = False,
@@ -197,7 +197,7 @@ def get_wallet_payments(
clause += "AND checking_id NOT LIKE 'temp_%' "
clause += "AND checking_id NOT LIKE 'internal_%' "
rows = g.db.fetchall(
rows = await db.fetchall(
f"""
SELECT *
FROM apipayments
@@ -210,8 +210,8 @@ def get_wallet_payments(
return [Payment.from_row(row) for row in rows]
def delete_expired_invoices() -> None:
rows = g.db.fetchall(
async def delete_expired_invoices() -> None:
rows = await db.fetchall(
"""
SELECT bolt11
FROM apipayments
@@ -228,7 +228,7 @@ def delete_expired_invoices() -> None:
if expiration_date > datetime.datetime.utcnow():
continue
g.db.execute(
await db.execute(
"""
DELETE FROM apipayments
WHERE pending = 1 AND hash = ?
@@ -241,7 +241,7 @@ def delete_expired_invoices() -> None:
# --------
def create_payment(
async def create_payment(
*,
wallet_id: str,
checking_id: str,
@@ -254,7 +254,7 @@ def create_payment(
pending: bool = True,
extra: Optional[Dict] = None,
) -> Payment:
g.db.execute(
await db.execute(
"""
INSERT INTO apipayments
(wallet, checking_id, bolt11, hash, preimage,
@@ -275,14 +275,14 @@ def create_payment(
),
)
new_payment = get_wallet_payment(wallet_id, payment_hash)
new_payment = await get_wallet_payment(wallet_id, payment_hash)
assert new_payment, "Newly created payment couldn't be retrieved"
return new_payment
def update_payment_status(checking_id: str, pending: bool) -> None:
g.db.execute(
async def update_payment_status(checking_id: str, pending: bool) -> None:
await db.execute(
"UPDATE apipayments SET pending = ? WHERE checking_id = ?",
(
int(pending),
@@ -291,12 +291,12 @@ def update_payment_status(checking_id: str, pending: bool) -> None:
)
def delete_payment(checking_id: str) -> None:
g.db.execute("DELETE FROM apipayments WHERE checking_id = ?", (checking_id,))
async def delete_payment(checking_id: str) -> None:
await db.execute("DELETE FROM apipayments WHERE checking_id = ?", (checking_id,))
def check_internal(payment_hash: str) -> Optional[str]:
row = g.db.fetchone(
async def check_internal(payment_hash: str) -> Optional[str]:
row = await db.fetchone(
"""
SELECT checking_id FROM apipayments
WHERE hash = ? AND pending AND amount > 0