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