butterrobot/internal/migration/migrations.go
Felipe M. 72c6dd6982
All checks were successful
ci/woodpecker/tag/release Pipeline was successful
feat: remindme plugin
2025-04-22 11:29:39 +02:00

128 lines
2.9 KiB
Go

package migration
import (
"database/sql"
"golang.org/x/crypto/bcrypt"
)
func init() {
// Register migrations
Register(1, "Initial schema with bcrypt passwords", migrateInitialSchemaUp, migrateInitialSchemaDown)
Register(2, "Add reminders table", migrateRemindersUp, migrateRemindersDown)
}
// Initial schema creation with bcrypt passwords - version 1
func migrateInitialSchemaUp(db *sql.DB) error {
// Create channels table
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS channels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT NOT NULL,
platform_channel_id TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT 0,
channel_raw TEXT NOT NULL,
UNIQUE(platform, platform_channel_id)
)
`)
if err != nil {
return err
}
// Create channel_plugin table
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS channel_plugin (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channel_id INTEGER NOT NULL,
plugin_id TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT 0,
config TEXT NOT NULL DEFAULT '{}',
UNIQUE(channel_id, plugin_id),
FOREIGN KEY (channel_id) REFERENCES channels (id) ON DELETE CASCADE
)
`)
if err != nil {
return err
}
// Create users table with bcrypt passwords
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL
)
`)
if err != nil {
return err
}
// Create default admin user with bcrypt password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte("admin"), 12)
if err != nil {
return err
}
// Check if users table is empty before inserting
var count int
err = db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
if err != nil {
return err
}
if count == 0 {
_, err = db.Exec(
"INSERT INTO users (username, password) VALUES (?, ?)",
"admin", string(hashedPassword),
)
if err != nil {
return err
}
}
return nil
}
func migrateInitialSchemaDown(db *sql.DB) error {
// Drop tables in reverse order of dependencies
_, err := db.Exec(`DROP TABLE IF EXISTS channel_plugin`)
if err != nil {
return err
}
_, err = db.Exec(`DROP TABLE IF EXISTS channels`)
if err != nil {
return err
}
_, err = db.Exec(`DROP TABLE IF EXISTS users`)
if err != nil {
return err
}
return nil
}
// Add reminders table - version 2
func migrateRemindersUp(db *sql.DB) error {
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS reminders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT NOT NULL,
channel_id TEXT NOT NULL,
message_id TEXT NOT NULL,
reply_to_id TEXT NOT NULL,
user_id TEXT NOT NULL,
username TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
trigger_at TIMESTAMP NOT NULL,
content TEXT NOT NULL,
processed BOOLEAN NOT NULL DEFAULT 0
)
`)
return err
}
func migrateRemindersDown(db *sql.DB) error {
_, err := db.Exec(`DROP TABLE IF EXISTS reminders`)
return err
}