Files
ai_site/platform/internal/dbsync/echo.go
2026-07-31 10:31:17 +08:00

78 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}
}