Add support for table versioning
This commit is contained in:
parent
de925ae16e
commit
8b0674c66d
5 changed files with 92 additions and 46 deletions
|
@ -341,6 +341,21 @@ func (d *document) shouldDrop(ctx context.Context) (bool, error) {
|
|||
|
||||
}
|
||||
|
||||
func (d *document) shouldVersn(ctx context.Context) (bool, error) {
|
||||
|
||||
// Check whether it is specified
|
||||
// that the table should drop
|
||||
// writes, and if so, then return.
|
||||
|
||||
tb, err := d.getTB(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return tb.Vers, err
|
||||
|
||||
}
|
||||
|
||||
func (d *document) storeThing(ctx context.Context) (err error) {
|
||||
|
||||
defer d.ulock(ctx)
|
||||
|
@ -362,7 +377,13 @@ func (d *document) storeThing(ctx context.Context) (err error) {
|
|||
// Write the value to the data
|
||||
// layer and return any errors.
|
||||
|
||||
if ok, err := d.shouldVersn(ctx); err != nil {
|
||||
return err
|
||||
} else if ok == true {
|
||||
_, err = d.i.e.dbo.Put(ctx, d.i.e.time, d.key.Encode(), d.current.Encode())
|
||||
} else if ok == false {
|
||||
_, err = d.i.e.dbo.Put(ctx, 0, d.key.Encode(), d.current.Encode())
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
|
@ -382,7 +403,13 @@ func (d *document) purgeThing(ctx context.Context) (err error) {
|
|||
// Reset the item by writing a
|
||||
// nil value to the storage.
|
||||
|
||||
if ok, err := d.shouldVersn(ctx); err != nil {
|
||||
return err
|
||||
} else if ok == true {
|
||||
_, err = d.i.e.dbo.Put(ctx, d.i.e.time, d.key.Encode(), nil)
|
||||
} else if ok == false {
|
||||
_, err = d.i.e.dbo.Clr(ctx, d.key.Encode())
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
|
|
|
@ -1923,6 +1923,7 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
txt := `
|
||||
USE NS test DB test;
|
||||
DEFINE TABLE person VERSIONED;
|
||||
CREATE |person:1..10|;
|
||||
SELECT * FROM person VERSION "2017-01-01";
|
||||
SELECT * FROM person;
|
||||
|
@ -1930,10 +1931,10 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
res, err := Execute(setupKV(), txt, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldHaveLength, 4)
|
||||
So(res[1].Result, ShouldHaveLength, 10)
|
||||
So(res[2].Result, ShouldHaveLength, 0)
|
||||
So(res[3].Result, ShouldHaveLength, 10)
|
||||
So(res, ShouldHaveLength, 5)
|
||||
So(res[2].Result, ShouldHaveLength, 10)
|
||||
So(res[3].Result, ShouldHaveLength, 0)
|
||||
So(res[4].Result, ShouldHaveLength, 10)
|
||||
|
||||
})
|
||||
|
||||
|
@ -1943,6 +1944,7 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
txt := `
|
||||
USE NS test DB test;
|
||||
DEFINE TABLE person VERSIONED;
|
||||
LET date = "2017-01-01";
|
||||
CREATE |person:1..10|;
|
||||
SELECT * FROM person VERSION $date;
|
||||
|
@ -1951,10 +1953,10 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
res, err := Execute(setupKV(), txt, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldHaveLength, 5)
|
||||
So(res[2].Result, ShouldHaveLength, 10)
|
||||
So(res[3].Result, ShouldHaveLength, 0)
|
||||
So(res[4].Result, ShouldHaveLength, 10)
|
||||
So(res, ShouldHaveLength, 6)
|
||||
So(res[3].Result, ShouldHaveLength, 10)
|
||||
So(res[4].Result, ShouldHaveLength, 0)
|
||||
So(res[5].Result, ShouldHaveLength, 10)
|
||||
|
||||
})
|
||||
|
||||
|
@ -1964,6 +1966,7 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
txt := `
|
||||
USE NS test DB test;
|
||||
DEFINE TABLE person VERSIONED;
|
||||
LET time = "2017-01-01T15:04:05+07:00";
|
||||
CREATE |person:1..10|;
|
||||
SELECT * FROM person VERSION $time;
|
||||
|
@ -1972,10 +1975,10 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
res, err := Execute(setupKV(), txt, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldHaveLength, 5)
|
||||
So(res[2].Result, ShouldHaveLength, 10)
|
||||
So(res[3].Result, ShouldHaveLength, 0)
|
||||
So(res[4].Result, ShouldHaveLength, 10)
|
||||
So(res, ShouldHaveLength, 6)
|
||||
So(res[3].Result, ShouldHaveLength, 10)
|
||||
So(res[4].Result, ShouldHaveLength, 0)
|
||||
So(res[5].Result, ShouldHaveLength, 10)
|
||||
|
||||
})
|
||||
|
||||
|
@ -1985,6 +1988,7 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
txt := `
|
||||
USE NS test DB test;
|
||||
DEFINE TABLE person VERSIONED;
|
||||
LET time = "test";
|
||||
CREATE |person:1..10|;
|
||||
SELECT * FROM person VERSION $time;
|
||||
|
@ -1993,12 +1997,12 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
res, err := Execute(setupKV(), txt, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldHaveLength, 5)
|
||||
So(res[2].Result, ShouldHaveLength, 10)
|
||||
So(res[3].Result, ShouldHaveLength, 0)
|
||||
So(res[3].Status, ShouldEqual, "ERR")
|
||||
So(res[3].Detail, ShouldEqual, "Found 'test' but VERSION expression must be a date or time")
|
||||
So(res[4].Result, ShouldHaveLength, 10)
|
||||
So(res, ShouldHaveLength, 6)
|
||||
So(res[3].Result, ShouldHaveLength, 10)
|
||||
So(res[4].Result, ShouldHaveLength, 0)
|
||||
So(res[4].Status, ShouldEqual, "ERR")
|
||||
So(res[4].Detail, ShouldEqual, "Found 'test' but VERSION expression must be a date or time")
|
||||
So(res[5].Result, ShouldHaveLength, 10)
|
||||
|
||||
})
|
||||
|
||||
|
@ -2008,6 +2012,7 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
txt := `
|
||||
USE NS test DB test;
|
||||
DEFINE TABLE person VERSIONED;
|
||||
LET old = time.now();
|
||||
CREATE person:test;
|
||||
UPDATE person:test SET test = 1;
|
||||
|
@ -2025,19 +2030,19 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
res, err := Execute(setupKV(), txt, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldHaveLength, 14)
|
||||
So(res[3].Result, ShouldHaveLength, 1)
|
||||
So(res[5].Result, ShouldHaveLength, 1)
|
||||
So(res[7].Result, ShouldHaveLength, 1)
|
||||
So(res[9].Result, ShouldHaveLength, 0)
|
||||
So(res[10].Result, ShouldHaveLength, 1)
|
||||
So(data.Consume(res[10].Result[0]).Get("test").Data(), ShouldEqual, 1)
|
||||
So(res, ShouldHaveLength, 15)
|
||||
So(res[4].Result, ShouldHaveLength, 1)
|
||||
So(res[6].Result, ShouldHaveLength, 1)
|
||||
So(res[8].Result, ShouldHaveLength, 1)
|
||||
So(res[10].Result, ShouldHaveLength, 0)
|
||||
So(res[11].Result, ShouldHaveLength, 1)
|
||||
So(data.Consume(res[11].Result[0]).Get("test").Data(), ShouldEqual, 2)
|
||||
So(data.Consume(res[11].Result[0]).Get("test").Data(), ShouldEqual, 1)
|
||||
So(res[12].Result, ShouldHaveLength, 1)
|
||||
So(data.Consume(res[12].Result[0]).Get("test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[12].Result[0]).Get("test").Data(), ShouldEqual, 2)
|
||||
So(res[13].Result, ShouldHaveLength, 1)
|
||||
So(data.Consume(res[13].Result[0]).Get("test").Data(), ShouldEqual, 3)
|
||||
So(res[14].Result, ShouldHaveLength, 1)
|
||||
So(data.Consume(res[14].Result[0]).Get("test").Data(), ShouldEqual, 3)
|
||||
|
||||
})
|
||||
|
||||
|
@ -2047,6 +2052,7 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
txt := `
|
||||
USE NS test DB test;
|
||||
DEFINE TABLE person VERSIONED;
|
||||
LET old = time.now();
|
||||
CREATE |person:1..3|;
|
||||
UPDATE person:1, person:2, person:3 SET test = 1;
|
||||
|
@ -2064,27 +2070,27 @@ func TestSelect(t *testing.T) {
|
|||
|
||||
res, err := Execute(setupKV(), txt, nil)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldHaveLength, 14)
|
||||
So(res[3].Result, ShouldHaveLength, 3)
|
||||
So(res[5].Result, ShouldHaveLength, 3)
|
||||
So(res[7].Result, ShouldHaveLength, 3)
|
||||
So(res[9].Result, ShouldHaveLength, 0)
|
||||
So(res[10].Result, ShouldHaveLength, 3)
|
||||
So(data.Consume(res[10].Result).Get("0.test").Data(), ShouldEqual, 1)
|
||||
So(data.Consume(res[10].Result).Get("1.test").Data(), ShouldEqual, 1)
|
||||
So(data.Consume(res[10].Result).Get("2.test").Data(), ShouldEqual, 1)
|
||||
So(res, ShouldHaveLength, 15)
|
||||
So(res[4].Result, ShouldHaveLength, 3)
|
||||
So(res[6].Result, ShouldHaveLength, 3)
|
||||
So(res[8].Result, ShouldHaveLength, 3)
|
||||
So(res[10].Result, ShouldHaveLength, 0)
|
||||
So(res[11].Result, ShouldHaveLength, 3)
|
||||
So(data.Consume(res[11].Result).Get("0.test").Data(), ShouldEqual, 2)
|
||||
So(data.Consume(res[11].Result).Get("1.test").Data(), ShouldEqual, 2)
|
||||
So(data.Consume(res[11].Result).Get("2.test").Data(), ShouldEqual, 2)
|
||||
So(data.Consume(res[11].Result).Get("0.test").Data(), ShouldEqual, 1)
|
||||
So(data.Consume(res[11].Result).Get("1.test").Data(), ShouldEqual, 1)
|
||||
So(data.Consume(res[11].Result).Get("2.test").Data(), ShouldEqual, 1)
|
||||
So(res[12].Result, ShouldHaveLength, 3)
|
||||
So(data.Consume(res[12].Result).Get("0.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[12].Result).Get("1.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[12].Result).Get("2.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[12].Result).Get("0.test").Data(), ShouldEqual, 2)
|
||||
So(data.Consume(res[12].Result).Get("1.test").Data(), ShouldEqual, 2)
|
||||
So(data.Consume(res[12].Result).Get("2.test").Data(), ShouldEqual, 2)
|
||||
So(res[13].Result, ShouldHaveLength, 3)
|
||||
So(data.Consume(res[13].Result).Get("0.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[13].Result).Get("1.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[13].Result).Get("2.test").Data(), ShouldEqual, 3)
|
||||
So(res[14].Result, ShouldHaveLength, 3)
|
||||
So(data.Consume(res[14].Result).Get("0.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[14].Result).Get("1.test").Data(), ShouldEqual, 3)
|
||||
So(data.Consume(res[14].Result).Get("2.test").Data(), ShouldEqual, 3)
|
||||
|
||||
})
|
||||
|
||||
|
|
|
@ -361,9 +361,10 @@ func (this RemoveScopeStatement) String() string {
|
|||
|
||||
func (this DefineTableStatement) String() (s string) {
|
||||
w := maybe(this.Cond != nil, print(" WHERE %v", this.Cond))
|
||||
return print("DEFINE TABLE %v%v%v%v%v",
|
||||
return print("DEFINE TABLE %v%v%v%v%v%v",
|
||||
maybe(this.Name != nil, print("%s", this.Name), print("%s", this.What)),
|
||||
maybe(this.Full, " SCHEMAFULL"),
|
||||
maybe(this.Vers, " VERSIONED"),
|
||||
maybe(this.Drop, " DROP"),
|
||||
maybe(this.Lock, print(" AS SELECT %v FROM %v%v%v", this.Expr, this.From, w, this.Group)),
|
||||
maybe(this.Perms != nil, this.Perms),
|
||||
|
|
10
sql/table.go
10
sql/table.go
|
@ -28,7 +28,7 @@ func (p *parser) parseDefineTableStatement() (stmt *DefineTableStatement, err er
|
|||
|
||||
for {
|
||||
|
||||
tok, _, exi := p.mightBe(DROP, SCHEMAFULL, SCHEMALESS, PERMISSIONS, AS)
|
||||
tok, _, exi := p.mightBe(DROP, SCHEMAFULL, SCHEMALESS, VERSIONED, UNVERSIONED, PERMISSIONS, AS)
|
||||
if !exi {
|
||||
break
|
||||
}
|
||||
|
@ -45,6 +45,14 @@ func (p *parser) parseDefineTableStatement() (stmt *DefineTableStatement, err er
|
|||
stmt.Full = false
|
||||
}
|
||||
|
||||
if is(tok, VERSIONED) {
|
||||
stmt.Vers = true
|
||||
}
|
||||
|
||||
if is(tok, UNVERSIONED) {
|
||||
stmt.Vers = false
|
||||
}
|
||||
|
||||
if is(tok, PERMISSIONS) {
|
||||
if stmt.Perms, err = p.parsePerms(); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -191,11 +191,13 @@ const (
|
|||
TRUE
|
||||
TYPE
|
||||
UNIQUE
|
||||
UNVERSIONED
|
||||
UPDATE
|
||||
UPSERT
|
||||
USE
|
||||
VALUE
|
||||
VERSION
|
||||
VERSIONED
|
||||
VOID
|
||||
WHEN
|
||||
WHERE
|
||||
|
@ -364,11 +366,13 @@ var tokens = [...]string{
|
|||
TRUE: "TRUE",
|
||||
TYPE: "TYPE",
|
||||
UNIQUE: "UNIQUE",
|
||||
UNVERSIONED: "UNVERSIONED",
|
||||
UPDATE: "UPDATE",
|
||||
UPSERT: "UPSERT",
|
||||
USE: "USE",
|
||||
VALUE: "VALUE",
|
||||
VERSION: "VERSION",
|
||||
VERSIONED: "VERSIONED",
|
||||
VOID: "VOID",
|
||||
WHEN: "WHEN",
|
||||
WHERE: "WHERE",
|
||||
|
|
Loading…
Reference in a new issue