package contracts import ( "git.fsdpf.net/go/db" "git.fsdpf.net/go/reflux" "git.fsdpf.net/go/req" "github.com/samber/do/v2" ) // ResVirtualTable 虚拟表接口,由业务层实现,框架通过 SQLite vtab 机制调用。 // Select 提供列表查询,Fetch 提供单条完整查询(含 Detail 补充字段), // Insert/Update/Delete 支持写操作并自动同步缓存。 type ResVirtualTable interface { Controller GetResource() req.Resource // Fetch 按主键获取单条完整数据,内部负责调用远端接口并补充 Detail 专属字段。 // 框架在 item cache miss 时调用,结果写入 item cache 供后续查询复用。 Fetch(pk any) (map[string]any, error) // Detail 对已有的 item 数据进行补充,填充列表接口不返回的详情字段。 // changed=true 时框架会将修改后的数据回写 item cache。 Detail(item reflux.R) (changed bool, err error) // Select 查询列表数据,filter 为过滤条件,pagesize/page 控制分页。 // 返回的 items 每项为 map[string]any,total 为总记录数。 Select(filter reflux.R, pagesize, page int) (items []any, total int64, err error) // Insert 新增一条记录,返回新记录的 rowid。 Insert(item reflux.R) (rowid int64, err error) // Update 按 rowid 更新记录。 Update(rowid any, item reflux.R) error // Delete 按 rowid 删除记录。 Delete(rowid any) error } type BaseResVirtualTable struct { Controller res req.Resource cache *db.Database } func (b *BaseResVirtualTable) Cache() *db.Database { // CREATE TABLE IF NOT EXISTS ` + res.Table + ` ( // id INTEGER PRIMARY KEY AUTOINCREMENT, // kind VARCHAR(8) NOT NULL DEFAULT 'list', // key VARCHAR(255) NOT NULL, // lmt INTEGER NOT NULL DEFAULT 0, // page INTEGER NOT NULL DEFAULT 0, // data TEXT NOT NULL, // total INTEGER NOT NULL DEFAULT 0, // expires_at BIGINT NOT NULL, // UNIQUE(kind, key, lmt, page) // ) return b.cache } func (b *BaseResVirtualTable) GetResource() req.Resource { return b.res } func (b *BaseResVirtualTable) GetExtraFields() []req.ResField { return nil } func (b *BaseResVirtualTable) Fetch(pk any) (map[string]any, error) { return nil, nil } func (b *BaseResVirtualTable) Detail(detail reflux.R) (changed bool, err error) { return false, nil } func (b *BaseResVirtualTable) Select(filter reflux.R, pagesize, page int) (items []any, total int64, err error) { return nil, 0, ErrFuncNotImplemented } func (b *BaseResVirtualTable) Insert(item reflux.R) (rowid int64, err error) { return 0, ErrFuncNotImplemented } func (b *BaseResVirtualTable) Update(rowid any, item reflux.R) error { return ErrFuncNotImplemented } func (b *BaseResVirtualTable) Delete(rowid any) error { return ErrFuncNotImplemented } func NewBaseResVirtualTable(container do.Injector, res req.Resource, conn *db.Database) ResVirtualTable { return &BaseResVirtualTable{ Controller: &BaseController{container}, res: res, cache: conn, } }