mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-10 00:31:10 +08:00
修改监控为证书监控支持文件导入和smtp监控
监控支持多渠道通知 将静态文件打包到二进制文件
This commit is contained in:
@@ -58,11 +58,6 @@ func NewSqlite(DbFile string, PreFix string) (*Sqlite, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = s.Conn.Exec("PRAGMA busy_timeout = 5000;")
|
||||
if err != nil {
|
||||
s.Close()
|
||||
return nil, fmt.Errorf("设置PRAGMA busy_timeout失败: %w", err)
|
||||
}
|
||||
|
||||
return &s, nil
|
||||
}
|
||||
@@ -80,7 +75,8 @@ func FileExists(file string) bool {
|
||||
* @return error 错误信息
|
||||
*/
|
||||
func (s *Sqlite) Connect() error {
|
||||
conn, err := sql.Open("sqlite", s.DbFile)
|
||||
dsn := fmt.Sprintf("file:%s?_pragma=busy_timeout(60000)", s.DbFile)
|
||||
conn, err := sql.Open("sqlite", dsn)
|
||||
if err == nil {
|
||||
s.Conn = conn
|
||||
s.closed = false
|
||||
|
||||
@@ -21,3 +21,58 @@ func Test(t *testing.T) {
|
||||
fmt.Println("错误:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test1(t *testing.T) {
|
||||
err := os.Chdir("D:/code/ALLinSSL")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "切换目录失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
columnMapping := map[string]string{
|
||||
"name": "name",
|
||||
"site_domain": "target",
|
||||
"report_type": "report_types",
|
||||
"active": "active",
|
||||
"last_time": "last_time",
|
||||
"except_end_time": "except_end_time",
|
||||
"update_time": "update_time",
|
||||
"create_time": "create_time",
|
||||
"cycle": "cycle",
|
||||
"repeat_send_gap": "repeat_send_gap",
|
||||
}
|
||||
|
||||
createTableSQL := `
|
||||
create table monitor
|
||||
(
|
||||
id integer not null
|
||||
constraint monitor_pk
|
||||
primary key autoincrement,
|
||||
name TEXT not null,
|
||||
target TEXT not null,
|
||||
monitor_type TEXT default 'https' not null,
|
||||
report_types TEXT not null,
|
||||
active integer default 1,
|
||||
info TEXT,
|
||||
last_time TEXT,
|
||||
except_end_time TEXT,
|
||||
update_time TEXT,
|
||||
create_time TEXT,
|
||||
cycle integer,
|
||||
repeat_send_gap integer default 10,
|
||||
advance_day integer default 30,
|
||||
valid INTEGER default 0 not null
|
||||
);`
|
||||
|
||||
err = MigrateSQLiteTable(
|
||||
"data/site_monitor.db",
|
||||
"site_monitor",
|
||||
"data/monitor.db",
|
||||
"monitor",
|
||||
columnMapping,
|
||||
createTableSQL,
|
||||
1000,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("迁移失败:", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,150 @@ func joinStrings(strs []string, sep string) string {
|
||||
return result
|
||||
}
|
||||
|
||||
// MigrateSQLiteTable 迁移方法
|
||||
func MigrateSQLiteTable(sourceDBPath, sourceTable, targetDBPath, targetTable string, columnMapping map[string]string, createTableSQL string, batchSize int) error {
|
||||
// 打开目标数据库
|
||||
targetDB, err := sql.Open("sqlite", targetDBPath)
|
||||
if err != nil {
|
||||
//return fmt.Errorf("打开目标数据库失败: %v", err)
|
||||
}
|
||||
defer targetDB.Close()
|
||||
|
||||
// 检查目标表
|
||||
exists, err := tableExists(targetDB, targetTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
//fmt.Printf("目标表 %s 已存在,跳过迁移。\n", targetTable)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建目标表
|
||||
//fmt.Printf("目标表 %s 不存在,正在创建...\n", targetTable)
|
||||
if _, err := targetDB.Exec(createTableSQL); err != nil {
|
||||
//return fmt.Errorf("创建目标表失败: %v", err)
|
||||
}
|
||||
fmt.Printf("目标表 %s 创建成功。\n", targetTable)
|
||||
|
||||
// 打开源数据库
|
||||
sourceDB, err := sql.Open("sqlite", sourceDBPath)
|
||||
if err != nil {
|
||||
//return fmt.Errorf("打开源数据库失败: %v", err)
|
||||
}
|
||||
defer sourceDB.Close()
|
||||
|
||||
// 检查源表
|
||||
exists, err = tableExists(sourceDB, sourceTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
//return fmt.Errorf("源表 %s 不存在,迁移终止", sourceTable)
|
||||
}
|
||||
|
||||
// 构建列映射
|
||||
sourceCols, targetCols, placeholders := buildColumnMappings(columnMapping)
|
||||
|
||||
selectSQL := fmt.Sprintf("SELECT %s FROM %s", sourceCols, sourceTable)
|
||||
insertSQL := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", targetTable, targetCols, placeholders)
|
||||
|
||||
rows, err := sourceDB.Query(selectSQL)
|
||||
if err != nil {
|
||||
//return fmt.Errorf("查询源数据失败: %v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
stmt, err := targetDB.Prepare(insertSQL)
|
||||
if err != nil {
|
||||
//return fmt.Errorf("准备插入语句失败: %v", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
colCount := len(columnMapping)
|
||||
batch := make([][]interface{}, 0, batchSize)
|
||||
total := 0
|
||||
|
||||
for rows.Next() {
|
||||
values := make([]interface{}, colCount)
|
||||
ptrs := make([]interface{}, colCount)
|
||||
for i := range ptrs {
|
||||
ptrs[i] = &values[i]
|
||||
}
|
||||
|
||||
if err := rows.Scan(ptrs...); err != nil {
|
||||
//return fmt.Errorf("读取行数据失败: %v", err)
|
||||
}
|
||||
|
||||
batch = append(batch, values)
|
||||
total++
|
||||
|
||||
if len(batch) >= batchSize {
|
||||
if err := insertBatch(targetDB, stmt, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
batch = batch[:0]
|
||||
}
|
||||
}
|
||||
|
||||
if len(batch) > 0 {
|
||||
if err := insertBatch(targetDB, stmt, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
//fmt.Printf("数据迁移完成,共迁移 %d 条记录。\n", total)
|
||||
return nil
|
||||
}
|
||||
|
||||
// tableExists 检查表是否存在
|
||||
func tableExists(db *sql.DB, tableName string) (bool, error) {
|
||||
query := `SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?`
|
||||
var count int
|
||||
if err := db.QueryRow(query, tableName).Scan(&count); err != nil {
|
||||
return false, fmt.Errorf("检查表是否存在失败: %v", err)
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// buildColumnMappings 构建列映射 SQL 片段
|
||||
func buildColumnMappings(mapping map[string]string) (string, string, string) {
|
||||
srcCols := ""
|
||||
tgtCols := ""
|
||||
placeholders := ""
|
||||
i := 0
|
||||
for src, tgt := range mapping {
|
||||
if i > 0 {
|
||||
srcCols += ", "
|
||||
tgtCols += ", "
|
||||
placeholders += ", "
|
||||
}
|
||||
srcCols += src
|
||||
tgtCols += tgt
|
||||
placeholders += "?"
|
||||
i++
|
||||
}
|
||||
return srcCols, tgtCols, placeholders
|
||||
}
|
||||
|
||||
// insertBatch 批量插入数据
|
||||
func insertBatch(db *sql.DB, stmt *sql.Stmt, batch [][]interface{}) error {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("开启事务失败: %v", err)
|
||||
}
|
||||
for _, vals := range batch {
|
||||
if _, err := tx.Stmt(stmt).Exec(vals...); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("插入数据失败: %v", err)
|
||||
}
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("提交事务失败: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 示例用法
|
||||
func main() {
|
||||
err := EnsureDatabaseWithTables(
|
||||
|
||||
Reference in New Issue
Block a user