chore: initial commit of ai site platform

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
whm
2026-07-31 10:31:17 +08:00
commit 4ca82fb58a
203 changed files with 45745 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
package dbsync
import (
"context"
"database/sql"
"fmt"
"time"
)
const FlagTable = "_ajz_sync_flag"
// EnsureFlagTableSQLite 用表标记「正在应用远端变更」,避免触发器回声。
func EnsureFlagTable(ctx context.Context, db *sql.DB, driver Driver) error {
if driver != DriverSQLite {
return nil
}
_, err := db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS `+FlagTable+` (
k TEXT PRIMARY KEY,
v INTEGER NOT NULL DEFAULT 0
);`)
if err != nil {
return err
}
_, _ = db.ExecContext(ctx, `INSERT OR IGNORE INTO `+FlagTable+`(k,v) VALUES('applying',0)`)
return nil
}
// WithApplying 在写入目标库时置位,使触发器不写 outbox防 A↔B 回声导致「多」)。
func WithApplying(ctx context.Context, db *sql.DB, driver Driver, fn func() error) error {
switch driver {
case DriverSQLite:
if err := EnsureFlagTable(ctx, db, driver); err != nil {
return err
}
if _, err := db.ExecContext(ctx, `UPDATE `+FlagTable+` SET v=1 WHERE k='applying'`); err != nil {
return err
}
defer func() {
_, _ = db.ExecContext(context.Background(), `UPDATE `+FlagTable+` SET v=0 WHERE k='applying'`)
}()
return fn()
case DriverMySQL:
if _, err := db.ExecContext(ctx, `SET @ajz_applying = 1`); err != nil {
return err
}
defer func() { _, _ = db.ExecContext(context.Background(), `SET @ajz_applying = 0`) }()
return fn()
case DriverPostgres:
if _, err := db.ExecContext(ctx, `SELECT set_config('ajz.applying', '1', false)`); err != nil {
return err
}
defer func() {
_, _ = db.ExecContext(context.Background(), `SELECT set_config('ajz.applying', '0', false)`)
}()
return fn()
default:
return fn()
}
}
func EnqueueOutbox(ctx context.Context, db *sql.DB, driver Driver, table, pk, op, payload string, version int64) error {
if version <= 0 {
version = time.Now().UnixMilli()
}
switch driver {
case DriverPostgres:
_, err := db.ExecContext(ctx, fmt.Sprintf(`
INSERT INTO %s(table_name,row_pk,op,payload,version) VALUES($1,$2,$3,$4,$5)`, OutboxTable),
table, pk, op, payload, version)
return err
default:
_, err := db.ExecContext(ctx, fmt.Sprintf(`
INSERT INTO %s(table_name,row_pk,op,payload,version) VALUES(?,?,?,?,?)`, OutboxTable),
table, pk, op, payload, version)
return err
}
}