mirror of https://github.com/pikami/cosmium.git
147 lines
3.7 KiB
Go
147 lines
3.7 KiB
Go
package repositories
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
"reflect"
|
|
|
|
"github.com/pikami/cosmium/api/config"
|
|
"github.com/pikami/cosmium/internal/logger"
|
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
|
)
|
|
|
|
var storedProcedures = []repositorymodels.StoredProcedure{}
|
|
var triggers = []repositorymodels.Trigger{}
|
|
var userDefinedFunctions = []repositorymodels.UserDefinedFunction{}
|
|
var storeState = repositorymodels.State{
|
|
Databases: make(map[string]repositorymodels.Database),
|
|
Collections: make(map[string]map[string]repositorymodels.Collection),
|
|
Documents: make(map[string]map[string]map[string]repositorymodels.Document),
|
|
}
|
|
|
|
func InitializeRepository() {
|
|
if config.Config.InitialDataFilePath != "" {
|
|
LoadStateFS(config.Config.InitialDataFilePath)
|
|
return
|
|
}
|
|
|
|
if config.Config.PersistDataFilePath != "" {
|
|
stat, err := os.Stat(config.Config.PersistDataFilePath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if stat.IsDir() {
|
|
logger.Error("Argument '-Persist' must be a path to file, not a directory.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
LoadStateFS(config.Config.PersistDataFilePath)
|
|
return
|
|
}
|
|
}
|
|
|
|
func LoadStateFS(filePath string) {
|
|
data, err := os.ReadFile(filePath)
|
|
if err != nil {
|
|
log.Fatalf("Error reading state JSON file: %v", err)
|
|
return
|
|
}
|
|
|
|
var state repositorymodels.State
|
|
if err := json.Unmarshal(data, &state); err != nil {
|
|
log.Fatalf("Error unmarshalling state JSON: %v", err)
|
|
return
|
|
}
|
|
|
|
logger.Info("Loaded state:")
|
|
logger.Infof("Databases: %d\n", getLength(state.Databases))
|
|
logger.Infof("Collections: %d\n", getLength(state.Collections))
|
|
logger.Infof("Documents: %d\n", getLength(state.Documents))
|
|
|
|
storeState = state
|
|
|
|
ensureStoreStateNoNullReferences()
|
|
}
|
|
|
|
func SaveStateFS(filePath string) {
|
|
data, err := json.MarshalIndent(storeState, "", "\t")
|
|
if err != nil {
|
|
logger.Errorf("Failed to save state: %v\n", err)
|
|
return
|
|
}
|
|
|
|
os.WriteFile(filePath, data, os.ModePerm)
|
|
|
|
logger.Info("Saved state:")
|
|
logger.Infof("Databases: %d\n", getLength(storeState.Databases))
|
|
logger.Infof("Collections: %d\n", getLength(storeState.Collections))
|
|
logger.Infof("Documents: %d\n", getLength(storeState.Documents))
|
|
}
|
|
|
|
func GetState() repositorymodels.State {
|
|
return storeState
|
|
}
|
|
|
|
func getLength(v interface{}) int {
|
|
switch v.(type) {
|
|
case repositorymodels.Database,
|
|
repositorymodels.Collection,
|
|
repositorymodels.Document:
|
|
return 1
|
|
}
|
|
|
|
rv := reflect.ValueOf(v)
|
|
if rv.Kind() != reflect.Map {
|
|
return -1
|
|
}
|
|
|
|
count := 0
|
|
for _, key := range rv.MapKeys() {
|
|
if rv.MapIndex(key).Kind() == reflect.Map {
|
|
count += getLength(rv.MapIndex(key).Interface())
|
|
} else {
|
|
count++
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
func ensureStoreStateNoNullReferences() {
|
|
if storeState.Databases == nil {
|
|
storeState.Databases = make(map[string]repositorymodels.Database)
|
|
}
|
|
|
|
if storeState.Collections == nil {
|
|
storeState.Collections = make(map[string]map[string]repositorymodels.Collection)
|
|
}
|
|
|
|
if storeState.Documents == nil {
|
|
storeState.Documents = make(map[string]map[string]map[string]repositorymodels.Document)
|
|
}
|
|
|
|
for database := range storeState.Databases {
|
|
if storeState.Collections[database] == nil {
|
|
storeState.Collections[database] = make(map[string]repositorymodels.Collection)
|
|
}
|
|
|
|
if storeState.Documents[database] == nil {
|
|
storeState.Documents[database] = make(map[string]map[string]repositorymodels.Document)
|
|
}
|
|
|
|
for collection := range storeState.Collections[database] {
|
|
if storeState.Documents[database][collection] == nil {
|
|
storeState.Documents[database][collection] = make(map[string]repositorymodels.Document)
|
|
}
|
|
|
|
for document := range storeState.Documents[database][collection] {
|
|
if storeState.Documents[database][collection][document] == nil {
|
|
delete(storeState.Documents[database][collection], document)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|