package dao import ( "context" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" "observer-server/biz/consts" "observer-server/biz/model/entity" "observer-server/common" ) // AppVersion App 版本表 DAO:写极低频、表极小,不做查询缓存; // 写链路经 common.Serial() 串行(与授权链路一致)。 type appVersionDao struct{} var AppVersion = &appVersionDao{} func init() { ctx := context.Background() _, err := g.DB().Exec(ctx, `CREATE TABLE IF NOT EXISTS app_version ( id INTEGER PRIMARY KEY AUTOINCREMENT, version TEXT NOT NULL UNIQUE, notes TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL )`) if err != nil { panic(err) } // v6 迁移:删除 url 列(下载地址改为固定文件 app.apkDir/observer-latest.apk, // 表内不再记录;新库建表已无此列直接跳过) cols, err := g.DB().GetAll(ctx, "PRAGMA table_info(app_version)") if err != nil { panic(err) } for _, col := range cols { if gconv.String(col["name"]) == "url" { if _, err := g.DB().Exec(ctx, "ALTER TABLE app_version DROP COLUMN url"); err != nil { panic(err) } g.Log().Warningf(ctx, "存量表 app_version 已迁移:删除 url 列") break } } } // Insert 新增版本记录(version UNIQUE 由库兜底防重复;id 自增不显式写入) func (d *appVersionDao) Insert(ctx context.Context, m *entity.AppVersion) error { _, err := g.DB().Model(consts.TableAppVersion).Ctx(ctx).Data(g.Map{ "version": m.Version, "notes": m.Notes, "created_at": m.CreatedAt, "updated_at": m.UpdatedAt, }).Insert() return err } // DeleteByVersion 按版本号删除记录(文件保存失败时的补偿回滚) func (d *appVersionDao) DeleteByVersion(ctx context.Context, version string) error { _, err := g.DB().Model(consts.TableAppVersion).Ctx(ctx). Where("version", version).Delete() return err } // GetById 按主键查询版本记录,不存在返回 nil func (d *appVersionDao) GetById(ctx context.Context, id int64) (*entity.AppVersion, error) { var e entity.AppVersion err := g.DB().Model(consts.TableAppVersion).Ctx(ctx).Where("id", id).Scan(&e) if err != nil { if common.IsNoRows(err) { return nil, nil } return nil, err } return &e, nil } // DeleteById 按主键删除版本记录 func (d *appVersionDao) DeleteById(ctx context.Context, id int64) error { _, err := g.DB().Model(consts.TableAppVersion).Ctx(ctx).Where("id", id).Delete() return err } // GetByVersion 按版本号查询(新增前查重,返回 nil 表示不存在) func (d *appVersionDao) GetByVersion(ctx context.Context, version string) (*entity.AppVersion, error) { var e entity.AppVersion err := g.DB().Model(consts.TableAppVersion).Ctx(ctx).Where("version", version).Scan(&e) if err != nil { if common.IsNoRows(err) { return nil, nil } return nil, err } return &e, nil } // Latest 最新一条版本记录(id 倒序,无记录返回 nil) func (d *appVersionDao) Latest(ctx context.Context) (*entity.AppVersion, error) { var e entity.AppVersion err := g.DB().Model(consts.TableAppVersion).Ctx(ctx). OrderDesc("id").Limit(1).Scan(&e) if err != nil { if common.IsNoRows(err) { return nil, nil } return nil, err } return &e, nil } // Page 管理端版本记录分页:按下发时间倒序 func (d *appVersionDao) Page(ctx context.Context, page, size int) ([]*entity.AppVersion, int64, error) { base := g.DB().Model(consts.TableAppVersion).Ctx(ctx) total, err := base.Count() if err != nil { return nil, 0, err } var list []*entity.AppVersion err = base.OrderDesc("id").Limit((page-1)*size, size).Scan(&list) if err != nil { if common.IsNoRows(err) { return []*entity.AppVersion{}, int64(total), nil } return nil, 0, err } return list, int64(total), nil }