// 初始化或重置 cursor 的脚本 package main import ( "context" "database/sql" "fmt" "log" "strings" "time" _ "github.com/lib/pq" ) const ( pgHost = "localhost" pgPort = 5432 pgUser = "postgres" pgPassword = "postgres" pgDatabase = "trustlog" ) func main() { fmt.Println("🔧 Cursor Initialization Tool") fmt.Println(strings.Repeat("=", 60)) // 连接数据库 dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", pgHost, pgPort, pgUser, pgPassword, pgDatabase) db, err := sql.Open("postgres", dsn) if err != nil { log.Fatalf("Failed to connect: %v", err) } defer db.Close() if err := db.Ping(); err != nil { log.Fatalf("Failed to ping: %v", err) } fmt.Println("✅ Connected to PostgreSQL") fmt.Println() ctx := context.Background() // 查询最早的 NOT_TRUSTLOGGED 记录 var earliestTime sql.NullTime err = db.QueryRowContext(ctx, "SELECT MIN(created_at) FROM operation WHERE trustlog_status = 'NOT_TRUSTLOGGED'", ).Scan(&earliestTime) if err != nil { log.Fatalf("Failed to query earliest record: %v", err) } var cursorValue string if earliestTime.Valid { // 设置为最早记录之前 1 秒 cursorValue = earliestTime.Time.Add(-1 * time.Second).Format(time.RFC3339Nano) fmt.Printf("📊 Earliest NOT_TRUSTLOGGED record: %v\n", earliestTime.Time) fmt.Printf("📍 Setting cursor to: %s\n", cursorValue) } else { // 如果没有未存证记录,使用一个很早的时间 cursorValue = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Format(time.RFC3339Nano) fmt.Println("📊 No NOT_TRUSTLOGGED records found") fmt.Printf("📍 Setting cursor to default: %s\n", cursorValue) } fmt.Println() // 插入或更新 cursor _, err = db.ExecContext(ctx, ` INSERT INTO trustlog_cursor (cursor_key, cursor_value, last_updated_at) VALUES ($1, $2, $3) ON CONFLICT (cursor_key) DO UPDATE SET cursor_value = EXCLUDED.cursor_value, last_updated_at = EXCLUDED.last_updated_at `, "operation_scan", cursorValue, time.Now()) if err != nil { log.Fatalf("Failed to init cursor: %v", err) } fmt.Println("✅ Cursor initialized successfully!") fmt.Println() // 验证 var savedValue string var updatedAt time.Time err = db.QueryRowContext(ctx, "SELECT cursor_value, last_updated_at FROM trustlog_cursor WHERE cursor_key = 'operation_scan'", ).Scan(&savedValue, &updatedAt) if err != nil { log.Fatalf("Failed to verify cursor: %v", err) } fmt.Println("📊 Cursor Status:") fmt.Printf(" Key: operation_scan\n") fmt.Printf(" Value: %s\n", savedValue) fmt.Printf(" Updated: %v\n", updatedAt) fmt.Println() // 统计 var notTrustloggedCount int db.QueryRowContext(ctx, "SELECT COUNT(*) FROM operation WHERE trustlog_status = 'NOT_TRUSTLOGGED'").Scan(¬TrustloggedCount) fmt.Printf("📝 Records to process: %d\n", notTrustloggedCount) fmt.Println() fmt.Println("✅ Cursor Worker 现在会处理这些记录") fmt.Println(strings.Repeat("=", 60)) }