Add SQL VIEWs
This commit is contained in:
parent
f37ec653d1
commit
66f09db9f5
7 changed files with 185 additions and 4 deletions
15
db/info.go
15
db/info.go
|
@ -42,13 +42,24 @@ func executeInfoStatement(txn kvs.TX, ast *sql.InfoStatement) (out []interface{}
|
||||||
// Get the table definitions
|
// Get the table definitions
|
||||||
tbeg := &keys.TB{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: keys.Prefix}
|
tbeg := &keys.TB{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: keys.Prefix}
|
||||||
tend := &keys.TB{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: keys.Suffix}
|
tend := &keys.TB{KV: ast.KV, NS: ast.NS, DB: ast.DB, TB: keys.Suffix}
|
||||||
kvs, _ := txn.RGet(tbeg.Encode(), tend.Encode(), 0)
|
tkvs, _ := txn.RGet(tbeg.Encode(), tend.Encode(), 0)
|
||||||
for _, kv := range kvs {
|
for _, kv := range tkvs {
|
||||||
key := &keys.TB{}
|
key := &keys.TB{}
|
||||||
key.Decode(kv.Key())
|
key.Decode(kv.Key())
|
||||||
res.Inc(key.TB, "tables")
|
res.Inc(key.TB, "tables")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the table definitions
|
||||||
|
vbeg := &keys.VW{KV: ast.KV, NS: ast.NS, DB: ast.DB, VW: keys.Prefix}
|
||||||
|
vend := &keys.VW{KV: ast.KV, NS: ast.NS, DB: ast.DB, VW: keys.Suffix}
|
||||||
|
vkvs, _ := txn.RGet(vbeg.Encode(), vend.Encode(), 0)
|
||||||
|
for _, kv := range vkvs {
|
||||||
|
key, val := &keys.VW{}, &sql.DefineViewStatement{}
|
||||||
|
key.Decode(kv.Key())
|
||||||
|
pack.Decode(kv.Val(), val)
|
||||||
|
res.Inc(val, "views")
|
||||||
|
}
|
||||||
|
|
||||||
out = append(out, res.Data())
|
out = append(out, res.Data())
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
24
sql/ast.go
24
sql/ast.go
|
@ -257,6 +257,30 @@ type RemoveIndexStatement struct {
|
||||||
What []string `codec:"-"`
|
What []string `codec:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// View
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
// DefineViewStatement represents an SQL DEFINE VIEW statement.
|
||||||
|
type DefineViewStatement struct {
|
||||||
|
KV string `codec:"-"`
|
||||||
|
NS string `codec:"-"`
|
||||||
|
DB string `codec:"-"`
|
||||||
|
Name string `codec:"name"`
|
||||||
|
Expr []*Field `codec:"expr"`
|
||||||
|
What []Expr `codec:"what"`
|
||||||
|
Cond []Expr `codec:"cond"`
|
||||||
|
Group []*Group `codec:"group"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveViewStatement represents an SQL REMOVE VIEW statement.
|
||||||
|
type RemoveViewStatement struct {
|
||||||
|
KV string `codec:"-"`
|
||||||
|
NS string `codec:"-"`
|
||||||
|
DB string `codec:"-"`
|
||||||
|
Name string `codec:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Literals
|
// Literals
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
|
@ -17,7 +17,7 @@ package sql
|
||||||
func (p *parser) parseDefineStatement() (Statement, error) {
|
func (p *parser) parseDefineStatement() (Statement, error) {
|
||||||
|
|
||||||
// Inspect the next token.
|
// Inspect the next token.
|
||||||
tok, _, err := p.shouldBe(TABLE, RULES, FIELD, INDEX)
|
tok, _, err := p.shouldBe(TABLE, RULES, FIELD, INDEX, VIEW)
|
||||||
|
|
||||||
switch tok {
|
switch tok {
|
||||||
case TABLE:
|
case TABLE:
|
||||||
|
@ -28,6 +28,8 @@ func (p *parser) parseDefineStatement() (Statement, error) {
|
||||||
return p.parseDefineFieldStatement()
|
return p.parseDefineFieldStatement()
|
||||||
case INDEX:
|
case INDEX:
|
||||||
return p.parseDefineIndexStatement()
|
return p.parseDefineIndexStatement()
|
||||||
|
case VIEW:
|
||||||
|
return p.parseDefineViewStatement()
|
||||||
default:
|
default:
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ package sql
|
||||||
func (p *parser) parseRemoveStatement() (Statement, error) {
|
func (p *parser) parseRemoveStatement() (Statement, error) {
|
||||||
|
|
||||||
// Inspect the next token.
|
// Inspect the next token.
|
||||||
tok, _, err := p.shouldBe(TABLE, RULES, FIELD, INDEX)
|
tok, _, err := p.shouldBe(TABLE, RULES, FIELD, INDEX, VIEW)
|
||||||
|
|
||||||
switch tok {
|
switch tok {
|
||||||
case TABLE:
|
case TABLE:
|
||||||
|
@ -28,6 +28,8 @@ func (p *parser) parseRemoveStatement() (Statement, error) {
|
||||||
return p.parseRemoveFieldStatement()
|
return p.parseRemoveFieldStatement()
|
||||||
case INDEX:
|
case INDEX:
|
||||||
return p.parseRemoveIndexStatement()
|
return p.parseRemoveIndexStatement()
|
||||||
|
case VIEW:
|
||||||
|
return p.parseRemoveViewStatement()
|
||||||
default:
|
default:
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,7 @@ const (
|
||||||
USE
|
USE
|
||||||
VALIDATE
|
VALIDATE
|
||||||
VERSION
|
VERSION
|
||||||
|
VIEW
|
||||||
VOID
|
VOID
|
||||||
WHERE
|
WHERE
|
||||||
|
|
||||||
|
@ -340,6 +341,7 @@ var tokens = [...]string{
|
||||||
USE: "USE",
|
USE: "USE",
|
||||||
VALIDATE: "VALIDATE",
|
VALIDATE: "VALIDATE",
|
||||||
VERSION: "VERSION",
|
VERSION: "VERSION",
|
||||||
|
VIEW: "VIEW",
|
||||||
VOID: "VOID",
|
VOID: "VOID",
|
||||||
WHERE: "WHERE",
|
WHERE: "WHERE",
|
||||||
}
|
}
|
||||||
|
|
86
sql/view.go
Normal file
86
sql/view.go
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// 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) parseDefineViewStatement() (stmt *DefineViewStatement, err error) {
|
||||||
|
|
||||||
|
stmt = &DefineViewStatement{}
|
||||||
|
|
||||||
|
stmt.KV = p.c.Get("KV").(string)
|
||||||
|
stmt.NS = p.c.Get("NS").(string)
|
||||||
|
stmt.DB = p.c.Get("DB").(string)
|
||||||
|
|
||||||
|
if stmt.Name, err = p.parseName(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = p.shouldBe(AS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = p.shouldBe(SELECT)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if stmt.Expr, err = p.parseExpr(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = p.shouldBe(FROM)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if stmt.What, err = p.parseWhat(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if stmt.Cond, err = p.parseCond(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if stmt.Group, err = p.parseGroup(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) parseRemoveViewStatement() (stmt *RemoveViewStatement, err error) {
|
||||||
|
|
||||||
|
stmt = &RemoveViewStatement{}
|
||||||
|
|
||||||
|
stmt.KV = p.c.Get("KV").(string)
|
||||||
|
stmt.NS = p.c.Get("NS").(string)
|
||||||
|
stmt.DB = p.c.Get("DB").(string)
|
||||||
|
|
||||||
|
if stmt.Name, err = p.parseName(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, _, err = p.shouldBe(EOF, SEMICOLON); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
54
util/keys/vw.go
Normal file
54
util/keys/vw.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// 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 keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VW ...
|
||||||
|
type VW struct {
|
||||||
|
KV interface{}
|
||||||
|
CF interface{}
|
||||||
|
TK interface{}
|
||||||
|
NS interface{}
|
||||||
|
DB interface{}
|
||||||
|
VW interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initialises the key
|
||||||
|
func (k *VW) init() *VW {
|
||||||
|
k.CF = "!"
|
||||||
|
k.TK = "v"
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes the key into binary
|
||||||
|
func (k *VW) Encode() []byte {
|
||||||
|
k.init()
|
||||||
|
return encode(k.KV, k.CF, k.TK, k.NS, k.DB, k.VW)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes the key from binary
|
||||||
|
func (k *VW) Decode(data []byte) {
|
||||||
|
k.init()
|
||||||
|
decode(data, &k.KV, &k.CF, &k.TK, &k.NS, &k.DB, &k.VW)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the key
|
||||||
|
func (k *VW) String() string {
|
||||||
|
k.init()
|
||||||
|
return fmt.Sprintf("/%s/%s/%s/%s/%s/%s", k.KV, k.CF, k.TK, k.NS, k.DB, k.VW)
|
||||||
|
}
|
Loading…
Reference in a new issue