(data): Schema and object model.

This commit is contained in:
2025-06-06 22:27:57 +10:00
parent 0adccaae02
commit 5efcdd6709
2 changed files with 298 additions and 0 deletions

View File

@@ -259,6 +259,31 @@ CREATE TABLE subscriber_events (
); );
CREATE VIEW event_details AS
SELECT
events.event_id AS event_id,
events.user_id AS user_id,
events.document_id AS document_id,
events.user_name AS user_name,
events.event_type AS event_type,
events.occurred_at AS occurred_at,
events.created_at AS created_at,
plain_events.message AS plain_message,
raid_events.visitor_count AS raid_visitor_count,
cheer_events.amount AS cheer_amount,
cheer_events.cheer_type AS cheer_type,
cheer_events.message AS cheer_message,
subscriber_events.subscribed_length AS subscriber_length,
subscriber_events.tier AS subscriber_tier,
subscriber_events.message AS subscriber_message,
FROM
events
LEFT JOIN plain_events USING (event_id)
LEFT JOIN raid_events USING (event_id)
LEFT JOIN cheer_events USING (event_id)
LEFT JOIN subscriber_events USING (event_id)
ORDER BY events.occurred_at ASC;
-- }}} -- }}}
-- Specimens {{{ -- Specimens {{{

273
src/datamodels.py Normal file
View File

@@ -0,0 +1,273 @@
from enum import Enum
from data import Registry, RowModel, Table, RegisterEnum
from data.columns import Integer, String, Timestamp, Column
class EventType(Enum):
SUBSCRIBER = 'subscriber',
RAID = 'raid',
CHEER = 'cheer',
PLAIN = 'plain',
class DataModel(Registry):
_EventType = RegisterEnum(EventType, 'EventType')
class UserPreferences(RowModel):
"""
Schema
------
CREATE TABLE user_preferences (
profileid INTEGER PRIMARY KEY REFERENCES user_profiles (profileid) ON DELETE CASCADE,
twitch_name TEXT,
preferences TEXT
);
"""
_tablename_ = 'user_preferences'
_cache_ = {}
profileid = Integer(primary=True)
twitch_name = String()
preferences = String()
class Dreamer(RowModel):
"""
Schema
------
CREATE VIEW dreamers AS
SELECT
user_profiles.profileid AS user_id,
user_preferences.twitch_name AS name,
profiles_twitch.userid AS twitch_id,
user_preferences.preferences AS preferences,
user_profiles.created_at AS created_at
FROM
user_profiles
LEFT JOIN profiles_twitch USING (profileid)
LEFT JOIN user_preferences USING (profileid);
"""
_tablename_ = ''
_readonly_ = True
profileid = Integer(primary=True)
name = String()
twitch_id = Integer()
preferences = String()
created_at = Timestamp()
class Transaction(RowModel):
"""
Schema
------
CREATE TABLE user_wallet (
transaction_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE,
amount INTEGER NOT NULL,
description TEXT NOT NULL,
reference TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
"""
_tablename_ = 'user_wallet'
_cache_ = {}
_immutable_ = True
transaction_id = Integer(primary=True)
user_id = Integer()
amount = Integer()
description = String()
reference = String()
created_at = Timestamp()
class StampType(RowModel):
"""
Schema
------
CREATE TABLE stamp_types (
stamp_type_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
stamp_type_name TEXT UNIQUE NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
"""
_tablename_ = 'stamp_types'
_cache_ = {}
stamp_type_id = Integer(primary=True)
stamp_type_name = String()
created_at = Timestamp()
class Document(RowModel):
"""
Schema
------
CREATE TABLE documents (
document_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
document_data VARCHAR NOT NULL,
seal INTEGER NOT NULL,
metadata TEXT
);
"""
_tablename_ = 'documents'
_cache_ = {}
document_id = Integer(primary=True)
document_data = Column()
seal = Integer()
metadata = String()
class DocumentStamp(RowModel):
"""
Schema
------
CREATE TABLE document_stamps (
stamp_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
document_id INTEGER NOT NULL REFERENCES documents (document_id) ON DELETE CASCADE,
stamp_type INTEGER NOT NULL REFERENCES stamp_types (stamp_type_id) ON DELETE CASCADE,
position_x INTEGER NOT NULL,
position_y INTEGER NOT NULL,
rotation REAL NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
"""
_tablename_ = 'document_stamps'
_cache_ = {}
stamp_id = Integer(primary=True)
document_id = Integer()
stamp_type = Integer()
position_x = Integer()
position_y = Integer()
rotation: Column[float] = Column()
created_at = Timestamp()
class Events(RowModel):
"""
Schema
------
CREATE TABLE events (
event_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE,
document_id INTEGER REFERENCES documents (document_id) ON DELETE SET NULL,
user_name TEXT,
event_type EventType NOT NULL,
occurred_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (event_id, event_type)
);
"""
_tablename_ = 'events'
_cache_ = {}
event_id = Integer(primary=True)
user_id = Integer()
document_id = Integer()
user_name = String()
event_type: Column[EventType] = Column()
occured_at = Timestamp()
created_at = Timestamp()
plain_events = Table('plain_events')
raid_events = Table('raid_events')
cheer_events = Table('cheer_events')
subscriber_events = Table('subscriber_events')
class EventDetails(RowModel):
"""
Schema
------
CREATE TABLE plain_events (
event_id integer PRIMARY KEY,
event_type EventType NOT NULL DEFAULT 'plain' CHECK (event_type = 'plain'),
message TEXT NOT NULL,
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
);
CREATE TABLE raid_events (
event_id integer PRIMARY KEY,
event_type EventType NOT NULL DEFAULT 'raid' CHECK (event_type = 'raid'),
visitor_count INTEGER NOT NULL,
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
);
CREATE TABLE cheer_events (
event_id integer PRIMARY KEY,
event_type EventType NOT NULL DEFAULT 'cheer' CHECK (event_type = 'cheer'),
amount INTEGER NOT NULL,
cheer_type TEXT,
message TEXT,
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
);
CREATE TABLE subscriber_events (
event_id integer PRIMARY KEY,
event_type EventType NOT NULL DEFAULT 'subscriber' CHECK (event_type = 'subscriber'),
subscribed_length INTEGER NOT NULL,
tier INTEGER NOT NULL,
message TEXT,
FOREIGN KEY (event_id, event_type) REFERENCES events (event_id, event_type)
);
CREATE VIEW event_details AS
SELECT
events.event_id AS event_id,
events.user_id AS user_id,
events.document_id AS document_id,
events.user_name AS user_name,
events.event_type AS event_type,
events.occurred_at AS occurred_at,
events.created_at AS created_at,
plain_events.message AS plain_message,
raid_events.visitor_count AS raid_visitor_count,
cheer_events.amount AS cheer_amount,
cheer_events.cheer_type AS cheer_type,
cheer_events.message AS cheer_message,
subscriber_events.subscribed_length AS subscriber_length,
subscriber_events.tier AS subscriber_tier,
subscriber_events.message AS subscriber_message,
FROM
events
LEFT JOIN plain_events USING (event_id)
LEFT JOIN raid_events USING (event_id)
LEFT JOIN cheer_events USING (event_id)
LEFT JOIN subscriber_events USING (event_id)
ORDER BY events.occurred_at ASC;
"""
_tablename_ = 'event_details'
_readonly_ = True
event_id = Integer(primary=True)
user_id = Integer()
document_id = Integer()
user_name = String()
event_type: Column[EventType] = Column()
occurred_at = Timestamp()
created_at = Timestamp()
plain_message = String()
raid_visitor_count = Integer()
cheer_amount = Integer()
cheer_type = String()
cheer_message = String()
subscriber_length = Integer()
subscriber_tier = Integer()
subscriber_message = String()
class Specimen(RowModel):
"""
Schema
------
CREATE TABLE user_specimens (
specimen_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
owner_id INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE,
born_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
forgotten_at TIMESTAMPTZ
);
"""
_tablename_ = 'user_specimens'
_cache_ = {}
specimen_id = Integer(primary=True)
owner_id = Integer(primary=True)
born_at = Timestamp()
forgotten_at = Timestamp()