micrach/db/db.go

104 lines
2.0 KiB
Go
Raw Permalink Normal View History

2021-08-26 16:16:50 +03:00
package db
import (
"context"
2026-07-15 22:24:28 +03:00
"errors"
2021-08-26 16:16:50 +03:00
"log"
"path/filepath"
"strconv"
"strings"
2021-08-26 16:16:50 +03:00
Config "micrach/config"
Files "micrach/files"
2021-08-26 16:16:50 +03:00
2026-07-15 22:24:28 +03:00
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool"
2021-08-26 16:16:50 +03:00
)
var Pool *pgxpool.Pool
type MigrationsMap map[int]string
type Migration struct {
ID int
Name string
}
2026-07-15 22:24:28 +03:00
func Init(ctx context.Context) {
2021-08-26 16:16:50 +03:00
var err error
2026-07-15 22:24:28 +03:00
Pool, err = pgxpool.New(ctx, Config.Db.Url)
2021-08-26 16:16:50 +03:00
if err != nil {
log.Println("database - offline")
log.Panicln(err)
}
log.Println("database - online")
}
2026-07-15 22:24:28 +03:00
func Migrate(ctx context.Context) {
dbMigrations := getDbMigrations(ctx)
sqlMigrations := Files.GetFullFilePathsInFolder("migrations")
for _, m := range sqlMigrations {
filename := filepath.Base(m)
splitted := strings.Split(filename, "-")
id, err := strconv.Atoi(splitted[0])
if err != nil {
log.Panicln(err)
}
// Get name without extension
name := strings.Split(splitted[1], ".")[0]
_, isMigrationInDb := dbMigrations[id]
if !isMigrationInDb {
2022-01-21 02:24:30 +03:00
sql := Files.ReadFileText(m)
2026-07-15 22:24:28 +03:00
runMigration(ctx, id, name, sql)
2022-05-18 10:23:35 +03:00
log.Println("migration - " + name + " - online")
}
}
2022-05-18 10:23:35 +03:00
log.Println("migrations - online")
}
2026-07-15 22:24:28 +03:00
func runMigration(ctx context.Context, mid int, mname, msql string) {
_, err := Pool.Exec(ctx, msql)
2022-01-21 02:24:30 +03:00
if err != nil {
log.Panicln(err)
}
2026-07-15 22:24:28 +03:00
_, err = Pool.Exec(ctx, `INSERT INTO migrations (id, name) VALUES ($1, $2)`, mid, mname)
2022-01-21 02:24:30 +03:00
if err != nil {
log.Panicln(err)
}
}
2026-07-15 22:24:28 +03:00
func getDbMigrations(ctx context.Context) MigrationsMap {
rows, err := Pool.Query(ctx, `SELECT id, name FROM migrations`)
if err != nil {
if isUndefinedTable(err) {
return make(MigrationsMap)
}
log.Panicln(err)
}
2026-07-15 22:24:28 +03:00
defer rows.Close()
migrationsMap := make(MigrationsMap)
for rows.Next() {
var m Migration
err = rows.Scan(&m.ID, &m.Name)
if err != nil {
log.Panicln(err)
}
migrationsMap[m.ID] = m.Name
}
2026-07-15 22:24:28 +03:00
if err := rows.Err(); err != nil {
log.Panicln(err)
}
return migrationsMap
}
2022-05-18 10:23:35 +03:00
2026-07-15 22:24:28 +03:00
func isUndefinedTable(err error) bool {
var pgErr *pgconn.PgError
return errors.As(err, &pgErr) && pgErr.Code == "42P01"
2022-05-18 10:23:35 +03:00
}