feat: harden loose-offline sync for user JWT, schema, and console ops
Enable Binding-scoped agent push/pull, empty-table schema ensure, SyncPage inspect/drop-table, default module import, and agent-bound publish docs from the 宇恒联调意见. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
73
platform/internal/dbsync/pull_test.go
Normal file
73
platform/internal/dbsync/pull_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package dbsync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPullFromRemoteBootstrapAndRows(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
dbPath := filepath.Join(dir, "remote.db")
|
||||
dsn := "file:" + filepath.ToSlash(dbPath) + "?_pragma=foreign_keys(1)"
|
||||
|
||||
db, err := Open(DriverSQLite, dsn)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
ctx := context.Background()
|
||||
if _, err := db.ExecContext(ctx, `CREATE TABLE orders (id TEXT PRIMARY KEY, title TEXT)`); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := EnsureMeta(ctx, db, DriverSQLite); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, id := range []string{"a-1", "a-2", "b-1"} {
|
||||
if _, err := db.ExecContext(ctx, `INSERT INTO orders(id,title) VALUES(?,?)`, id, "t-"+id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_ = UpsertMeta(ctx, db, DriverSQLite, "orders", id, time.Now().UnixNano())
|
||||
}
|
||||
_ = db.Close()
|
||||
|
||||
st, err := NewFileStore(filepath.Join(dir, "dbsync"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ch := &Channel{
|
||||
ID: "ch1",
|
||||
TenantID: 1,
|
||||
Remote: Endpoint{
|
||||
Driver: DriverSQLite,
|
||||
DSN: dsn,
|
||||
Tables: []string{"orders"},
|
||||
},
|
||||
PKColumns: map[string]string{"orders": "id"},
|
||||
}
|
||||
|
||||
boot, err := PullFromRemote(ctx, ch, st, PullRequest{Mode: PullModeBootstrap, Table: "orders", Limit: 2})
|
||||
if err != nil || !boot.OK || len(boot.Items) != 2 || !boot.HasMore {
|
||||
t.Fatalf("bootstrap page1: %+v err=%v", boot, err)
|
||||
}
|
||||
boot2, err := PullFromRemote(ctx, ch, st, PullRequest{
|
||||
Mode: PullModeBootstrap, Table: "orders", Limit: 2, AfterPK: boot.NextAfterPK,
|
||||
})
|
||||
if err != nil || len(boot2.Items) != 1 || boot2.HasMore {
|
||||
t.Fatalf("bootstrap page2: %+v err=%v", boot2, err)
|
||||
}
|
||||
|
||||
pks, err := PullFromRemote(ctx, ch, st, PullRequest{Mode: PullModePKs, Table: "orders", Limit: 10})
|
||||
if err != nil || len(pks.PKs) != 3 {
|
||||
t.Fatalf("pks: %+v err=%v", pks, err)
|
||||
}
|
||||
|
||||
rows, err := PullFromRemote(ctx, ch, st, PullRequest{
|
||||
Mode: PullModeRows, Table: "orders", RowPKs: []string{"a-2", "missing"},
|
||||
})
|
||||
if err != nil || len(rows.Items) != 1 || rows.Items[0].RowPK != "a-2" {
|
||||
t.Fatalf("rows: %+v err=%v", rows, err)
|
||||
}
|
||||
CloseAllRemotes()
|
||||
}
|
||||
Reference in New Issue
Block a user