finish index feature

This commit is contained in:
2026-04-07 11:49:42 +06:00
parent 8ba956d8c5
commit 15db6e81db
37 changed files with 1047 additions and 170 deletions

View File

@@ -0,0 +1,88 @@
package nonpartitioned
import (
"errors"
"os"
"path/filepath"
"strings"
"testing"
"linedb/pkg/linedb"
)
// failingLookupStore — IndexStore, у которого Lookup всегда возвращает ошибку (для проверки FailOnFailureIndexRead).
type failingLookupStore struct {
inner linedb.IndexStore
}
func (f *failingLookupStore) Lookup(collection, field, value string) ([]linedb.IndexPosition, error) {
return nil, errors.New("simulated index lookup failure")
}
func (f *failingLookupStore) IndexRecord(collection, partition string, fields []string, record map[string]any, lineIndex int) {
f.inner.IndexRecord(collection, partition, fields, record, lineIndex)
}
func (f *failingLookupStore) UnindexRecord(collection, partition string, fields []string, record map[string]any, lineIndex int) {
f.inner.UnindexRecord(collection, partition, fields, record, lineIndex)
}
func (f *failingLookupStore) Rebuild(collection, partition string, fields []string, records []any) error {
return f.inner.Rebuild(collection, partition, fields, records)
}
func (f *failingLookupStore) Clear(collection string) error {
return f.inner.Clear(collection)
}
func TestReadByFilter_FailOnFailureIndexRead_ReturnsError(t *testing.T) {
dir := filepath.Join(dbDir, "index_fail")
_ = os.RemoveAll(dir)
if err := os.MkdirAll(dir, 0755); err != nil {
t.Fatalf("mkdir: %v", err)
}
initOptions := &linedb.LineDbInitOptions{
DBFolder: dir,
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "users",
AllocSize: 512,
IndexedFields: []string{"id", "email"},
},
},
}
inner := linedb.NewInMemoryIndexStore()
store := &failingLookupStore{inner: inner}
db := linedb.NewLineDb(&linedb.LineDbOptions{IndexStore: store})
if err := db.Init(true, initOptions); err != nil {
t.Fatalf("Init: %v", err)
}
defer db.Close()
if err := db.Insert(map[string]any{"id": 1, "email": "x@test.com"}, "users", linedb.LineDbAdapterOptions{}); err != nil {
t.Fatalf("Insert: %v", err)
}
// Без опции — ошибка индекса игнорируется, полный перебор находит запись
found, err := db.ReadByFilter(map[string]any{"email": "x@test.com"}, "users", linedb.LineDbAdapterOptions{})
if err != nil {
t.Fatalf("ReadByFilter without flag: %v", err)
}
if len(found) != 1 {
t.Fatalf("expected 1 via fallback, got %d", len(found))
}
// С FailOnFailureIndexRead — возвращается ошибка индекса
_, err = db.ReadByFilter(map[string]any{"email": "x@test.com"}, "users", linedb.LineDbAdapterOptions{
FailOnFailureIndexRead: true,
})
if err == nil {
t.Fatal("expected error when FailOnFailureIndexRead and index Lookup fails")
}
if !strings.Contains(err.Error(), "index read failed") || !strings.Contains(err.Error(), "simulated index lookup failure") {
t.Fatalf("unexpected error: %v", err)
}
}