import { Database } from "bun:sqlite"; import type { TEvent } from "./event.types"; import { transformArray } from "../../util"; const BASE_URL = "https://77th-jsoc.com/service.php?action=get_events"; export type TEventEntity = TEvent & { event_uid: number notification: "new" | "changed" | "deleted" | "done" } export type TEventEntityNew = Omit export class Event implements TEventEntity { static table_name: "events" static createTable (db: Database): void { const query = db.query(`CREATE TABLE IF NOT EXISTS events ( event_uid INTEGER PRIMARY KEY, uid TEXT NOT NULL UNIQUE, title TEXT NOT NULL, date_at DATETIME NOT NULL, time_start TEXT NOT NULL, time_end TEXT NOT NULL, posted_by TEXT NOT NULL, location TEXT NOT NULL, event_type TEXT NOT NULL, link TEXT NOT NULL, description TEXT NOT NULL, timezone TEXT NOT NULL, notification TEXT NOT NULL DEFAULT "new" );`); query.run(); } static insert ( events: TEventEntityNew[], db: Database ) { const insert = db.prepare("INSERT OR REPLACE INTO events (uid, title, date_at, time_start, time_end, posted_by, location, event_type, link, description, timezone, notification) VALUES ($uid, $title, $date_at, $time_start, $time_end, $posted_by, $location, $event_type, $link, $description, $timezone, $notification)"); const insertEvents = db.transaction(events => { for (const event of events) insert.run(event); return events.length; }); const transforedEventArray = transformArray( events ); const count = insertEvents(transforedEventArray); console.log(`Inserted ${count} events`); } static async fetch_events( _year_: number, _month_: number, timezone: number) { const url = `${BASE_URL}&year=${_year_}&month=${_month_}&timezone=${timezone}` const response = await fetch(url, { method: "GET", }); const body = await response.json() as {events: TEvent[] }; const events = body.events.sort( ( a, b ) => ( new Date(a.date_at) < new Date(b.date_at ) ) ? -1 : 1 ); return events; } static get_events (notification: TEventEntity["notification"][] | null, db: Database ) { const whereConditions: string[] = []; if ( notification ) { whereConditions.push( `notification IN ('${ notification.join("', '") }')` ) } const where = ( () => { let str = "WHERE "; if ( whereConditions.length >= 1 ) { str += whereConditions.join(" AND "); } return str; })() const query = db.query(`SELECT * FROM events${ where ? ( " " + where ) : ""};`).as(Event); return query.all(); } event_uid: number; uid: string; title: string; description: string; date_at: string; time_start: string; time_end: string; posted_by: string; location: string; event_type: TEventEntity["event_type"]; timezone: string; link: string; notification: TEventEntity["notification"] constructor(event_uid: number, uid: string, title: string, description: string, date_at: string, time_start: string, time_end: string, posted_by: string, location: string, event_type: TEventEntity["event_type"], timezone: string, link: string, notification: TEventEntity["notification"]) { this.event_uid = event_uid; this.uid = uid; this.title = title; this.description = description; this.date_at = date_at; this.time_start = time_start; this.time_end = time_end; this.posted_by = posted_by; this.location = location; this.event_type = event_type; this.timezone = timezone; this.link = link; this.notification = notification; } syncWithDb ( db: Database ) { const query = db.prepare( `SELECT * FROM ${Event.table_name} WHERE event_uid = $event_uid;`).as(Event); const entity = query.get({$event_uid: this.event_uid }); if ( ! entity ) { throw new Error(`Could not find Event with event_uid ${this.event_uid} in DB!`); } this.uid = entity.uid; this.title = entity.title; this.description = entity.description; this.date_at = entity.date_at; this.time_start = entity.time_start; this.time_end = entity.time_end; this.posted_by = entity.posted_by; this.location = entity.location; this.event_type = entity.event_type; this.timezone = entity.timezone; this.link = entity.link; this.notification = entity.notification; return this; } set_notification ( newValue: TEventEntity["notification"], db: Database ) { const query = db.prepare( `UPDATE events SET notification = $notification WHERE event_uid = $event_uid;` ); query.get({$notification: newValue, $event_uid: this.event_uid }); } }