package store import ( "database/sql" "fmt" "strings" ) // dialect 收敛 SQLite / PostgreSQL 差异。全部查询以 ? 占位符书写,PG 执行前 rebind。 type dialect interface { name() string rebind(query string) string // lockConversation 在事务内锁定会话的事件序列分配(跨实例安全)。 // PG:事务级咨询锁;SQLite:单写连接天然串行,无需额外锁。 lockConversation(tx *sql.Tx, conversationID string) error // lockScope 锁定设置 scope 的读改写(owner+scope)。 lockScope(tx *sql.Tx, owner, scope string) error // lockAdmission 锁定执行许可账本的清点与登记(U3 admission)。 lockAdmission(tx *sql.Tx) error // lockBootstrap 锁定首次管理员引导的「核验无用户→建号→激活 Key」串行段 //(KTD12:防两个进程并发引导出双管理员)。 lockBootstrap(tx *sql.Tx) error // lockAccount serializes credential and session admission for one owner. lockAccount(tx *sql.Tx, owner string) error } // ---- SQLite(嵌入式档)---- type sqliteDialect struct{} func (sqliteDialect) name() string { return "sqlite" } func (sqliteDialect) rebind(q string) string { return q } func (sqliteDialect) lockConversation(*sql.Tx, string) error { return nil } func (sqliteDialect) lockScope(*sql.Tx, string, string) error { return nil } func (sqliteDialect) lockAdmission(*sql.Tx) error { return nil } func (sqliteDialect) lockBootstrap(*sql.Tx) error { return nil } func (sqliteDialect) lockAccount(*sql.Tx, string) error { return nil } // ---- PostgreSQL(多用户/多实例档)---- type postgresDialect struct{} func (postgresDialect) name() string { return "postgres" } func (postgresDialect) rebind(q string) string { var b strings.Builder n := 0 for i := 0; i < len(q); i++ { if q[i] == '?' { n++ fmt.Fprintf(&b, "$%d", n) continue } b.WriteByte(q[i]) } return b.String() } func (postgresDialect) lockConversation(tx *sql.Tx, conversationID string) error { _, err := tx.Exec(`SELECT pg_advisory_xact_lock(hashtext($1))`, "conv:"+conversationID) return err } func (postgresDialect) lockScope(tx *sql.Tx, owner, scope string) error { _, err := tx.Exec(`SELECT pg_advisory_xact_lock(hashtext($1))`, "scope:"+owner+"/"+scope) return err } func (postgresDialect) lockAdmission(tx *sql.Tx) error { _, err := tx.Exec(`SELECT pg_advisory_xact_lock(hashtext($1))`, "admission:exec-slots") return err } func (postgresDialect) lockBootstrap(tx *sql.Tx) error { _, err := tx.Exec(`SELECT pg_advisory_xact_lock(hashtext($1))`, "bootstrap:first-admin") return err } func (postgresDialect) lockAccount(tx *sql.Tx, owner string) error { _, err := tx.Exec(`SELECT pg_advisory_xact_lock(hashtext($1))`, "account:"+owner) return err }