161 lines
4.0 KiB
Go
161 lines
4.0 KiB
Go
// internal/db/db.go
|
|
package db
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
// DB holds the database connection
|
|
type DB struct {
|
|
*sqlx.DB
|
|
}
|
|
|
|
// New creates a new DB instance
|
|
func New(dbPath string) (*DB, error) {
|
|
// Ensure the directory exists
|
|
dir := filepath.Dir(dbPath)
|
|
if err := ensureDir(dir); err != nil {
|
|
return nil, fmt.Errorf("failed to create database directory: %w", err)
|
|
}
|
|
|
|
// Connect to the database
|
|
db, err := sqlx.Connect("sqlite3", dbPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to database: %w", err)
|
|
}
|
|
|
|
// Set pragmas for better performance
|
|
db.MustExec("PRAGMA journal_mode=WAL;")
|
|
db.MustExec("PRAGMA foreign_keys=ON;")
|
|
|
|
return &DB{db}, nil
|
|
|
|
}
|
|
|
|
// Initialize creates the database schema if it doesn't exist
|
|
func (db *DB) Initialize() error {
|
|
// Create bots table with updated fields
|
|
_, err := db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS bots (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
pubkey TEXT NOT NULL UNIQUE,
|
|
encrypted_privkey TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
display_name TEXT,
|
|
bio TEXT,
|
|
nip05 TEXT,
|
|
zap_address TEXT,
|
|
profile_picture TEXT,
|
|
banner TEXT,
|
|
website TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
owner_pubkey TEXT NOT NULL
|
|
)`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create bots table: %w", err)
|
|
}
|
|
|
|
// Check if website column exists, add it if it doesn't
|
|
var columnExists int
|
|
err = db.Get(&columnExists, `
|
|
SELECT COUNT(*) FROM pragma_table_info('bots') WHERE name = 'website'
|
|
`)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to check if website column exists: %w", err)
|
|
}
|
|
|
|
if columnExists == 0 {
|
|
// Add the website column
|
|
_, err = db.Exec(`ALTER TABLE bots ADD COLUMN website TEXT`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to add website column: %w", err)
|
|
}
|
|
}
|
|
|
|
// Create post_config table
|
|
_, err = db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS post_config (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
bot_id INTEGER NOT NULL,
|
|
hashtags TEXT,
|
|
interval_minutes INTEGER NOT NULL DEFAULT 60,
|
|
post_template TEXT,
|
|
enabled BOOLEAN NOT NULL DEFAULT 0,
|
|
FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
|
|
)`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create post_config table: %w", err)
|
|
}
|
|
|
|
// Create media_config table
|
|
_, err = db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS media_config (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
bot_id INTEGER NOT NULL,
|
|
primary_service TEXT NOT NULL,
|
|
fallback_service TEXT,
|
|
nip94_server_url TEXT,
|
|
blossom_server_url TEXT,
|
|
FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
|
|
)`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create media_config table: %w", err)
|
|
}
|
|
|
|
// Create relays table
|
|
_, err = db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS relays (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
bot_id INTEGER NOT NULL,
|
|
url TEXT NOT NULL,
|
|
read BOOLEAN NOT NULL DEFAULT 1,
|
|
write BOOLEAN NOT NULL DEFAULT 1,
|
|
FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE,
|
|
UNIQUE (bot_id, url)
|
|
)`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create relays table: %w", err)
|
|
}
|
|
|
|
// Create posts table
|
|
_, err = db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS posts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
bot_id INTEGER NOT NULL,
|
|
content_filename TEXT,
|
|
media_url TEXT,
|
|
event_id TEXT,
|
|
status TEXT NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
error TEXT,
|
|
FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
|
|
)`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create posts table: %w", err)
|
|
}
|
|
|
|
_, err = db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS global_relays (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
url TEXT NOT NULL,
|
|
read BOOLEAN NOT NULL DEFAULT 1,
|
|
write BOOLEAN NOT NULL DEFAULT 1,
|
|
owner_pubkey TEXT NOT NULL,
|
|
UNIQUE(url, owner_pubkey)
|
|
)`)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create global_relays table: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ensureDir makes sure the directory exists
|
|
func ensureDir(dir string) error {
|
|
return nil // This will be implemented in a file utility package
|
|
} |