// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. package iplibrary import ( "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeNode/internal/events" "github.com/TeaOSLab/EdgeNode/internal/remotelogs" "github.com/TeaOSLab/EdgeNode/internal/utils/dbs" "github.com/TeaOSLab/EdgeNode/internal/utils/goman" "github.com/TeaOSLab/EdgeNode/internal/utils/idles" "github.com/iwind/TeaGo/Tea" "os" "path/filepath" "time" ) type SQLiteIPList struct { db *dbs.DB itemTableName string versionTableName string deleteExpiredItemsStmt *dbs.Stmt deleteItemStmt *dbs.Stmt insertItemStmt *dbs.Stmt selectItemsStmt *dbs.Stmt selectMaxItemVersionStmt *dbs.Stmt selectVersionStmt *dbs.Stmt updateVersionStmt *dbs.Stmt cleanTicker *time.Ticker dir string isClosed bool } func NewSQLiteIPList() (*SQLiteIPList, error) { var db = &SQLiteIPList{ itemTableName: "ipItems", versionTableName: "versions", dir: filepath.Clean(Tea.Root + "/data"), cleanTicker: time.NewTicker(24 * time.Hour), } err := db.init() return db, err } func (this *SQLiteIPList) init() error { // 检查目录是否存在 _, err := os.Stat(this.dir) if err != nil { err = os.MkdirAll(this.dir, 0777) if err != nil { return err } remotelogs.Println("IP_LIST_DB", "create data dir '"+this.dir+"'") } var path = this.dir + "/ip_list.db" db, err := dbs.OpenWriter("file:" + path + "?cache=shared&mode=rwc&_journal_mode=WAL&_sync=" + dbs.SyncMode + "&_locking_mode=EXCLUSIVE") if err != nil { return err } db.SetMaxOpenConns(1) //_, err = db.Exec("VACUUM") //if err != nil { // return err //} this.db = db // 恢复数据库 var recoverEnv, _ = os.LookupEnv("EdgeRecover") if len(recoverEnv) > 0 { for _, indexName := range []string{"ip_list_itemId", "ip_list_expiredAt"} { _, _ = db.Exec(`REINDEX "` + indexName + `"`) } } // 初始化数据库 _, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + this.itemTableName + `" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "listId" integer DEFAULT 0, "listType" varchar(32), "isGlobal" integer(1) DEFAULT 0, "type" varchar(16), "itemId" integer DEFAULT 0, "ipFrom" varchar(64) DEFAULT 0, "ipTo" varchar(64) DEFAULT 0, "expiredAt" integer DEFAULT 0, "eventLevel" varchar(32), "isDeleted" integer(1) DEFAULT 0, "version" integer DEFAULT 0, "nodeId" integer DEFAULT 0, "serverId" integer DEFAULT 0 ); CREATE INDEX IF NOT EXISTS "ip_list_itemId" ON "` + this.itemTableName + `" ( "itemId" ASC ); CREATE INDEX IF NOT EXISTS "ip_list_expiredAt" ON "` + this.itemTableName + `" ( "expiredAt" ASC ); `) if err != nil { return err } _, err = db.Exec(`CREATE TABLE IF NOT EXISTS "` + this.versionTableName + `" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "version" integer DEFAULT 0 ); `) if err != nil { return err } // 初始化SQL语句 this.deleteExpiredItemsStmt, err = this.db.Prepare(`DELETE FROM "` + this.itemTableName + `" WHERE "expiredAt">0 AND "expiredAt"