Compare commits
7 Commits
af3e55e518
...
v6.4.3
| Author | SHA1 | Date | |
|---|---|---|---|
| 2459988ff0 | |||
| 6ab08fe97f | |||
| 2dafe4a981 | |||
| ec24e0713d | |||
| 969ccae25c | |||
| 5b46ff0efd | |||
| d234616406 |
9
go.mod
9
go.mod
@@ -13,7 +13,6 @@ require (
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/hexops/valast v1.5.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
@@ -21,10 +20,8 @@ require (
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
@@ -33,4 +30,8 @@ require (
|
||||
mvdan.cc/gofumpt v0.4.0 // indirect
|
||||
)
|
||||
|
||||
require gorm.io/driver/sqlite v1.6.0
|
||||
require (
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
gorm.io/driver/sqlite v1.6.0
|
||||
)
|
||||
|
||||
3
go.sum
3
go.sum
@@ -36,15 +36,12 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
||||
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
|
||||
22
main.go
22
main.go
@@ -82,7 +82,7 @@ func main() {
|
||||
}
|
||||
mainLogger.Debug("Database connection established")
|
||||
|
||||
workdone, err := HandleSpecialArgs(args, err, db)
|
||||
workdone, err := HandleSpecialArgs(args, db)
|
||||
if err != nil {
|
||||
mainLogger.Error("Failed to handle special args: %v", err)
|
||||
return
|
||||
@@ -366,28 +366,34 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func HandleSpecialArgs(args []string, err error, db utils.DB) (bool, error) {
|
||||
func HandleSpecialArgs(args []string, db utils.DB) (bool, error) {
|
||||
handleSpecialArgsLogger := logger.Default.WithPrefix("HandleSpecialArgs")
|
||||
handleSpecialArgsLogger.Debug("Handling special arguments: %v", args)
|
||||
if len(args) == 0 {
|
||||
handleSpecialArgsLogger.Warning("No arguments provided to HandleSpecialArgs")
|
||||
return false, nil
|
||||
}
|
||||
switch args[0] {
|
||||
case "reset":
|
||||
handleSpecialArgsLogger.Info("Resetting all files")
|
||||
err = utils.ResetAllFiles(db)
|
||||
handleSpecialArgsLogger.Info("Resetting all files to their original state from database")
|
||||
err := utils.ResetAllFiles(db)
|
||||
if err != nil {
|
||||
handleSpecialArgsLogger.Error("Failed to reset all files: %v", err)
|
||||
return true, err
|
||||
}
|
||||
handleSpecialArgsLogger.Info("All files reset")
|
||||
handleSpecialArgsLogger.Info("Successfully reset all files to original state")
|
||||
return true, nil
|
||||
case "dump":
|
||||
handleSpecialArgsLogger.Info("Dumping all files from database")
|
||||
err = db.RemoveAllFiles()
|
||||
handleSpecialArgsLogger.Info("Dumping all files from database (clearing snapshots)")
|
||||
err := db.RemoveAllFiles()
|
||||
if err != nil {
|
||||
handleSpecialArgsLogger.Error("Failed to remove all files from database: %v", err)
|
||||
return true, err
|
||||
}
|
||||
handleSpecialArgsLogger.Info("All files removed from database")
|
||||
handleSpecialArgsLogger.Info("Successfully cleared all file snapshots from database")
|
||||
return true, nil
|
||||
default:
|
||||
handleSpecialArgsLogger.Debug("Unknown special argument: %q", args[0])
|
||||
}
|
||||
handleSpecialArgsLogger.Debug("No special arguments handled, returning false")
|
||||
return false, nil
|
||||
|
||||
@@ -89,10 +89,11 @@ func ProcessJSON(content string, command utils.ModifyCommand, filename string) (
|
||||
return commands, fmt.Errorf("failed to convert Lua table back to Go: %v", err)
|
||||
}
|
||||
|
||||
commands, err = applyJSONChanges(content, jsonData, goData)
|
||||
processJsonLogger.Debug("About to call applyChanges with original data and modified data")
|
||||
commands, err = applyChanges(content, jsonData, goData)
|
||||
if err != nil {
|
||||
processJsonLogger.Error("Failed to apply JSON changes: %v", err)
|
||||
return commands, fmt.Errorf("failed to apply JSON changes: %v", err)
|
||||
processJsonLogger.Error("Failed to apply surgical JSON changes: %v", err)
|
||||
return commands, fmt.Errorf("failed to apply surgical JSON changes: %v", err)
|
||||
}
|
||||
|
||||
processJsonLogger.Debug("Total JSON processing time: %v", time.Since(startTime))
|
||||
@@ -145,24 +146,23 @@ func applyChanges(content string, originalData, modifiedData interface{}) ([]uti
|
||||
// Apply removals first (from end to beginning to avoid index shifting)
|
||||
for _, removalPath := range removals {
|
||||
actualPath := strings.TrimSuffix(removalPath, "@remove")
|
||||
index := extractIndexFromRemovalPath(removalPath)
|
||||
elementIndex := extractIndexFromRemovalPath(actualPath)
|
||||
arrayPath := getArrayPathFromElementPath(actualPath)
|
||||
|
||||
// Get the array element to remove
|
||||
result := gjson.Get(content, actualPath)
|
||||
if !result.Exists() {
|
||||
continue
|
||||
}
|
||||
jsonLogger.Debug("Processing removal: path=%s, index=%d, arrayPath=%s", actualPath, elementIndex, arrayPath)
|
||||
|
||||
// Find the exact byte range to remove
|
||||
from, to := findArrayElementRemovalRange(content, arrayPath, elementIndex)
|
||||
|
||||
jsonLogger.Debug("Removing bytes %d-%d", from, to)
|
||||
|
||||
// Find the exact byte range to remove (including comma/formatting)
|
||||
startPos, endPos := findArrayElementRemovalRange(content, arrayPath, index)
|
||||
if startPos >= 0 && endPos > startPos {
|
||||
commands = append(commands, utils.ReplaceCommand{
|
||||
From: startPos,
|
||||
To: endPos,
|
||||
With: "", // Remove the element
|
||||
From: from,
|
||||
To: to,
|
||||
With: "",
|
||||
})
|
||||
}
|
||||
|
||||
jsonLogger.Debug("Added removal command: From=%d, To=%d, With=\"\"", from, to)
|
||||
}
|
||||
|
||||
// Apply additions (new fields)
|
||||
@@ -200,10 +200,11 @@ func applyChanges(content string, originalData, modifiedData interface{}) ([]uti
|
||||
// Convert the new value to JSON string
|
||||
newValueStr := convertValueToJSONString(newValue)
|
||||
|
||||
// Insert the new field
|
||||
|
||||
// Insert the new field with pretty-printed formatting
|
||||
// Format: ,"fieldName": { ... }
|
||||
insertText := fmt.Sprintf(`,"%s": %s`, fieldName, newValueStr)
|
||||
|
||||
jsonLogger.Debug("Inserting text: %q", insertText)
|
||||
|
||||
commands = append(commands, utils.ReplaceCommand{
|
||||
From: startPos,
|
||||
@@ -311,10 +312,31 @@ func convertValueToJSONString(value interface{}) string {
|
||||
return strconv.FormatBool(v)
|
||||
case nil:
|
||||
return "null"
|
||||
case map[string]interface{}:
|
||||
// Handle maps specially to avoid double-escaping of keys
|
||||
var pairs []string
|
||||
for key, val := range v {
|
||||
// The key might already have escaped quotes from Lua, so we need to be careful
|
||||
// If the key already contains escaped quotes, we need to unescape them first
|
||||
keyStr := key
|
||||
if strings.Contains(key, `\"`) {
|
||||
// Key already has escaped quotes, use it as-is
|
||||
keyStr = `"` + key + `"`
|
||||
} else {
|
||||
// Normal key, escape quotes
|
||||
keyStr = `"` + strings.ReplaceAll(key, `"`, `\"`) + `"`
|
||||
}
|
||||
valStr := convertValueToJSONString(val)
|
||||
pairs = append(pairs, keyStr+":"+valStr)
|
||||
}
|
||||
return "{" + strings.Join(pairs, ",") + "}"
|
||||
default:
|
||||
// For complex types, we need to avoid json.Marshal
|
||||
// This should not happen if we're doing true surgical edits
|
||||
return ""
|
||||
// For other complex types (arrays), we need to use json.Marshal
|
||||
jsonBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return "null" // Fallback to null if marshaling fails
|
||||
}
|
||||
return string(jsonBytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -487,17 +487,8 @@ func EvalRegex(L *lua.LState) int {
|
||||
evalRegexLogger := processorLogger.WithPrefix("evalRegex")
|
||||
evalRegexLogger.Debug("Lua evalRegex function called")
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
evalRegexLogger.Error("Panic in EvalRegex: %v", r)
|
||||
// Push empty table on panic
|
||||
emptyTable := L.NewTable()
|
||||
L.Push(emptyTable)
|
||||
}
|
||||
}()
|
||||
|
||||
pattern := L.ToString(1)
|
||||
input := L.ToString(2)
|
||||
input := L.ToString(1)
|
||||
pattern := L.ToString(2)
|
||||
|
||||
evalRegexLogger.Debug("Pattern: %q, Input: %q", pattern, input)
|
||||
|
||||
@@ -506,13 +497,17 @@ func EvalRegex(L *lua.LState) int {
|
||||
|
||||
evalRegexLogger.Debug("Go regex matches: %v (count: %d)", matches, len(matches))
|
||||
|
||||
if len(matches) > 0 {
|
||||
matchesTable := L.NewTable()
|
||||
for i, match := range matches {
|
||||
matchesTable.RawSetInt(i, lua.LString(match))
|
||||
evalRegexLogger.Debug("Set table[%d] = %q", i, match)
|
||||
}
|
||||
|
||||
L.Push(matchesTable)
|
||||
} else {
|
||||
L.Push(lua.LNil)
|
||||
}
|
||||
|
||||
evalRegexLogger.Debug("Pushed matches table to Lua stack")
|
||||
|
||||
return 1
|
||||
|
||||
@@ -3,6 +3,8 @@ package processor
|
||||
import (
|
||||
"cook/utils"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestSurgicalJSONEditing(t *testing.T) {
|
||||
@@ -92,6 +94,11 @@ modified = true
|
||||
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
||||
}
|
||||
|
||||
diff := cmp.Diff(result, tt.expected)
|
||||
if diff != "" {
|
||||
t.Errorf("Differences:\n%s", diff)
|
||||
}
|
||||
|
||||
// Check the actual result matches expected
|
||||
if result != tt.expected {
|
||||
t.Errorf("Expected:\n%s\n\nGot:\n%s", tt.expected, result)
|
||||
@@ -178,6 +185,11 @@ modified = true
|
||||
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
||||
}
|
||||
|
||||
diff := cmp.Diff(result, expected)
|
||||
if diff != "" {
|
||||
t.Errorf("Differences:\n%s", diff)
|
||||
}
|
||||
|
||||
// Check that the result matches expected (preserves formatting and changes weight)
|
||||
if result != expected {
|
||||
t.Errorf("Expected:\n%s\n\nGot:\n%s", expected, result)
|
||||
@@ -500,6 +512,11 @@ func TestSurgicalJSONPreservesFormatting2(t *testing.T) {
|
||||
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
||||
}
|
||||
|
||||
diff := cmp.Diff(result, expected)
|
||||
if diff != "" {
|
||||
t.Errorf("Differences:\n%s", diff)
|
||||
}
|
||||
|
||||
// Check that the result matches expected (preserves formatting and changes weight)
|
||||
if result != expected {
|
||||
t.Errorf("Expected:\n%s\n\nGot:\n%s", expected, result)
|
||||
@@ -592,8 +609,239 @@ func TestRetardedJSONEditing(t *testing.T) {
|
||||
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
||||
}
|
||||
|
||||
diff := cmp.Diff(result, expected)
|
||||
if diff != "" {
|
||||
t.Errorf("Differences:\n%s", diff)
|
||||
}
|
||||
|
||||
// Check that the weight was changed
|
||||
if result != expected {
|
||||
t.Errorf("Expected:\n%s\nGot:\n%s", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetardedJSONEditing2(t *testing.T) {
|
||||
original := `
|
||||
{
|
||||
"Rows": [
|
||||
{
|
||||
"Name": "Deep_Mining_Drill_Biofuel",
|
||||
"Meshable": {
|
||||
"RowName": "Mesh_Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Itemable": {
|
||||
"RowName": "Item_Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Interactable": {
|
||||
"RowName": "Deployable"
|
||||
},
|
||||
"Focusable": {
|
||||
"RowName": "Focusable_1H"
|
||||
},
|
||||
"Highlightable": {
|
||||
"RowName": "Generic"
|
||||
},
|
||||
"Actionable": {
|
||||
"RowName": "Deployable"
|
||||
},
|
||||
"Usable": {
|
||||
"RowName": "Place"
|
||||
},
|
||||
"Deployable": {
|
||||
"RowName": "Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Durable": {
|
||||
"RowName": "Deployable_750"
|
||||
},
|
||||
"Inventory": {
|
||||
"RowName": "Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Decayable": {
|
||||
"RowName": "Decay_MetaItem"
|
||||
},
|
||||
"Generator": {
|
||||
"RowName": "Deep_Mining_Biofuel_Drill"
|
||||
},
|
||||
"Resource": {
|
||||
"RowName": "Simple_Internal_Flow_Only"
|
||||
},
|
||||
"Manual_Tags": {
|
||||
"GameplayTags": [
|
||||
{
|
||||
"TagName": "Item.Machine"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Generated_Tags": {
|
||||
"GameplayTags": [
|
||||
{
|
||||
"TagName": "Item.Machine"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Meshable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Itemable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Interactable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Highlightable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Actionable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Usable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Deployable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Durable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Inventory"
|
||||
}
|
||||
],
|
||||
"ParentTags": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
|
||||
expected := `
|
||||
{
|
||||
"Rows": [
|
||||
{
|
||||
"Name": "Deep_Mining_Drill_Biofuel",
|
||||
"Meshable": {
|
||||
"RowName": "Mesh_Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Itemable": {
|
||||
"RowName": "Item_Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Interactable": {
|
||||
"RowName": "Deployable"
|
||||
},
|
||||
"Focusable": {
|
||||
"RowName": "Focusable_1H"
|
||||
},
|
||||
"Highlightable": {
|
||||
"RowName": "Generic"
|
||||
},
|
||||
"Actionable": {
|
||||
"RowName": "Deployable"
|
||||
},
|
||||
"Usable": {
|
||||
"RowName": "Place"
|
||||
},
|
||||
"Deployable": {
|
||||
"RowName": "Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Durable": {
|
||||
"RowName": "Deployable_750"
|
||||
},
|
||||
"Inventory": {
|
||||
"RowName": "Deep_Mining_Drill_Biofuel"
|
||||
},
|
||||
"Decayable": {
|
||||
"RowName": "Decay_MetaItem"
|
||||
},
|
||||
"Generator": {
|
||||
"RowName": "Deep_Mining_Biofuel_Drill"
|
||||
},
|
||||
"Resource": {
|
||||
"RowName": "Simple_Internal_Flow_Only"
|
||||
},
|
||||
"Manual_Tags": {
|
||||
"GameplayTags": [
|
||||
{
|
||||
"TagName": "Item.Machine"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Generated_Tags": {
|
||||
"GameplayTags": [
|
||||
{
|
||||
"TagName": "Item.Machine"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Meshable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Itemable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Interactable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Highlightable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Actionable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Usable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Deployable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Durable"
|
||||
},
|
||||
{
|
||||
"TagName": "Traits.Inventory"
|
||||
}
|
||||
],
|
||||
"ParentTags": []
|
||||
}
|
||||
,"AdditionalStats": {"(Value=\"BaseDeepMiningDrillSpeed_+%\")":4000}}
|
||||
]
|
||||
}
|
||||
`
|
||||
|
||||
command := utils.ModifyCommand{
|
||||
Name: "test",
|
||||
Lua: `
|
||||
for i, row in ipairs(data.Rows) do
|
||||
-- Special case: Deep_Mining_Drill_Biofuel
|
||||
if string.find(row.Name, "Deep_Mining_Drill_Biofuel") then
|
||||
print("[DEBUG] Special case: Deep_Mining_Drill_Biofuel")
|
||||
if not row.AdditionalStats then
|
||||
print("[DEBUG] Creating AdditionalStats table for Deep_Mining_Drill_Biofuel")
|
||||
row.AdditionalStats = {}
|
||||
end
|
||||
print("[DEBUG] Setting BaseDeepMiningDrillSpeed_+% to 4000")
|
||||
row.AdditionalStats["(Value=\\\"BaseDeepMiningDrillSpeed_+%\\\")"] = 4000
|
||||
end
|
||||
end
|
||||
`,
|
||||
}
|
||||
|
||||
commands, err := ProcessJSON(original, command, "test.json")
|
||||
if err != nil {
|
||||
t.Fatalf("ProcessJSON failed: %v", err)
|
||||
}
|
||||
|
||||
if len(commands) == 0 {
|
||||
t.Fatal("Expected at least one command")
|
||||
}
|
||||
|
||||
// Apply the commands
|
||||
result := original
|
||||
for _, cmd := range commands {
|
||||
result = result[:cmd.From] + cmd.With + result[cmd.To:]
|
||||
}
|
||||
|
||||
diff := cmp.Diff(result, expected)
|
||||
if diff != "" {
|
||||
t.Errorf("Differences:\n%s", diff)
|
||||
}
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("Expected:\n%s\nGot:\n%s", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
23
utils/db.go
23
utils/db.go
@@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
@@ -41,24 +42,25 @@ func GetDB() (DB, error) {
|
||||
|
||||
dbFile := filepath.Join("data.sqlite")
|
||||
getDBLogger.Debug("Opening database file: %q", dbFile)
|
||||
getDBLogger.Trace("Database configuration: PrepareStmt=true, GORM logger=Silent")
|
||||
db, err := gorm.Open(sqlite.Open(dbFile), &gorm.Config{
|
||||
// SkipDefaultTransaction: true,
|
||||
PrepareStmt: true,
|
||||
Logger: gormlogger.Default.LogMode(gormlogger.Silent),
|
||||
})
|
||||
if err != nil {
|
||||
getDBLogger.Error("Failed to open database: %v", err)
|
||||
getDBLogger.Error("Failed to open database file %q: %v", dbFile, err)
|
||||
return nil, err
|
||||
}
|
||||
getDBLogger.Debug("Database opened successfully, running auto migration")
|
||||
getDBLogger.Debug("Database opened successfully, running auto migration for FileSnapshot model")
|
||||
if err := db.AutoMigrate(&FileSnapshot{}); err != nil {
|
||||
getDBLogger.Error("Auto migration failed: %v", err)
|
||||
getDBLogger.Error("Auto migration failed for FileSnapshot model: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
getDBLogger.Debug("Auto migration completed")
|
||||
getDBLogger.Info("Database initialized and migrated successfully")
|
||||
|
||||
globalDB = &DBWrapper{db: db}
|
||||
getDBLogger.Debug("Database wrapper initialized")
|
||||
getDBLogger.Debug("Database wrapper initialized and cached globally")
|
||||
return globalDB, nil
|
||||
}
|
||||
|
||||
@@ -88,7 +90,7 @@ func (db *DBWrapper) FileExists(filePath string) (bool, error) {
|
||||
}
|
||||
|
||||
func (db *DBWrapper) SaveFile(filePath string, fileData []byte) error {
|
||||
saveFileLogger := dbLogger.WithPrefix("SaveFile").WithField("filePath", filePath)
|
||||
saveFileLogger := dbLogger.WithPrefix("SaveFile").WithField("filePath", filePath).WithField("dataSize", len(fileData))
|
||||
saveFileLogger.Debug("Attempting to save file to database")
|
||||
saveFileLogger.Trace("File data length: %d", len(fileData))
|
||||
|
||||
@@ -98,7 +100,7 @@ func (db *DBWrapper) SaveFile(filePath string, fileData []byte) error {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
saveFileLogger.Debug("File already exists, skipping save")
|
||||
saveFileLogger.Debug("File already exists in database, skipping save to avoid overwriting original snapshot")
|
||||
return nil
|
||||
}
|
||||
saveFileLogger.Debug("Creating new file snapshot in database")
|
||||
@@ -110,7 +112,7 @@ func (db *DBWrapper) SaveFile(filePath string, fileData []byte) error {
|
||||
if err != nil {
|
||||
saveFileLogger.Error("Failed to create file snapshot: %v", err)
|
||||
} else {
|
||||
saveFileLogger.Debug("File saved successfully to database")
|
||||
saveFileLogger.Info("File successfully saved to database")
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -121,8 +123,11 @@ func (db *DBWrapper) GetFile(filePath string) ([]byte, error) {
|
||||
var fileSnapshot FileSnapshot
|
||||
err := db.db.Model(&FileSnapshot{}).Where("file_path = ?", filePath).First(&fileSnapshot).Error
|
||||
if err != nil {
|
||||
// Downgrade not-found to warning to avoid noisy errors during first run
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
getFileLogger.Debug("File not found in database: %v", err)
|
||||
} else {
|
||||
getFileLogger.Warning("Failed to get file from database: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
getFileLogger.Debug("File found in database")
|
||||
|
||||
@@ -16,6 +16,7 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
flagsLogger.Debug("Initializing flags")
|
||||
flagsLogger.Trace("ParallelFiles initial value: %d, Filter initial value: %q, JSON initial value: %t", *ParallelFiles, *Filter, *JSON)
|
||||
flagsLogger.Debug("Initializing command-line flags")
|
||||
flagsLogger.Trace("Initial flag values - ParallelFiles: %d, Filter: %q, JSON: %t", *ParallelFiles, *Filter, *JSON)
|
||||
flagsLogger.Debug("Flag definitions: -P (parallel files), -f (filter), -json (JSON mode)")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user