// Тесты для дебага точечного Update через индекс. // Случай 1: изменение поля, не входящего в индекс (поиск по email, обновляем name). // Случай 2: изменение поля, входящего в индекс (поиск по email, обновляем email). package tests import ( "os" "testing" "time" "linedb/pkg/linedb" ) func setupPointUpdateDB(t *testing.T) (*linedb.LineDb, func()) { t.Helper() dir := "./data/test-point-update" os.RemoveAll(dir) initOptions := &linedb.LineDbInitOptions{ CacheSize: 100, CacheTTL: time.Minute, DBFolder: dir, Collections: []linedb.JSONLFileOptions{ { CollectionName: "users", AllocSize: 256, IndexedFields: []string{"id", "email", "name"}, }, }, } db := linedb.NewLineDb(nil) if err := db.Init(false, initOptions); err != nil { t.Fatalf("Init failed: %v", err) } return db, func() { db.Close(); os.RemoveAll(dir) } } // TestPointUpdate_NonIndexedField: поиск по email (индекс), обновление name (не индекс). func TestPointUpdate_NonIndexedField(t *testing.T) { // db, cleanup := setupPointUpdateDB(t) db, _ := setupPointUpdateDB(t) // defer cleanup() opts := linedb.LineDbAdapterOptions{} if err := db.Insert(map[string]any{"id": 1, "name": "alice", "email": "alice@test.com"}, "users", opts); err != nil { t.Fatalf("Insert 1 failed: %v", err) } if err := db.Insert(map[string]any{"id": 2, "name": "bob", "email": "bob@test.com"}, "users", opts); err != nil { t.Fatalf("Insert 2 failed: %v", err) } if err := db.Insert(map[string]any{"id": 3, "name": "sam", "email": "sam@test.com"}, "users", opts); err != nil { t.Fatalf("Insert 2 failed: %v", err) } if err := db.Insert(map[string]any{"id": 4, "name": "chuck", "email": "chuck@test.com"}, "users", opts); err != nil { t.Fatalf("Insert 2 failed: %v", err) } // Поиск по email (индекс), обновляем name (не индекс) updated, err := db.Update( map[string]any{"name": "Bobina"}, "users", map[string]any{"email": "bob@test.com"}, opts, ) if err != nil { t.Fatalf("Update failed: %v", err) } if len(updated) != 1 { t.Fatalf("Expected 1 updated record, got %d", len(updated)) } m := updated[0].(map[string]any) if m["name"] != "Bobina" || m["email"] != "bob@test.com" { t.Errorf("Expected name=Bobina email=bob@test.com, got name=%v email=%v", m["name"], m["email"]) } // Проверяем ReadByFilter по старому email — должен найти обновлённую запись found, err := db.ReadByFilter(map[string]any{"email": "bob@test.com"}, "users", opts) if err != nil { t.Fatalf("ReadByFilter failed: %v", err) } if len(found) != 1 { t.Fatalf("Expected 1 record by email bob@test.com, got %d", len(found)) } if m2 := found[0].(map[string]any); m2["name"] != "Bobina" { t.Errorf("Expected name=bob_renamed, got %v", m2["name"]) } } // TestPointUpdate_IndexedField: поиск по email (индекс), обновление email. func TestPointUpdate_IndexedField(t *testing.T) { db, cleanup := setupPointUpdateDB(t) defer cleanup() opts := linedb.LineDbAdapterOptions{} if err := db.Insert(map[string]any{"name": "alice", "email": "alice@test.com"}, "users", opts); err != nil { t.Fatalf("Insert 1 failed: %v", err) } if err := db.Insert(map[string]any{"name": "bob", "email": "bob@test.com"}, "users", opts); err != nil { t.Fatalf("Insert 2 failed: %v", err) } // Поиск по email, обновляем тот же email updated, err := db.Update( map[string]any{"email": "bob_new@test.com"}, "users", map[string]any{"email": "bob@test.com"}, opts, ) if err != nil { t.Fatalf("Update failed: %v", err) } if len(updated) != 1 { t.Fatalf("Expected 1 updated record, got %d", len(updated)) } m := updated[0].(map[string]any) if m["email"] != "bob_new@test.com" || m["name"] != "bob" { t.Errorf("Expected email=bob_new@test.com name=bob, got email=%v name=%v", m["email"], m["name"]) } // По старому email записей быть не должно foundOld, err := db.ReadByFilter(map[string]any{"email": "bob@test.com"}, "users", opts) if err != nil { t.Fatalf("ReadByFilter old failed: %v", err) } if len(foundOld) != 0 { t.Errorf("Expected 0 records for old email bob@test.com, got %d", len(foundOld)) } // По новому email — одна запись foundNew, err := db.ReadByFilter(map[string]any{"email": "bob_new@test.com"}, "users", opts) if err != nil { t.Fatalf("ReadByFilter new failed: %v", err) } if len(foundNew) != 1 { t.Fatalf("Expected 1 record for new email bob_new@test.com, got %d", len(foundNew)) } if m2 := foundNew[0].(map[string]any); m2["name"] != "bob" { t.Errorf("Expected name=bob, got %v", m2["name"]) } }