// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. package iplibrary import ( "database/sql" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeNode/internal/events" "github.com/TeaOSLab/EdgeNode/internal/goman" "github.com/TeaOSLab/EdgeNode/internal/remotelogs" "github.com/iwind/TeaGo/Tea" _ "github.com/mattn/go-sqlite3" "os" "path/filepath" "time" ) type IPListDB struct { db *sql.DB itemTableName string deleteExpiredItemsStmt *sql.Stmt deleteItemStmt *sql.Stmt insertItemStmt *sql.Stmt selectItemsStmt *sql.Stmt selectMaxVersionStmt *sql.Stmt cleanTicker *time.Ticker dir string isClosed bool } func NewIPListDB() (*IPListDB, error) { var db = &IPListDB{ itemTableName: "ipItems", dir: filepath.Clean(Tea.Root + "/data"), cleanTicker: time.NewTicker(24 * time.Hour), } err := db.init() return db, err } func (this *IPListDB) 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+"'") } db, err := sql.Open("sqlite3", "file:"+this.dir+"/ip_list.db?cache=shared&mode=rwc&_journal_mode=WAL&_sync=OFF") if err != nil { return err } db.SetMaxOpenConns(1) //_, err = db.Exec("VACUUM") //if err != nil { // return err //} this.db = db // 初始化数据库 _, 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 } // 初始化SQL语句 this.deleteExpiredItemsStmt, err = this.db.Prepare(`DELETE FROM "` + this.itemTableName + `" WHERE "expiredAt">0 AND "expiredAt"