tableDB/cache.go

102 lines
2.2 KiB
Go
Raw Permalink Normal View History

package tableDB
import (
"sync"
"time"
"apigo.cc/go/cast"
)
type SchemaCache struct {
Tables map[string]map[string]any // name -> table record
Fields map[string][]FieldSchema // tableId -> fields
Policies []map[string]any
lock sync.RWMutex
lastLoad time.Time
}
var GlobalCache = &SchemaCache{
Tables: make(map[string]map[string]any),
Fields: make(map[string][]FieldSchema),
}
func (c *SchemaCache) Load(tDB *TableDB) error {
dbInst := tDB.Base()
// Check if _Table exists first
res := dbInst.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='_Table'")
if dbInst.Config.Type == "mysql" {
res = dbInst.Query("SELECT TABLE_NAME name FROM information_schema.TABLES WHERE TABLE_SCHEMA=? AND TABLE_NAME='_Table'", dbInst.Config.DB)
}
if res.Error != nil || res.MapOnR1()["name"] == nil {
return nil // System tables not yet created
}
c.lock.Lock()
defer c.lock.Unlock()
// Load Tables
tables, err := tDB.Table("_Table").List(nil)
if err != nil {
return err
}
newTables := make(map[string]map[string]any)
for _, t := range tables {
newTables[cast.String(t["name"])] = t
}
c.Tables = newTables
// Load Fields
fields, err := tDB.Table("_Field").List(nil)
if err != nil {
return err
}
newFields := make(map[string][]FieldSchema)
for _, f := range fields {
var fs FieldSchema
cast.Convert(&fs, f)
tid := fs.TableID
newFields[tid] = append(newFields[tid], fs)
}
c.Fields = newFields
// Load Policies
policies, err := tDB.Table("_Policy").List(nil)
if err != nil {
return err
}
c.Policies = policies
c.lastLoad = time.Now()
return nil
}
func (c *SchemaCache) GetTable(name string) map[string]any {
c.lock.RLock()
defer c.lock.RUnlock()
return c.Tables[name]
}
func (c *SchemaCache) GetFields(tableID string) []FieldSchema {
c.lock.RLock()
defer c.lock.RUnlock()
return c.Fields[tableID]
}
func (c *SchemaCache) GetValidFields(tableName string) []string {
c.lock.RLock()
defer c.lock.RUnlock()
table := c.Tables[tableName]
if table == nil {
return nil
}
tid := cast.String(table["id"])
fields := c.Fields[tid]
var names []string
for _, f := range fields {
names = append(names, f.Name)
}
return names
}