feat: automate business upgrades and sync reviewed frontend
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
// Package migrations contains the reviewed SQL bundled with the application.
|
||||
// SQL execution and database lifecycle remain in internal/data.
|
||||
package migrations
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed legacy-framework.sql
|
||||
var frameworkSQL string
|
||||
|
||||
//go:embed cleanup-legacy.sql
|
||||
var cleanupSQL string
|
||||
|
||||
func FrameworkSQL() string { return frameworkSQL }
|
||||
func CleanupSQL() string { return cleanupSQL }
|
||||
|
||||
// Statements understands the DELIMITER directives in the bundled, trusted
|
||||
// scripts. It does not split stored-procedure bodies on their semicolons.
|
||||
func Statements(source string) ([]string, error) {
|
||||
delimiter := ";"
|
||||
var buffer strings.Builder
|
||||
var statements []string
|
||||
for _, line := range strings.Split(source, "\n") {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if strings.HasPrefix(trimmed, "DELIMITER ") {
|
||||
delimiter = strings.TrimSpace(strings.TrimPrefix(trimmed, "DELIMITER "))
|
||||
if delimiter == "" {
|
||||
return nil, fmt.Errorf("empty SQL delimiter")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if buffer.Len() == 0 && (trimmed == "" || strings.HasPrefix(trimmed, "--")) {
|
||||
continue
|
||||
}
|
||||
buffer.WriteString(line)
|
||||
buffer.WriteByte('\n')
|
||||
if strings.HasSuffix(trimmed, delimiter) {
|
||||
statement := strings.TrimSuffix(strings.TrimSpace(buffer.String()), delimiter)
|
||||
statements = append(statements, statement)
|
||||
buffer.Reset()
|
||||
}
|
||||
}
|
||||
if strings.TrimSpace(buffer.String()) != "" {
|
||||
return nil, fmt.Errorf("unterminated SQL script")
|
||||
}
|
||||
return statements, nil
|
||||
}
|
||||
|
||||
func CleanupTables() []string {
|
||||
block := regexp.MustCompile(`(?s)INSERT INTO _sw_cleanup_targets_20261106\([^\n]+\) VALUES\s*(.*?);`).FindStringSubmatch(cleanupSQL)
|
||||
if len(block) != 2 {
|
||||
panic("cleanup table manifest is missing")
|
||||
}
|
||||
var names []string
|
||||
for _, match := range regexp.MustCompile(`\('([a-z0-9_]+)'`).FindAllStringSubmatch(block[1], -1) {
|
||||
names = append(names, match[1])
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
func LegacyArchives() map[string]string {
|
||||
archives := map[string]string{}
|
||||
for _, match := range regexp.MustCompile("`([a-z0-9_]+)` TO `(legacy_sw_20261103_[a-z0-9_]+)`").FindAllStringSubmatch(frameworkSQL, -1) {
|
||||
archives[match[1]] = match[2]
|
||||
}
|
||||
return archives
|
||||
}
|
||||
|
||||
func FrameworkCreatedTables() []string {
|
||||
var names []string
|
||||
for _, match := range regexp.MustCompile("(?m)^CREATE TABLE `?([a-z0-9_]+)`? ").FindAllStringSubmatch(frameworkSQL, -1) {
|
||||
names = append(names, match[1])
|
||||
}
|
||||
return names
|
||||
}
|
||||
Reference in New Issue
Block a user