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 }