diff --git a/db/document.go b/db/document.go index 63441ce2..e7b16bbf 100644 --- a/db/document.go +++ b/db/document.go @@ -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. - _, 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 @@ -382,7 +403,13 @@ func (d *document) purgeThing(ctx context.Context) (err error) { // Reset the item by writing a // 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 diff --git a/db/select_test.go b/db/select_test.go index 471caee2..d48fb788 100644 --- a/db/select_test.go +++ b/db/select_test.go @@ -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) }) diff --git a/sql/string.go b/sql/string.go index 8c8aca37..2af3310a 100644 --- a/sql/string.go +++ b/sql/string.go @@ -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), diff --git a/sql/table.go b/sql/table.go index 28d3363e..4678fb09 100644 --- a/sql/table.go +++ b/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 diff --git a/sql/tokens.go b/sql/tokens.go index 7e6659fd..d5c23621 100644 --- a/sql/tokens.go +++ b/sql/tokens.go @@ -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",