Feat: migration on startup
This commit is contained in:
@@ -19,3 +19,4 @@
|
||||
### FIX:
|
||||
- bot responding (or haninging) blocks everything; +
|
||||
- programm requires history folder, but it is .gitignore; +
|
||||
- at first run chat table does not exist; run migrations sql on startup; +
|
||||
|
||||
3
bot.go
3
bot.go
@@ -276,10 +276,9 @@ func init() {
|
||||
if err := os.MkdirAll(historyDir, os.ModePerm); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store = storage.NewProviderSQL("test.db")
|
||||
// defer file.Close()
|
||||
logger = slog.New(slog.NewTextHandler(file, nil))
|
||||
logger.Info("test msg")
|
||||
store = storage.NewProviderSQL("test.db", logger)
|
||||
// https://github.com/coreydaley/ggerganov-llama.cpp/blob/master/examples/server/README.md
|
||||
// load all chats in memory
|
||||
loadHistoryChats()
|
||||
|
||||
59
storage/migrate.go
Normal file
59
storage/migrate.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed migrations/*
|
||||
var migrationsFS embed.FS
|
||||
|
||||
func (p *ProviderSQL) Migrate() {
|
||||
// Get the embedded filesystem
|
||||
migrationsDir, err := fs.Sub(migrationsFS, "migrations")
|
||||
if err != nil {
|
||||
p.logger.Error("Failed to get embedded migrations directory;", "error", err)
|
||||
}
|
||||
// List all .up.sql files
|
||||
files, err := migrationsFS.ReadDir("migrations")
|
||||
if err != nil {
|
||||
p.logger.Error("Failed to read migrations directory;", "error", err)
|
||||
}
|
||||
// Execute each .up.sql file
|
||||
for _, file := range files {
|
||||
if strings.HasSuffix(file.Name(), ".up.sql") {
|
||||
err := p.executeMigration(migrationsDir, file.Name())
|
||||
if err != nil {
|
||||
p.logger.Error("Failed to execute migration %s: %v", file.Name(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
p.logger.Info("All migrations executed successfully!")
|
||||
}
|
||||
|
||||
func (p *ProviderSQL) executeMigration(migrationsDir fs.FS, fileName string) error {
|
||||
// Open the migration file
|
||||
migrationFile, err := migrationsDir.Open(fileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open migration file %s: %w", fileName, err)
|
||||
}
|
||||
defer migrationFile.Close()
|
||||
// Read the migration file content
|
||||
migrationContent, err := fs.ReadFile(migrationsDir, fileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read migration file %s: %w", fileName, err)
|
||||
}
|
||||
// Execute the migration content
|
||||
return p.executeSQL(migrationContent)
|
||||
}
|
||||
|
||||
func (p *ProviderSQL) executeSQL(sqlContent []byte) error {
|
||||
// Connect to the database (example using a simple connection)
|
||||
_, err := p.db.Exec(string(sqlContent))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute SQL: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
CREATE TABLE chat (
|
||||
CREATE TABLE IF NOT EXISTS chat (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
msgs TEXT NOT NULL, -- Store messages as a comma-separated string
|
||||
|
||||
@@ -2,7 +2,7 @@ package storage
|
||||
|
||||
import (
|
||||
"elefant/models"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
_ "github.com/glebarez/go-sqlite"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@@ -17,7 +17,8 @@ type ChatHistory interface {
|
||||
}
|
||||
|
||||
type ProviderSQL struct {
|
||||
db *sqlx.DB
|
||||
db *sqlx.DB
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (p ProviderSQL) ListChats() ([]models.Chat, error) {
|
||||
@@ -60,13 +61,13 @@ func (p ProviderSQL) RemoveChat(id uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func NewProviderSQL(dbPath string) ChatHistory {
|
||||
func NewProviderSQL(dbPath string, logger *slog.Logger) ChatHistory {
|
||||
db, err := sqlx.Open("sqlite", dbPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// get SQLite version
|
||||
res := db.QueryRow("select sqlite_version()")
|
||||
fmt.Println(res)
|
||||
return ProviderSQL{db: db}
|
||||
p := ProviderSQL{db: db, logger: logger}
|
||||
p.Migrate()
|
||||
return p
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user