-
Notifications
You must be signed in to change notification settings - Fork 0
Persistance #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Persistance #12
Changes from all commits
dfb658a
f3400ae
ea699c7
b79031b
6f01088
4012a54
5ee6776
c7796c5
8e1fb60
bb2c96c
325c70c
4a8d0cf
60a895c
1f7b5c9
f6c45d4
da87c14
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,22 +5,28 @@ import ( | |||||
| "fmt" | ||||||
| "log" | ||||||
| "os" | ||||||
| "path/filepath" | ||||||
|
|
||||||
| "github.com/SuperALKALINEdroiD/timelyDB/manifest" | ||||||
| "github.com/SuperALKALINEdroiD/timelyDB/utils/common" | ||||||
| "github.com/go-playground/validator/v10" | ||||||
| ) | ||||||
|
|
||||||
| func LoadConfig(filePath string) (*DatabaseConfig, error) { | ||||||
| if filePath == "" { | ||||||
| config, error := GenerateConfig("default-config.json") | ||||||
|
|
||||||
| if error != nil { | ||||||
| return nil, fmt.Errorf("failed to create config file: %v", error) | ||||||
| } | ||||||
|
|
||||||
| return config, nil | ||||||
| return GenerateConfig() | ||||||
| } | ||||||
|
|
||||||
| log.Printf("Loading config at %s", filePath) | ||||||
|
|
||||||
| file, err := os.Open(filePath) | ||||||
|
|
||||||
| if err != nil { | ||||||
| if os.IsNotExist(err) { | ||||||
| log.Println("Config file not found. Generating default config.") | ||||||
| return GenerateConfig() | ||||||
| } | ||||||
|
|
||||||
| return nil, fmt.Errorf("failed to open config file: %v", err) | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -35,6 +41,11 @@ func LoadConfig(filePath string) (*DatabaseConfig, error) { | |||||
| } | ||||||
|
|
||||||
| if config.validateConfig() { | ||||||
| manifest, err := manifest.GetManifest() | ||||||
| if err != nil { | ||||||
| return nil, fmt.Errorf("failed to parse config file: %v", err) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error message "failed to parse config file" is misleading here. The error comes from
Suggested change
|
||||||
| } | ||||||
| config.Manifest = *manifest | ||||||
| return &config, nil | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -43,9 +54,23 @@ func LoadConfig(filePath string) (*DatabaseConfig, error) { | |||||
| } | ||||||
|
|
||||||
| func (config *DatabaseConfig) validateConfig() bool { | ||||||
| if len(config.Nodes) == 0 { | ||||||
| if len(config.Nodes) == 0 && config.NodeCount > 0 { | ||||||
| config.Nodes = generateNodeConfig(config.NodeCount, "") | ||||||
| } | ||||||
| validate := validator.New() | ||||||
| err := validate.Struct(config) | ||||||
| if err != nil { | ||||||
| for _, err := range err.(validator.ValidationErrors) { | ||||||
| log.Printf("Validation error: Field '%s', Tag: '%s', Param: '%s'\n", err.Field(), err.Tag(), err.Param()) | ||||||
| } | ||||||
|
|
||||||
| return false | ||||||
| } | ||||||
|
|
||||||
| if len(config.Nodes) != config.NodeCount { | ||||||
| log.Printf("Validation error: Node count mismatch. Expected %d nodes, but got %d nodes.\n", config.NodeCount, len(config.Nodes)) | ||||||
| return false | ||||||
| } | ||||||
|
|
||||||
| return true | ||||||
| } | ||||||
|
|
@@ -68,21 +93,40 @@ func (c *DatabaseConfig) SaveConfig(filePath string) error { | |||||
| return nil | ||||||
| } | ||||||
|
|
||||||
| func GenerateConfig(filePath string) (*DatabaseConfig, error) { | ||||||
| file, err := os.Create(filePath) | ||||||
| func GenerateConfig() (*DatabaseConfig, error) { | ||||||
| defaultConfigFile := "default-config.json" | ||||||
|
|
||||||
| defaultDbPath := common.GetAppPath() | ||||||
| configData := GenerateExampleConfig(2, "localhost") | ||||||
|
|
||||||
| defaultConfigPath := filepath.Join(defaultDbPath, defaultConfigFile) | ||||||
| os.Setenv("DATABASE_SETTINGS", defaultDbPath) | ||||||
|
|
||||||
| data, err := json.Marshal(configData) | ||||||
| if err != nil { | ||||||
| return nil, fmt.Errorf("failed to create config file: %v", err) | ||||||
| fmt.Println("Error marshalling example config:", err) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The codebase predominantly uses the
Suggested change
|
||||||
| return nil, err | ||||||
| } | ||||||
|
|
||||||
| if _, err := os.Stat(defaultDbPath); os.IsNotExist(err) { | ||||||
| err := os.MkdirAll(defaultDbPath, os.ModePerm) | ||||||
| if err != nil { | ||||||
| return nil, err | ||||||
| } | ||||||
| } | ||||||
| defer file.Close() | ||||||
|
|
||||||
| exampleConfig := GenerateExampleConfig(2, "") // if no config, start with 1 node on local machine | ||||||
| err = os.WriteFile(defaultConfigPath, data, 0644) | ||||||
| if err != nil { | ||||||
| fmt.Println("Error writing config to file:", err) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| return nil, err | ||||||
| } | ||||||
|
|
||||||
| encoder := json.NewEncoder(file) | ||||||
| encoder.SetIndent("", " ") | ||||||
| if err := encoder.Encode(exampleConfig); err != nil { | ||||||
| return nil, fmt.Errorf("failed to save config file, error on encoder: %v", err) | ||||||
| manifest, err := manifest.GetManifest() | ||||||
| if err != nil { | ||||||
| return nil, fmt.Errorf("failed to parse config file: %v", err) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error message here is misleading. The error is returned from
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| log.Println("Configuration file created successfully at:", filePath) | ||||||
| return &exampleConfig, nil | ||||||
| configData.Manifest = *manifest | ||||||
|
|
||||||
| return &configData, nil | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,29 @@ | ||
| package config | ||
|
|
||
| import "fmt" | ||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/SuperALKALINEdroiD/timelyDB/manifest" | ||
| ) | ||
|
|
||
| type StoreMode string | ||
|
|
||
| type DatabaseConfig struct { | ||
| StoreName string `json:"dbName"` | ||
| Port int `json:"port"` | ||
| IsLockEnabled bool `json:"isLockEnabled"` | ||
| TimelyConfig TimelyConfig `json:"timelyConfig"` | ||
| Nodes []NodeConfig `json:"nodes"` | ||
| NodeCount int `json:"nodeCount"` | ||
| Mode StoreMode `json:"mode"` | ||
| InMemoryStorageThreshold int64 `json:"inMemoryStorageThreshold"` | ||
| MetaDataConfig MetaDataConfig `json:"metaDataConfig"` | ||
| StoreName string `json:"dbName" validate:"required"` | ||
| Port int `json:"port" validate:"required,gt=0"` | ||
| IsLockEnabled bool `json:"isLockEnabled"` | ||
| TimelyConfig TimelyConfig `json:"timelyConfig"` | ||
| Nodes []NodeConfig `json:"nodes" validate:"required"` | ||
| NodeCount int `json:"nodeCount" validate:"required,gt=0"` | ||
| Mode StoreMode `json:"mode" validate:"required"` | ||
| InMemoryStorageThreshold int64 `json:"inMemoryStorageThreshold" validate:"required,gt=0"` | ||
| MetaDataConfig MetaDataConfig `json:"metaDataConfig" validate:"required"` | ||
| Manifest manifest.Manifest `validate:"omitempty"` | ||
| } | ||
|
|
||
| type MetaDataConfig struct { | ||
| State NodeState `json:"state"` | ||
| WALPath string `json:"walPath"` | ||
| WALName string `json:"walPath"` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| type NodeState int | ||
|
|
@@ -62,10 +67,10 @@ func GenerateExampleConfig(nodeCount int, host string) DatabaseConfig { | |
| Mode: KV, | ||
| Nodes: nodes, | ||
| NodeCount: nodeCount, | ||
| InMemoryStorageThreshold: 2000, | ||
| InMemoryStorageThreshold: 2024, // 2MB | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| MetaDataConfig: MetaDataConfig{ | ||
| State: NodeStateReady, | ||
| WALPath: "/var/lib/db/wal", | ||
| WALName: "wal-storage", | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package config | ||
|
|
||
| import ( | ||
| "bufio" | ||
| "fmt" | ||
| "os" | ||
| "strings" | ||
| ) | ||
|
|
||
| var restrictedWords map[string]struct{} | ||
|
|
||
| func LoadRestrictedWords(filePath string) error { | ||
| restrictedWords = make(map[string]struct{}) | ||
|
|
||
| file, err := os.Open(filePath) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to open restricted words file: %v", err) | ||
| } | ||
| defer file.Close() | ||
|
|
||
| scanner := bufio.NewScanner(file) | ||
| for scanner.Scan() { | ||
| word := strings.TrimSpace(scanner.Text()) | ||
| if word != "" { | ||
| restrictedWords[word] = struct{}{} | ||
| } | ||
| } | ||
|
|
||
| if err := scanner.Err(); err != nil { | ||
| return fmt.Errorf("failed to read restricted words file: %v", err) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func IsARestrictedWord(word string) bool { | ||
| _, exists := restrictedWords[word] | ||
| return exists | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function
GetAppPathis a wrapper aroundcommon.GetAppPathbut it's not used anywhere in thecmdpackage. Themainfunction callscommon.GetAppPathdirectly. This function appears to be dead code and should be removed to avoid confusion.