postgres support.

This commit is contained in:
fiatjaf 2021-06-21 23:22:52 -03:00
parent eeb3e66529
commit 2f309c9863
54 changed files with 624 additions and 540 deletions

View file

@ -8,7 +8,11 @@ PORT=5000
LNBITS_ALLOWED_USERS="" LNBITS_ALLOWED_USERS=""
LNBITS_DEFAULT_WALLET_NAME="LNbits wallet" LNBITS_DEFAULT_WALLET_NAME="LNbits wallet"
# Database: by default we will use SQLite, but you can replace that with a Postgres URL
LNBITS_DATA_FOLDER="./data" LNBITS_DATA_FOLDER="./data"
# LNBITS_DATABASE_URL="postgres:///"
LNBITS_DISABLED_EXTENSIONS="amilk" LNBITS_DISABLED_EXTENSIONS="amilk"
LNBITS_FORCE_HTTPS=true LNBITS_FORCE_HTTPS=true
LNBITS_SERVICE_FEE="0.0" LNBITS_SERVICE_FEE="0.0"

64
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "8c4056a80c682fac834266c11892573ce53807226c0810e4564976656ea5ff45" "sha256": "4067e94f45066ab088fc12ce09371b360c2bdb6b29f10c84f8ca06b3a9ede22a"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -289,42 +289,6 @@
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==3.12.1" "version": "==3.12.1"
}, },
"mypy": {
"hashes": [
"sha256:0190fb77e93ce971954c9e54ea61de2802065174e5e990c9d4c1d0f54fbeeca2",
"sha256:0756529da2dd4d53d26096b7969ce0a47997123261a5432b48cc6848a2cb0bd4",
"sha256:2f9fedc1f186697fda191e634ac1d02f03d4c260212ccb018fabbb6d4b03eee8",
"sha256:353aac2ce41ddeaf7599f1c73fed2b75750bef3b44b6ad12985a991bc002a0da",
"sha256:3f12705eabdd274b98f676e3e5a89f247ea86dc1af48a2d5a2b080abac4e1243",
"sha256:4efc67b9b3e2fddbe395700f91d5b8deb5980bfaaccb77b306310bd0b9e002eb",
"sha256:517e7528d1be7e187a5db7f0a3e479747307c1b897d9706b1c662014faba3116",
"sha256:68a098c104ae2b75e946b107ef69dd8398d54cb52ad57580dfb9fc78f7f997f0",
"sha256:746e0b0101b8efec34902810047f26a8c80e1efbb4fc554956d848c05ef85d76",
"sha256:8be7bbd091886bde9fcafed8dd089a766fa76eb223135fe5c9e9798f78023a20",
"sha256:9236c21194fde5df1b4d8ebc2ef2c1f2a5dc7f18bcbea54274937cae2e20a01c",
"sha256:9ef5355eaaf7a23ab157c21a44c614365238a7bdb3552ec3b80c393697d974e1",
"sha256:9f1d74eeb3f58c7bd3f3f92b8f63cb1678466a55e2c4612bf36909105d0724ab",
"sha256:a26d0e53e90815c765f91966442775cf03b8a7514a4e960de7b5320208b07269",
"sha256:ae94c31bb556ddb2310e4f913b706696ccbd43c62d3331cd3511caef466871d2",
"sha256:b5ba1f0d5f9087e03bf5958c28d421a03a4c1ad260bf81556195dffeccd979c4",
"sha256:b5dfcd22c6bab08dfeded8d5b44bdcb68c6f1ab261861e35c470b89074f78a70",
"sha256:cd01c599cf9f897b6b6c6b5d8b182557fb7d99326bcdf5d449a0fbbb4ccee4b9",
"sha256:e89880168c67cf4fde4506b80ee42f1537ad66ad366c101d388b3fd7d7ce2afd",
"sha256:ebe2bc9cb638475f5d39068d2dbe8ae1d605bb8d8d3ff281c695df1670ab3987",
"sha256:f89bfda7f0f66b789792ab64ce0978e4a991a0e4dd6197349d0767b0f1095b21",
"sha256:fc4d63da57ef0e8cd4ab45131f3fe5c286ce7dd7f032650d0fbc239c6190e167",
"sha256:fd634bc17b1e2d6ce716f0e43446d0d61cdadb1efcad5c56ca211c22b246ebc8"
],
"markers": "implementation_name == 'cpython'",
"version": "==0.902"
},
"mypy-extensions": {
"hashes": [
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
],
"version": "==0.4.3"
},
"outcome": { "outcome": {
"hashes": [ "hashes": [
"sha256:c7dd9375cfd3c12db9801d080a3b63d4b0a261aa996c4c13152380587288d958", "sha256:c7dd9375cfd3c12db9801d080a3b63d4b0a261aa996c4c13152380587288d958",
@ -447,14 +411,6 @@
], ],
"version": "==1.5.0" "version": "==1.5.0"
}, },
"secure": {
"hashes": [
"sha256:6e30939d8f95bf3b8effb8a36ebb5ed57f265daeeae905e3aa9677ea538ab64e",
"sha256:a93b720c7614809c131ca80e477263140107c6c212829d0a6e1f7bc8d859c608"
],
"index": "pypi",
"version": "==0.3.0"
},
"shortuuid": { "shortuuid": {
"hashes": [ "hashes": [
"sha256:3c11d2007b915c43bee3e10625f068d8a349e04f0d81f08f5fa08507427ebf1f", "sha256:3c11d2007b915c43bee3e10625f068d8a349e04f0d81f08f5fa08507427ebf1f",
@ -554,14 +510,6 @@
"index": "pypi", "index": "pypi",
"version": "==0.16.0" "version": "==0.16.0"
}, },
"trio-typing": {
"hashes": [
"sha256:35f1bec8df2150feab6c8b073b54135321722c9d9289bbffa78a9a091ea83b72",
"sha256:f2007df617a6c26a2294db0dd63645b5451149757e1bde4cb8dbf3e1369174fb"
],
"index": "pypi",
"version": "==0.5.0"
},
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
@ -725,7 +673,7 @@
"sha256:fc4d63da57ef0e8cd4ab45131f3fe5c286ce7dd7f032650d0fbc239c6190e167", "sha256:fc4d63da57ef0e8cd4ab45131f3fe5c286ce7dd7f032650d0fbc239c6190e167",
"sha256:fd634bc17b1e2d6ce716f0e43446d0d61cdadb1efcad5c56ca211c22b246ebc8" "sha256:fd634bc17b1e2d6ce716f0e43446d0d61cdadb1efcad5c56ca211c22b246ebc8"
], ],
"markers": "implementation_name == 'cpython'", "index": "pypi",
"version": "==0.902" "version": "==0.902"
}, },
"mypy-extensions": { "mypy-extensions": {
@ -882,6 +830,14 @@
"index": "pypi", "index": "pypi",
"version": "==0.16.0" "version": "==0.16.0"
}, },
"trio-typing": {
"hashes": [
"sha256:35f1bec8df2150feab6c8b073b54135321722c9d9289bbffa78a9a091ea83b72",
"sha256:f2007df617a6c26a2294db0dd63645b5451149757e1bde4cb8dbf3e1369174fb"
],
"index": "pypi",
"version": "==0.5.0"
},
"typed-ast": { "typed-ast": {
"hashes": [ "hashes": [
"sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace", "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace",

View file

@ -4,8 +4,8 @@ import click
import importlib import importlib
import re import re
import os import os
from sqlalchemy.exc import OperationalError # type: ignore
from .db import SQLITE, POSTGRES
from .core import db as core_db, migrations as core_migrations from .core import db as core_db, migrations as core_migrations
from .helpers import ( from .helpers import (
get_valid_extensions, get_valid_extensions,
@ -53,41 +53,59 @@ def bundle_vendored():
async def migrate_databases(): async def migrate_databases():
"""Creates the necessary databases if they don't exist already; or migrates them.""" """Creates the necessary databases if they don't exist already; or migrates them."""
async with core_db.connect() as conn: async def set_migration_version(conn, db_name, version):
try: await conn.execute(
rows = await (await conn.execute("SELECT * FROM dbversions")).fetchall() """
except OperationalError: INSERT INTO dbversions (db, version) VALUES (?, ?)
# migration 3 wasn't ran ON CONFLICT (db) DO UPDATE SET version = ?
await core_migrations.m000_create_migrations_table(conn) """,
rows = await (await conn.execute("SELECT * FROM dbversions")).fetchall() (db_name, version, version),
)
async def run_migration(db, migrations_module):
db_name = migrations_module.__name__.split(".")[-2]
for key, migrate in migrations_module.__dict__.items():
match = match = matcher.match(key)
if match:
version = int(match.group(1))
if version > current_versions.get(db_name, 0):
print(f"running migration {db_name}.{version}")
await migrate(db)
if db.schema == None:
await set_migration_version(db, db_name, version)
else:
async with core_db.connect() as conn:
await set_migration_version(conn, db_name, version)
async with core_db.connect() as conn:
if conn.type == SQLITE:
exists = await conn.fetchone(
"SELECT * FROM sqlite_master WHERE type='table' AND name='dbversions'"
)
elif conn.type == POSTGRES:
exists = await conn.fetchone(
"SELECT * FROM information_schema.tables WHERE table_name = 'dbversions'"
)
if not exists:
await core_migrations.m000_create_migrations_table(conn)
rows = await (await conn.execute("SELECT * FROM dbversions")).fetchall()
current_versions = {row["db"]: row["version"] for row in rows} current_versions = {row["db"]: row["version"] for row in rows}
matcher = re.compile(r"^m(\d\d\d)_") matcher = re.compile(r"^m(\d\d\d)_")
async def run_migration(db, migrations_module):
db_name = migrations_module.__name__.split(".")[-2]
for key, migrate in migrations_module.__dict__.items():
match = match = matcher.match(key)
if match:
version = int(match.group(1))
if version > current_versions.get(db_name, 0):
print(f"running migration {db_name}.{version}")
await migrate(db)
await conn.execute(
"INSERT OR REPLACE INTO dbversions (db, version) VALUES (?, ?)",
(db_name, version),
)
await run_migration(conn, core_migrations) await run_migration(conn, core_migrations)
for ext in get_valid_extensions(): for ext in get_valid_extensions():
try: try:
ext_migrations = importlib.import_module( ext_migrations = importlib.import_module(
f"lnbits.extensions.{ext.code}.migrations" f"lnbits.extensions.{ext.code}.migrations"
) )
ext_db = importlib.import_module(f"lnbits.extensions.{ext.code}").db ext_db = importlib.import_module(f"lnbits.extensions.{ext.code}").db
await run_migration(ext_db, ext_migrations) except ImportError:
except ImportError: raise ImportError(
raise ImportError( f"Please make sure that the extension `{ext.code}` has a migrations file."
f"Please make sure that the extension `{ext.code}` has a migrations file." )
)
async with ext_db.connect() as ext_conn:
await run_migration(ext_conn, ext_migrations)

View file

@ -5,7 +5,7 @@ from typing import List, Optional, Dict, Any
from urllib.parse import urlparse from urllib.parse import urlparse
from lnbits import bolt11 from lnbits import bolt11
from lnbits.db import Connection from lnbits.db import Connection, POSTGRES
from lnbits.settings import DEFAULT_WALLET_NAME from lnbits.settings import DEFAULT_WALLET_NAME
from . import db from . import db
@ -43,13 +43,14 @@ async def get_user(user_id: str, conn: Optional[Connection] = None) -> Optional[
if user: if user:
extensions = await (conn or db).fetchall( extensions = await (conn or db).fetchall(
"SELECT extension FROM extensions WHERE user = ? AND active = 1", (user_id,) """SELECT extension FROM extensions WHERE "user" = ? AND active""",
(user_id,),
) )
wallets = await (conn or db).fetchall( wallets = await (conn or db).fetchall(
""" """
SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) AS balance_msat SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) AS balance_msat
FROM wallets FROM wallets
WHERE user = ? WHERE "user" = ?
""", """,
(user_id,), (user_id,),
) )
@ -70,14 +71,14 @@ async def get_user(user_id: str, conn: Optional[Connection] = None) -> Optional[
async def update_user_extension( async def update_user_extension(
*, user_id: str, extension: str, active: int, conn: Optional[Connection] = None *, user_id: str, extension: str, active: bool, conn: Optional[Connection] = None
) -> None: ) -> None:
await (conn or db).execute( await (conn or db).execute(
""" """
INSERT OR REPLACE INTO extensions (user, extension, active) INSERT INTO extensions ("user", extension, active) VALUES (?, ?, ?)
VALUES (?, ?, ?) ON CONFLICT ("user", extension) DO UPDATE SET active = ?
""", """,
(user_id, extension, active), (user_id, extension, active, active),
) )
@ -94,7 +95,7 @@ async def create_wallet(
wallet_id = uuid4().hex wallet_id = uuid4().hex
await (conn or db).execute( await (conn or db).execute(
""" """
INSERT INTO wallets (id, name, user, adminkey, inkey) INSERT INTO wallets (id, name, "user", adminkey, inkey)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""", """,
( (
@ -119,10 +120,10 @@ async def delete_wallet(
""" """
UPDATE wallets AS w UPDATE wallets AS w
SET SET
user = 'del:' || w.user, "user" = 'del:' || w."user",
adminkey = 'del:' || w.adminkey, adminkey = 'del:' || w.adminkey,
inkey = 'del:' || w.inkey inkey = 'del:' || w.inkey
WHERE id = ? AND user = ? WHERE id = ? AND "user" = ?
""", """,
(wallet_id, user_id), (wallet_id, user_id),
) )
@ -218,7 +219,10 @@ async def get_payments(
clause: List[str] = [] clause: List[str] = []
if since != None: if since != None:
clause.append("time > ?") if db.type == POSTGRES:
clause.append("time > to_timestamp(?)")
else:
clause.append("time > ?")
args.append(since) args.append(since)
if wallet_id: if wallet_id:
@ -228,9 +232,9 @@ async def get_payments(
if complete and pending: if complete and pending:
pass pass
elif complete: elif complete:
clause.append("((amount > 0 AND pending = 0) OR amount < 0)") clause.append("((amount > 0 AND pending = false) OR amount < 0)")
elif pending: elif pending:
clause.append("pending = 1") clause.append("pending = true")
else: else:
pass pass
@ -269,20 +273,21 @@ async def delete_expired_invoices(
) -> None: ) -> None:
# first we delete all invoices older than one month # first we delete all invoices older than one month
await (conn or db).execute( await (conn or db).execute(
""" f"""
DELETE FROM apipayments DELETE FROM apipayments
WHERE pending = 1 AND amount > 0 AND time < strftime('%s', 'now') - 2592000 WHERE pending = true AND amount > 0
AND time < {db.timestamp_now} - {db.interval_seconds(2592000)}
""" """
) )
# then we delete all expired invoices, checking one by one # then we delete all expired invoices, checking one by one
rows = await (conn or db).fetchall( rows = await (conn or db).fetchall(
""" f"""
SELECT bolt11 SELECT bolt11
FROM apipayments FROM apipayments
WHERE pending = 1 WHERE pending = true
AND bolt11 IS NOT NULL AND bolt11 IS NOT NULL
AND amount > 0 AND time < strftime('%s', 'now') - 86400 AND amount > 0 AND time < {db.timestamp_now} - {db.interval_seconds(86400)}
""" """
) )
for (payment_request,) in rows: for (payment_request,) in rows:
@ -298,7 +303,7 @@ async def delete_expired_invoices(
await (conn or db).execute( await (conn or db).execute(
""" """
DELETE FROM apipayments DELETE FROM apipayments
WHERE pending = 1 AND hash = ? WHERE pending = true AND hash = ?
""", """,
(invoice.payment_hash,), (invoice.payment_hash,),
) )
@ -337,7 +342,7 @@ async def create_payment(
payment_hash, payment_hash,
preimage, preimage,
amount, amount,
int(pending), pending,
memo, memo,
fee, fee,
json.dumps(extra) json.dumps(extra)
@ -361,7 +366,7 @@ async def update_payment_status(
await (conn or db).execute( await (conn or db).execute(
"UPDATE apipayments SET pending = ? WHERE checking_id = ?", "UPDATE apipayments SET pending = ? WHERE checking_id = ?",
( (
int(pending), pending,
checking_id, checking_id,
), ),
) )
@ -406,10 +411,10 @@ async def save_balance_check(
await (conn or db).execute( await (conn or db).execute(
""" """
INSERT OR REPLACE INTO balance_check (wallet, service, url) INSERT INTO balance_check (wallet, service, url) VALUES (?, ?, ?)
VALUES (?, ?, ?) ON CONFLICT (wallet, service) DO UPDATE SET url = ?
""", """,
(wallet_id, domain, url), (wallet_id, domain, url, url),
) )
@ -445,10 +450,10 @@ async def save_balance_notify(
): ):
await (conn or db).execute( await (conn or db).execute(
""" """
INSERT OR REPLACE INTO balance_notify (wallet, url) INSERT INTO balance_notify (wallet, url) VALUES (?, ?)
VALUES (?, ?) ON CONFLICT (wallet) DO UPDATE SET url = ?
""", """,
(wallet_id, url), (wallet_id, url, url),
) )

View file

@ -18,7 +18,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS accounts ( CREATE TABLE accounts (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
email TEXT, email TEXT,
pass TEXT pass TEXT
@ -27,37 +27,36 @@ async def m001_initial(db):
) )
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS extensions ( CREATE TABLE extensions (
user TEXT NOT NULL, "user" TEXT NOT NULL,
extension TEXT NOT NULL, extension TEXT NOT NULL,
active BOOLEAN DEFAULT 0, active BOOLEAN DEFAULT false,
UNIQUE (user, extension) UNIQUE ("user", extension)
); );
""" """
) )
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS wallets ( CREATE TABLE wallets (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
user TEXT NOT NULL, "user" TEXT NOT NULL,
adminkey TEXT NOT NULL, adminkey TEXT NOT NULL,
inkey TEXT inkey TEXT
); );
""" """
) )
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS apipayments ( CREATE TABLE apipayments (
payhash TEXT NOT NULL, payhash TEXT NOT NULL,
amount INTEGER NOT NULL, amount INTEGER NOT NULL,
fee INTEGER NOT NULL DEFAULT 0, fee INTEGER NOT NULL DEFAULT 0,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
pending BOOLEAN NOT NULL, pending BOOLEAN NOT NULL,
memo TEXT, memo TEXT,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')), time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now},
UNIQUE (wallet, payhash) UNIQUE (wallet, payhash)
); );
""" """
@ -65,18 +64,18 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE VIEW IF NOT EXISTS balances AS CREATE VIEW balances AS
SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM ( SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM (
SELECT wallet, SUM(amount) AS s -- incoming SELECT wallet, SUM(amount) AS s -- incoming
FROM apipayments FROM apipayments
WHERE amount > 0 AND pending = 0 -- don't sum pending WHERE amount > 0 AND pending = false -- don't sum pending
GROUP BY wallet GROUP BY wallet
UNION ALL UNION ALL
SELECT wallet, SUM(amount + fee) AS s -- outgoing, sum fees SELECT wallet, SUM(amount + fee) AS s -- outgoing, sum fees
FROM apipayments FROM apipayments
WHERE amount < 0 -- do sum pending WHERE amount < 0 -- do sum pending
GROUP BY wallet GROUP BY wallet
) )x
GROUP BY wallet; GROUP BY wallet;
""" """
) )
@ -143,21 +142,20 @@ async def m004_ensure_fees_are_always_negative(db):
""" """
await db.execute("DROP VIEW balances") await db.execute("DROP VIEW balances")
await db.execute( await db.execute(
""" """
CREATE VIEW IF NOT EXISTS balances AS CREATE VIEW balances AS
SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM ( SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM (
SELECT wallet, SUM(amount) AS s -- incoming SELECT wallet, SUM(amount) AS s -- incoming
FROM apipayments FROM apipayments
WHERE amount > 0 AND pending = 0 -- don't sum pending WHERE amount > 0 AND pending = false -- don't sum pending
GROUP BY wallet GROUP BY wallet
UNION ALL UNION ALL
SELECT wallet, SUM(amount - abs(fee)) AS s -- outgoing, sum fees SELECT wallet, SUM(amount - abs(fee)) AS s -- outgoing, sum fees
FROM apipayments FROM apipayments
WHERE amount < 0 -- do sum pending WHERE amount < 0 -- do sum pending
GROUP BY wallet GROUP BY wallet
) )x
GROUP BY wallet; GROUP BY wallet;
""" """
) )
@ -171,7 +169,7 @@ async def m005_balance_check_balance_notify(db):
await db.execute( await db.execute(
""" """
CREATE TABLE balance_check ( CREATE TABLE balance_check (
wallet INTEGER NOT NULL REFERENCES wallets (id), wallet TEXT NOT NULL REFERENCES wallets (id),
service TEXT NOT NULL, service TEXT NOT NULL,
url TEXT NOT NULL, url TEXT NOT NULL,
@ -183,7 +181,7 @@ async def m005_balance_check_balance_notify(db):
await db.execute( await db.execute(
""" """
CREATE TABLE balance_notify ( CREATE TABLE balance_notify (
wallet INTEGER NOT NULL REFERENCES wallets (id), wallet TEXT NOT NULL REFERENCES wallets (id),
url TEXT NOT NULL, url TEXT NOT NULL,
UNIQUE(wallet, url) UNIQUE(wallet, url)

View file

@ -202,9 +202,7 @@ new Vue({
return this.parse.invoice.sat <= this.balance return this.parse.invoice.sat <= this.balance
}, },
pendingPaymentsExist: function () { pendingPaymentsExist: function () {
return this.payments return this.payments.findIndex(payment => payment.pending) !== -1
? _.where(this.payments, {pending: 1}).length > 0
: false
} }
}, },
filters: { filters: {

View file

@ -66,7 +66,7 @@ async def dispatch_webhook(payment: Payment):
async def mark_webhook_sent(payment: Payment, status: int) -> None: async def mark_webhook_sent(payment: Payment, status: int) -> None:
await db.execute( await db.execute(
""" """
UPDATE apipayments SET webhook_status = ? UPDATE core.apipayments SET webhook_status = ?
WHERE hash = ? WHERE hash = ?
""", """,
(status, payment.payment_hash), (status, payment.payment_hash),

View file

@ -56,11 +56,11 @@ async def extensions():
if extension_to_enable: if extension_to_enable:
await update_user_extension( await update_user_extension(
user_id=g.user.id, extension=extension_to_enable, active=1 user_id=g.user.id, extension=extension_to_enable, active=True
) )
elif extension_to_disable: elif extension_to_disable:
await update_user_extension( await update_user_extension(
user_id=g.user.id, extension=extension_to_disable, active=0 user_id=g.user.id, extension=extension_to_disable, active=False
) )
return await render_template("core/extensions.html", user=await get_user(g.user.id)) return await render_template("core/extensions.html", user=await get_user(g.user.id))

View file

@ -1,36 +1,107 @@
import os import os
import trio import trio
import psycopg2
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from sqlalchemy import create_engine # type: ignore from sqlalchemy import create_engine # type: ignore
from sqlalchemy_aio import TRIO_STRATEGY # type: ignore from sqlalchemy_aio import TRIO_STRATEGY # type: ignore
from sqlalchemy_aio.base import AsyncConnection # type: ignore from sqlalchemy_aio.base import AsyncConnection # type: ignore
from .settings import LNBITS_DATA_FOLDER from .settings import LNBITS_DATA_FOLDER, LNBITS_DATABASE_URL
POSTGRES = "POSTGRES"
SQLITE = "SQLITE"
class Connection: class Compat:
def __init__(self, conn: AsyncConnection): type = "<inherited>"
schema = "<inherited>"
def interval_seconds(self, seconds: int) -> str:
if self.type == POSTGRES:
return f"interval '{seconds} seconds'"
elif self.type == SQLITE:
return f"{seconds}"
return "<nothing>"
@property
def timestamp_now(self) -> str:
if self.type == POSTGRES:
return "now()"
elif self.type == SQLITE:
return "(strftime('%s', 'now'))"
return "<nothing>"
@property
def serial_primary_key(self) -> str:
if self.type == POSTGRES:
return "SERIAL PRIMARY KEY"
elif self.type == SQLITE:
return "INTEGER PRIMARY KEY AUTOINCREMENT"
return "<nothing>"
@property
def references_schema(self) -> str:
if self.type == POSTGRES:
return f"{self.schema}."
elif self.type == SQLITE:
return ""
return "<nothing>"
class Connection(Compat):
def __init__(self, conn: AsyncConnection, txn, typ, name, schema):
self.conn = conn self.conn = conn
self.txn = txn
self.type = typ
self.name = name
self.schema = schema
def rewrite_query(self, query) -> str:
if self.type == POSTGRES:
query = query.replace("%", "%%")
query = query.replace("?", "%s")
return query
async def fetchall(self, query: str, values: tuple = ()) -> list: async def fetchall(self, query: str, values: tuple = ()) -> list:
result = await self.conn.execute(query, values) result = await self.conn.execute(self.rewrite_query(query), values)
return await result.fetchall() return await result.fetchall()
async def fetchone(self, query: str, values: tuple = ()): async def fetchone(self, query: str, values: tuple = ()):
result = await self.conn.execute(query, values) result = await self.conn.execute(self.rewrite_query(query), values)
row = await result.fetchone() row = await result.fetchone()
await result.close() await result.close()
return row return row
async def execute(self, query: str, values: tuple = ()): async def execute(self, query: str, values: tuple = ()):
return await self.conn.execute(query, values) return await self.conn.execute(self.rewrite_query(query), values)
class Database: class Database(Compat):
def __init__(self, db_name: str): def __init__(self, db_name: str):
self.db_name = db_name self.name = db_name
db_path = os.path.join(LNBITS_DATA_FOLDER, f"{db_name}.sqlite3")
self.engine = create_engine(f"sqlite:///{db_path}", strategy=TRIO_STRATEGY) if LNBITS_DATABASE_URL:
database_uri = LNBITS_DATABASE_URL
self.type = POSTGRES
DEC2FLOAT = psycopg2.extensions.new_type(
psycopg2.extensions.DECIMAL.values,
"DEC2FLOAT",
lambda value, curs: float(value) if value is not None else None,
)
psycopg2.extensions.register_type(DEC2FLOAT)
else:
self.path = os.path.join(LNBITS_DATA_FOLDER, f"{self.name}.sqlite3")
database_uri = f"sqlite:///{self.path}"
self.type = SQLITE
self.schema = self.name
if self.name.startswith("ext_"):
self.schema = self.name[4:]
else:
self.schema = None
self.engine = create_engine(database_uri, strategy=TRIO_STRATEGY)
self.lock = trio.StrictFIFOLock() self.lock = trio.StrictFIFOLock()
@asynccontextmanager @asynccontextmanager
@ -38,8 +109,20 @@ class Database:
await self.lock.acquire() await self.lock.acquire()
try: try:
async with self.engine.connect() as conn: async with self.engine.connect() as conn:
async with conn.begin(): async with conn.begin() as txn:
yield Connection(conn) wconn = Connection(conn, txn, self.type, self.name, self.schema)
if self.schema:
if self.type == POSTGRES:
await wconn.execute(
f"CREATE SCHEMA IF NOT EXISTS {self.schema}"
)
elif self.type == SQLITE:
await wconn.execute(
f"ATTACH '{self.path}' AS {self.schema}"
)
yield wconn
finally: finally:
self.lock.release() self.lock.release()

View file

@ -10,7 +10,7 @@ async def create_amilk(*, wallet_id: str, lnurl: str, atime: int, amount: int) -
amilk_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8") amilk_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8")
await db.execute( await db.execute(
""" """
INSERT INTO amilks (id, wallet, lnurl, atime, amount) INSERT INTO amilk.amilks (id, wallet, lnurl, atime, amount)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""", """,
(amilk_id, wallet_id, lnurl, atime, amount), (amilk_id, wallet_id, lnurl, atime, amount),
@ -22,7 +22,7 @@ async def create_amilk(*, wallet_id: str, lnurl: str, atime: int, amount: int) -
async def get_amilk(amilk_id: str) -> Optional[AMilk]: async def get_amilk(amilk_id: str) -> Optional[AMilk]:
row = await db.fetchone("SELECT * FROM amilks WHERE id = ?", (amilk_id,)) row = await db.fetchone("SELECT * FROM amilk.amilks WHERE id = ?", (amilk_id,))
return AMilk(**row) if row else None return AMilk(**row) if row else None
@ -32,11 +32,11 @@ async def get_amilks(wallet_ids: Union[str, List[str]]) -> List[AMilk]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM amilks WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM amilk.amilks WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [AMilk(**row) for row in rows] return [AMilk(**row) for row in rows]
async def delete_amilk(amilk_id: str) -> None: async def delete_amilk(amilk_id: str) -> None:
await db.execute("DELETE FROM amilks WHERE id = ?", (amilk_id,)) await db.execute("DELETE FROM amilk.amilks WHERE id = ?", (amilk_id,))

View file

@ -4,7 +4,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS amilks ( CREATE TABLE amilk.amilks (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
lnurl TEXT NOT NULL, lnurl TEXT NOT NULL,

View file

@ -21,7 +21,7 @@ async def create_bleskomat(
api_key_encoding = "hex" api_key_encoding = "hex"
await db.execute( await db.execute(
""" """
INSERT INTO bleskomats (id, wallet, api_key_id, api_key_secret, api_key_encoding, name, fiat_currency, exchange_rate_provider, fee) INSERT INTO bleskomat.bleskomats (id, wallet, api_key_id, api_key_secret, api_key_encoding, name, fiat_currency, exchange_rate_provider, fee)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -42,13 +42,13 @@ async def create_bleskomat(
async def get_bleskomat(bleskomat_id: str) -> Optional[Bleskomat]: async def get_bleskomat(bleskomat_id: str) -> Optional[Bleskomat]:
row = await db.fetchone("SELECT * FROM bleskomats WHERE id = ?", (bleskomat_id,)) row = await db.fetchone("SELECT * FROM bleskomat.bleskomats WHERE id = ?", (bleskomat_id,))
return Bleskomat(**row) if row else None return Bleskomat(**row) if row else None
async def get_bleskomat_by_api_key_id(api_key_id: str) -> Optional[Bleskomat]: async def get_bleskomat_by_api_key_id(api_key_id: str) -> Optional[Bleskomat]:
row = await db.fetchone( row = await db.fetchone(
"SELECT * FROM bleskomats WHERE api_key_id = ?", (api_key_id,) "SELECT * FROM bleskomat.bleskomats WHERE api_key_id = ?", (api_key_id,)
) )
return Bleskomat(**row) if row else None return Bleskomat(**row) if row else None
@ -58,7 +58,7 @@ async def get_bleskomats(wallet_ids: Union[str, List[str]]) -> List[Bleskomat]:
wallet_ids = [wallet_ids] wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM bleskomats WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM bleskomat.bleskomats WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Bleskomat(**row) for row in rows] return [Bleskomat(**row) for row in rows]
@ -66,14 +66,14 @@ async def get_bleskomats(wallet_ids: Union[str, List[str]]) -> List[Bleskomat]:
async def update_bleskomat(bleskomat_id: str, **kwargs) -> Optional[Bleskomat]: async def update_bleskomat(bleskomat_id: str, **kwargs) -> Optional[Bleskomat]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE bleskomats SET {q} WHERE id = ?", (*kwargs.values(), bleskomat_id) f"UPDATE bleskomat.bleskomats SET {q} WHERE id = ?", (*kwargs.values(), bleskomat_id)
) )
row = await db.fetchone("SELECT * FROM bleskomats WHERE id = ?", (bleskomat_id,)) row = await db.fetchone("SELECT * FROM bleskomat.bleskomats WHERE id = ?", (bleskomat_id,))
return Bleskomat(**row) if row else None return Bleskomat(**row) if row else None
async def delete_bleskomat(bleskomat_id: str) -> None: async def delete_bleskomat(bleskomat_id: str) -> None:
await db.execute("DELETE FROM bleskomats WHERE id = ?", (bleskomat_id,)) await db.execute("DELETE FROM bleskomat.bleskomats WHERE id = ?", (bleskomat_id,))
async def create_bleskomat_lnurl( async def create_bleskomat_lnurl(
@ -84,7 +84,7 @@ async def create_bleskomat_lnurl(
now = int(time.time()) now = int(time.time())
await db.execute( await db.execute(
""" """
INSERT INTO bleskomat_lnurls (id, bleskomat, wallet, hash, tag, params, api_key_id, initial_uses, remaining_uses, created_time, updated_time) INSERT INTO bleskomat.bleskomat_lnurls (id, bleskomat, wallet, hash, tag, params, api_key_id, initial_uses, remaining_uses, created_time, updated_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -108,5 +108,5 @@ async def create_bleskomat_lnurl(
async def get_bleskomat_lnurl(secret: str) -> Optional[BleskomatLnurl]: async def get_bleskomat_lnurl(secret: str) -> Optional[BleskomatLnurl]:
hash = generate_bleskomat_lnurl_hash(secret) hash = generate_bleskomat_lnurl_hash(secret)
row = await db.fetchone("SELECT * FROM bleskomat_lnurls WHERE hash = ?", (hash,)) row = await db.fetchone("SELECT * FROM bleskomat.bleskomat_lnurls WHERE hash = ?", (hash,))
return BleskomatLnurl(**row) if row else None return BleskomatLnurl(**row) if row else None

View file

@ -2,7 +2,7 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS bleskomats ( CREATE TABLE bleskomat.bleskomats (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
api_key_id TEXT NOT NULL, api_key_id TEXT NOT NULL,
@ -19,7 +19,7 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS bleskomat_lnurls ( CREATE TABLE bleskomat.bleskomat_lnurls (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
bleskomat TEXT NOT NULL, bleskomat TEXT NOT NULL,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,

View file

@ -100,7 +100,7 @@ class BleskomatLnurl(NamedTuple):
now = int(time.time()) now = int(time.time())
result = await conn.execute( result = await conn.execute(
""" """
UPDATE bleskomat_lnurls UPDATE bleskomat.bleskomat_lnurls
SET remaining_uses = remaining_uses - 1, updated_time = ? SET remaining_uses = remaining_uses - 1, updated_time = ?
WHERE id = ? WHERE id = ?
AND remaining_uses > 0 AND remaining_uses > 0

View file

@ -18,7 +18,7 @@ async def create_captcha(
captcha_id = urlsafe_short_hash() captcha_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO captchas (id, wallet, url, memo, description, amount, remembers) INSERT INTO captcha.captchas (id, wallet, url, memo, description, amount, remembers)
VALUES (?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
""", """,
(captcha_id, wallet_id, url, memo, description, amount, int(remembers)), (captcha_id, wallet_id, url, memo, description, amount, int(remembers)),
@ -30,7 +30,7 @@ async def create_captcha(
async def get_captcha(captcha_id: str) -> Optional[Captcha]: async def get_captcha(captcha_id: str) -> Optional[Captcha]:
row = await db.fetchone("SELECT * FROM captchas WHERE id = ?", (captcha_id,)) row = await db.fetchone("SELECT * FROM captcha.captchas WHERE id = ?", (captcha_id,))
return Captcha.from_row(row) if row else None return Captcha.from_row(row) if row else None
@ -41,11 +41,11 @@ async def get_captchas(wallet_ids: Union[str, List[str]]) -> List[Captcha]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM captchas WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM captcha.captchas WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Captcha.from_row(row) for row in rows] return [Captcha.from_row(row) for row in rows]
async def delete_captcha(captcha_id: str) -> None: async def delete_captcha(captcha_id: str) -> None:
await db.execute("DELETE FROM captchas WHERE id = ?", (captcha_id,)) await db.execute("DELETE FROM captcha.captchas WHERE id = ?", (captcha_id,))

View file

@ -1,20 +1,19 @@
from sqlalchemy.exc import OperationalError # type: ignore
async def m001_initial(db): async def m001_initial(db):
""" """
Initial captchas table. Initial captchas table.
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS captchas ( CREATE TABLE captcha.captchas (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
secret TEXT NOT NULL, secret TEXT NOT NULL,
url TEXT NOT NULL, url TEXT NOT NULL,
memo TEXT NOT NULL, memo TEXT NOT NULL,
amount INTEGER NOT NULL, amount INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """
+ db.timestamp_now
+ """
); );
""" """
) )
@ -24,44 +23,41 @@ async def m002_redux(db):
""" """
Creates an improved captchas table and migrates the existing data. Creates an improved captchas table and migrates the existing data.
""" """
try: await db.execute("ALTER TABLE captcha.captchas RENAME TO captchas_old")
await db.execute("SELECT remembers FROM captchas") await db.execute(
"""
CREATE TABLE captcha.captchas (
id TEXT PRIMARY KEY,
wallet TEXT NOT NULL,
url TEXT NOT NULL,
memo TEXT NOT NULL,
description TEXT NULL,
amount INTEGER DEFAULT 0,
time TIMESTAMP NOT NULL DEFAULT """
+ db.timestamp_now
+ """,
remembers INTEGER DEFAULT 0,
extras TEXT NULL
);
"""
)
except OperationalError: for row in [
await db.execute("ALTER TABLE captchas RENAME TO captchas_old") list(row) for row in await db.fetchall("SELECT * FROM captcha.captchas_old")
]:
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS captchas ( INSERT INTO captcha.captchas (
id TEXT PRIMARY KEY, id,
wallet TEXT NOT NULL, wallet,
url TEXT NOT NULL, url,
memo TEXT NOT NULL, memo,
description TEXT NULL, amount,
amount INTEGER DEFAULT 0, time
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')),
remembers INTEGER DEFAULT 0,
extras TEXT NULL
);
"""
)
await db.execute("CREATE INDEX IF NOT EXISTS wallet_idx ON captchas (wallet)")
for row in [
list(row) for row in await db.fetchall("SELECT * FROM captchas_old")
]:
await db.execute(
"""
INSERT INTO captchas (
id,
wallet,
url,
memo,
amount,
time
)
VALUES (?, ?, ?, ?, ?, ?)
""",
(row[0], row[1], row[3], row[4], row[5], row[6]),
) )
VALUES (?, ?, ?, ?, ?, ?)
""",
(row[0], row[1], row[3], row[4], row[5], row[6]),
)
await db.execute("DROP TABLE captchas_old") await db.execute("DROP TABLE captcha.captchas_old")

View file

@ -34,7 +34,7 @@ def create_diagonalleys_product(
product_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8") product_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8")
db.execute( db.execute(
""" """
INSERT INTO products (id, wallet, product, categories, description, image, price, quantity) INSERT INTO diagonalley.products (id, wallet, product, categories, description, image, price, quantity)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -57,16 +57,16 @@ def update_diagonalleys_product(product_id: str, **kwargs) -> Optional[Indexers]
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
f"UPDATE products SET {q} WHERE id = ?", (*kwargs.values(), product_id) f"UPDATE diagonalley.products SET {q} WHERE id = ?", (*kwargs.values(), product_id)
) )
row = db.fetchone("SELECT * FROM products WHERE id = ?", (product_id,)) row = db.fetchone("SELECT * FROM diagonalley.products WHERE id = ?", (product_id,))
return get_diagonalleys_indexer(product_id) return get_diagonalleys_indexer(product_id)
def get_diagonalleys_product(product_id: str) -> Optional[Products]: def get_diagonalleys_product(product_id: str) -> Optional[Products]:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
row = db.fetchone("SELECT * FROM products WHERE id = ?", (product_id,)) row = db.fetchone("SELECT * FROM diagonalley.products WHERE id = ?", (product_id,))
return Products(**row) if row else None return Products(**row) if row else None
@ -78,7 +78,7 @@ def get_diagonalleys_products(wallet_ids: Union[str, List[str]]) -> List[Product
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = db.fetchall( rows = db.fetchall(
f"SELECT * FROM products WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM diagonalley.products WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Products(**row) for row in rows] return [Products(**row) for row in rows]
@ -86,7 +86,7 @@ def get_diagonalleys_products(wallet_ids: Union[str, List[str]]) -> List[Product
def delete_diagonalleys_product(product_id: str) -> None: def delete_diagonalleys_product(product_id: str) -> None:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute("DELETE FROM products WHERE id = ?", (product_id,)) db.execute("DELETE FROM diagonalley.products WHERE id = ?", (product_id,))
###Indexers ###Indexers
@ -106,7 +106,7 @@ def create_diagonalleys_indexer(
indexer_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8") indexer_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8")
db.execute( db.execute(
""" """
INSERT INTO indexers (id, wallet, shopname, indexeraddress, online, rating, shippingzone1, shippingzone2, zone1cost, zone2cost, email) INSERT INTO diagonalley.indexers (id, wallet, shopname, indexeraddress, online, rating, shippingzone1, shippingzone2, zone1cost, zone2cost, email)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -131,16 +131,16 @@ def update_diagonalleys_indexer(indexer_id: str, **kwargs) -> Optional[Indexers]
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
f"UPDATE indexers SET {q} WHERE id = ?", (*kwargs.values(), indexer_id) f"UPDATE diagonalley.indexers SET {q} WHERE id = ?", (*kwargs.values(), indexer_id)
) )
row = db.fetchone("SELECT * FROM indexers WHERE id = ?", (indexer_id,)) row = db.fetchone("SELECT * FROM diagonalley.indexers WHERE id = ?", (indexer_id,))
return get_diagonalleys_indexer(indexer_id) return get_diagonalleys_indexer(indexer_id)
def get_diagonalleys_indexer(indexer_id: str) -> Optional[Indexers]: def get_diagonalleys_indexer(indexer_id: str) -> Optional[Indexers]:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
roww = db.fetchone("SELECT * FROM indexers WHERE id = ?", (indexer_id,)) roww = db.fetchone("SELECT * FROM diagonalley.indexers WHERE id = ?", (indexer_id,))
try: try:
x = httpx.get(roww["indexeraddress"] + "/" + roww["ratingkey"]) x = httpx.get(roww["indexeraddress"] + "/" + roww["ratingkey"])
if x.status_code == 200: if x.status_code == 200:
@ -148,7 +148,7 @@ def get_diagonalleys_indexer(indexer_id: str) -> Optional[Indexers]:
print("poo") print("poo")
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE indexers SET online = ? WHERE id = ?", "UPDATE diagonalley.indexers SET online = ? WHERE id = ?",
( (
True, True,
indexer_id, indexer_id,
@ -157,7 +157,7 @@ def get_diagonalleys_indexer(indexer_id: str) -> Optional[Indexers]:
else: else:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE indexers SET online = ? WHERE id = ?", "UPDATE diagonalley.indexers SET online = ? WHERE id = ?",
( (
False, False,
indexer_id, indexer_id,
@ -166,7 +166,7 @@ def get_diagonalleys_indexer(indexer_id: str) -> Optional[Indexers]:
except: except:
print("An exception occurred") print("An exception occurred")
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
row = db.fetchone("SELECT * FROM indexers WHERE id = ?", (indexer_id,)) row = db.fetchone("SELECT * FROM diagonalley.indexers WHERE id = ?", (indexer_id,))
return Indexers(**row) if row else None return Indexers(**row) if row else None
@ -177,7 +177,7 @@ def get_diagonalleys_indexers(wallet_ids: Union[str, List[str]]) -> List[Indexer
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = db.fetchall( rows = db.fetchall(
f"SELECT * FROM indexers WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM diagonalley.indexers WHERE wallet IN ({q})", (*wallet_ids,)
) )
for r in rows: for r in rows:
@ -186,7 +186,7 @@ def get_diagonalleys_indexers(wallet_ids: Union[str, List[str]]) -> List[Indexer
if x.status_code == 200: if x.status_code == 200:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE indexers SET online = ? WHERE id = ?", "UPDATE diagonalley.indexers SET online = ? WHERE id = ?",
( (
True, True,
r["id"], r["id"],
@ -195,7 +195,7 @@ def get_diagonalleys_indexers(wallet_ids: Union[str, List[str]]) -> List[Indexer
else: else:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE indexers SET online = ? WHERE id = ?", "UPDATE diagonalley.indexers SET online = ? WHERE id = ?",
( (
False, False,
r["id"], r["id"],
@ -206,14 +206,14 @@ def get_diagonalleys_indexers(wallet_ids: Union[str, List[str]]) -> List[Indexer
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = db.fetchall( rows = db.fetchall(
f"SELECT * FROM indexers WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM diagonalley.indexers WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Indexers(**row) for row in rows] return [Indexers(**row) for row in rows]
def delete_diagonalleys_indexer(indexer_id: str) -> None: def delete_diagonalleys_indexer(indexer_id: str) -> None:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute("DELETE FROM indexers WHERE id = ?", (indexer_id,)) db.execute("DELETE FROM diagonalley.indexers WHERE id = ?", (indexer_id,))
###Orders ###Orders
@ -236,7 +236,7 @@ def create_diagonalleys_order(
order_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8") order_id = urlsafe_b64encode(uuid4().bytes_le).decode("utf-8")
db.execute( db.execute(
""" """
INSERT INTO orders (id, productid, wallet, product, quantity, shippingzone, address, email, invoiceid, paid, shipped) INSERT INTO diagonalley.orders (id, productid, wallet, product, quantity, shippingzone, address, email, invoiceid, paid, shipped)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -259,7 +259,7 @@ def create_diagonalleys_order(
def get_diagonalleys_order(order_id: str) -> Optional[Orders]: def get_diagonalleys_order(order_id: str) -> Optional[Orders]:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
row = db.fetchone("SELECT * FROM orders WHERE id = ?", (order_id,)) row = db.fetchone("SELECT * FROM diagonalley.orders WHERE id = ?", (order_id,))
return Orders(**row) if row else None return Orders(**row) if row else None
@ -271,25 +271,25 @@ def get_diagonalleys_orders(wallet_ids: Union[str, List[str]]) -> List[Orders]:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = db.fetchall( rows = db.fetchall(
f"SELECT * FROM orders WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM diagonalley.orders WHERE wallet IN ({q})", (*wallet_ids,)
) )
for r in rows: for r in rows:
PAID = (await WALLET.get_invoice_status(r["invoiceid"])).paid PAID = (await WALLET.get_invoice_status(r["invoiceid"])).paid
if PAID: if PAID:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE orders SET paid = ? WHERE id = ?", "UPDATE diagonalley.orders SET paid = ? WHERE id = ?",
( (
True, True,
r["id"], r["id"],
), ),
) )
rows = db.fetchall( rows = db.fetchall(
f"SELECT * FROM orders WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM diagonalley.orders WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Orders(**row) for row in rows] return [Orders(**row) for row in rows]
def delete_diagonalleys_order(order_id: str) -> None: def delete_diagonalleys_order(order_id: str) -> None:
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute("DELETE FROM orders WHERE id = ?", (order_id,)) db.execute("DELETE FROM diagonalley.orders WHERE id = ?", (order_id,))

View file

@ -4,7 +4,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS products ( CREATE TABLE diagonalley.products (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
product TEXT NOT NULL, product TEXT NOT NULL,
@ -22,7 +22,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS indexers ( CREATE TABLE diagonalley.indexers (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
shopname TEXT NOT NULL, shopname TEXT NOT NULL,
@ -43,7 +43,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS orders ( CREATE TABLE diagonalley.orders (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
productid TEXT NOT NULL, productid TEXT NOT NULL,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,

View file

@ -230,7 +230,7 @@ async def api_diagonalley_order_delete(order_id):
async def api_diagonalleys_order_paid(order_id): async def api_diagonalleys_order_paid(order_id):
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE orders SET paid = ? WHERE id = ?", "UPDATE diagonalley.orders SET paid = ? WHERE id = ?",
( (
True, True,
order_id, order_id,
@ -244,13 +244,13 @@ async def api_diagonalleys_order_paid(order_id):
async def api_diagonalleys_order_shipped(order_id): async def api_diagonalleys_order_shipped(order_id):
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
"UPDATE orders SET shipped = ? WHERE id = ?", "UPDATE diagonalley.orders SET shipped = ? WHERE id = ?",
( (
True, True,
order_id, order_id,
), ),
) )
order = db.fetchone("SELECT * FROM orders WHERE id = ?", (order_id,)) order = db.fetchone("SELECT * FROM diagonalley.orders WHERE id = ?", (order_id,))
return ( return (
jsonify( jsonify(
@ -268,12 +268,12 @@ async def api_diagonalleys_order_shipped(order_id):
) )
async def api_diagonalleys_stall_products(indexer_id): async def api_diagonalleys_stall_products(indexer_id):
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
rows = db.fetchone("SELECT * FROM indexers WHERE id = ?", (indexer_id,)) rows = db.fetchone("SELECT * FROM diagonalley.indexers WHERE id = ?", (indexer_id,))
print(rows[1]) print(rows[1])
if not rows: if not rows:
return jsonify({"message": "Indexer does not exist."}), HTTPStatus.NOT_FOUND return jsonify({"message": "Indexer does not exist."}), HTTPStatus.NOT_FOUND
products = db.fetchone("SELECT * FROM products WHERE wallet = ?", (rows[1],)) products = db.fetchone("SELECT * FROM diagonalley.products WHERE wallet = ?", (rows[1],))
if not products: if not products:
return jsonify({"message": "No products"}), HTTPStatus.NOT_FOUND return jsonify({"message": "No products"}), HTTPStatus.NOT_FOUND
@ -293,7 +293,7 @@ async def api_diagonalleys_stall_products(indexer_id):
) )
async def api_diagonalleys_stall_checkshipped(checking_id): async def api_diagonalleys_stall_checkshipped(checking_id):
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
rows = db.fetchone("SELECT * FROM orders WHERE invoiceid = ?", (checking_id,)) rows = db.fetchone("SELECT * FROM diagonalley.orders WHERE invoiceid = ?", (checking_id,))
return jsonify({"shipped": rows["shipped"]}), HTTPStatus.OK return jsonify({"shipped": rows["shipped"]}), HTTPStatus.OK
@ -329,7 +329,7 @@ async def api_diagonalley_stall_order(indexer_id):
with open_ext_db("diagonalley") as db: with open_ext_db("diagonalley") as db:
db.execute( db.execute(
""" """
INSERT INTO orders (id, productid, wallet, product, quantity, shippingzone, address, email, invoiceid, paid, shipped) INSERT INTO diagonalley.orders (id, productid, wallet, product, quantity, shippingzone, address, email, invoiceid, paid, shipped)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (

View file

@ -14,7 +14,7 @@ async def create_ticket(
) -> Tickets: ) -> Tickets:
await db.execute( await db.execute(
""" """
INSERT INTO ticket (id, wallet, event, name, email, registered, paid) INSERT INTO events.ticket (id, wallet, event, name, email, registered, paid)
VALUES (?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
""", """,
(payment_hash, wallet, event, name, email, False, False), (payment_hash, wallet, event, name, email, False, False),
@ -26,11 +26,11 @@ async def create_ticket(
async def set_ticket_paid(payment_hash: str) -> Tickets: async def set_ticket_paid(payment_hash: str) -> Tickets:
row = await db.fetchone("SELECT * FROM ticket WHERE id = ?", (payment_hash,)) row = await db.fetchone("SELECT * FROM events.ticket WHERE id = ?", (payment_hash,))
if row[6] != True: if row[6] != True:
await db.execute( await db.execute(
""" """
UPDATE ticket UPDATE events.ticket
SET paid = true SET paid = true
WHERE id = ? WHERE id = ?
""", """,
@ -44,7 +44,7 @@ async def set_ticket_paid(payment_hash: str) -> Tickets:
amount_tickets = eventdata.amount_tickets - 1 amount_tickets = eventdata.amount_tickets - 1
await db.execute( await db.execute(
""" """
UPDATE events UPDATE events.events
SET sold = ?, amount_tickets = ? SET sold = ?, amount_tickets = ?
WHERE id = ? WHERE id = ?
""", """,
@ -57,7 +57,7 @@ async def set_ticket_paid(payment_hash: str) -> Tickets:
async def get_ticket(payment_hash: str) -> Optional[Tickets]: async def get_ticket(payment_hash: str) -> Optional[Tickets]:
row = await db.fetchone("SELECT * FROM ticket WHERE id = ?", (payment_hash,)) row = await db.fetchone("SELECT * FROM events.ticket WHERE id = ?", (payment_hash,))
return Tickets(**row) if row else None return Tickets(**row) if row else None
@ -67,13 +67,13 @@ async def get_tickets(wallet_ids: Union[str, List[str]]) -> List[Tickets]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM ticket WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM events.ticket WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Tickets(**row) for row in rows] return [Tickets(**row) for row in rows]
async def delete_ticket(payment_hash: str) -> None: async def delete_ticket(payment_hash: str) -> None:
await db.execute("DELETE FROM ticket WHERE id = ?", (payment_hash,)) await db.execute("DELETE FROM events.ticket WHERE id = ?", (payment_hash,))
# EVENTS # EVENTS
@ -93,7 +93,7 @@ async def create_event(
event_id = urlsafe_short_hash() event_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO events (id, wallet, name, info, closing_date, event_start_date, event_end_date, amount_tickets, price_per_ticket, sold) INSERT INTO events.events (id, wallet, name, info, closing_date, event_start_date, event_end_date, amount_tickets, price_per_ticket, sold)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -118,7 +118,7 @@ async def create_event(
async def update_event(event_id: str, **kwargs) -> Events: async def update_event(event_id: str, **kwargs) -> Events:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE events SET {q} WHERE id = ?", (*kwargs.values(), event_id) f"UPDATE events.events SET {q} WHERE id = ?", (*kwargs.values(), event_id)
) )
event = await get_event(event_id) event = await get_event(event_id)
assert event, "Newly updated event couldn't be retrieved" assert event, "Newly updated event couldn't be retrieved"
@ -126,7 +126,7 @@ async def update_event(event_id: str, **kwargs) -> Events:
async def get_event(event_id: str) -> Optional[Events]: async def get_event(event_id: str) -> Optional[Events]:
row = await db.fetchone("SELECT * FROM events WHERE id = ?", (event_id,)) row = await db.fetchone("SELECT * FROM events.events WHERE id = ?", (event_id,))
return Events(**row) if row else None return Events(**row) if row else None
@ -136,14 +136,14 @@ async def get_events(wallet_ids: Union[str, List[str]]) -> List[Events]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM events WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM events.events WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Events(**row) for row in rows] return [Events(**row) for row in rows]
async def delete_event(event_id: str) -> None: async def delete_event(event_id: str) -> None:
await db.execute("DELETE FROM events WHERE id = ?", (event_id,)) await db.execute("DELETE FROM events.events WHERE id = ?", (event_id,))
# EVENTTICKETS # EVENTTICKETS
@ -151,13 +151,13 @@ async def delete_event(event_id: str) -> None:
async def get_event_tickets(event_id: str, wallet_id: str) -> List[Tickets]: async def get_event_tickets(event_id: str, wallet_id: str) -> List[Tickets]:
rows = await db.fetchall( rows = await db.fetchall(
"SELECT * FROM ticket WHERE wallet = ? AND event = ?", (wallet_id, event_id) "SELECT * FROM events.ticket WHERE wallet = ? AND event = ?", (wallet_id, event_id)
) )
return [Tickets(**row) for row in rows] return [Tickets(**row) for row in rows]
async def reg_ticket(ticket_id: str) -> List[Tickets]: async def reg_ticket(ticket_id: str) -> List[Tickets]:
await db.execute("UPDATE ticket SET registered = ? WHERE id = ?", (True, ticket_id)) await db.execute("UPDATE events.ticket SET registered = ? WHERE id = ?", (True, ticket_id))
ticket = await db.fetchone("SELECT * FROM ticket WHERE id = ?", (ticket_id,)) ticket = await db.fetchone("SELECT * FROM events.ticket WHERE id = ?", (ticket_id,))
rows = await db.fetchall("SELECT * FROM ticket WHERE event = ?", (ticket[1],)) rows = await db.fetchall("SELECT * FROM events.ticket WHERE event = ?", (ticket[1],))
return [Tickets(**row) for row in rows] return [Tickets(**row) for row in rows]

View file

@ -2,7 +2,7 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS events ( CREATE TABLE events.events (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
@ -13,21 +13,21 @@ async def m001_initial(db):
amount_tickets INTEGER NOT NULL, amount_tickets INTEGER NOT NULL,
price_per_ticket INTEGER NOT NULL, price_per_ticket INTEGER NOT NULL,
sold INTEGER NOT NULL, sold INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS tickets ( CREATE TABLE events.tickets (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
event TEXT NOT NULL, event TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
email TEXT NOT NULL, email TEXT NOT NULL,
registered BOOLEAN NOT NULL, registered BOOLEAN NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
@ -37,7 +37,7 @@ async def m002_changed(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS ticket ( CREATE TABLE events.ticket (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
event TEXT NOT NULL, event TEXT NOT NULL,
@ -45,12 +45,12 @@ async def m002_changed(db):
email TEXT NOT NULL, email TEXT NOT NULL,
registered BOOLEAN NOT NULL, registered BOOLEAN NOT NULL,
paid BOOLEAN NOT NULL, paid BOOLEAN NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
for row in [list(row) for row in await db.fetchall("SELECT * FROM tickets")]: for row in [list(row) for row in await db.fetchall("SELECT * FROM events.tickets")]:
usescsv = "" usescsv = ""
for i in range(row[5]): for i in range(row[5]):
@ -61,7 +61,7 @@ async def m002_changed(db):
usescsv = usescsv[1:] usescsv = usescsv[1:]
await db.execute( await db.execute(
""" """
INSERT INTO ticket ( INSERT INTO events.ticket (
id, id,
wallet, wallet,
event, event,
@ -82,4 +82,4 @@ async def m002_changed(db):
True, True,
), ),
) )
await db.execute("DROP TABLE tickets") await db.execute("DROP TABLE events.tickets")

View file

@ -2,10 +2,10 @@
# await db.execute( # await db.execute(
# """ # """
# CREATE TABLE IF NOT EXISTS example ( # CREATE TABLE example.example (
# id TEXT PRIMARY KEY, # id TEXT PRIMARY KEY,
# wallet TEXT NOT NULL, # wallet TEXT NOT NULL,
# time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) # time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
# ); # );
# """ # """
# ) # )

View file

@ -21,7 +21,7 @@ async def create_jukebox(
juke_id = urlsafe_short_hash() juke_id = urlsafe_short_hash()
result = await db.execute( result = await db.execute(
""" """
INSERT INTO jukebox (id, user, title, wallet, sp_user, sp_secret, sp_access_token, sp_refresh_token, sp_device, sp_playlists, price, profit) INSERT INTO jukebox.jukebox (id, user, title, wallet, sp_user, sp_secret, sp_access_token, sp_refresh_token, sp_device, sp_playlists, price, profit)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -47,35 +47,35 @@ async def create_jukebox(
async def update_jukebox(juke_id: str, **kwargs) -> Optional[Jukebox]: async def update_jukebox(juke_id: str, **kwargs) -> Optional[Jukebox]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE jukebox SET {q} WHERE id = ?", (*kwargs.values(), juke_id) f"UPDATE jukebox.jukebox SET {q} WHERE id = ?", (*kwargs.values(), juke_id)
) )
row = await db.fetchone("SELECT * FROM jukebox WHERE id = ?", (juke_id,)) row = await db.fetchone("SELECT * FROM jukebox.jukebox WHERE id = ?", (juke_id,))
return Jukebox(**row) if row else None return Jukebox(**row) if row else None
async def get_jukebox(juke_id: str) -> Optional[Jukebox]: async def get_jukebox(juke_id: str) -> Optional[Jukebox]:
row = await db.fetchone("SELECT * FROM jukebox WHERE id = ?", (juke_id,)) row = await db.fetchone("SELECT * FROM jukebox.jukebox WHERE id = ?", (juke_id,))
return Jukebox(**row) if row else None return Jukebox(**row) if row else None
async def get_jukebox_by_user(user: str) -> Optional[Jukebox]: async def get_jukebox_by_user(user: str) -> Optional[Jukebox]:
row = await db.fetchone("SELECT * FROM jukebox WHERE sp_user = ?", (user,)) row = await db.fetchone("SELECT * FROM jukebox.jukebox WHERE sp_user = ?", (user,))
return Jukebox(**row) if row else None return Jukebox(**row) if row else None
async def get_jukeboxs(user: str) -> List[Jukebox]: async def get_jukeboxs(user: str) -> List[Jukebox]:
rows = await db.fetchall("SELECT * FROM jukebox WHERE user = ?", (user,)) rows = await db.fetchall("SELECT * FROM jukebox.jukebox WHERE user = ?", (user,))
for row in rows: for row in rows:
if row.sp_playlists == "": if row.sp_playlists == "":
await delete_jukebox(row.id) await delete_jukebox(row.id)
rows = await db.fetchall("SELECT * FROM jukebox WHERE user = ?", (user,)) rows = await db.fetchall("SELECT * FROM jukebox.jukebox WHERE user = ?", (user,))
return [Jukebox.from_row(row) for row in rows] return [Jukebox.from_row(row) for row in rows]
async def delete_jukebox(juke_id: str): async def delete_jukebox(juke_id: str):
await db.execute( await db.execute(
""" """
DELETE FROM jukebox WHERE id = ? DELETE FROM jukebox.jukebox WHERE id = ?
""", """,
(juke_id), (juke_id),
) )
@ -89,7 +89,7 @@ async def create_jukebox_payment(
) -> JukeboxPayment: ) -> JukeboxPayment:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO jukebox_payment (payment_hash, juke_id, song_id, paid) INSERT INTO jukebox.jukebox_payment (payment_hash, juke_id, song_id, paid)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""", """,
( (
@ -109,7 +109,7 @@ async def update_jukebox_payment(
) -> Optional[JukeboxPayment]: ) -> Optional[JukeboxPayment]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE jukebox_payment SET {q} WHERE payment_hash = ?", f"UPDATE jukebox.jukebox_payment SET {q} WHERE payment_hash = ?",
(*kwargs.values(), payment_hash), (*kwargs.values(), payment_hash),
) )
return await get_jukebox_payment(payment_hash) return await get_jukebox_payment(payment_hash)
@ -117,6 +117,6 @@ async def update_jukebox_payment(
async def get_jukebox_payment(payment_hash: str) -> Optional[JukeboxPayment]: async def get_jukebox_payment(payment_hash: str) -> Optional[JukeboxPayment]:
row = await db.fetchone( row = await db.fetchone(
"SELECT * FROM jukebox_payment WHERE payment_hash = ?", (payment_hash,) "SELECT * FROM jukebox.jukebox_payment WHERE payment_hash = ?", (payment_hash,)
) )
return JukeboxPayment(**row) if row else None return JukeboxPayment(**row) if row else None

View file

@ -4,9 +4,9 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE jukebox ( CREATE TABLE jukebox.jukebox (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
user TEXT, "user" TEXT,
title TEXT, title TEXT,
wallet TEXT, wallet TEXT,
inkey TEXT, inkey TEXT,
@ -29,7 +29,7 @@ async def m002_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE jukebox_payment ( CREATE TABLE jukebox.jukebox_payment (
payment_hash TEXT PRIMARY KEY, payment_hash TEXT PRIMARY KEY,
juke_id TEXT, juke_id TEXT,
song_id TEXT, song_id TEXT,

View file

@ -9,7 +9,7 @@ from .models import Livestream, Track, Producer
async def create_livestream(*, wallet_id: str) -> int: async def create_livestream(*, wallet_id: str) -> int:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO livestreams (wallet) INSERT INTO livestream.livestreams (wallet)
VALUES (?) VALUES (?)
""", """,
(wallet_id,), (wallet_id,),
@ -18,14 +18,16 @@ async def create_livestream(*, wallet_id: str) -> int:
async def get_livestream(ls_id: int) -> Optional[Livestream]: async def get_livestream(ls_id: int) -> Optional[Livestream]:
row = await db.fetchone("SELECT * FROM livestreams WHERE id = ?", (ls_id,)) row = await db.fetchone(
"SELECT * FROM livestream.livestreams WHERE id = ?", (ls_id,)
)
return Livestream(**dict(row)) if row else None return Livestream(**dict(row)) if row else None
async def get_livestream_by_track(track_id: int) -> Optional[Livestream]: async def get_livestream_by_track(track_id: int) -> Optional[Livestream]:
row = await db.fetchone( row = await db.fetchone(
""" """
SELECT livestreams.* FROM livestreams SELECT livestreams.* FROM livestream.livestreams
INNER JOIN tracks ON tracks.livestream = livestreams.id INNER JOIN tracks ON tracks.livestream = livestreams.id
WHERE tracks.id = ? WHERE tracks.id = ?
""", """,
@ -35,7 +37,9 @@ async def get_livestream_by_track(track_id: int) -> Optional[Livestream]:
async def get_or_create_livestream_by_wallet(wallet: str) -> Optional[Livestream]: async def get_or_create_livestream_by_wallet(wallet: str) -> Optional[Livestream]:
row = await db.fetchone("SELECT * FROM livestreams WHERE wallet = ?", (wallet,)) row = await db.fetchone(
"SELECT * FROM livestream.livestreams WHERE wallet = ?", (wallet,)
)
if not row: if not row:
# create on the fly # create on the fly
@ -47,14 +51,14 @@ async def get_or_create_livestream_by_wallet(wallet: str) -> Optional[Livestream
async def update_current_track(ls_id: int, track_id: Optional[int]): async def update_current_track(ls_id: int, track_id: Optional[int]):
await db.execute( await db.execute(
"UPDATE livestreams SET current_track = ? WHERE id = ?", "UPDATE livestream.livestreams SET current_track = ? WHERE id = ?",
(track_id, ls_id), (track_id, ls_id),
) )
async def update_livestream_fee(ls_id: int, fee_pct: int): async def update_livestream_fee(ls_id: int, fee_pct: int):
await db.execute( await db.execute(
"UPDATE livestreams SET fee_pct = ? WHERE id = ?", "UPDATE livestream.livestreams SET fee_pct = ? WHERE id = ?",
(fee_pct, ls_id), (fee_pct, ls_id),
) )
@ -68,7 +72,7 @@ async def add_track(
) -> int: ) -> int:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO tracks (livestream, name, download_url, price_msat, producer) INSERT INTO livestream.tracks (livestream, name, download_url, price_msat, producer)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""", """,
(livestream, name, download_url, price_msat, producer), (livestream, name, download_url, price_msat, producer),
@ -86,7 +90,7 @@ async def update_track(
) -> int: ) -> int:
result = await db.execute( result = await db.execute(
""" """
UPDATE tracks SET UPDATE livestream.tracks SET
name = ?, name = ?,
download_url = ?, download_url = ?,
price_msat = ?, price_msat = ?,
@ -105,7 +109,7 @@ async def get_track(track_id: Optional[int]) -> Optional[Track]:
row = await db.fetchone( row = await db.fetchone(
""" """
SELECT id, download_url, price_msat, name, producer SELECT id, download_url, price_msat, name, producer
FROM tracks WHERE id = ? FROM livestream.tracks WHERE id = ?
""", """,
(track_id,), (track_id,),
) )
@ -116,7 +120,7 @@ async def get_tracks(livestream: int) -> List[Track]:
rows = await db.fetchall( rows = await db.fetchall(
""" """
SELECT id, download_url, price_msat, name, producer SELECT id, download_url, price_msat, name, producer
FROM tracks WHERE livestream = ? FROM livestream.tracks WHERE livestream = ?
""", """,
(livestream,), (livestream,),
) )
@ -126,7 +130,7 @@ async def get_tracks(livestream: int) -> List[Track]:
async def delete_track_from_livestream(livestream: int, track_id: int): async def delete_track_from_livestream(livestream: int, track_id: int):
await db.execute( await db.execute(
""" """
DELETE FROM tracks WHERE livestream = ? AND id = ? DELETE FROM livestream.tracks WHERE livestream = ? AND id = ?
""", """,
(livestream, track_id), (livestream, track_id),
) )
@ -137,7 +141,7 @@ async def add_producer(livestream: int, name: str) -> int:
existing = await db.fetchall( existing = await db.fetchall(
""" """
SELECT id FROM producers SELECT id FROM livestream.producers
WHERE livestream = ? AND lower(name) = ? WHERE livestream = ? AND lower(name) = ?
""", """,
(livestream, name.lower()), (livestream, name.lower()),
@ -150,7 +154,7 @@ async def add_producer(livestream: int, name: str) -> int:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO producers (livestream, name, user, wallet) INSERT INTO livestream.producers (livestream, name, "user", wallet)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""", """,
(livestream, name, user.id, wallet.id), (livestream, name, user.id, wallet.id),
@ -161,8 +165,8 @@ async def add_producer(livestream: int, name: str) -> int:
async def get_producer(producer_id: int) -> Optional[Producer]: async def get_producer(producer_id: int) -> Optional[Producer]:
row = await db.fetchone( row = await db.fetchone(
""" """
SELECT id, user, wallet, name SELECT id, "user", wallet, name
FROM producers WHERE id = ? FROM livestream.producers WHERE id = ?
""", """,
(producer_id,), (producer_id,),
) )
@ -172,8 +176,8 @@ async def get_producer(producer_id: int) -> Optional[Producer]:
async def get_producers(livestream: int) -> List[Producer]: async def get_producers(livestream: int) -> List[Producer]:
rows = await db.fetchall( rows = await db.fetchall(
""" """
SELECT id, user, wallet, name SELECT id, "user", wallet, name
FROM producers WHERE livestream = ? FROM livestream.producers WHERE livestream = ?
""", """,
(livestream,), (livestream,),
) )

View file

@ -3,9 +3,9 @@ async def m001_initial(db):
Initial livestream tables. Initial livestream tables.
""" """
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS livestreams ( CREATE TABLE livestream.livestreams (
id INTEGER PRIMARY KEY AUTOINCREMENT, id {db.serial_primary_key},
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
fee_pct INTEGER NOT NULL DEFAULT 10, fee_pct INTEGER NOT NULL DEFAULT 10,
current_track INTEGER current_track INTEGER
@ -14,11 +14,11 @@ async def m001_initial(db):
) )
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS producers ( CREATE TABLE livestream.producers (
livestream INTEGER NOT NULL REFERENCES livestreams (id), livestream INTEGER NOT NULL REFERENCES {db.references_schema}livestreams (id),
id INTEGER PRIMARY KEY AUTOINCREMENT, id {db.serial_primary_key},
user TEXT NOT NULL, "user" TEXT NOT NULL,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
name TEXT NOT NULL name TEXT NOT NULL
); );
@ -26,14 +26,14 @@ async def m001_initial(db):
) )
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS tracks ( CREATE TABLE livestream.tracks (
livestream INTEGER NOT NULL REFERENCES livestreams (id), livestream INTEGER NOT NULL REFERENCES {db.references_schema}livestreams (id),
id INTEGER PRIMARY KEY AUTOINCREMENT, id {db.serial_primary_key},
download_url TEXT, download_url TEXT,
price_msat INTEGER NOT NULL DEFAULT 0, price_msat INTEGER NOT NULL DEFAULT 0,
name TEXT, name TEXT,
producer INTEGER REFERENCES producers (id) NOT NULL producer INTEGER REFERENCES {db.references_schema}producers (id) NOT NULL
); );
""" """
) )

View file

@ -49,7 +49,7 @@ async def on_invoice_paid(payment: Payment) -> None:
# and reduce it by the amount we're going to send to the producer # and reduce it by the amount we're going to send to the producer
await core_db.execute( await core_db.execute(
""" """
UPDATE apipayments UPDATE livestream.apipayments
SET extra = ?, amount = ? SET extra = ?, amount = ?
WHERE hash = ? WHERE hash = ?
AND checking_id NOT LIKE 'internal_%' AND checking_id NOT LIKE 'internal_%'

View file

@ -18,7 +18,7 @@ async def create_ticket(
) -> Tickets: ) -> Tickets:
await db.execute( await db.execute(
""" """
INSERT INTO ticket (id, form, email, ltext, name, wallet, sats, paid) INSERT INTO lnticket.ticket (id, form, email, ltext, name, wallet, sats, paid)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", """,
(payment_hash, form, email, ltext, name, wallet, sats, False), (payment_hash, form, email, ltext, name, wallet, sats, False),
@ -30,11 +30,11 @@ async def create_ticket(
async def set_ticket_paid(payment_hash: str) -> Tickets: async def set_ticket_paid(payment_hash: str) -> Tickets:
row = await db.fetchone("SELECT * FROM ticket WHERE id = ?", (payment_hash,)) row = await db.fetchone("SELECT * FROM lnticket.ticket WHERE id = ?", (payment_hash,))
if row[7] == False: if row[7] == False:
await db.execute( await db.execute(
""" """
UPDATE ticket UPDATE lnticket.ticket
SET paid = true SET paid = true
WHERE id = ? WHERE id = ?
""", """,
@ -47,7 +47,7 @@ async def set_ticket_paid(payment_hash: str) -> Tickets:
amount = formdata.amountmade + row[7] amount = formdata.amountmade + row[7]
await db.execute( await db.execute(
""" """
UPDATE form UPDATE lnticket.form
SET amountmade = ? SET amountmade = ?
WHERE id = ? WHERE id = ?
""", """,
@ -77,7 +77,7 @@ async def set_ticket_paid(payment_hash: str) -> Tickets:
async def get_ticket(ticket_id: str) -> Optional[Tickets]: async def get_ticket(ticket_id: str) -> Optional[Tickets]:
row = await db.fetchone("SELECT * FROM ticket WHERE id = ?", (ticket_id,)) row = await db.fetchone("SELECT * FROM lnticket.ticket WHERE id = ?", (ticket_id,))
return Tickets(**row) if row else None return Tickets(**row) if row else None
@ -87,14 +87,14 @@ async def get_tickets(wallet_ids: Union[str, List[str]]) -> List[Tickets]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM ticket WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM lnticket.ticket WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Tickets(**row) for row in rows] return [Tickets(**row) for row in rows]
async def delete_ticket(ticket_id: str) -> None: async def delete_ticket(ticket_id: str) -> None:
await db.execute("DELETE FROM ticket WHERE id = ?", (ticket_id,)) await db.execute("DELETE FROM lnticket.ticket WHERE id = ?", (ticket_id,))
# FORMS # FORMS
@ -111,7 +111,7 @@ async def create_form(
form_id = urlsafe_short_hash() form_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO form (id, wallet, name, webhook, description, costpword, amountmade) INSERT INTO lnticket.form (id, wallet, name, webhook, description, costpword, amountmade)
VALUES (?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
""", """,
(form_id, wallet, name, webhook, description, costpword, 0), (form_id, wallet, name, webhook, description, costpword, 0),
@ -124,14 +124,14 @@ async def create_form(
async def update_form(form_id: str, **kwargs) -> Forms: async def update_form(form_id: str, **kwargs) -> Forms:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(f"UPDATE form SET {q} WHERE id = ?", (*kwargs.values(), form_id)) await db.execute(f"UPDATE lnticket.form SET {q} WHERE id = ?", (*kwargs.values(), form_id))
row = await db.fetchone("SELECT * FROM form WHERE id = ?", (form_id,)) row = await db.fetchone("SELECT * FROM lnticket.form WHERE id = ?", (form_id,))
assert row, "Newly updated form couldn't be retrieved" assert row, "Newly updated form couldn't be retrieved"
return Forms(**row) return Forms(**row)
async def get_form(form_id: str) -> Optional[Forms]: async def get_form(form_id: str) -> Optional[Forms]:
row = await db.fetchone("SELECT * FROM form WHERE id = ?", (form_id,)) row = await db.fetchone("SELECT * FROM lnticket.form WHERE id = ?", (form_id,))
return Forms(**row) if row else None return Forms(**row) if row else None
@ -141,11 +141,11 @@ async def get_forms(wallet_ids: Union[str, List[str]]) -> List[Forms]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM form WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM lnticket.form WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Forms(**row) for row in rows] return [Forms(**row) for row in rows]
async def delete_form(form_id: str) -> None: async def delete_form(form_id: str) -> None:
await db.execute("DELETE FROM form WHERE id = ?", (form_id,)) await db.execute("DELETE FROM lnticket.form WHERE id = ?", (form_id,))

View file

@ -2,21 +2,21 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS forms ( CREATE TABLE lnticket.forms (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
description TEXT NOT NULL, description TEXT NOT NULL,
costpword INTEGER NOT NULL, costpword INTEGER NOT NULL,
amountmade INTEGER NOT NULL, amountmade INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS tickets ( CREATE TABLE lnticket.tickets (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
form TEXT NOT NULL, form TEXT NOT NULL,
email TEXT NOT NULL, email TEXT NOT NULL,
@ -24,7 +24,7 @@ async def m001_initial(db):
name TEXT NOT NULL, name TEXT NOT NULL,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
sats INTEGER NOT NULL, sats INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
@ -34,7 +34,7 @@ async def m002_changed(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS ticket ( CREATE TABLE lnticket.ticket (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
form TEXT NOT NULL, form TEXT NOT NULL,
email TEXT NOT NULL, email TEXT NOT NULL,
@ -43,12 +43,12 @@ async def m002_changed(db):
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
sats INTEGER NOT NULL, sats INTEGER NOT NULL,
paid BOOLEAN NOT NULL, paid BOOLEAN NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
for row in [list(row) for row in await db.fetchall("SELECT * FROM tickets")]: for row in [list(row) for row in await db.fetchall("SELECT * FROM lnticket.tickets")]:
usescsv = "" usescsv = ""
for i in range(row[5]): for i in range(row[5]):
@ -59,7 +59,7 @@ async def m002_changed(db):
usescsv = usescsv[1:] usescsv = usescsv[1:]
await db.execute( await db.execute(
""" """
INSERT INTO ticket ( INSERT INTO lnticket.ticket (
id, id,
form, form,
email, email,
@ -82,14 +82,14 @@ async def m002_changed(db):
True, True,
), ),
) )
await db.execute("DROP TABLE tickets") await db.execute("DROP TABLE lnticket.tickets")
async def m003_changed(db): async def m003_changed(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS form ( CREATE TABLE lnticket.form (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
@ -97,12 +97,12 @@ async def m003_changed(db):
description TEXT NOT NULL, description TEXT NOT NULL,
costpword INTEGER NOT NULL, costpword INTEGER NOT NULL,
amountmade INTEGER NOT NULL, amountmade INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
for row in [list(row) for row in await db.fetchall("SELECT * FROM forms")]: for row in [list(row) for row in await db.fetchall("SELECT * FROM lnticket.forms")]:
usescsv = "" usescsv = ""
for i in range(row[5]): for i in range(row[5]):
@ -113,7 +113,7 @@ async def m003_changed(db):
usescsv = usescsv[1:] usescsv = usescsv[1:]
await db.execute( await db.execute(
""" """
INSERT INTO form ( INSERT INTO lnticket.form (
id, id,
wallet, wallet,
name, name,
@ -134,4 +134,4 @@ async def m003_changed(db):
row[6], row[6],
), ),
) )
await db.execute("DROP TABLE forms") await db.execute("DROP TABLE lnticket.forms")

View file

@ -18,7 +18,7 @@ async def create_pay_link(
) -> PayLink: ) -> PayLink:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO pay_links ( INSERT INTO lnurlp.pay_links (
wallet, wallet,
description, description,
min, min,
@ -52,7 +52,7 @@ async def create_pay_link(
async def get_pay_link(link_id: int) -> Optional[PayLink]: async def get_pay_link(link_id: int) -> Optional[PayLink]:
row = await db.fetchone("SELECT * FROM pay_links WHERE id = ?", (link_id,)) row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
return PayLink.from_row(row) if row else None return PayLink.from_row(row) if row else None
@ -63,7 +63,7 @@ async def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f""" f"""
SELECT * FROM pay_links WHERE wallet IN ({q}) SELECT * FROM lnurlp.pay_links WHERE wallet IN ({q})
ORDER BY Id ORDER BY Id
""", """,
(*wallet_ids,), (*wallet_ids,),
@ -75,20 +75,20 @@ async def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:
async def update_pay_link(link_id: int, **kwargs) -> Optional[PayLink]: async def update_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id) f"UPDATE lnurlp.pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id)
) )
row = await db.fetchone("SELECT * FROM pay_links WHERE id = ?", (link_id,)) row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
return PayLink.from_row(row) if row else None return PayLink.from_row(row) if row else None
async def increment_pay_link(link_id: int, **kwargs) -> Optional[PayLink]: async def increment_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:
q = ", ".join([f"{field[0]} = {field[0]} + ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = {field[0]} + ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id) f"UPDATE lnurlp.pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id)
) )
row = await db.fetchone("SELECT * FROM pay_links WHERE id = ?", (link_id,)) row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
return PayLink.from_row(row) if row else None return PayLink.from_row(row) if row else None
async def delete_pay_link(link_id: int) -> None: async def delete_pay_link(link_id: int) -> None:
await db.execute("DELETE FROM pay_links WHERE id = ?", (link_id,)) await db.execute("DELETE FROM lnurlp.pay_links WHERE id = ?", (link_id,))

View file

@ -3,9 +3,9 @@ async def m001_initial(db):
Initial pay table. Initial pay table.
""" """
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS pay_links ( CREATE TABLE lnurlp.pay_links (
id INTEGER PRIMARY KEY AUTOINCREMENT, id {db.serial_primary_key},
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
description TEXT NOT NULL, description TEXT NOT NULL,
amount INTEGER NOT NULL, amount INTEGER NOT NULL,
@ -20,13 +20,13 @@ async def m002_webhooks_and_success_actions(db):
""" """
Webhooks and success actions. Webhooks and success actions.
""" """
await db.execute("ALTER TABLE pay_links ADD COLUMN webhook_url TEXT;") await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_url TEXT;")
await db.execute("ALTER TABLE pay_links ADD COLUMN success_text TEXT;") await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN success_text TEXT;")
await db.execute("ALTER TABLE pay_links ADD COLUMN success_url TEXT;") await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN success_url TEXT;")
await db.execute( await db.execute(
""" f"""
CREATE TABLE invoices ( CREATE TABLE lnurlp.invoices (
pay_link INTEGER NOT NULL REFERENCES pay_links (id), pay_link INTEGER NOT NULL REFERENCES {db.references_schema}pay_links (id),
payment_hash TEXT NOT NULL, payment_hash TEXT NOT NULL,
webhook_sent INT, -- null means not sent, otherwise store status webhook_sent INT, -- null means not sent, otherwise store status
expiry INT expiry INT
@ -41,12 +41,12 @@ async def m003_min_max_comment_fiat(db):
converted automatically to satoshis based on some API. converted automatically to satoshis based on some API.
""" """
await db.execute( await db.execute(
"ALTER TABLE pay_links ADD COLUMN currency TEXT;" "ALTER TABLE lnurlp.pay_links ADD COLUMN currency TEXT;"
) # null = satoshis ) # null = satoshis
await db.execute( await db.execute(
"ALTER TABLE pay_links ADD COLUMN comment_chars INTEGER DEFAULT 0;" "ALTER TABLE lnurlp.pay_links ADD COLUMN comment_chars INTEGER DEFAULT 0;"
) )
await db.execute("ALTER TABLE pay_links RENAME COLUMN amount TO min;") await db.execute("ALTER TABLE lnurlp.pay_links RENAME COLUMN amount TO min;")
await db.execute("ALTER TABLE pay_links ADD COLUMN max INTEGER;") await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN max INTEGER;")
await db.execute("UPDATE pay_links SET max = min;") await db.execute("UPDATE lnurlp.pay_links SET max = min;")
await db.execute("DROP TABLE invoices") await db.execute("DROP TABLE lnurlp.invoices")

View file

@ -54,7 +54,7 @@ async def mark_webhook_sent(payment: Payment, status: int) -> None:
await core_db.execute( await core_db.execute(
""" """
UPDATE apipayments SET extra = ? UPDATE lnurlp.apipayments SET extra = ?
WHERE hash = ? WHERE hash = ?
""", """,
(json.dumps(payment.extra), payment.payment_hash), (json.dumps(payment.extra), payment.payment_hash),

View file

@ -8,7 +8,7 @@ from .models import Shop, Item
async def create_shop(*, wallet_id: str) -> int: async def create_shop(*, wallet_id: str) -> int:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO shops (wallet, wordlist, method) INSERT INTO offlineshop.shops (wallet, wordlist, method)
VALUES (?, ?, 'wordlist') VALUES (?, ?, 'wordlist')
""", """,
(wallet_id, "\n".join(animals)), (wallet_id, "\n".join(animals)),
@ -17,12 +17,12 @@ async def create_shop(*, wallet_id: str) -> int:
async def get_shop(id: int) -> Optional[Shop]: async def get_shop(id: int) -> Optional[Shop]:
row = await db.fetchone("SELECT * FROM shops WHERE id = ?", (id,)) row = await db.fetchone("SELECT * FROM offlineshop.shops WHERE id = ?", (id,))
return Shop(**dict(row)) if row else None return Shop(**dict(row)) if row else None
async def get_or_create_shop_by_wallet(wallet: str) -> Optional[Shop]: async def get_or_create_shop_by_wallet(wallet: str) -> Optional[Shop]:
row = await db.fetchone("SELECT * FROM shops WHERE wallet = ?", (wallet,)) row = await db.fetchone("SELECT * FROM offlineshop.shops WHERE wallet = ?", (wallet,))
if not row: if not row:
# create on the fly # create on the fly
@ -34,7 +34,7 @@ async def get_or_create_shop_by_wallet(wallet: str) -> Optional[Shop]:
async def set_method(shop: int, method: str, wordlist: str = "") -> Optional[Shop]: async def set_method(shop: int, method: str, wordlist: str = "") -> Optional[Shop]:
await db.execute( await db.execute(
"UPDATE shops SET method = ?, wordlist = ? WHERE id = ?", "UPDATE offlineshop.shops SET method = ?, wordlist = ? WHERE id = ?",
(method, wordlist, shop), (method, wordlist, shop),
) )
return await get_shop(shop) return await get_shop(shop)
@ -50,7 +50,7 @@ async def add_item(
) -> int: ) -> int:
result = await db.execute( result = await db.execute(
""" """
INSERT INTO items (shop, name, description, image, price, unit) INSERT INTO offlineshop.items (shop, name, description, image, price, unit)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
""", """,
(shop, name, description, image, price, unit), (shop, name, description, image, price, unit),
@ -69,7 +69,7 @@ async def update_item(
) -> int: ) -> int:
await db.execute( await db.execute(
""" """
UPDATE items SET UPDATE offlineshop.items SET
name = ?, name = ?,
description = ?, description = ?,
image = ?, image = ?,
@ -83,19 +83,19 @@ async def update_item(
async def get_item(id: int) -> Optional[Item]: async def get_item(id: int) -> Optional[Item]:
row = await db.fetchone("SELECT * FROM items WHERE id = ? LIMIT 1", (id,)) row = await db.fetchone("SELECT * FROM offlineshop.items WHERE id = ? LIMIT 1", (id,))
return Item(**dict(row)) if row else None return Item(**dict(row)) if row else None
async def get_items(shop: int) -> List[Item]: async def get_items(shop: int) -> List[Item]:
rows = await db.fetchall("SELECT * FROM items WHERE shop = ?", (shop,)) rows = await db.fetchall("SELECT * FROM offlineshop.items WHERE shop = ?", (shop,))
return [Item(**dict(row)) for row in rows] return [Item(**dict(row)) for row in rows]
async def delete_item_from_shop(shop: int, item_id: int): async def delete_item_from_shop(shop: int, item_id: int):
await db.execute( await db.execute(
""" """
DELETE FROM items WHERE shop = ? AND id = ? DELETE FROM offlineshop.items WHERE shop = ? AND id = ?
""", """,
(shop, item_id), (shop, item_id),
) )

View file

@ -3,9 +3,9 @@ async def m001_initial(db):
Initial offlineshop tables. Initial offlineshop tables.
""" """
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS shops ( CREATE TABLE offlineshop.shops (
id INTEGER PRIMARY KEY AUTOINCREMENT, id {db.serial_primary_key},
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
method TEXT NOT NULL, method TEXT NOT NULL,
wordlist TEXT wordlist TEXT
@ -14,10 +14,10 @@ async def m001_initial(db):
) )
await db.execute( await db.execute(
""" f"""
CREATE TABLE IF NOT EXISTS items ( CREATE TABLE offlineshop.items (
shop INTEGER NOT NULL REFERENCES shop (id), shop INTEGER NOT NULL REFERENCES {db.references_schema}shops (id),
id INTEGER PRIMARY KEY AUTOINCREMENT, id {db.serial_primary_key},
name TEXT NOT NULL, name TEXT NOT NULL,
description TEXT NOT NULL, description TEXT NOT NULL,
image TEXT, -- image/png;base64,... image TEXT, -- image/png;base64,...

View file

@ -18,7 +18,7 @@ async def create_paywall(
paywall_id = urlsafe_short_hash() paywall_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO paywalls (id, wallet, url, memo, description, amount, remembers) INSERT INTO paywall.paywalls (id, wallet, url, memo, description, amount, remembers)
VALUES (?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
""", """,
(paywall_id, wallet_id, url, memo, description, amount, int(remembers)), (paywall_id, wallet_id, url, memo, description, amount, int(remembers)),
@ -30,7 +30,7 @@ async def create_paywall(
async def get_paywall(paywall_id: str) -> Optional[Paywall]: async def get_paywall(paywall_id: str) -> Optional[Paywall]:
row = await db.fetchone("SELECT * FROM paywalls WHERE id = ?", (paywall_id,)) row = await db.fetchone("SELECT * FROM paywall.paywalls WHERE id = ?", (paywall_id,))
return Paywall.from_row(row) if row else None return Paywall.from_row(row) if row else None
@ -41,11 +41,11 @@ async def get_paywalls(wallet_ids: Union[str, List[str]]) -> List[Paywall]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM paywalls WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM paywall.paywalls WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Paywall.from_row(row) for row in rows] return [Paywall.from_row(row) for row in rows]
async def delete_paywall(paywall_id: str) -> None: async def delete_paywall(paywall_id: str) -> None:
await db.execute("DELETE FROM paywalls WHERE id = ?", (paywall_id,)) await db.execute("DELETE FROM paywall.paywalls WHERE id = ?", (paywall_id,))

View file

@ -7,14 +7,16 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS paywalls ( CREATE TABLE paywall.paywalls (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
secret TEXT NOT NULL, secret TEXT NOT NULL,
url TEXT NOT NULL, url TEXT NOT NULL,
memo TEXT NOT NULL, memo TEXT NOT NULL,
amount INTEGER NOT NULL, amount INTEGER NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """
+ db.timestamp_now
+ """
); );
""" """
) )
@ -24,44 +26,41 @@ async def m002_redux(db):
""" """
Creates an improved paywalls table and migrates the existing data. Creates an improved paywalls table and migrates the existing data.
""" """
try: await db.execute("ALTER TABLE paywall.paywalls RENAME TO paywalls_old")
await db.execute("SELECT remembers FROM paywalls") await db.execute(
"""
CREATE TABLE paywall.paywalls (
id TEXT PRIMARY KEY,
wallet TEXT NOT NULL,
url TEXT NOT NULL,
memo TEXT NOT NULL,
description TEXT NULL,
amount INTEGER DEFAULT 0,
time TIMESTAMP NOT NULL DEFAULT """
+ db.timestamp_now
+ """,
remembers INTEGER DEFAULT 0,
extras TEXT NULL
);
"""
)
except OperationalError: for row in [
await db.execute("ALTER TABLE paywalls RENAME TO paywalls_old") list(row) for row in await db.fetchall("SELECT * FROM paywall.paywalls_old")
]:
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS paywalls ( INSERT INTO paywall.paywalls (
id TEXT PRIMARY KEY, id,
wallet TEXT NOT NULL, wallet,
url TEXT NOT NULL, url,
memo TEXT NOT NULL, memo,
description TEXT NULL, amount,
amount INTEGER DEFAULT 0, time
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')),
remembers INTEGER DEFAULT 0,
extras TEXT NULL
);
"""
)
await db.execute("CREATE INDEX IF NOT EXISTS wallet_idx ON paywalls (wallet)")
for row in [
list(row) for row in await db.fetchall("SELECT * FROM paywalls_old")
]:
await db.execute(
"""
INSERT INTO paywalls (
id,
wallet,
url,
memo,
amount,
time
)
VALUES (?, ?, ?, ?, ?, ?)
""",
(row[0], row[1], row[3], row[4], row[5], row[6]),
) )
VALUES (?, ?, ?, ?, ?, ?)
""",
(row[0], row[1], row[3], row[4], row[5], row[6]),
)
await db.execute("DROP TABLE paywalls_old") await db.execute("DROP TABLE paywall.paywalls_old")

View file

@ -42,9 +42,9 @@ async def create_charge(
payment_request = None payment_request = None
await db.execute( await db.execute(
""" """
INSERT INTO charges ( INSERT INTO satspay.charges (
id, id,
user, "user",
description, description,
onchainwallet, onchainwallet,
onchainaddress, onchainaddress,
@ -83,24 +83,26 @@ async def create_charge(
async def update_charge(charge_id: str, **kwargs) -> Optional[Charges]: async def update_charge(charge_id: str, **kwargs) -> Optional[Charges]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE charges SET {q} WHERE id = ?", (*kwargs.values(), charge_id) f"UPDATE satspay.charges SET {q} WHERE id = ?", (*kwargs.values(), charge_id)
) )
row = await db.fetchone("SELECT * FROM charges WHERE id = ?", (charge_id,)) row = await db.fetchone("SELECT * FROM satspay.charges WHERE id = ?", (charge_id,))
return Charges.from_row(row) if row else None return Charges.from_row(row) if row else None
async def get_charge(charge_id: str) -> Charges: async def get_charge(charge_id: str) -> Charges:
row = await db.fetchone("SELECT * FROM charges WHERE id = ?", (charge_id,)) row = await db.fetchone("SELECT * FROM satspay.charges WHERE id = ?", (charge_id,))
return Charges.from_row(row) if row else None return Charges.from_row(row) if row else None
async def get_charges(user: str) -> List[Charges]: async def get_charges(user: str) -> List[Charges]:
rows = await db.fetchall("SELECT * FROM charges WHERE user = ?", (user,)) rows = await db.fetchall(
"""SELECT * FROM satspay.charges WHERE "user" = ?""", (user,)
)
return [Charges.from_row(row) for row in rows] return [Charges.from_row(row) for row in rows]
async def delete_charge(charge_id: str) -> None: async def delete_charge(charge_id: str) -> None:
await db.execute("DELETE FROM charges WHERE id = ?", (charge_id,)) await db.execute("DELETE FROM satspay.charges WHERE id = ?", (charge_id,))
async def check_address_balance(charge_id: str) -> List[Charges]: async def check_address_balance(charge_id: str) -> List[Charges]:
@ -124,5 +126,5 @@ async def check_address_balance(charge_id: str) -> List[Charges]:
) )
if invoice_status.paid: if invoice_status.paid:
return await update_charge(charge_id=charge_id, balance=charge.amount) return await update_charge(charge_id=charge_id, balance=charge.amount)
row = await db.fetchone("SELECT * FROM charges WHERE id = ?", (charge_id,)) row = await db.fetchone("SELECT * FROM satspay.charges WHERE id = ?", (charge_id,))
return Charges.from_row(row) if row else None return Charges.from_row(row) if row else None

View file

@ -5,9 +5,9 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS charges ( CREATE TABLE satspay.charges (
id TEXT NOT NULL PRIMARY KEY, id TEXT NOT NULL PRIMARY KEY,
user TEXT, "user" TEXT,
description TEXT, description TEXT,
onchainwallet TEXT, onchainwallet TEXT,
onchainaddress TEXT, onchainaddress TEXT,
@ -20,7 +20,9 @@ async def m001_initial(db):
time INTEGER, time INTEGER,
amount INTEGER, amount INTEGER,
balance INTEGER DEFAULT 0, balance INTEGER DEFAULT 0,
timestamp TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) timestamp TIMESTAMP NOT NULL DEFAULT """
+ db.timestamp_now
+ """
); );
""" """
) )

View file

@ -5,17 +5,17 @@ from .models import Target
async def get_targets(source_wallet: str) -> List[Target]: async def get_targets(source_wallet: str) -> List[Target]:
rows = await db.fetchall("SELECT * FROM targets WHERE source = ?", (source_wallet,)) rows = await db.fetchall("SELECT * FROM splitpayments.targets WHERE source = ?", (source_wallet,))
return [Target(**dict(row)) for row in rows] return [Target(**dict(row)) for row in rows]
async def set_targets(source_wallet: str, targets: List[Target]): async def set_targets(source_wallet: str, targets: List[Target]):
async with db.connect() as conn: async with db.connect() as conn:
await conn.execute("DELETE FROM targets WHERE source = ?", (source_wallet,)) await conn.execute("DELETE FROM splitpayments.targets WHERE source = ?", (source_wallet,))
for target in targets: for target in targets:
await conn.execute( await conn.execute(
""" """
INSERT INTO targets INSERT INTO splitpayments.targets
(source, wallet, percent, alias) (source, wallet, percent, alias)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""", """,

View file

@ -4,7 +4,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS targets ( CREATE TABLE splitpayments.targets (
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
source TEXT NOT NULL, source TEXT NOT NULL,
percent INTEGER NOT NULL CHECK (percent >= 0 AND percent <= 100), percent INTEGER NOT NULL CHECK (percent >= 0 AND percent <= 100),

View file

@ -47,7 +47,7 @@ async def on_invoice_paid(payment: Payment) -> None:
# and reduce it by the amount we're going to send to the producer # and reduce it by the amount we're going to send to the producer
await core_db.execute( await core_db.execute(
""" """
UPDATE apipayments UPDATE splitpayments.apipayments
SET extra = ?, amount = ? SET extra = ?, amount = ?
WHERE hash = ? WHERE hash = ?
AND checking_id NOT LIKE 'internal_%' AND checking_id NOT LIKE 'internal_%'

View file

@ -19,7 +19,7 @@ async def create_subdomain(
) -> Subdomains: ) -> Subdomains:
await db.execute( await db.execute(
""" """
INSERT INTO subdomain (id, domain, email, subdomain, ip, wallet, sats, duration, paid, record_type) INSERT INTO subdomains.subdomain (id, domain, email, subdomain, ip, wallet, sats, duration, paid, record_type)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -43,13 +43,13 @@ async def create_subdomain(
async def set_subdomain_paid(payment_hash: str) -> Subdomains: async def set_subdomain_paid(payment_hash: str) -> Subdomains:
row = await db.fetchone( row = await db.fetchone(
"SELECT s.*, d.domain as domain_name FROM subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.id = ?", "SELECT s.*, d.domain as domain_name FROM subdomains.subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.id = ?",
(payment_hash,), (payment_hash,),
) )
if row[8] == False: if row[8] == False:
await db.execute( await db.execute(
""" """
UPDATE subdomain UPDATE subdomains.subdomain
SET paid = true SET paid = true
WHERE id = ? WHERE id = ?
""", """,
@ -62,7 +62,7 @@ async def set_subdomain_paid(payment_hash: str) -> Subdomains:
amount = domaindata.amountmade + row[8] amount = domaindata.amountmade + row[8]
await db.execute( await db.execute(
""" """
UPDATE domain UPDATE subdomains.domain
SET amountmade = ? SET amountmade = ?
WHERE id = ? WHERE id = ?
""", """,
@ -76,7 +76,7 @@ async def set_subdomain_paid(payment_hash: str) -> Subdomains:
async def get_subdomain(subdomain_id: str) -> Optional[Subdomains]: async def get_subdomain(subdomain_id: str) -> Optional[Subdomains]:
row = await db.fetchone( row = await db.fetchone(
"SELECT s.*, d.domain as domain_name FROM subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.id = ?", "SELECT s.*, d.domain as domain_name FROM subdomains.subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.id = ?",
(subdomain_id,), (subdomain_id,),
) )
return Subdomains(**row) if row else None return Subdomains(**row) if row else None
@ -84,7 +84,7 @@ async def get_subdomain(subdomain_id: str) -> Optional[Subdomains]:
async def get_subdomainBySubdomain(subdomain: str) -> Optional[Subdomains]: async def get_subdomainBySubdomain(subdomain: str) -> Optional[Subdomains]:
row = await db.fetchone( row = await db.fetchone(
"SELECT s.*, d.domain as domain_name FROM subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.subdomain = ?", "SELECT s.*, d.domain as domain_name FROM subdomains.subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.subdomain = ?",
(subdomain,), (subdomain,),
) )
print(row) print(row)
@ -97,7 +97,7 @@ async def get_subdomains(wallet_ids: Union[str, List[str]]) -> List[Subdomains]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT s.*, d.domain as domain_name FROM subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.wallet IN ({q})", f"SELECT s.*, d.domain as domain_name FROM subdomains.subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.wallet IN ({q})",
(*wallet_ids,), (*wallet_ids,),
) )
@ -105,7 +105,7 @@ async def get_subdomains(wallet_ids: Union[str, List[str]]) -> List[Subdomains]:
async def delete_subdomain(subdomain_id: str) -> None: async def delete_subdomain(subdomain_id: str) -> None:
await db.execute("DELETE FROM subdomain WHERE id = ?", (subdomain_id,)) await db.execute("DELETE FROM subdomains.subdomain WHERE id = ?", (subdomain_id,))
# Domains # Domains
@ -125,7 +125,7 @@ async def create_domain(
domain_id = urlsafe_short_hash() domain_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO domain (id, wallet, domain, webhook, cf_token, cf_zone_id, description, cost, amountmade, allowed_record_types) INSERT INTO subdomains.domain (id, wallet, domain, webhook, cf_token, cf_zone_id, description, cost, amountmade, allowed_record_types)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
@ -150,15 +150,15 @@ async def create_domain(
async def update_domain(domain_id: str, **kwargs) -> Domains: async def update_domain(domain_id: str, **kwargs) -> Domains:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE domain SET {q} WHERE id = ?", (*kwargs.values(), domain_id) f"UPDATE subdomains.domain SET {q} WHERE id = ?", (*kwargs.values(), domain_id)
) )
row = await db.fetchone("SELECT * FROM domain WHERE id = ?", (domain_id,)) row = await db.fetchone("SELECT * FROM subdomains.domain WHERE id = ?", (domain_id,))
assert row, "Newly updated domain couldn't be retrieved" assert row, "Newly updated domain couldn't be retrieved"
return Domains(**row) return Domains(**row)
async def get_domain(domain_id: str) -> Optional[Domains]: async def get_domain(domain_id: str) -> Optional[Domains]:
row = await db.fetchone("SELECT * FROM domain WHERE id = ?", (domain_id,)) row = await db.fetchone("SELECT * FROM subdomains.domain WHERE id = ?", (domain_id,))
return Domains(**row) if row else None return Domains(**row) if row else None
@ -168,11 +168,11 @@ async def get_domains(wallet_ids: Union[str, List[str]]) -> List[Domains]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM domain WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM subdomains.domain WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [Domains(**row) for row in rows] return [Domains(**row) for row in rows]
async def delete_domain(domain_id: str) -> None: async def delete_domain(domain_id: str) -> None:
await db.execute("DELETE FROM domain WHERE id = ?", (domain_id,)) await db.execute("DELETE FROM subdomains.domain WHERE id = ?", (domain_id,))

View file

@ -2,7 +2,7 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS domain ( CREATE TABLE subdomains.domain (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
domain TEXT NOT NULL, domain TEXT NOT NULL,
@ -13,14 +13,14 @@ async def m001_initial(db):
cost INTEGER NOT NULL, cost INTEGER NOT NULL,
amountmade INTEGER NOT NULL, amountmade INTEGER NOT NULL,
allowed_record_types TEXT NOT NULL, allowed_record_types TEXT NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS subdomain ( CREATE TABLE subdomains.subdomain (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
domain TEXT NOT NULL, domain TEXT NOT NULL,
email TEXT NOT NULL, email TEXT NOT NULL,
@ -31,7 +31,7 @@ async def m001_initial(db):
duration INTEGER NOT NULL, duration INTEGER NOT NULL,
paid BOOLEAN NOT NULL, paid BOOLEAN NOT NULL,
record_type TEXT NOT NULL, record_type TEXT NOT NULL,
time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')) time TIMESTAMP NOT NULL DEFAULT """ + db.timestamp_now + """
); );
""" """
) )

View file

@ -10,7 +10,7 @@ async def create_tpos(*, wallet_id: str, name: str, currency: str) -> TPoS:
tpos_id = urlsafe_short_hash() tpos_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO tposs (id, wallet, name, currency) INSERT INTO tpos.tposs (id, wallet, name, currency)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""", """,
(tpos_id, wallet_id, name, currency), (tpos_id, wallet_id, name, currency),
@ -22,7 +22,7 @@ async def create_tpos(*, wallet_id: str, name: str, currency: str) -> TPoS:
async def get_tpos(tpos_id: str) -> Optional[TPoS]: async def get_tpos(tpos_id: str) -> Optional[TPoS]:
row = await db.fetchone("SELECT * FROM tposs WHERE id = ?", (tpos_id,)) row = await db.fetchone("SELECT * FROM tpos.tposs WHERE id = ?", (tpos_id,))
return TPoS.from_row(row) if row else None return TPoS.from_row(row) if row else None
@ -32,11 +32,11 @@ async def get_tposs(wallet_ids: Union[str, List[str]]) -> List[TPoS]:
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM tposs WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM tpos.tposs WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [TPoS.from_row(row) for row in rows] return [TPoS.from_row(row) for row in rows]
async def delete_tpos(tpos_id: str) -> None: async def delete_tpos(tpos_id: str) -> None:
await db.execute("DELETE FROM tposs WHERE id = ?", (tpos_id,)) await db.execute("DELETE FROM tpos.tposs WHERE id = ?", (tpos_id,))

View file

@ -4,7 +4,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS tposs ( CREATE TABLE tpos.tposs (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,

View file

@ -31,7 +31,7 @@ async def create_usermanager_user(
await db.execute( await db.execute(
""" """
INSERT INTO users (id, name, admin, email, password) INSERT INTO usermanager.users (id, name, admin, email, password)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""", """,
(user.id, user_name, admin_id, email, password), (user.id, user_name, admin_id, email, password),
@ -39,7 +39,7 @@ async def create_usermanager_user(
await db.execute( await db.execute(
""" """
INSERT INTO wallets (id, admin, name, user, adminkey, inkey) INSERT INTO usermanager.wallets (id, admin, name, "user", adminkey, inkey)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
""", """,
(wallet.id, admin_id, wallet_name, user.id, wallet.adminkey, wallet.inkey), (wallet.id, admin_id, wallet_name, user.id, wallet.adminkey, wallet.inkey),
@ -51,12 +51,12 @@ async def create_usermanager_user(
async def get_usermanager_user(user_id: str) -> Optional[Users]: async def get_usermanager_user(user_id: str) -> Optional[Users]:
row = await db.fetchone("SELECT * FROM users WHERE id = ?", (user_id,)) row = await db.fetchone("SELECT * FROM usermanager.users WHERE id = ?", (user_id,))
return Users(**row) if row else None return Users(**row) if row else None
async def get_usermanager_users(user_id: str) -> List[Users]: async def get_usermanager_users(user_id: str) -> List[Users]:
rows = await db.fetchall("SELECT * FROM users WHERE admin = ?", (user_id,)) rows = await db.fetchall("SELECT * FROM usermanager.users WHERE admin = ?", (user_id,))
return [Users(**row) for row in rows] return [Users(**row) for row in rows]
@ -65,8 +65,8 @@ async def delete_usermanager_user(user_id: str) -> None:
for wallet in wallets: for wallet in wallets:
await delete_wallet(user_id=user_id, wallet_id=wallet.id) await delete_wallet(user_id=user_id, wallet_id=wallet.id)
await db.execute("DELETE FROM users WHERE id = ?", (user_id,)) await db.execute("DELETE FROM usermanager.users WHERE id = ?", (user_id,))
await db.execute("DELETE FROM wallets WHERE user = ?", (user_id,)) await db.execute("""DELETE FROM usermanager.wallets WHERE "user" = ?""", (user_id,))
### Wallets ### Wallets
@ -78,7 +78,7 @@ async def create_usermanager_wallet(
wallet = await create_wallet(user_id=user_id, wallet_name=wallet_name) wallet = await create_wallet(user_id=user_id, wallet_name=wallet_name)
await db.execute( await db.execute(
""" """
INSERT INTO wallets (id, admin, name, user, adminkey, inkey) INSERT INTO usermanager.wallets (id, admin, name, "user", adminkey, inkey)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
""", """,
(wallet.id, admin_id, wallet_name, user_id, wallet.adminkey, wallet.inkey), (wallet.id, admin_id, wallet_name, user_id, wallet.adminkey, wallet.inkey),
@ -89,17 +89,17 @@ async def create_usermanager_wallet(
async def get_usermanager_wallet(wallet_id: str) -> Optional[Wallets]: async def get_usermanager_wallet(wallet_id: str) -> Optional[Wallets]:
row = await db.fetchone("SELECT * FROM wallets WHERE id = ?", (wallet_id,)) row = await db.fetchone("SELECT * FROM usermanager.wallets WHERE id = ?", (wallet_id,))
return Wallets(**row) if row else None return Wallets(**row) if row else None
async def get_usermanager_wallets(admin_id: str) -> Optional[Wallets]: async def get_usermanager_wallets(admin_id: str) -> Optional[Wallets]:
rows = await db.fetchall("SELECT * FROM wallets WHERE admin = ?", (admin_id,)) rows = await db.fetchall("SELECT * FROM usermanager.wallets WHERE admin = ?", (admin_id,))
return [Wallets(**row) for row in rows] return [Wallets(**row) for row in rows]
async def get_usermanager_users_wallets(user_id: str) -> Optional[Wallets]: async def get_usermanager_users_wallets(user_id: str) -> Optional[Wallets]:
rows = await db.fetchall("SELECT * FROM wallets WHERE user = ?", (user_id,)) rows = await db.fetchall("""SELECT * FROM usermanager.wallets WHERE "user" = ?""", (user_id,))
return [Wallets(**row) for row in rows] return [Wallets(**row) for row in rows]
@ -111,4 +111,4 @@ async def get_usermanager_wallet_transactions(wallet_id: str) -> Optional[Paymen
async def delete_usermanager_wallet(wallet_id: str, user_id: str) -> None: async def delete_usermanager_wallet(wallet_id: str, user_id: str) -> None:
await delete_wallet(user_id=user_id, wallet_id=wallet_id) await delete_wallet(user_id=user_id, wallet_id=wallet_id)
await db.execute("DELETE FROM wallets WHERE id = ?", (wallet_id,)) await db.execute("DELETE FROM usermanager.wallets WHERE id = ?", (wallet_id,))

View file

@ -4,7 +4,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS users ( CREATE TABLE usermanager.users (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
admin TEXT NOT NULL, admin TEXT NOT NULL,
@ -19,11 +19,11 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS wallets ( CREATE TABLE usermanager.wallets (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
admin TEXT NOT NULL, admin TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
user TEXT NOT NULL, "user" TEXT NOT NULL,
adminkey TEXT NOT NULL, adminkey TEXT NOT NULL,
inkey TEXT NOT NULL inkey TEXT NOT NULL
); );

View file

@ -1,16 +1,13 @@
from typing import List, Optional, Union from typing import List, Optional
# from lnbits.db import open_ext_db
from . import db from . import db
from .models import Wallets, Addresses, Mempool from .models import Wallets, Addresses, Mempool
from lnbits.helpers import urlsafe_short_hash from lnbits.helpers import urlsafe_short_hash
from embit.descriptor import Descriptor, Key from embit.descriptor import Descriptor, Key # type: ignore
from embit.descriptor.arguments import AllowedDerivation from embit.descriptor.arguments import AllowedDerivation # type: ignore
from embit.networks import NETWORKS from embit.networks import NETWORKS # type: ignore
import httpx
##########################WALLETS#################### ##########################WALLETS####################
@ -83,9 +80,9 @@ async def create_watch_wallet(*, user: str, masterpub: str, title: str) -> Walle
wallet_id = urlsafe_short_hash() wallet_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO wallets ( INSERT INTO watchonly.wallets (
id, id,
user, "user",
masterpub, masterpub,
title, title,
address_no, address_no,
@ -101,13 +98,17 @@ async def create_watch_wallet(*, user: str, masterpub: str, title: str) -> Walle
return await get_watch_wallet(wallet_id) return await get_watch_wallet(wallet_id)
async def get_watch_wallet(wallet_id: str) -> Wallets: async def get_watch_wallet(wallet_id: str) -> Optional[Wallets]:
row = await db.fetchone("SELECT * FROM wallets WHERE id = ?", (wallet_id,)) row = await db.fetchone(
"SELECT * FROM watchonly.wallets WHERE id = ?", (wallet_id,)
)
return Wallets.from_row(row) if row else None return Wallets.from_row(row) if row else None
async def get_watch_wallets(user: str) -> List[Wallets]: async def get_watch_wallets(user: str) -> List[Wallets]:
rows = await db.fetchall("SELECT * FROM wallets WHERE user = ?", (user,)) rows = await db.fetchall(
"""SELECT * FROM watchonly.wallets WHERE "user" = ?""", (user,)
)
return [Wallets(**row) for row in rows] return [Wallets(**row) for row in rows]
@ -115,28 +116,31 @@ async def update_watch_wallet(wallet_id: str, **kwargs) -> Optional[Wallets]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE wallets SET {q} WHERE id = ?", (*kwargs.values(), wallet_id) f"UPDATE watchonly.wallets SET {q} WHERE id = ?", (*kwargs.values(), wallet_id)
)
row = await db.fetchone(
"SELECT * FROM watchonly.wallets WHERE id = ?", (wallet_id,)
) )
row = await db.fetchone("SELECT * FROM wallets WHERE id = ?", (wallet_id,))
return Wallets.from_row(row) if row else None return Wallets.from_row(row) if row else None
async def delete_watch_wallet(wallet_id: str) -> None: async def delete_watch_wallet(wallet_id: str) -> None:
await db.execute("DELETE FROM wallets WHERE id = ?", (wallet_id,)) await db.execute("DELETE FROM watchonly.wallets WHERE id = ?", (wallet_id,))
########################ADDRESSES####################### ########################ADDRESSES#######################
async def get_derive_address(wallet_id: str, num: int): async def get_derive_address(wallet_id: str, num: int):
wallet = await get_watch_wallet(wallet_id) wallet = await get_watch_wallet(wallet_id)
key = wallet[2] key = wallet[2]
desc, network = parse_key(key) desc, network = parse_key(key)
return desc.derive(num).address(network=network) return desc.derive(num).address(network=network)
async def get_fresh_address(wallet_id: str) -> Addresses: async def get_fresh_address(wallet_id: str) -> Optional[Addresses]:
wallet = await get_watch_wallet(wallet_id) wallet = await get_watch_wallet(wallet_id)
if not wallet:
return None
address = await get_derive_address(wallet_id, wallet[4] + 1) address = await get_derive_address(wallet_id, wallet[4] + 1)
@ -144,7 +148,7 @@ async def get_fresh_address(wallet_id: str) -> Addresses:
masterpub_id = urlsafe_short_hash() masterpub_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO addresses ( INSERT INTO watchonly.addresses (
id, id,
address, address,
wallet, wallet,
@ -158,42 +162,52 @@ async def get_fresh_address(wallet_id: str) -> Addresses:
return await get_address(address) return await get_address(address)
async def get_address(address: str) -> Addresses: async def get_address(address: str) -> Optional[Addresses]:
row = await db.fetchone("SELECT * FROM addresses WHERE address = ?", (address,)) row = await db.fetchone(
"SELECT * FROM watchonly.addresses WHERE address = ?", (address,)
)
return Addresses.from_row(row) if row else None return Addresses.from_row(row) if row else None
async def get_addresses(wallet_id: str) -> List[Addresses]: async def get_addresses(wallet_id: str) -> List[Addresses]:
rows = await db.fetchall("SELECT * FROM addresses WHERE wallet = ?", (wallet_id,)) rows = await db.fetchall(
"SELECT * FROM watchonly.addresses WHERE wallet = ?", (wallet_id,)
)
return [Addresses(**row) for row in rows] return [Addresses(**row) for row in rows]
######################MEMPOOL####################### ######################MEMPOOL#######################
async def create_mempool(user: str) -> Mempool: async def create_mempool(user: str) -> Optional[Mempool]:
await db.execute( await db.execute(
""" """
INSERT INTO mempool ( INSERT INTO watchonly.mempool ("user",endpoint)
user,
endpoint
)
VALUES (?, ?) VALUES (?, ?)
""", """,
(user, "https://mempool.space"), (user, "https://mempool.space"),
) )
row = await db.fetchone("SELECT * FROM mempool WHERE user = ?", (user,)) row = await db.fetchone(
"""SELECT * FROM watchonly.mempool WHERE "user" = ?""", (user,)
)
return Mempool.from_row(row) if row else None return Mempool.from_row(row) if row else None
async def update_mempool(user: str, **kwargs) -> Optional[Mempool]: async def update_mempool(user: str, **kwargs) -> Optional[Mempool]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(f"UPDATE mempool SET {q} WHERE user = ?", (*kwargs.values(), user)) await db.execute(
row = await db.fetchone("SELECT * FROM mempool WHERE user = ?", (user,)) f"""UPDATE watchonly.mempool SET {q} WHERE "user" = ?""",
(*kwargs.values(), user),
)
row = await db.fetchone(
"""SELECT * FROM watchonly.mempool WHERE "user" = ?""", (user,)
)
return Mempool.from_row(row) if row else None return Mempool.from_row(row) if row else None
async def get_mempool(user: str) -> Mempool: async def get_mempool(user: str) -> Mempool:
row = await db.fetchone("SELECT * FROM mempool WHERE user = ?", (user,)) row = await db.fetchone(
"""SELECT * FROM watchonly.mempool WHERE "user" = ?""", (user,)
)
return Mempool.from_row(row) if row else None return Mempool.from_row(row) if row else None

View file

@ -4,9 +4,9 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS wallets ( CREATE TABLE watchonly.wallets (
id TEXT NOT NULL PRIMARY KEY, id TEXT NOT NULL PRIMARY KEY,
user TEXT, "user" TEXT,
masterpub TEXT NOT NULL, masterpub TEXT NOT NULL,
title TEXT NOT NULL, title TEXT NOT NULL,
address_no INTEGER NOT NULL DEFAULT 0, address_no INTEGER NOT NULL DEFAULT 0,
@ -17,7 +17,7 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS addresses ( CREATE TABLE watchonly.addresses (
id TEXT NOT NULL PRIMARY KEY, id TEXT NOT NULL PRIMARY KEY,
address TEXT NOT NULL, address TEXT NOT NULL,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
@ -28,8 +28,8 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS mempool ( CREATE TABLE watchonly.mempool (
user TEXT NOT NULL, "user" TEXT NOT NULL,
endpoint TEXT NOT NULL endpoint TEXT NOT NULL
); );
""" """

View file

@ -20,7 +20,7 @@ async def create_withdraw_link(
link_id = urlsafe_short_hash() link_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO withdraw_link ( INSERT INTO withdraw.withdraw_link (
id, id,
wallet, wallet,
title, title,
@ -57,7 +57,7 @@ async def create_withdraw_link(
async def get_withdraw_link(link_id: str, num=0) -> Optional[WithdrawLink]: async def get_withdraw_link(link_id: str, num=0) -> Optional[WithdrawLink]:
row = await db.fetchone("SELECT * FROM withdraw_link WHERE id = ?", (link_id,)) row = await db.fetchone("SELECT * FROM withdraw.withdraw_link WHERE id = ?", (link_id,))
if not row: if not row:
return None return None
@ -70,7 +70,7 @@ async def get_withdraw_link(link_id: str, num=0) -> Optional[WithdrawLink]:
async def get_withdraw_link_by_hash(unique_hash: str, num=0) -> Optional[WithdrawLink]: async def get_withdraw_link_by_hash(unique_hash: str, num=0) -> Optional[WithdrawLink]:
row = await db.fetchone( row = await db.fetchone(
"SELECT * FROM withdraw_link WHERE unique_hash = ?", (unique_hash,) "SELECT * FROM withdraw.withdraw_link WHERE unique_hash = ?", (unique_hash,)
) )
if not row: if not row:
return None return None
@ -88,7 +88,7 @@ async def get_withdraw_links(wallet_ids: Union[str, List[str]]) -> List[Withdraw
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM withdraw_link WHERE wallet IN ({q})", (*wallet_ids,) f"SELECT * FROM withdraw.withdraw_link WHERE wallet IN ({q})", (*wallet_ids,)
) )
return [WithdrawLink.from_row(row) for row in rows] return [WithdrawLink.from_row(row) for row in rows]
@ -97,14 +97,14 @@ async def get_withdraw_links(wallet_ids: Union[str, List[str]]) -> List[Withdraw
async def update_withdraw_link(link_id: str, **kwargs) -> Optional[WithdrawLink]: async def update_withdraw_link(link_id: str, **kwargs) -> Optional[WithdrawLink]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(
f"UPDATE withdraw_link SET {q} WHERE id = ?", (*kwargs.values(), link_id) f"UPDATE withdraw.withdraw_link SET {q} WHERE id = ?", (*kwargs.values(), link_id)
) )
row = await db.fetchone("SELECT * FROM withdraw_link WHERE id = ?", (link_id,)) row = await db.fetchone("SELECT * FROM withdraw.withdraw_link WHERE id = ?", (link_id,))
return WithdrawLink.from_row(row) if row else None return WithdrawLink.from_row(row) if row else None
async def delete_withdraw_link(link_id: str) -> None: async def delete_withdraw_link(link_id: str) -> None:
await db.execute("DELETE FROM withdraw_link WHERE id = ?", (link_id,)) await db.execute("DELETE FROM withdraw.withdraw_link WHERE id = ?", (link_id,))
def chunks(lst, n): def chunks(lst, n):
@ -118,7 +118,7 @@ async def create_hash_check(
) -> HashCheck: ) -> HashCheck:
await db.execute( await db.execute(
""" """
INSERT INTO hash_check ( INSERT INTO withdraw.hash_check (
id, id,
lnurl_id lnurl_id
) )
@ -134,9 +134,9 @@ async def create_hash_check(
async def get_hash_check(the_hash: str, lnurl_id: str) -> Optional[HashCheck]: async def get_hash_check(the_hash: str, lnurl_id: str) -> Optional[HashCheck]:
rowid = await db.fetchone("SELECT * FROM hash_check WHERE id = ?", (the_hash,)) rowid = await db.fetchone("SELECT * FROM withdraw.hash_check WHERE id = ?", (the_hash,))
rowlnurl = await db.fetchone( rowlnurl = await db.fetchone(
"SELECT * FROM hash_check WHERE lnurl_id = ?", (lnurl_id,) "SELECT * FROM withdraw.hash_check WHERE lnurl_id = ?", (lnurl_id,)
) )
if not rowlnurl: if not rowlnurl:
await create_hash_check(the_hash, lnurl_id) await create_hash_check(the_hash, lnurl_id)

View file

@ -4,7 +4,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS withdraw_links ( CREATE TABLE withdraw.withdraw_links (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT, wallet TEXT,
title TEXT, title TEXT,
@ -29,7 +29,7 @@ async def m002_change_withdraw_table(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS withdraw_link ( CREATE TABLE withdraw.withdraw_link (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT, wallet TEXT,
title TEXT, title TEXT,
@ -46,12 +46,8 @@ async def m002_change_withdraw_table(db):
); );
""" """
) )
await db.execute("CREATE INDEX IF NOT EXISTS wallet_idx ON withdraw_link (wallet)")
await db.execute(
"CREATE UNIQUE INDEX IF NOT EXISTS unique_hash_idx ON withdraw_link (unique_hash)"
)
for row in [list(row) for row in await db.fetchall("SELECT * FROM withdraw_links")]: for row in [list(row) for row in await db.fetchall("SELECT * FROM withdraw.withdraw_links")]:
usescsv = "" usescsv = ""
for i in range(row[5]): for i in range(row[5]):
@ -62,7 +58,7 @@ async def m002_change_withdraw_table(db):
usescsv = usescsv[1:] usescsv = usescsv[1:]
await db.execute( await db.execute(
""" """
INSERT INTO withdraw_link ( INSERT INTO withdraw.withdraw_link (
id, id,
wallet, wallet,
title, title,
@ -95,7 +91,7 @@ async def m002_change_withdraw_table(db):
usescsv, usescsv,
), ),
) )
await db.execute("DROP TABLE withdraw_links") await db.execute("DROP TABLE withdraw.withdraw_links")
async def m003_make_hash_check(db): async def m003_make_hash_check(db):
@ -104,7 +100,7 @@ async def m003_make_hash_check(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS hash_check ( CREATE TABLE withdraw.hash_check (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
lnurl_id TEXT lnurl_id TEXT
); );

View file

@ -23,6 +23,8 @@ LNBITS_PATH = path.dirname(path.realpath(__file__))
LNBITS_DATA_FOLDER = env.str( LNBITS_DATA_FOLDER = env.str(
"LNBITS_DATA_FOLDER", default=path.join(LNBITS_PATH, "data") "LNBITS_DATA_FOLDER", default=path.join(LNBITS_PATH, "data")
) )
LNBITS_DATABASE_URL = env.str("LNBITS_DATABASE_URL", default=None)
LNBITS_ALLOWED_USERS: List[str] = env.list( LNBITS_ALLOWED_USERS: List[str] = env.list(
"LNBITS_ALLOWED_USERS", default=[], subcast=str "LNBITS_ALLOWED_USERS", default=[], subcast=str
) )

View file

@ -190,7 +190,7 @@ window.LNbits = {
obj.fsat = new Intl.NumberFormat(window.LOCALE).format(obj.sat) obj.fsat = new Intl.NumberFormat(window.LOCALE).format(obj.sat)
obj.isIn = obj.amount > 0 obj.isIn = obj.amount > 0
obj.isOut = obj.amount < 0 obj.isOut = obj.amount < 0
obj.isPaid = obj.pending === 0 obj.isPaid = !obj.pending
obj._q = [obj.memo, obj.sat].join(' ').toLowerCase() obj._q = [obj.memo, obj.sat].join(' ').toLowerCase()
return obj return obj
} }

View file

@ -28,7 +28,14 @@ class LNbitsWallet(Wallet):
async def status(self) -> StatusResponse: async def status(self) -> StatusResponse:
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
r = await client.get(url=f"{self.endpoint}/api/v1/wallet", headers=self.key) try:
r = await client.get(
url=f"{self.endpoint}/api/v1/wallet", headers=self.key
)
except Exception as exc:
return StatusResponse(
f"Failed to connect to {self.endpoint} due to: {exc}", 0
)
try: try:
data = r.json() data = r.json()