Add PERMISSIONS and remove DEFINE / REMOVE RULES
This commit is contained in:
parent
2b47e6e0a9
commit
fbe34c6083
10 changed files with 184 additions and 321 deletions
35
sql/ast.go
35
sql/ast.go
|
@ -287,6 +287,7 @@ type DefineTableStatement struct {
|
||||||
DB string `cork:"-" codec:"-"`
|
DB string `cork:"-" codec:"-"`
|
||||||
What []string `cork:"-" codec:"-"`
|
What []string `cork:"-" codec:"-"`
|
||||||
Full bool `cork:"full" codec:"full"`
|
Full bool `cork:"full" codec:"full"`
|
||||||
|
Perm *PermExpression `cork:"perm" codec:"perm"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveTableStatement represents an SQL REMOVE TABLE statement.
|
// RemoveTableStatement represents an SQL REMOVE TABLE statement.
|
||||||
|
@ -297,30 +298,6 @@ type RemoveTableStatement struct {
|
||||||
What []string `cork:"-" codec:"-"`
|
What []string `cork:"-" codec:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Rules
|
|
||||||
// --------------------------------------------------
|
|
||||||
|
|
||||||
// DefineRulesStatement represents an SQL DEFINE RULES statement.
|
|
||||||
type DefineRulesStatement struct {
|
|
||||||
KV string `cork:"-" codec:"-"`
|
|
||||||
NS string `cork:"-" codec:"-"`
|
|
||||||
DB string `cork:"-" codec:"-"`
|
|
||||||
What []string `cork:"-" codec:"-"`
|
|
||||||
When []string `cork:"-" codec:"-"`
|
|
||||||
Rule string `cork:"rule" codec:"rule"`
|
|
||||||
Cond Expr `cork:"cond" codec:"cond"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveRulesStatement represents an SQL REMOVE RULES statement.
|
|
||||||
type RemoveRulesStatement struct {
|
|
||||||
KV string `cork:"-" codec:"-"`
|
|
||||||
NS string `cork:"-" codec:"-"`
|
|
||||||
DB string `cork:"-" codec:"-"`
|
|
||||||
What []string `cork:"-" codec:"-"`
|
|
||||||
When []string `cork:"-" codec:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Field
|
// Field
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -333,6 +310,7 @@ type DefineFieldStatement struct {
|
||||||
Name string `cork:"name" codec:"name"`
|
Name string `cork:"name" codec:"name"`
|
||||||
What []string `cork:"-" codec:"-"`
|
What []string `cork:"-" codec:"-"`
|
||||||
Type string `cork:"type" codec:"type"`
|
Type string `cork:"type" codec:"type"`
|
||||||
|
Perm *PermExpression `cork:"perm" codec:"perm"`
|
||||||
Enum []interface{} `cork:"enum" codec:"enum"`
|
Enum []interface{} `cork:"enum" codec:"enum"`
|
||||||
Code string `cork:"code" codec:"code"`
|
Code string `cork:"code" codec:"code"`
|
||||||
Min float64 `cork:"min" codec:"min"`
|
Min float64 `cork:"min" codec:"min"`
|
||||||
|
@ -498,6 +476,15 @@ type SubpExpression struct {
|
||||||
Cond Expr
|
Cond Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PermExpression represents a permissions expression.
|
||||||
|
type PermExpression struct {
|
||||||
|
Select Expr
|
||||||
|
Create Expr
|
||||||
|
Update Expr
|
||||||
|
Relate Expr
|
||||||
|
Delete Expr
|
||||||
|
}
|
||||||
|
|
||||||
// DiffExpression represents a JSON to DIFF
|
// DiffExpression represents a JSON to DIFF
|
||||||
type DiffExpression struct {
|
type DiffExpression struct {
|
||||||
JSON interface{}
|
JSON interface{}
|
||||||
|
|
72
sql/cork.go
72
sql/cork.go
|
@ -1298,66 +1298,6 @@ func (this *RemoveTableStatement) UnmarshalCORK(src []byte) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
|
||||||
// DefineRulesStatement
|
|
||||||
// --------------------------------------------------
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
cork.Register(&DefineRulesStatement{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DefineRulesStatement) ExtendCORK() byte {
|
|
||||||
return 0x85
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DefineRulesStatement) MarshalCORK() (dst []byte, err error) {
|
|
||||||
b := bytes.NewBuffer(dst)
|
|
||||||
e := cork.NewEncoder(b)
|
|
||||||
e.Encode(this.What)
|
|
||||||
e.Encode(this.When)
|
|
||||||
e.Encode(this.Rule)
|
|
||||||
e.Encode(this.Cond)
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DefineRulesStatement) UnmarshalCORK(src []byte) (err error) {
|
|
||||||
b := bytes.NewBuffer(src)
|
|
||||||
d := cork.NewDecoder(b)
|
|
||||||
d.Decode(&this.What)
|
|
||||||
d.Decode(&this.When)
|
|
||||||
d.Decode(&this.Rule)
|
|
||||||
d.Decode(&this.Cond)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
|
||||||
// RemoveTableStatement
|
|
||||||
// --------------------------------------------------
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
cork.Register(&RemoveRulesStatement{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RemoveRulesStatement) ExtendCORK() byte {
|
|
||||||
return 0x86
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RemoveRulesStatement) MarshalCORK() (dst []byte, err error) {
|
|
||||||
b := bytes.NewBuffer(dst)
|
|
||||||
e := cork.NewEncoder(b)
|
|
||||||
e.Encode(this.What)
|
|
||||||
e.Encode(this.When)
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RemoveRulesStatement) UnmarshalCORK(src []byte) (err error) {
|
|
||||||
b := bytes.NewBuffer(src)
|
|
||||||
d := cork.NewDecoder(b)
|
|
||||||
d.Decode(&this.What)
|
|
||||||
d.Decode(&this.When)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// DefineFieldStatement
|
// DefineFieldStatement
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -1367,7 +1307,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefineFieldStatement) ExtendCORK() byte {
|
func (this *DefineFieldStatement) ExtendCORK() byte {
|
||||||
return 0x87
|
return 0x85
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefineFieldStatement) MarshalCORK() (dst []byte, err error) {
|
func (this *DefineFieldStatement) MarshalCORK() (dst []byte, err error) {
|
||||||
|
@ -1417,7 +1357,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RemoveFieldStatement) ExtendCORK() byte {
|
func (this *RemoveFieldStatement) ExtendCORK() byte {
|
||||||
return 0x88
|
return 0x86
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RemoveFieldStatement) MarshalCORK() (dst []byte, err error) {
|
func (this *RemoveFieldStatement) MarshalCORK() (dst []byte, err error) {
|
||||||
|
@ -1445,7 +1385,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefineIndexStatement) ExtendCORK() byte {
|
func (this *DefineIndexStatement) ExtendCORK() byte {
|
||||||
return 0x89
|
return 0x87
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefineIndexStatement) MarshalCORK() (dst []byte, err error) {
|
func (this *DefineIndexStatement) MarshalCORK() (dst []byte, err error) {
|
||||||
|
@ -1477,7 +1417,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RemoveIndexStatement) ExtendCORK() byte {
|
func (this *RemoveIndexStatement) ExtendCORK() byte {
|
||||||
return 0x90
|
return 0x88
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RemoveIndexStatement) MarshalCORK() (dst []byte, err error) {
|
func (this *RemoveIndexStatement) MarshalCORK() (dst []byte, err error) {
|
||||||
|
@ -1505,7 +1445,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefineViewStatement) ExtendCORK() byte {
|
func (this *DefineViewStatement) ExtendCORK() byte {
|
||||||
return 0x91
|
return 0x89
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefineViewStatement) MarshalCORK() (dst []byte, err error) {
|
func (this *DefineViewStatement) MarshalCORK() (dst []byte, err error) {
|
||||||
|
@ -1539,7 +1479,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RemoveViewStatement) ExtendCORK() byte {
|
func (this *RemoveViewStatement) ExtendCORK() byte {
|
||||||
return 0x92
|
return 0x90
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RemoveViewStatement) MarshalCORK() (dst []byte, err error) {
|
func (this *RemoveViewStatement) MarshalCORK() (dst []byte, err error) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ func (p *parser) parseDefineStatement() (Statement, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspect the next token.
|
// Inspect the next token.
|
||||||
tok, _, err := p.shouldBe(NAMESPACE, DATABASE, LOGIN, TOKEN, SCOPE, TABLE, RULES, FIELD, INDEX, VIEW)
|
tok, _, err := p.shouldBe(NAMESPACE, DATABASE, LOGIN, TOKEN, SCOPE, TABLE, FIELD, INDEX, VIEW)
|
||||||
|
|
||||||
switch tok {
|
switch tok {
|
||||||
case NAMESPACE:
|
case NAMESPACE:
|
||||||
|
@ -36,8 +36,6 @@ func (p *parser) parseDefineStatement() (Statement, error) {
|
||||||
return p.parseDefineScopeStatement()
|
return p.parseDefineScopeStatement()
|
||||||
case TABLE:
|
case TABLE:
|
||||||
return p.parseDefineTableStatement()
|
return p.parseDefineTableStatement()
|
||||||
case RULES:
|
|
||||||
return p.parseDefineRulesStatement()
|
|
||||||
case FIELD:
|
case FIELD:
|
||||||
return p.parseDefineFieldStatement()
|
return p.parseDefineFieldStatement()
|
||||||
case INDEX:
|
case INDEX:
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (p *parser) parseDefineFieldStatement() (stmt *DefineFieldStatement, err er
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
tok, _, exi := p.mightBe(MIN, MAX, TYPE, ENUM, CODE, MATCH, DEFAULT, NOTNULL, READONLY, MANDATORY, VALIDATE)
|
tok, _, exi := p.mightBe(MIN, MAX, TYPE, ENUM, CODE, MATCH, DEFAULT, NOTNULL, READONLY, MANDATORY, VALIDATE, PERMISSIONS)
|
||||||
if !exi {
|
if !exi {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,12 @@ func (p *parser) parseDefineFieldStatement() (stmt *DefineFieldStatement, err er
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.is(tok, PERMISSIONS) {
|
||||||
|
if stmt.Perm, err = p.parsePerms(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
||||||
|
|
110
sql/perms.go
Normal file
110
sql/perms.go
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// Copyright © 2016 Abcum Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sql
|
||||||
|
|
||||||
|
func (p *parser) parsePerms() (exp *PermExpression, err error) {
|
||||||
|
|
||||||
|
exp = &PermExpression{}
|
||||||
|
|
||||||
|
tok, _, err := p.shouldBe(FOR, NONE, FULL, WHERE)
|
||||||
|
if err != nil {
|
||||||
|
return exp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.is(tok, NONE, FULL, WHERE) {
|
||||||
|
|
||||||
|
var expr Expr
|
||||||
|
|
||||||
|
switch tok {
|
||||||
|
case FULL:
|
||||||
|
expr = true
|
||||||
|
case NONE:
|
||||||
|
expr = false
|
||||||
|
case WHERE:
|
||||||
|
if expr, err = p.parseExpr(); err != nil {
|
||||||
|
return exp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exp.Select = expr
|
||||||
|
exp.Create = expr
|
||||||
|
exp.Update = expr
|
||||||
|
exp.Delete = expr
|
||||||
|
exp.Relate = expr
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.is(tok, FOR) {
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
var expr Expr
|
||||||
|
var when []Token
|
||||||
|
|
||||||
|
for {
|
||||||
|
tok, _, err := p.shouldBe(SELECT, CREATE, UPDATE, DELETE, RELATE)
|
||||||
|
if err != nil {
|
||||||
|
return exp, err
|
||||||
|
}
|
||||||
|
when = append(when, tok)
|
||||||
|
if _, _, exi := p.mightBe(COMMA); !exi {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tok, _, err := p.shouldBe(FULL, NONE, WHERE)
|
||||||
|
if err != nil {
|
||||||
|
return exp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch tok {
|
||||||
|
case FULL:
|
||||||
|
expr = true
|
||||||
|
case NONE:
|
||||||
|
expr = false
|
||||||
|
case WHERE:
|
||||||
|
if expr, err = p.parseExpr(); err != nil {
|
||||||
|
return exp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, w := range when {
|
||||||
|
switch w {
|
||||||
|
case SELECT:
|
||||||
|
exp.Select = expr
|
||||||
|
case CREATE:
|
||||||
|
exp.Create = expr
|
||||||
|
case UPDATE:
|
||||||
|
exp.Update = expr
|
||||||
|
case DELETE:
|
||||||
|
exp.Delete = expr
|
||||||
|
case RELATE:
|
||||||
|
exp.Relate = expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, _, exi := p.mightBe(FOR); !exi {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ func (p *parser) parseRemoveStatement() (Statement, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspect the next token.
|
// Inspect the next token.
|
||||||
tok, _, err := p.shouldBe(NAMESPACE, DATABASE, LOGIN, TOKEN, SCOPE, TABLE, RULES, FIELD, INDEX, VIEW)
|
tok, _, err := p.shouldBe(NAMESPACE, DATABASE, LOGIN, TOKEN, SCOPE, TABLE, FIELD, INDEX, VIEW)
|
||||||
|
|
||||||
switch tok {
|
switch tok {
|
||||||
case NAMESPACE:
|
case NAMESPACE:
|
||||||
|
@ -36,8 +36,6 @@ func (p *parser) parseRemoveStatement() (Statement, error) {
|
||||||
return p.parseRemoveScopeStatement()
|
return p.parseRemoveScopeStatement()
|
||||||
case TABLE:
|
case TABLE:
|
||||||
return p.parseRemoveTableStatement()
|
return p.parseRemoveTableStatement()
|
||||||
case RULES:
|
|
||||||
return p.parseRemoveRulesStatement()
|
|
||||||
case FIELD:
|
case FIELD:
|
||||||
return p.parseRemoveFieldStatement()
|
return p.parseRemoveFieldStatement()
|
||||||
case INDEX:
|
case INDEX:
|
||||||
|
|
117
sql/rules.go
117
sql/rules.go
|
@ -1,117 +0,0 @@
|
||||||
// Copyright © 2016 Abcum Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package sql
|
|
||||||
|
|
||||||
func (p *parser) parseDefineRulesStatement() (stmt *DefineRulesStatement, err error) {
|
|
||||||
|
|
||||||
stmt = &DefineRulesStatement{}
|
|
||||||
|
|
||||||
if stmt.KV, stmt.NS, stmt.DB, err = p.o.get(AuthDB); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(ON); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if stmt.What, err = p.parseNames(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(FOR); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
|
|
||||||
tok, _, exi := p.mightBe(SELECT, CREATE, UPDATE, DELETE, RELATE)
|
|
||||||
if !exi {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt.When = append(stmt.When, tok.String())
|
|
||||||
|
|
||||||
if _, _, exi := p.mightBe(COMMA); !exi {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(stmt.When) == 0 {
|
|
||||||
return nil, &ParseError{Found: "", Expected: []string{"SELECT", "CREATE", "UPDATE", "DELETE", "RELATE"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, stmt.Rule, err = p.shouldBe(ACCEPT, REJECT); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if stmt.Cond, err = p.parseCond(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *parser) parseRemoveRulesStatement() (stmt *RemoveRulesStatement, err error) {
|
|
||||||
|
|
||||||
stmt = &RemoveRulesStatement{}
|
|
||||||
|
|
||||||
if stmt.KV, stmt.NS, stmt.DB, err = p.o.get(AuthDB); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(ON); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if stmt.What, err = p.parseNames(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(FOR); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
|
|
||||||
tok, _, exi := p.mightBe(SELECT, CREATE, UPDATE, DELETE, RELATE)
|
|
||||||
if !exi {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt.When = append(stmt.When, tok.String())
|
|
||||||
|
|
||||||
if _, _, exi := p.mightBe(COMMA); !exi {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(stmt.When) == 0 {
|
|
||||||
return nil, &ParseError{Found: "", Expected: []string{"SELECT", "CREATE", "UPDATE", "DELETE", "RELATE"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
|
@ -1600,7 +1600,7 @@ func Test_Parse_Queries_Define(t *testing.T) {
|
||||||
var tests = []tester{
|
var tests = []tester{
|
||||||
{
|
{
|
||||||
sql: `DEFINE`,
|
sql: `DEFINE`,
|
||||||
err: "Found `` but expected `NAMESPACE, DATABASE, SCOPE, TABLE, RULES, FIELD, INDEX, VIEW`",
|
err: "Found `` but expected `NAMESPACE, DATABASE, SCOPE, TABLE, FIELD, INDEX, VIEW`",
|
||||||
},
|
},
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
|
@ -1657,57 +1657,6 @@ func Test_Parse_Queries_Define(t *testing.T) {
|
||||||
err: "Found `something` but expected `EOF, ;`",
|
err: "Found `something` but expected `EOF, ;`",
|
||||||
},
|
},
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
{
|
|
||||||
sql: `DEFINE RULES`,
|
|
||||||
err: "Found `` but expected `ON`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON`,
|
|
||||||
err: "Found `` but expected `name`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person`,
|
|
||||||
err: "Found `` but expected `FOR`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR`,
|
|
||||||
err: "Found `` but expected `SELECT, CREATE, UPDATE, DELETE, RELATE`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR select, create, update, delete`,
|
|
||||||
err: "Found `` but expected `ACCEPT, REJECT`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR select, create, update, delete ACCEPT`,
|
|
||||||
res: &Query{Statements: []Statement{&DefineRulesStatement{
|
|
||||||
KV: "*", NS: "*", DB: "*",
|
|
||||||
What: []string{"person"},
|
|
||||||
When: []string{"SELECT", "CREATE", "UPDATE", "DELETE"},
|
|
||||||
Rule: "ACCEPT",
|
|
||||||
}}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR select, create, update, delete ACCEPT something`,
|
|
||||||
err: "Found `something` but expected `EOF, ;`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR select, create, update, delete REJECT`,
|
|
||||||
res: &Query{Statements: []Statement{&DefineRulesStatement{
|
|
||||||
KV: "*", NS: "*", DB: "*",
|
|
||||||
What: []string{"person"},
|
|
||||||
When: []string{"SELECT", "CREATE", "UPDATE", "DELETE"},
|
|
||||||
Rule: "REJECT",
|
|
||||||
}}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR select, create, update, delete ACCEPT something`,
|
|
||||||
err: "Found `something` but expected `EOF, ;`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `DEFINE RULES ON person FOR select, create, update, delete REJECT something`,
|
|
||||||
err: "Found `something` but expected `EOF, ;`",
|
|
||||||
},
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
{
|
{
|
||||||
sql: `DEFINE FIELD`,
|
sql: `DEFINE FIELD`,
|
||||||
err: "Found `` but expected `name`",
|
err: "Found `` but expected `name`",
|
||||||
|
@ -2242,7 +2191,7 @@ func Test_Parse_Queries_Remove(t *testing.T) {
|
||||||
var tests = []tester{
|
var tests = []tester{
|
||||||
{
|
{
|
||||||
sql: `REMOVE`,
|
sql: `REMOVE`,
|
||||||
err: "Found `` but expected `NAMESPACE, DATABASE, SCOPE, TABLE, RULES, FIELD, INDEX, VIEW`",
|
err: "Found `` but expected `NAMESPACE, DATABASE, SCOPE, TABLE, FIELD, INDEX, VIEW`",
|
||||||
},
|
},
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
|
@ -2275,35 +2224,6 @@ func Test_Parse_Queries_Remove(t *testing.T) {
|
||||||
err: "Found `something` but expected `EOF, ;`",
|
err: "Found `something` but expected `EOF, ;`",
|
||||||
},
|
},
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
{
|
|
||||||
sql: `REMOVE RULES`,
|
|
||||||
err: "Found `` but expected `ON`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `REMOVE RULES ON`,
|
|
||||||
err: "Found `` but expected `name`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `REMOVE RULES ON person`,
|
|
||||||
err: "Found `` but expected `FOR`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `REMOVE RULES ON person FOR`,
|
|
||||||
err: "Found `` but expected `SELECT, CREATE, UPDATE, DELETE, RELATE`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `REMOVE RULES ON person FOR select, create, update, delete`,
|
|
||||||
res: &Query{Statements: []Statement{&RemoveRulesStatement{
|
|
||||||
KV: "*", NS: "*", DB: "*",
|
|
||||||
What: []string{"person"},
|
|
||||||
When: []string{"SELECT", "CREATE", "UPDATE", "DELETE"},
|
|
||||||
}}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sql: `REMOVE RULES ON person FOR select, create, update, delete something`,
|
|
||||||
err: "Found `something` but expected `EOF, ;`",
|
|
||||||
},
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
{
|
{
|
||||||
sql: `REMOVE FIELD`,
|
sql: `REMOVE FIELD`,
|
||||||
err: "Found `` but expected `name`",
|
err: "Found `` but expected `name`",
|
||||||
|
|
21
sql/table.go
21
sql/table.go
|
@ -26,10 +26,29 @@ func (p *parser) parseDefineTableStatement() (stmt *DefineTableStatement, err er
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if tok, _, exi := p.mightBe(SCHEMAFULL, SCHEMALESS); exi && tok == SCHEMAFULL {
|
for {
|
||||||
|
|
||||||
|
tok, _, exi := p.mightBe(SCHEMAFULL, SCHEMALESS, PERMISSIONS)
|
||||||
|
if !exi {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.is(tok, SCHEMAFULL) {
|
||||||
stmt.Full = true
|
stmt.Full = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.is(tok, SCHEMALESS) {
|
||||||
|
stmt.Full = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.is(tok, PERMISSIONS) {
|
||||||
|
if stmt.Perm, err = p.parsePerms(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ const (
|
||||||
FIELD
|
FIELD
|
||||||
FOR
|
FOR
|
||||||
FROM
|
FROM
|
||||||
|
FULL
|
||||||
GROUP
|
GROUP
|
||||||
ID
|
ID
|
||||||
IF
|
IF
|
||||||
|
@ -157,12 +158,12 @@ const (
|
||||||
OR
|
OR
|
||||||
ORDER
|
ORDER
|
||||||
PASSWORD
|
PASSWORD
|
||||||
|
PERMISSIONS
|
||||||
READONLY
|
READONLY
|
||||||
REJECT
|
REJECT
|
||||||
RELATE
|
RELATE
|
||||||
REMOVE
|
REMOVE
|
||||||
RETURN
|
RETURN
|
||||||
RULES
|
|
||||||
SCHEMAFULL
|
SCHEMAFULL
|
||||||
SCHEMALESS
|
SCHEMALESS
|
||||||
SCOPE
|
SCOPE
|
||||||
|
@ -292,6 +293,7 @@ var tokens = [...]string{
|
||||||
FIELD: "FIELD",
|
FIELD: "FIELD",
|
||||||
FOR: "FOR",
|
FOR: "FOR",
|
||||||
FROM: "FROM",
|
FROM: "FROM",
|
||||||
|
FULL: "FULL",
|
||||||
GROUP: "GROUP",
|
GROUP: "GROUP",
|
||||||
ID: "ID",
|
ID: "ID",
|
||||||
IF: "IF",
|
IF: "IF",
|
||||||
|
@ -320,12 +322,12 @@ var tokens = [...]string{
|
||||||
OR: "OR",
|
OR: "OR",
|
||||||
ORDER: "ORDER",
|
ORDER: "ORDER",
|
||||||
PASSWORD: "PASSWORD",
|
PASSWORD: "PASSWORD",
|
||||||
|
PERMISSIONS: "PERMISSIONS",
|
||||||
READONLY: "READONLY",
|
READONLY: "READONLY",
|
||||||
REJECT: "REJECT",
|
REJECT: "REJECT",
|
||||||
RELATE: "RELATE",
|
RELATE: "RELATE",
|
||||||
REMOVE: "REMOVE",
|
REMOVE: "REMOVE",
|
||||||
RETURN: "RETURN",
|
RETURN: "RETURN",
|
||||||
RULES: "RULES",
|
|
||||||
SCHEMAFULL: "SCHEMAFULL",
|
SCHEMAFULL: "SCHEMAFULL",
|
||||||
SCHEMALESS: "SCHEMALESS",
|
SCHEMALESS: "SCHEMALESS",
|
||||||
SCOPE: "SCOPE",
|
SCOPE: "SCOPE",
|
||||||
|
|
Loading…
Reference in a new issue