108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
package index
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"github.com/iancoleman/orderedmap"
|
||
"go.mongodb.org/mongo-driver/bson"
|
||
"git.pyer.club/kingecg/godocdb/storage"
|
||
)
|
||
|
||
// IndexType 表示索引类型
|
||
type IndexType string
|
||
|
||
const (
|
||
SingleField IndexType = "single"
|
||
Composite IndexType = "composite"
|
||
)
|
||
|
||
// IndexSortOrder 表示索引的排序方式
|
||
type IndexSortOrder string
|
||
|
||
const (
|
||
Ascending IndexSortOrder = "asc"
|
||
Descending IndexSortOrder = "desc"
|
||
)
|
||
|
||
// IndexMetadata 索引元数据
|
||
type IndexMetadata struct {
|
||
Name string
|
||
Type IndexType
|
||
KeyFields []string
|
||
SortOrders []IndexSortOrder // 每个字段对应的排序方式(长度应与KeyFields一致)
|
||
}
|
||
|
||
// IndexStore 管理索引的存储和查询
|
||
type IndexStore struct {
|
||
storage *storage.LevelDBStorage
|
||
}
|
||
|
||
// NewIndexStore 创建新的索引存储实例
|
||
func NewIndexStore(path string) (*IndexStore, error) {
|
||
storage, err := storage.NewLevelDBStorage(path)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &IndexStore{storage: storage}, nil
|
||
}
|
||
|
||
// CreateIndex 创建索引
|
||
func (is *IndexStore) CreateIndex(indexName string, indexType IndexType, keyFields []string, sortOrders []IndexSortOrder) error {
|
||
// 验证keyFields和sortOrders长度一致
|
||
if len(keyFields) != len(sortOrders) {
|
||
return fmt.Errorf("keyFields and sortOrders must have the same length")
|
||
}
|
||
|
||
// 存储索引元数据
|
||
metadata := IndexMetadata{
|
||
Name: indexName,
|
||
Type: indexType,
|
||
KeyFields: keyFields,
|
||
SortOrders: sortOrders, // 使用字段级排序方式
|
||
}
|
||
|
||
data, err := bson.Marshal(metadata)
|
||
if err != nil {
|
||
return fmt.Errorf("failed to marshal index metadata: %v", err)
|
||
}
|
||
|
||
key := []byte(fmt.Sprintf("indexes:metadata:%s", indexName))
|
||
if err := is.storage.Put(key, data); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 初始化索引存储结构
|
||
indexKey := fmt.Sprintf("indexes:data:%s", indexName)
|
||
index := orderedmap.New()
|
||
indexData, _ := bson.Marshal(index)
|
||
return is.storage.Put([]byte(indexKey), indexData)
|
||
}
|
||
|
||
// DropIndex 删除索引
|
||
func (is *IndexStore) DropIndex(indexName string) error {
|
||
// 删除元数据
|
||
metadataKey := []byte(fmt.Sprintf("indexes:metadata:%s", indexName))
|
||
if err := is.storage.Delete(metadataKey); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 删除索引数据
|
||
indexKey := []byte(fmt.Sprintf("indexes:data:%s", indexName))
|
||
return is.storage.Delete(indexKey)
|
||
}
|
||
|
||
// GetIndexMetadata 获取索引元数据
|
||
func (is *IndexStore) GetIndexMetadata(indexName string) (*IndexMetadata, error) {
|
||
key := []byte(fmt.Sprintf("indexes:metadata:%s", indexName))
|
||
rawData, err := is.storage.Get(key)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("index not found: %v", err)
|
||
}
|
||
|
||
var metadata IndexMetadata
|
||
if err := bson.Unmarshal(rawData, &metadata); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return &metadata, nil
|
||
} |