package main import ( "database/sql" _ "github.com/mattn/go-sqlite3" ) type Database struct { db *sql.DB } func NewDatabase(path string) (*Database, error) { db, err := sql.Open("sqlite3", path+"?_journal_mode=WAL&_busy_timeout=5000") if err != nil { return nil, err } d := &Database{db: db} if err = d.migrate(); err != nil { db.Close() return nil, err } return d, nil } func (d *Database) Close() error { return d.db.Close() } func (d *Database) migrate() error { for _, q := range []string{ `CREATE TABLE IF NOT EXISTS spaces ( user_mxid TEXT PRIMARY KEY, space_room_id TEXT NOT NULL )`, `CREATE TABLE IF NOT EXISTS bridges ( ntfy_topic TEXT PRIMARY KEY, matrix_room_id TEXT NOT NULL )`, } { if _, err := d.db.Exec(q); err != nil { return err } } return nil } func (d *Database) GetSpaceRoomID(userMXID string) (string, error) { var roomID string err := d.db.QueryRow("SELECT space_room_id FROM spaces WHERE user_mxid = ?", userMXID).Scan(&roomID) if err == sql.ErrNoRows { return "", nil } return roomID, err } func (d *Database) SetSpaceRoomID(userMXID, spaceRoomID string) error { _, err := d.db.Exec( "INSERT OR REPLACE INTO spaces (user_mxid, space_room_id) VALUES (?, ?)", userMXID, spaceRoomID, ) return err } func (d *Database) GetAllBridges() (map[string]string, error) { rows, err := d.db.Query("SELECT ntfy_topic, matrix_room_id FROM bridges") if err != nil { return nil, err } defer rows.Close() bridges := make(map[string]string) for rows.Next() { var topic, roomID string if err := rows.Scan(&topic, &roomID); err != nil { return nil, err } bridges[topic] = roomID } return bridges, rows.Err() } func (d *Database) GetBridgeByRoom(matrixRoomID string) (string, error) { var topic string err := d.db.QueryRow("SELECT ntfy_topic FROM bridges WHERE matrix_room_id = ?", matrixRoomID).Scan(&topic) if err == sql.ErrNoRows { return "", nil } return topic, err } func (d *Database) GetBridgeByTopic(ntfyTopic string) (string, error) { var roomID string err := d.db.QueryRow("SELECT matrix_room_id FROM bridges WHERE ntfy_topic = ?", ntfyTopic).Scan(&roomID) if err == sql.ErrNoRows { return "", nil } return roomID, err } func (d *Database) SetBridge(ntfyTopic, matrixRoomID string) error { _, err := d.db.Exec( "INSERT OR REPLACE INTO bridges (ntfy_topic, matrix_room_id) VALUES (?, ?)", ntfyTopic, matrixRoomID, ) return err }