1.4.5.2
This commit is contained in:
783
EdgeDNS/internal/dbs/db.go
Normal file
783
EdgeDNS/internal/dbs/db.go
Normal file
@@ -0,0 +1,783 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package dbs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||
"github.com/TeaOSLab/EdgeDNS/internal/models"
|
||||
"github.com/TeaOSLab/EdgeDNS/internal/remotelogs"
|
||||
dbutils "github.com/TeaOSLab/EdgeDNS/internal/utils/dbs"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
tableDomains = "domains_v2"
|
||||
tableRecords = "records_v2"
|
||||
tableRoutes = "routes_v2"
|
||||
tableKeys = "keys"
|
||||
tableAgentIPs = "agentIPs"
|
||||
)
|
||||
|
||||
type DB struct {
|
||||
db *dbutils.DB
|
||||
path string
|
||||
|
||||
insertDomainStmt *dbutils.Stmt
|
||||
updateDomainStmt *dbutils.Stmt
|
||||
deleteDomainStmt *dbutils.Stmt
|
||||
existsDomainStmt *dbutils.Stmt
|
||||
listDomainsStmt *dbutils.Stmt
|
||||
|
||||
insertRecordStmt *dbutils.Stmt
|
||||
updateRecordStmt *dbutils.Stmt
|
||||
existsRecordStmt *dbutils.Stmt
|
||||
deleteRecordStmt *dbutils.Stmt
|
||||
listRecordsStmt *dbutils.Stmt
|
||||
|
||||
insertRouteStmt *dbutils.Stmt
|
||||
updateRouteStmt *dbutils.Stmt
|
||||
deleteRouteStmt *dbutils.Stmt
|
||||
listRoutesStmt *dbutils.Stmt
|
||||
existsRouteStmt *dbutils.Stmt
|
||||
|
||||
insertKeyStmt *dbutils.Stmt
|
||||
updateKeyStmt *dbutils.Stmt
|
||||
deleteKeyStmt *dbutils.Stmt
|
||||
listKeysStmt *dbutils.Stmt
|
||||
existsKeyStmt *dbutils.Stmt
|
||||
|
||||
insertAgentIPStmt *dbutils.Stmt
|
||||
listAgentIPsStmt *dbutils.Stmt
|
||||
}
|
||||
|
||||
func NewDB(path string) *DB {
|
||||
return &DB{path: path}
|
||||
}
|
||||
|
||||
func (this *DB) Init() error {
|
||||
// 检查目录是否存在
|
||||
var dir = filepath.Dir(this.path)
|
||||
|
||||
_, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
err = os.MkdirAll(dir, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remotelogs.Println("DB", "create database dir '"+dir+"'")
|
||||
}
|
||||
|
||||
// TODO 思考 data.db 的数据安全性
|
||||
db, err := dbutils.OpenWriter("file:" + this.path + "?cache=shared&mode=rwc&_journal_mode=WAL&_locking_mode=EXCLUSIVE")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db.SetMaxOpenConns(1)
|
||||
|
||||
/**_, err = db.Exec("VACUUM")
|
||||
if err != nil {
|
||||
return err
|
||||
}**/
|
||||
|
||||
// 创建数据表
|
||||
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + tableDomains + `" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"clusterId" integer DEFAULT 0,
|
||||
"userId" integer DEFAULT 0,
|
||||
"name" varchar(255),
|
||||
"version" integer DEFAULT 0,
|
||||
"tsig" text
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "clusterId"
|
||||
ON "` + tableDomains + `" (
|
||||
"clusterId"
|
||||
);
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + tableRecords + `" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"domainId" integer DEFAULT 0,
|
||||
"name" varchar(255),
|
||||
"type" varchar(32),
|
||||
"value" varchar(4096),
|
||||
"mxPriority" integer DEFAULT 10,
|
||||
"srvPriority" integer DEFAULT 10,
|
||||
"srvWeight" integer DEFAULT 10,
|
||||
"srvPort" integer DEFAULT 0,
|
||||
"caaFlag" integer DEFAULT 0,
|
||||
"caaTag" varchar(16),
|
||||
"ttl" integer DEFAULT 0,
|
||||
"weight" integer DEFAULT 0,
|
||||
"routeIds" varchar(512),
|
||||
"version" integer DEFAULT 0
|
||||
);
|
||||
`)
|
||||
if err != nil {
|
||||
// 忽略可以预期的错误
|
||||
if strings.Contains(err.Error(), "duplicate column name") {
|
||||
err = nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + tableRoutes + `" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"ranges" text,
|
||||
"order" integer DEFAULT 0,
|
||||
"priority" integer DEFAULT 0,
|
||||
"userId" integer DEFAULT 0,
|
||||
"version" integer DEFAULT 0
|
||||
);
|
||||
`)
|
||||
if err != nil {
|
||||
// 忽略可以预期的错误
|
||||
if strings.Contains(err.Error(), "duplicate column name") {
|
||||
err = nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + tableKeys + `" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"domainId" integer DEFAULT 0,
|
||||
"zoneId" integer DEFAULT 0,
|
||||
"algo" varchar(128),
|
||||
"secret" varchar(4096),
|
||||
"secretType" varchar(32),
|
||||
"version" integer DEFAULT 0
|
||||
);`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + tableAgentIPs + `" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"ip" varchar(64),
|
||||
"agentCode" varchar(128)
|
||||
);`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 预编译语句
|
||||
// domain statements
|
||||
this.insertDomainStmt, err = db.Prepare(`INSERT INTO "` + tableDomains + `" ("id", "clusterId", "userId", "name", "tsig", "version") VALUES (?, ?, ?, ?, ?, ?)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.updateDomainStmt, err = db.Prepare(`UPDATE "` + tableDomains + `" SET "clusterId"=?, "userId"=?, "name"=?, "tsig"=?, "version"=? WHERE "id"=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.deleteDomainStmt, err = db.Prepare(`DELETE FROM "` + tableDomains + `" WHERE id=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.existsDomainStmt, err = db.Prepare(`SELECT "id" FROM "` + tableDomains + `" WHERE "id"=? LIMIT 1`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.listDomainsStmt, err = db.Prepare(`SELECT "id", "clusterId", "userId", "name", "tsig", "version" FROM "` + tableDomains + `" WHERE "clusterId"=? ORDER BY "id" ASC LIMIT ? OFFSET ?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record statements
|
||||
this.insertRecordStmt, err = db.Prepare(`INSERT INTO "` + tableRecords + `" ("id", "domainId", "name", "type", "value", "mxPriority", "srvPriority", "srvWeight", "srvPort", "caaFlag", "caaTag", "ttl", "weight", "routeIds", "version") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.updateRecordStmt, err = db.Prepare(`UPDATE "` + tableRecords + `" SET "domainId"=?, "name"=?, "type"=?, "value"=?, "mxPriority"=?, "srvPriority"=?, "srvWeight"=?, "srvPort"=?, "caaFlag"=?, "caaTag"=?, "ttl"=?, "weight"=?, "routeIds"=?, "version"=? WHERE "id"=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.existsRecordStmt, err = db.Prepare(`SELECT "id" FROM "` + tableRecords + `" WHERE "id"=? LIMIT 1`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.deleteRecordStmt, err = db.Prepare(`DELETE FROM "` + tableRecords + `" WHERE id=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.listRecordsStmt, err = db.Prepare(`SELECT "id", "domainId", "name", "type", "value", "mxPriority", "srvPriority", "srvWeight", "srvPort", "caaFlag", "caaTag", "ttl", "weight", "routeIds", "version" FROM "` + tableRecords + `" ORDER BY "id" ASC LIMIT ? OFFSET ?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// route statements
|
||||
this.insertRouteStmt, err = db.Prepare(`INSERT INTO "` + tableRoutes + `" ("id", "userId", "ranges", "order", "priority", "version") VALUES (?, ?, ?, ?, ?, ?)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.updateRouteStmt, err = db.Prepare(`UPDATE "` + tableRoutes + `" SET "userId"=?, "ranges"=?, "order"=?, "priority"=?, "version"=? WHERE "id"=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.deleteRouteStmt, err = db.Prepare(`DELETE FROM "` + tableRoutes + `" WHERE "id"=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.listRoutesStmt, err = db.Prepare(`SELECT "id", "userId", "ranges", "priority", "order", "version" FROM "` + tableRoutes + `" ORDER BY "id" ASC LIMIT ? OFFSET ?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.existsRouteStmt, err = db.Prepare(`SELECT "id" FROM "` + tableRoutes + `" WHERE "id"=? LIMIT 1`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// key statements
|
||||
this.insertKeyStmt, err = db.Prepare(`INSERT INTO "` + tableKeys + `" ("id", "domainId", "zoneId", "algo", "secret", "secretType", "version") VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.updateKeyStmt, err = db.Prepare(`UPDATE "` + tableKeys + `" SET "domainId"=?, "zoneId"=?, "algo"=?, "secret"=?, "secretType"=?, "version"=? WHERE "id"=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.deleteKeyStmt, err = db.Prepare(`DELETE FROM "` + tableKeys + `" WHERE "id"=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.listKeysStmt, err = db.Prepare(`SELECT "id", "domainId", "zoneId", "algo", "secret", "secretType", "version" FROM "` + tableKeys + `" ORDER BY "id" ASC LIMIT ? OFFSET ?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.existsKeyStmt, err = db.Prepare(`SELECT "id" FROM "` + tableKeys + `" WHERE "id"=? LIMIT 1`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// agent ip record statements
|
||||
this.insertAgentIPStmt, err = db.Prepare(`INSERT INTO "` + tableAgentIPs + `" ("id", "ip", "agentCode") VALUES (?, ?, ?)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.listAgentIPsStmt, err = db.Prepare(`SELECT "id", "ip", "agentCode" FROM "` + tableAgentIPs + `" ORDER BY "id" ASC LIMIT ? OFFSET ?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
this.db = db
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) InsertDomain(domainId int64, clusterId int64, userId int64, name string, tsigJSON []byte, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("InsertDomain", "domain:", domainId, "user:", userId, "name:", name)
|
||||
|
||||
_, err := this.insertDomainStmt.Exec(domainId, clusterId, userId, name, string(tsigJSON), version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) UpdateDomain(domainId int64, clusterId int64, userId int64, name string, tsigJSON []byte, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("UpdateDomain", "domain:", domainId, "user:", userId, "name:", name)
|
||||
|
||||
_, err := this.updateDomainStmt.Exec(clusterId, userId, name, string(tsigJSON), version, domainId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) DeleteDomain(domainId int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("DeleteDomain", "domain:", domainId)
|
||||
|
||||
_, err := this.deleteDomainStmt.Exec(domainId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) ExistsDomain(domainId int64) (bool, error) {
|
||||
if this.db == nil {
|
||||
return false, errors.New("db should not be nil")
|
||||
}
|
||||
rows, err := this.existsDomainStmt.Query(domainId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return false, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
if rows.Next() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (this *DB) ListDomains(clusterId int64, offset int, size int) (domains []*models.NSDomain, err error) {
|
||||
if this.db == nil {
|
||||
return nil, errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
rows, err := this.listDomainsStmt.Query(clusterId, size, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
|
||||
for rows.Next() {
|
||||
var domain = &models.NSDomain{}
|
||||
var tsigString string
|
||||
err = rows.Scan(&domain.Id, &domain.ClusterId, &domain.UserId, &domain.Name, &tsigString, &domain.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(tsigString) > 0 {
|
||||
var tsigConfig = &dnsconfigs.NSTSIGConfig{}
|
||||
err = json.Unmarshal([]byte(tsigString), tsigConfig)
|
||||
if err != nil {
|
||||
remotelogs.Error("decode tsig string failed: "+err.Error()+", domain:"+domain.Name, ", domainId: "+types.String(domain.Id))
|
||||
} else {
|
||||
domain.TSIG = tsigConfig
|
||||
}
|
||||
}
|
||||
|
||||
domains = append(domains, domain)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *DB) InsertRecord(recordId int64, domainId int64, name string, recordType dnsconfigs.RecordType, value string, mxPriority int32, srvPriority int32, srvWeight int32, srvPort int32, caaFlag int32, caaTag string, ttl int32, weight int32, routeIds []string, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("InsertRecord", "domain:", domainId, "name:", name)
|
||||
|
||||
_, err := this.insertRecordStmt.Exec(recordId, domainId, name, recordType, value, mxPriority, srvPriority, srvWeight, srvPort, caaFlag, caaTag, ttl, weight, strings.Join(routeIds, ","), version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) UpdateRecord(recordId int64, domainId int64, name string, recordType dnsconfigs.RecordType, value string, mxPriority int32, srvPriority int32, srvWeight int32, srvPort int32, caaFlag int32, caaTag string, ttl int32, weight int32, routeIds []string, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("UpdateRecord", "domain:", domainId, "name:", name)
|
||||
|
||||
_, err := this.updateRecordStmt.Exec(domainId, name, recordType, value, mxPriority, srvPriority, srvWeight, srvPort, caaFlag, caaTag, ttl, weight, strings.Join(routeIds, ","), version, recordId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) DeleteRecord(recordId int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("DeleteRecord", "record:", recordId)
|
||||
|
||||
_, err := this.deleteRecordStmt.Exec(recordId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) ExistsRecord(recordId int64) (bool, error) {
|
||||
if this.db == nil {
|
||||
return false, errors.New("db should not be nil")
|
||||
}
|
||||
rows, err := this.existsRecordStmt.Query(recordId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return false, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
if rows.Next() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// ListRecords 列出一组记录
|
||||
// TODO 将来只加载本集群上的记录
|
||||
func (this *DB) ListRecords(offset int, size int) (records []*models.NSRecord, err error) {
|
||||
if this.db == nil {
|
||||
return nil, errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
rows, err := this.listRecordsStmt.Query(size, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
|
||||
for rows.Next() {
|
||||
var record = &models.NSRecord{}
|
||||
var routeIds = ""
|
||||
err = rows.Scan(&record.Id, &record.DomainId, &record.Name, &record.Type, &record.Value, &record.MXPriority, &record.SRVPriority, &record.SRVWeight, &record.SRVPort, &record.CAAFlag, &record.CAATag, &record.Ttl, &record.Weight, &routeIds, &record.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(routeIds) > 0 {
|
||||
record.RouteIds = strings.Split(routeIds, ",")
|
||||
}
|
||||
records = append(records, record)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// InsertRoute 创建线路
|
||||
func (this *DB) InsertRoute(routeId int64, userId int64, rangesJSON []byte, order int32, priority int32, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("InsertRoute", "route:", routeId, "user:", userId)
|
||||
|
||||
_, err := this.insertRouteStmt.Exec(routeId, userId, string(rangesJSON), order, priority, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateRoute 修改线路
|
||||
func (this *DB) UpdateRoute(routeId int64, userId int64, rangesJSON []byte, order int32, priority int32, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("UpdateRoute", "route:", routeId, "user:", userId)
|
||||
|
||||
_, err := this.updateRouteStmt.Exec(userId, string(rangesJSON), order, priority, version, routeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteRoute 删除线路
|
||||
func (this *DB) DeleteRoute(routeId int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("DeleteRoute", "route:", routeId)
|
||||
|
||||
_, err := this.deleteRouteStmt.Exec(routeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExistsRoute 检查是否存在线路
|
||||
func (this *DB) ExistsRoute(routeId int64) (bool, error) {
|
||||
if this.db == nil {
|
||||
return false, errors.New("db should not be nil")
|
||||
}
|
||||
rows, err := this.existsRouteStmt.Query(routeId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return false, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
if rows.Next() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// ListRoutes 查找所有线路
|
||||
func (this *DB) ListRoutes(offset int64, size int64) (routes []*models.NSRoute, err error) {
|
||||
if this.db == nil {
|
||||
return nil, errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
rows, err := this.listRoutesStmt.Query(size, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
|
||||
for rows.Next() {
|
||||
var route = &models.NSRoute{}
|
||||
var rangesString = ""
|
||||
err = rows.Scan(&route.Id, &route.UserId, &rangesString, &route.Priority, &route.Order, &route.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
route.Ranges, err = models.InitRangesFromJSON([]byte(rangesString))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routes = append(routes, route)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *DB) InsertKey(keyId int64, domainId int64, zoneId int64, algo string, secret string, secretType string, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("InsertKey", "key:", keyId, "domain:", domainId, "zone:", zoneId)
|
||||
|
||||
_, err := this.insertKeyStmt.Exec(keyId, domainId, zoneId, algo, secret, secretType, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) UpdateKey(keyId int64, domainId int64, zoneId int64, algo string, secret string, secretType string, version int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("UpdateKey", "key:", keyId, "domain:", domainId, "zone:", zoneId)
|
||||
|
||||
_, err := this.updateKeyStmt.Exec(domainId, zoneId, algo, secret, secretType, version, keyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) ListKeys(offset int, size int) (keys []*models.NSKey, err error) {
|
||||
if this.db == nil {
|
||||
return nil, errors.New("db should not be nil")
|
||||
}
|
||||
rows, err := this.listKeysStmt.Query(size, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
for rows.Next() {
|
||||
var key = &models.NSKey{}
|
||||
err = rows.Scan(&key.Id, &key.DomainId, &key.ZoneId, &key.Algo, &key.Secret, &key.SecretType, &key.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *DB) DeleteKey(keyId int64) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("DeleteKey", "key:", keyId)
|
||||
|
||||
_, err := this.deleteKeyStmt.Exec(keyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) ExistsKey(keyId int64) (bool, error) {
|
||||
if this.db == nil {
|
||||
return false, errors.New("db should not be nil")
|
||||
}
|
||||
rows, err := this.existsKeyStmt.Query(keyId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return false, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
if rows.Next() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (this *DB) InsertAgentIP(ipId int64, ip string, agentCode string) error {
|
||||
if this.db == nil {
|
||||
return errors.New("db should not be nil")
|
||||
}
|
||||
|
||||
this.log("InsertAgentIP", "id:", ipId, "ip:", ip, "agent:", agentCode)
|
||||
_, err := this.insertAgentIPStmt.Exec(ipId, ip, agentCode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DB) ListAgentIPs(offset int64, size int64) (agentIPs []*models.AgentIP, err error) {
|
||||
if this.db == nil {
|
||||
return nil, errors.New("db should not be nil")
|
||||
}
|
||||
rows, err := this.listAgentIPsStmt.Query(size, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
defer func() {
|
||||
_ = rows.Close()
|
||||
}()
|
||||
for rows.Next() {
|
||||
var agentIP = &models.AgentIP{}
|
||||
err = rows.Scan(&agentIP.Id, &agentIP.IP, &agentIP.AgentCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
agentIPs = append(agentIPs, agentIP)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *DB) Close() error {
|
||||
if this.db == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, stmt := range []*dbutils.Stmt{
|
||||
this.insertDomainStmt,
|
||||
this.updateDomainStmt,
|
||||
this.deleteDomainStmt,
|
||||
this.existsDomainStmt,
|
||||
this.listDomainsStmt,
|
||||
|
||||
this.insertRecordStmt,
|
||||
this.updateRecordStmt,
|
||||
this.existsRecordStmt,
|
||||
this.deleteRecordStmt,
|
||||
this.listRecordsStmt,
|
||||
|
||||
this.insertRouteStmt,
|
||||
this.updateRouteStmt,
|
||||
this.deleteRouteStmt,
|
||||
this.listRoutesStmt,
|
||||
this.existsRouteStmt,
|
||||
|
||||
this.insertKeyStmt,
|
||||
this.updateKeyStmt,
|
||||
this.deleteKeyStmt,
|
||||
this.listKeysStmt,
|
||||
this.existsKeyStmt,
|
||||
|
||||
this.insertAgentIPStmt,
|
||||
this.listAgentIPsStmt,
|
||||
} {
|
||||
if stmt != nil {
|
||||
_ = stmt.Close()
|
||||
}
|
||||
}
|
||||
|
||||
err := this.db.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 打印日志
|
||||
func (this *DB) log(args ...any) {
|
||||
if !Tea.IsTesting() {
|
||||
return
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
args[0] = "[" + types.String(args[0]) + "]"
|
||||
log.Println(args...)
|
||||
}
|
||||
Reference in New Issue
Block a user