feat: backend core - auth, user, role, permission, device, webhook, monitoring, cache, repository, service, middleware, API handlers
This commit is contained in:
117
tools/sqlite_snapshot_check.go
Normal file
117
tools/sqlite_snapshot_check.go
Normal file
@@ -0,0 +1,117 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type snapshot struct {
|
||||
GeneratedAt string `json:"generated_at"`
|
||||
Path string `json:"path"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
Existing []string `json:"existing_tables"`
|
||||
Missing []string `json:"missing_tables"`
|
||||
Tables map[string]int64 `json:"tables"`
|
||||
SampleUsers []string `json:"sample_users"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
dbPath := flag.String("db", "./data/user_management.db", "sqlite database path")
|
||||
jsonOutput := flag.Bool("json", false, "emit snapshot as JSON")
|
||||
flag.Parse()
|
||||
|
||||
info, err := os.Stat(*dbPath)
|
||||
if err != nil {
|
||||
log.Fatalf("stat db failed: %v", err)
|
||||
}
|
||||
|
||||
db, err := gorm.Open(sqlite.Open(*dbPath), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatalf("open db failed: %v", err)
|
||||
}
|
||||
|
||||
tableNames := []string{
|
||||
"users",
|
||||
"roles",
|
||||
"permissions",
|
||||
"user_roles",
|
||||
"role_permissions",
|
||||
"devices",
|
||||
"login_logs",
|
||||
"operation_logs",
|
||||
"social_accounts",
|
||||
"webhooks",
|
||||
"webhook_deliveries",
|
||||
"password_histories",
|
||||
}
|
||||
|
||||
var existingTables []string
|
||||
if err := db.Raw("SELECT name FROM sqlite_master WHERE type = 'table'").Scan(&existingTables).Error; err != nil {
|
||||
log.Fatalf("load sqlite table names failed: %v", err)
|
||||
}
|
||||
sort.Strings(existingTables)
|
||||
existingTableSet := make(map[string]struct{}, len(existingTables))
|
||||
for _, tableName := range existingTables {
|
||||
existingTableSet[tableName] = struct{}{}
|
||||
}
|
||||
|
||||
tableCounts := make(map[string]int64, len(tableNames))
|
||||
missingTables := make([]string, 0)
|
||||
for _, tableName := range tableNames {
|
||||
if _, ok := existingTableSet[tableName]; !ok {
|
||||
missingTables = append(missingTables, tableName)
|
||||
continue
|
||||
}
|
||||
var count int64
|
||||
if err := db.Raw("SELECT COUNT(*) FROM " + tableName).Scan(&count).Error; err != nil {
|
||||
log.Fatalf("count table %s failed: %v", tableName, err)
|
||||
}
|
||||
tableCounts[tableName] = count
|
||||
}
|
||||
|
||||
var sampleUsers []string
|
||||
if err := db.Raw("SELECT username FROM users ORDER BY id ASC LIMIT 10").Scan(&sampleUsers).Error; err != nil {
|
||||
log.Fatalf("load sample users failed: %v", err)
|
||||
}
|
||||
sort.Strings(sampleUsers)
|
||||
|
||||
result := snapshot{
|
||||
GeneratedAt: time.Now().Format(time.RFC3339),
|
||||
Path: *dbPath,
|
||||
FileSize: info.Size(),
|
||||
Existing: existingTables,
|
||||
Missing: missingTables,
|
||||
Tables: tableCounts,
|
||||
SampleUsers: sampleUsers,
|
||||
}
|
||||
|
||||
if *jsonOutput {
|
||||
encoder := json.NewEncoder(os.Stdout)
|
||||
encoder.SetIndent("", " ")
|
||||
if err := encoder.Encode(result); err != nil {
|
||||
log.Fatalf("encode snapshot failed: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("snapshot generated_at=%s\n", result.GeneratedAt)
|
||||
fmt.Printf("path=%s size=%d\n", result.Path, result.FileSize)
|
||||
for _, tableName := range tableNames {
|
||||
if count, ok := result.Tables[tableName]; ok {
|
||||
fmt.Printf("%s=%d\n", tableName, count)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("%s=missing\n", tableName)
|
||||
}
|
||||
fmt.Printf("sample_users=%v\n", result.SampleUsers)
|
||||
}
|
||||
Reference in New Issue
Block a user