Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 68e6e3d02e | |||
| a77145e08e |
1 changed files with 57 additions and 57 deletions
114
crud.py
114
crud.py
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
@ -6,6 +7,30 @@ from lnbits.helpers import urlsafe_short_hash
|
||||||
|
|
||||||
from .models import CreateEvent, Event, Ticket, TicketExtra
|
from .models import CreateEvent, Event, Ticket, TicketExtra
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_ticket_row(row) -> dict:
|
||||||
|
"""
|
||||||
|
Parse a database row into a dict suitable for Ticket model creation.
|
||||||
|
Handles:
|
||||||
|
- Empty string to None conversion for name/email
|
||||||
|
- JSON string to dict conversion for extra field
|
||||||
|
"""
|
||||||
|
ticket_data = dict(row)
|
||||||
|
|
||||||
|
# Convert empty strings back to None for the model
|
||||||
|
if ticket_data.get("name") == "":
|
||||||
|
ticket_data["name"] = None
|
||||||
|
if ticket_data.get("email") == "":
|
||||||
|
ticket_data["email"] = None
|
||||||
|
|
||||||
|
# Parse extra field from JSON string if needed
|
||||||
|
# (db.insert() serializes to JSON, but manual fetchone/fetchall returns string)
|
||||||
|
extra = ticket_data.get("extra")
|
||||||
|
if isinstance(extra, str):
|
||||||
|
ticket_data["extra"] = json.loads(extra)
|
||||||
|
|
||||||
|
return ticket_data
|
||||||
|
|
||||||
db = Database("ext_events")
|
db = Database("ext_events")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,7 +45,12 @@ async def create_ticket(
|
||||||
) -> Ticket:
|
) -> Ticket:
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
|
|
||||||
# Handle database constraints: if user_id is provided, use empty strings for name/email
|
# TODO: Check if this empty string workaround is still needed.
|
||||||
|
# This converts None to empty strings for database storage because:
|
||||||
|
# 1. Database may have NOT NULL constraints on name/email columns
|
||||||
|
# 2. When user_id is provided, name/email are not used (mutually exclusive)
|
||||||
|
# 3. The get_ticket() functions convert empty strings back to None when reading
|
||||||
|
# Consider using nullable columns instead of this empty string pattern.
|
||||||
if user_id:
|
if user_id:
|
||||||
db_name = ""
|
db_name = ""
|
||||||
db_email = ""
|
db_email = ""
|
||||||
|
|
@ -28,7 +58,28 @@ async def create_ticket(
|
||||||
db_name = name or ""
|
db_name = name or ""
|
||||||
db_email = email or ""
|
db_email = email or ""
|
||||||
|
|
||||||
ticket = Ticket(
|
# Create ticket with database-compatible values for insertion
|
||||||
|
# Using db.insert() ensures proper serialization of the extra field (TicketExtra)
|
||||||
|
# across all database backends (SQLite, PostgreSQL, CockroachDB)
|
||||||
|
db_ticket = Ticket(
|
||||||
|
id=payment_hash,
|
||||||
|
wallet=wallet,
|
||||||
|
event=event,
|
||||||
|
name=db_name,
|
||||||
|
email=db_email,
|
||||||
|
user_id=user_id,
|
||||||
|
registered=False,
|
||||||
|
paid=False,
|
||||||
|
reg_timestamp=now,
|
||||||
|
time=now,
|
||||||
|
extra=TicketExtra(**extra) if extra else TicketExtra(),
|
||||||
|
)
|
||||||
|
|
||||||
|
await db.insert("events.ticket", db_ticket)
|
||||||
|
|
||||||
|
# Return ticket with original name/email values (not empty strings)
|
||||||
|
# This maintains consistency with how get_ticket() converts empty strings back to None
|
||||||
|
return Ticket(
|
||||||
id=payment_hash,
|
id=payment_hash,
|
||||||
wallet=wallet,
|
wallet=wallet,
|
||||||
event=event,
|
event=event,
|
||||||
|
|
@ -42,20 +93,6 @@ async def create_ticket(
|
||||||
extra=TicketExtra(**extra) if extra else TicketExtra(),
|
extra=TicketExtra(**extra) if extra else TicketExtra(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a dict for database insertion with proper handling of constraints
|
|
||||||
ticket_dict = ticket.dict()
|
|
||||||
ticket_dict["name"] = db_name
|
|
||||||
ticket_dict["email"] = db_email
|
|
||||||
|
|
||||||
await db.execute(
|
|
||||||
"""
|
|
||||||
INSERT INTO events.ticket (id, wallet, event, name, email, user_id, registered, paid, time, reg_timestamp, extra)
|
|
||||||
VALUES (:id, :wallet, :event, :name, :email, :user_id, :registered, :paid, :time, :reg_timestamp, :extra)
|
|
||||||
""",
|
|
||||||
ticket_dict
|
|
||||||
)
|
|
||||||
return ticket
|
|
||||||
|
|
||||||
|
|
||||||
async def update_ticket(ticket: Ticket) -> Ticket:
|
async def update_ticket(ticket: Ticket) -> Ticket:
|
||||||
# Create a new Ticket object with corrected values for database constraints
|
# Create a new Ticket object with corrected values for database constraints
|
||||||
|
|
@ -82,14 +119,7 @@ async def get_ticket(payment_hash: str) -> Optional[Ticket]:
|
||||||
if not row:
|
if not row:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Convert empty strings back to None for the model
|
return Ticket(**_parse_ticket_row(row))
|
||||||
ticket_data = dict(row)
|
|
||||||
if ticket_data.get("name") == "":
|
|
||||||
ticket_data["name"] = None
|
|
||||||
if ticket_data.get("email") == "":
|
|
||||||
ticket_data["email"] = None
|
|
||||||
|
|
||||||
return Ticket(**ticket_data)
|
|
||||||
|
|
||||||
|
|
||||||
async def get_tickets(wallet_ids: str | list[str]) -> list[Ticket]:
|
async def get_tickets(wallet_ids: str | list[str]) -> list[Ticket]:
|
||||||
|
|
@ -98,17 +128,7 @@ async def get_tickets(wallet_ids: str | list[str]) -> list[Ticket]:
|
||||||
q = ",".join([f"'{wallet_id}'" for wallet_id in wallet_ids])
|
q = ",".join([f"'{wallet_id}'" for wallet_id in wallet_ids])
|
||||||
rows = await db.fetchall(f"SELECT * FROM events.ticket WHERE wallet IN ({q})")
|
rows = await db.fetchall(f"SELECT * FROM events.ticket WHERE wallet IN ({q})")
|
||||||
|
|
||||||
tickets = []
|
return [Ticket(**_parse_ticket_row(row)) for row in rows]
|
||||||
for row in rows:
|
|
||||||
# Convert empty strings back to None for the model
|
|
||||||
ticket_data = dict(row)
|
|
||||||
if ticket_data.get("name") == "":
|
|
||||||
ticket_data["name"] = None
|
|
||||||
if ticket_data.get("email") == "":
|
|
||||||
ticket_data["email"] = None
|
|
||||||
tickets.append(Ticket(**ticket_data))
|
|
||||||
|
|
||||||
return tickets
|
|
||||||
|
|
||||||
|
|
||||||
async def get_tickets_by_user_id(user_id: str) -> list[Ticket]:
|
async def get_tickets_by_user_id(user_id: str) -> list[Ticket]:
|
||||||
|
|
@ -118,17 +138,7 @@ async def get_tickets_by_user_id(user_id: str) -> list[Ticket]:
|
||||||
{"user_id": user_id}
|
{"user_id": user_id}
|
||||||
)
|
)
|
||||||
|
|
||||||
tickets = []
|
return [Ticket(**_parse_ticket_row(row)) for row in rows]
|
||||||
for row in rows:
|
|
||||||
# Convert empty strings back to None for the model
|
|
||||||
ticket_data = dict(row)
|
|
||||||
if ticket_data.get("name") == "":
|
|
||||||
ticket_data["name"] = None
|
|
||||||
if ticket_data.get("email") == "":
|
|
||||||
ticket_data["email"] = None
|
|
||||||
tickets.append(Ticket(**ticket_data))
|
|
||||||
|
|
||||||
return tickets
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_ticket(payment_hash: str) -> None:
|
async def delete_ticket(payment_hash: str) -> None:
|
||||||
|
|
@ -200,14 +210,4 @@ async def get_event_tickets(event_id: str) -> list[Ticket]:
|
||||||
{"event": event_id},
|
{"event": event_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
tickets = []
|
return [Ticket(**_parse_ticket_row(row)) for row in rows]
|
||||||
for row in rows:
|
|
||||||
# Convert empty strings back to None for the model
|
|
||||||
ticket_data = dict(row)
|
|
||||||
if ticket_data.get("name") == "":
|
|
||||||
ticket_data["name"] = None
|
|
||||||
if ticket_data.get("email") == "":
|
|
||||||
ticket_data["email"] = None
|
|
||||||
tickets.append(Ticket(**ticket_data))
|
|
||||||
|
|
||||||
return tickets
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue