feat: services: crus, migrations

This commit is contained in:
2025-01-04 01:36:01 +07:00
parent 0c9f60bba5
commit 081ebf2b28
22 changed files with 533 additions and 63 deletions

View File

@@ -0,0 +1,36 @@
package services
import (
"app/internal/dialogs"
"fmt"
)
func InsertDefaultData() {
insertPosts()
}
func InsertDefaultEntityData[T any](service Service[T], entities []T) {
for _, item := range entities {
createdItem, err := service.Create(item)
if err != nil {
dialogs.ErrorDialog("Ошибка при вставке данных по умолчанию", fmt.Sprintf("Произошла ошибка при вставке значения %#v: %s", createdItem, err))
}
}
}
func insertPosts() {
InsertDefaultEntityData(&PostService{}, []Post{
{
Id: 1,
Text: "Жителям Кузбасса запретили болеть.",
},
{
Id: 2,
Text: "⚡️⚡️⚡️Дома будут летать.",
},
{
Id: 3,
Text: "В Кузбассе начали строить дома выше, чтобы жители были ближе к богу и солнцу.",
},
})
}

View File

@@ -0,0 +1,116 @@
package services
import (
"app/internal/database"
"app/internal/models"
"context"
"crypto/sha256"
"fmt"
"github.com/wailsapp/wails/v3/pkg/application"
"io"
"log/slog"
"os"
)
type Migrator struct{}
var MigratorService = application.NewService(&Migrator{})
var db = database.GetInstance()
func CalculateFileSha256Checksum(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
hasher := sha256.New()
if _, err := io.Copy(hasher, file); err != nil {
return "", err
}
return fmt.Sprintf("%x", hasher.Sum(nil)), nil
}
func dropDatabase() error {
_ = database.Shutdown()
if _, err := os.Stat(database.Path); err == nil {
err := os.Remove(database.Path)
if err != nil {
return err
}
}
return nil
}
func createDatabase(entities ...any) error {
// Close current connections and create new database
err := dropDatabase()
if err != nil {
return err
}
db = database.GetInstance()
err = db.AutoMigrate(entities...)
if err != nil {
return err
}
InsertDefaultData()
return nil
}
func Migrate(entities ...any) error {
hashBeforeMigration, err := CalculateFileSha256Checksum(database.Path)
slog.Info("Calculating hash...")
if err != nil {
return err
}
slog.Info("Apply migrations")
err = db.AutoMigrate(entities...)
if err != nil {
slog.Info("Error occurred while migrations: %s. Recreate database...", err)
if err = createDatabase(entities...); err != nil {
slog.Error("Error occurred again: %s. Panic!", err)
return err
}
} else {
slog.Info("Calculating hash after migrations...")
var hashAfterMigration string
hashAfterMigration, err = CalculateFileSha256Checksum(database.Path)
if err != nil {
slog.Error("Failed to calc hash: %s", err)
return err
}
if hashAfterMigration != hashBeforeMigration {
slog.Info("Hashes before and after migrations are different. Recreate database...")
err = createDatabase(entities...)
if err != nil {
slog.Error("Failed to create new database: %s", err)
return err
}
}
}
slog.Info("Migrations proceeded")
return nil
}
func (migrator *Migrator) OnStartup(ctx context.Context, options application.ServiceOptions) error {
return Migrate(models.Entities...)
}
func (migrator *Migrator) OnShutdown() {
err := database.Shutdown()
if err != nil {
panic(err)
}
}

View File

@@ -4,7 +4,6 @@ import (
"app/internal/dal"
"app/internal/models"
"errors"
"gorm.io/gen/field"
"gorm.io/gorm"
)

View File

@@ -0,0 +1,10 @@
package services
type Service[T any] interface {
GetAll() ([]*T, error)
GetById(id uint) (*T, error)
Create(item T) (T, error)
Update(item T) (T, error)
Delete(item T) (T, error)
Count() (int64, error)
}

View File

@@ -0,0 +1,7 @@
package services
import "github.com/wailsapp/wails/v3/pkg/application"
var ExportedServices = []application.Service{
application.NewService(&PostService{}),
}