Ensure unique indexes work with record ids
This commit is contained in:
parent
ef3ec7c51f
commit
9819b64dc6
2 changed files with 90 additions and 14 deletions
|
@ -1075,14 +1075,14 @@ func TestDefine(t *testing.T) {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("Define a unique index on a table, and ensure it prevents duplicate record values", t, func() {
|
Convey("Define a single-field unique index on a table, and ensure it prevents duplicate record values", t, func() {
|
||||||
|
|
||||||
setupDB(20)
|
setupDB(20)
|
||||||
|
|
||||||
txt := `
|
txt := `
|
||||||
USE NS test DB test;
|
USE NS test DB test;
|
||||||
DEFINE INDEX test ON person COLUMNS account, email UNIQUE;
|
DEFINE INDEX test ON person COLUMNS email UNIQUE;
|
||||||
UPDATE person:one SET account="demo", email="info@demo.com";
|
UPDATE person:one SET account="one", email="info@demo.com";
|
||||||
UPDATE person:one SET account="demo", email="info@demo.com";
|
UPDATE person:one SET account="demo", email="info@demo.com";
|
||||||
UPDATE person:one SET account="demo", email="info@demo.com";
|
UPDATE person:one SET account="demo", email="info@demo.com";
|
||||||
UPDATE person:two SET account="demo", email="info@demo.com";
|
UPDATE person:two SET account="demo", email="info@demo.com";
|
||||||
|
@ -1109,6 +1109,78 @@ func TestDefine(t *testing.T) {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("Define a multiple-field unique index on a table, and ensure it prevents duplicate record values", t, func() {
|
||||||
|
|
||||||
|
setupDB(20)
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
USE NS test DB test;
|
||||||
|
DEFINE INDEX test ON person COLUMNS account, email UNIQUE;
|
||||||
|
UPDATE person:one SET account="one", email="info@demo.com";
|
||||||
|
UPDATE person:one SET account="one", email="info@demo.com";
|
||||||
|
UPDATE person:one SET account="one", email="info@demo.com";
|
||||||
|
UPDATE person:two SET account="two", email="info@demo.com";
|
||||||
|
UPDATE person:tre SET account="tre", email="info@demo.com";
|
||||||
|
SELECT * FROM person ORDER BY meta.id;
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 8)
|
||||||
|
So(res[1].Status, ShouldEqual, "OK")
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[2].Status, ShouldEqual, "OK")
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Status, ShouldEqual, "OK")
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Status, ShouldEqual, "OK")
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Status, ShouldEqual, "OK")
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Status, ShouldEqual, "OK")
|
||||||
|
So(res[7].Result, ShouldHaveLength, 3)
|
||||||
|
So(data.Consume(res[7].Result[0]).Get("id").Data(), ShouldResemble, &sql.Thing{"person", "one"})
|
||||||
|
So(data.Consume(res[7].Result[1]).Get("id").Data(), ShouldResemble, &sql.Thing{"person", "tre"})
|
||||||
|
So(data.Consume(res[7].Result[2]).Get("id").Data(), ShouldResemble, &sql.Thing{"person", "two"})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Define a multiple-field foreign record unique index on a table, and ensure it prevents duplicate record values", t, func() {
|
||||||
|
|
||||||
|
setupDB(20)
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
USE NS test DB test;
|
||||||
|
DEFINE INDEX test ON person COLUMNS account, email UNIQUE;
|
||||||
|
UPDATE person:one SET account=tester:one, email="info@demo.com";
|
||||||
|
UPDATE person:one SET account=tester:one, email="info@demo.com";
|
||||||
|
UPDATE person:one SET account=tester:one, email="info@demo.com";
|
||||||
|
UPDATE person:two SET account=tester:two, email="info@demo.com";
|
||||||
|
UPDATE person:tre SET account=tester:tre, email="info@demo.com";
|
||||||
|
SELECT * FROM person ORDER BY meta.id;
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 8)
|
||||||
|
So(res[1].Status, ShouldEqual, "OK")
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[2].Status, ShouldEqual, "OK")
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Status, ShouldEqual, "OK")
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Status, ShouldEqual, "OK")
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Status, ShouldEqual, "OK")
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Status, ShouldEqual, "OK")
|
||||||
|
So(res[7].Result, ShouldHaveLength, 3)
|
||||||
|
So(data.Consume(res[7].Result[0]).Get("id").Data(), ShouldResemble, &sql.Thing{"person", "one"})
|
||||||
|
So(data.Consume(res[7].Result[1]).Get("id").Data(), ShouldResemble, &sql.Thing{"person", "tre"})
|
||||||
|
So(data.Consume(res[7].Result[2]).Get("id").Data(), ShouldResemble, &sql.Thing{"person", "two"})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
Convey("Redefine a unique index on a table, and ensure it prevents duplicate record values", t, func() {
|
Convey("Redefine a unique index on a table, and ensure it prevents duplicate record values", t, func() {
|
||||||
|
|
||||||
setupDB(20)
|
setupDB(20)
|
||||||
|
|
|
@ -360,7 +360,7 @@ func (d *document) storeThing(ctx context.Context) (err error) {
|
||||||
|
|
||||||
defer d.ulock(ctx)
|
defer d.ulock(ctx)
|
||||||
|
|
||||||
// Check that the rcord has been
|
// Check that the record has been
|
||||||
// changed, and if not, return.
|
// changed, and if not, return.
|
||||||
|
|
||||||
if ok := d.changed(ctx); !ok {
|
if ok := d.changed(ctx); !ok {
|
||||||
|
@ -475,27 +475,31 @@ func (d *document) storeIndex(ctx context.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ix.Uniq == true {
|
if ix.Uniq == true {
|
||||||
for _, v := range del {
|
for _, f := range del {
|
||||||
didx := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: v}
|
enfd := data.Consume(f).Encode()
|
||||||
|
didx := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd}
|
||||||
d.i.e.dbo.DelC(ctx, d.i.e.time, didx.Encode(), d.id.Bytes())
|
d.i.e.dbo.DelC(ctx, d.i.e.time, didx.Encode(), d.id.Bytes())
|
||||||
}
|
}
|
||||||
for _, v := range add {
|
for _, f := range add {
|
||||||
aidx := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: v}
|
enfd := data.Consume(f).Encode()
|
||||||
|
aidx := &keys.Index{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd}
|
||||||
if _, err = d.i.e.dbo.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
|
if _, err = d.i.e.dbo.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
|
||||||
return &IndexError{tb: d.key.TB, name: ix.Name, cols: ix.Cols, vals: v}
|
return &IndexError{tb: d.key.TB, name: ix.Name, cols: ix.Cols, vals: f}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ix.Uniq == false {
|
if ix.Uniq == false {
|
||||||
for _, v := range del {
|
for _, f := range del {
|
||||||
didx := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: v, ID: d.key.ID}
|
enfd := data.Consume(f).Encode()
|
||||||
|
didx := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd, ID: d.key.ID}
|
||||||
d.i.e.dbo.DelC(ctx, d.i.e.time, didx.Encode(), d.id.Bytes())
|
d.i.e.dbo.DelC(ctx, d.i.e.time, didx.Encode(), d.id.Bytes())
|
||||||
}
|
}
|
||||||
for _, v := range add {
|
for _, f := range add {
|
||||||
aidx := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: v, ID: d.key.ID}
|
enfd := data.Consume(f).Encode()
|
||||||
|
aidx := &keys.Point{KV: d.key.KV, NS: d.key.NS, DB: d.key.DB, TB: d.key.TB, IX: ix.Name.VA, FD: enfd, ID: d.key.ID}
|
||||||
if _, err = d.i.e.dbo.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
|
if _, err = d.i.e.dbo.PutC(ctx, 0, aidx.Encode(), d.id.Bytes(), nil); err != nil {
|
||||||
return &IndexError{tb: d.key.TB, name: ix.Name, cols: ix.Cols, vals: v}
|
return &IndexError{tb: d.key.TB, name: ix.Name, cols: ix.Cols, vals: f}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue