TODO: parse field
This commit is contained in:
parent
28fce16157
commit
7f137471f9
16
base.go
Normal file
16
base.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
// skipSpace
|
||||||
|
func skipSpace(content *string, i *int) {
|
||||||
|
|
||||||
|
ct := *content
|
||||||
|
idx := *i
|
||||||
|
|
||||||
|
for ; idx < len(ct); idx++ {
|
||||||
|
if ct[idx] == ' ' {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
field.go
Normal file
84
field.go
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldMap map[string]ValueType
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
fieldMap["bool"] = VT_BOOL
|
||||||
|
|
||||||
|
fieldMap["int"] = VT_INT
|
||||||
|
fieldMap["int16"] = VT_INT16
|
||||||
|
fieldMap["int32"] = VT_INT32
|
||||||
|
fieldMap["int64"] = VT_INT64
|
||||||
|
|
||||||
|
fieldMap["uint"] = VT_UINT
|
||||||
|
fieldMap["uint16"] = VT_UINT16
|
||||||
|
fieldMap["uint32"] = VT_UINT32
|
||||||
|
fieldMap["uint64"] = VT_UINT64
|
||||||
|
|
||||||
|
fieldMap["char"] = VT_CHAR
|
||||||
|
fieldMap["varchar"] = VT_VARCHAR
|
||||||
|
fieldMap["text"] = VT_TEXT
|
||||||
|
|
||||||
|
fieldMap["timestamp"] = VT_TIMESTAMP
|
||||||
|
fieldMap["date"] = VT_DATE
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueType 值 类型
|
||||||
|
type ValueType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VT_BOOL 布尔类型
|
||||||
|
VT_BOOL ValueType = 00000 + iota
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VT_INT ValueType = 10000 + iota
|
||||||
|
VT_INT8
|
||||||
|
VT_INT16
|
||||||
|
VT_INT32
|
||||||
|
VT_INT64
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VT_UINT ValueType = 11000 + iota
|
||||||
|
VT_UINT8
|
||||||
|
VT_UINT16
|
||||||
|
VT_UINT32
|
||||||
|
VT_UINT64
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VT_CHAR ValueType = 12000 + iota
|
||||||
|
VT_VARCHAR
|
||||||
|
VT_TEXT
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VT_TIMESTAMP ValueType = 13000 + iota
|
||||||
|
VT_DATE
|
||||||
|
)
|
||||||
|
|
||||||
|
// Field 字段
|
||||||
|
type Field struct {
|
||||||
|
Key []byte
|
||||||
|
|
||||||
|
VT ValueType
|
||||||
|
|
||||||
|
ID uint16
|
||||||
|
|
||||||
|
ArrayNumber int
|
||||||
|
IsIndex bool
|
||||||
|
IsUnique bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse 从字符串中解析 var a int; a = 0; a < 0 && a > 5 ;
|
||||||
|
func (field *Field) Parse(code string) {
|
||||||
|
codes := strings.Split(code, ";")
|
||||||
|
re := regexp.MustCompile("var +([a-zA-Z_]+) +[a-zA-Z]+[8|16|32|64]{0,1}")
|
||||||
|
re.FindStringSubmatch(codes[0])
|
||||||
|
}
|
126
rocksdb.go
126
rocksdb.go
|
@ -4,10 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tecbot/gorocksdb"
|
"github.com/tecbot/gorocksdb"
|
||||||
|
@ -31,128 +27,6 @@ func init() {
|
||||||
EDB = NewEasyDataBase()
|
EDB = NewEasyDataBase()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEasyDataBase() *EasyDataBase {
|
|
||||||
|
|
||||||
edb := &EasyDataBase{}
|
|
||||||
db, cfs := OpenDataBase()
|
|
||||||
edb.DB = db
|
|
||||||
edb.CFS = cfs
|
|
||||||
return edb
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type EasyDataBase struct {
|
|
||||||
DB *gorocksdb.DB
|
|
||||||
CFS gorocksdb.ColumnFamilyHandles
|
|
||||||
|
|
||||||
Tables map[uint32]*Table
|
|
||||||
TableDict map[string]uint32
|
|
||||||
|
|
||||||
Metadata
|
|
||||||
}
|
|
||||||
|
|
||||||
type Metadata struct {
|
|
||||||
tidCount uint32 // int16
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValueType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
VT_BOOL ValueType = 00000 + iota
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
VT_INT ValueType = 10000 + iota
|
|
||||||
VT_INT8
|
|
||||||
VT_INT16
|
|
||||||
VT_INT32
|
|
||||||
VT_INT64
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
VT_UINT ValueType = 11000 + iota
|
|
||||||
VT_UINT8
|
|
||||||
VT_UINT16
|
|
||||||
VT_UINT32
|
|
||||||
VT_UINT64
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
VT_CHAR ValueType = 12000 + iota
|
|
||||||
VT_VARCHAR
|
|
||||||
VT_TEXT
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
VT_TIMESTAMP ValueType = 13000 + iota
|
|
||||||
VT_DATE
|
|
||||||
)
|
|
||||||
|
|
||||||
type Field struct {
|
|
||||||
Key []byte
|
|
||||||
|
|
||||||
VT ValueType
|
|
||||||
ID uint16
|
|
||||||
|
|
||||||
IsIndex bool
|
|
||||||
IsUnique bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse 从字符串中解析 var a int; a = 0; a < 0 && a > 5 ;
|
|
||||||
func (field *Field) Parse(code string) {
|
|
||||||
codes := strings.Split(code, ";")
|
|
||||||
re := regexp.MustCompile("var +([a-zA-Z_]+) +[a-zA-Z]+[8|16|32|64]{0,1}")
|
|
||||||
re.FindStringSubmatch(codes[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table 表结构
|
|
||||||
type Table struct {
|
|
||||||
tableLock *sync.Mutex
|
|
||||||
|
|
||||||
Name string
|
|
||||||
Type int
|
|
||||||
|
|
||||||
ID uint32 // uint16
|
|
||||||
|
|
||||||
IsAllKey bool
|
|
||||||
Fields []*Field
|
|
||||||
|
|
||||||
fidCount uint16 // uint16
|
|
||||||
idxCount uint64
|
|
||||||
rawCount uint64
|
|
||||||
delCount uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateField 创建字段
|
|
||||||
func (table *Table) CreateField(key []byte, vt ValueType, isIndex bool, isUnique bool) *Field {
|
|
||||||
|
|
||||||
table.tableLock.Lock()
|
|
||||||
defer table.tableLock.Unlock()
|
|
||||||
|
|
||||||
field := &Field{}
|
|
||||||
field.ID = table.fidCount
|
|
||||||
field.IsIndex = isIndex
|
|
||||||
field.IsUnique = isUnique
|
|
||||||
field.Key = key
|
|
||||||
field.VT = vt
|
|
||||||
|
|
||||||
table.fidCount++
|
|
||||||
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateTable 创建表
|
|
||||||
func CreateTable(name string, fields []*Field) {
|
|
||||||
if _, ok := EDB.TableDict[name]; !ok {
|
|
||||||
ntid := atomic.AddUint32(&EDB.Metadata.tidCount, 1)
|
|
||||||
table := &Table{Name: name, ID: ntid, Type: 1}
|
|
||||||
table.Fields = fields
|
|
||||||
} else {
|
|
||||||
log.Println("table name is exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenDataBase (cf-key.{tableid(2)}{fieldid(2)}) {value}{indexid(6)} = {rowid(6)} (cf-row.{tableid(2)} {row-sharding-id}){rowid(6)} = {values}
|
// OpenDataBase (cf-key.{tableid(2)}{fieldid(2)}) {value}{indexid(6)} = {rowid(6)} (cf-row.{tableid(2)} {row-sharding-id}){rowid(6)} = {values}
|
||||||
func OpenDataBase() (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle) {
|
func OpenDataBase() (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle) {
|
||||||
|
|
||||||
|
|
81
table.go
Normal file
81
table.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/tecbot/gorocksdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewEasyDataBase() *EasyDataBase {
|
||||||
|
|
||||||
|
edb := &EasyDataBase{}
|
||||||
|
db, cfs := OpenDataBase()
|
||||||
|
edb.DB = db
|
||||||
|
edb.CFS = cfs
|
||||||
|
return edb
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type EasyDataBase struct {
|
||||||
|
DB *gorocksdb.DB
|
||||||
|
CFS gorocksdb.ColumnFamilyHandles
|
||||||
|
|
||||||
|
Tables map[uint32]*Table
|
||||||
|
TableDict map[string]uint32
|
||||||
|
|
||||||
|
Metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
type Metadata struct {
|
||||||
|
tidCount uint32 // int16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table 表结构
|
||||||
|
type Table struct {
|
||||||
|
tableLock *sync.Mutex
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Type int
|
||||||
|
|
||||||
|
ID uint32 // uint16
|
||||||
|
|
||||||
|
IsAllKey bool
|
||||||
|
Fields []*Field
|
||||||
|
|
||||||
|
fidCount uint16 // uint16
|
||||||
|
idxCount uint64
|
||||||
|
rawCount uint64
|
||||||
|
delCount uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateField 创建字段
|
||||||
|
func (table *Table) CreateField(key []byte, vt ValueType, isIndex bool, isUnique bool) *Field {
|
||||||
|
|
||||||
|
table.tableLock.Lock()
|
||||||
|
defer table.tableLock.Unlock()
|
||||||
|
|
||||||
|
field := &Field{}
|
||||||
|
field.ID = table.fidCount
|
||||||
|
field.IsIndex = isIndex
|
||||||
|
field.IsUnique = isUnique
|
||||||
|
field.Key = key
|
||||||
|
field.VT = vt
|
||||||
|
|
||||||
|
table.fidCount++
|
||||||
|
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTable 创建表
|
||||||
|
func CreateTable(name string, fields []*Field) {
|
||||||
|
if _, ok := EDB.TableDict[name]; !ok {
|
||||||
|
ntid := atomic.AddUint32(&EDB.Metadata.tidCount, 1)
|
||||||
|
table := &Table{Name: name, ID: ntid, Type: 1}
|
||||||
|
table.Fields = fields
|
||||||
|
} else {
|
||||||
|
log.Println("table name is exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -18,30 +19,104 @@ func TestParseRe(t *testing.T) {
|
||||||
var parseCollection []parseTest
|
var parseCollection []parseTest
|
||||||
parseCollection = append(parseCollection,
|
parseCollection = append(parseCollection,
|
||||||
parseTest{
|
parseTest{
|
||||||
PS: "var a int; a = 0 ; a >= 1 && a <= 4",
|
PS: "var a int = 0; ($ >= 1 && $ <= 4)?$+1:$-1 ; $+=1",
|
||||||
Result: []string{"a", "int"},
|
Result: []string{"a", "int"},
|
||||||
},
|
},
|
||||||
parseTest{
|
parseTest{
|
||||||
PS: "var das_das int64; das_das = 0 ; das_das >= 1 && das_das <= 4",
|
PS: "var das_das int64; $ = 0 ; if $ >= 1 && $ <= 4 { push() }",
|
||||||
Result: []string{"das_das", "int64"},
|
Result: []string{"das_das", "int64"},
|
||||||
},
|
},
|
||||||
parseTest{
|
parseTest{
|
||||||
PS: "var BitTkoen text; BitTkoen = 0 ; BitTkoen >= 1 && BitTkoen <= 4",
|
PS: "var BitTkoen []text; BitTkoen = 0 ; BitTkoen >= 1 && BitTkoen <= 4",
|
||||||
Result: []string{"BitTkoen", "text"},
|
Result: []string{"BitTkoen", "text"},
|
||||||
},
|
},
|
||||||
parseTest{
|
parseTest{
|
||||||
PS: "var BitTkoen char(24); BitTkoen = 0 ; BitTkoen >= 1 && BitTkoen <= 4",
|
PS: "var BitTkoen [24]char; BitTkoen = 0 ; BitTkoen >= 1 && BitTkoen <= 4",
|
||||||
Result: []string{"BitTkoen", "text"},
|
Result: []string{"BitTkoen", "text"},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
field := &Field{}
|
||||||
|
|
||||||
for _, parse := range parseCollection {
|
for _, parse := range parseCollection {
|
||||||
codes := strings.Split(parse.PS, ";")
|
codes := strings.Split(parse.PS, ";")
|
||||||
result := ReKeyDefined.FindStringSubmatch(codes[0])
|
definestr := codes[0]
|
||||||
if len(result) >= 3 && !(result[1] == parse.Result[0] && result[2] == parse.Result[1]) {
|
i := 0
|
||||||
t.Error(result)
|
|
||||||
|
// 检查定义头是否存在
|
||||||
|
for ; i < len(definestr); i++ {
|
||||||
|
if definestr[i] == 'v' && definestr[i+1] == 'a' && definestr[i+2] == 'r' {
|
||||||
|
i += 2
|
||||||
|
|
||||||
|
skipSpace(&definestr, &i)
|
||||||
|
|
||||||
|
GET_KEY:
|
||||||
|
for ; i < len(definestr); i++ {
|
||||||
|
switch c := definestr[i]; {
|
||||||
|
case (c <= 'Z' && c >= 'A' && c <= 'z' && c >= 'a') || c == '_':
|
||||||
|
field.Key = append(field.Key, c)
|
||||||
|
case c == ' ':
|
||||||
|
break GET_KEY
|
||||||
|
default:
|
||||||
|
t.Error("错误")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
skipSpace(&definestr, &i)
|
||||||
|
|
||||||
|
for ; i < len(definestr); i++ {
|
||||||
|
switch c := definestr[i]; {
|
||||||
|
case c == ' ':
|
||||||
|
continue
|
||||||
|
case (c <= 'Z' && c >= 'A' && c <= 'z' && c >= 'a'):
|
||||||
|
|
||||||
|
var valueType []byte
|
||||||
|
for ; i < len(definestr); i++ {
|
||||||
|
cc := definestr[i]
|
||||||
|
if cc == ';' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
valueType = append(valueType, cc)
|
||||||
|
}
|
||||||
|
|
||||||
|
case c == '[':
|
||||||
|
i++
|
||||||
|
|
||||||
|
var arrayNum []byte
|
||||||
|
GET_ARRAY:
|
||||||
|
for ; i < len(definestr); i++ {
|
||||||
|
switch cc := definestr[i]; {
|
||||||
|
case cc == ']':
|
||||||
|
break GET_ARRAY
|
||||||
|
default:
|
||||||
|
arrayNum = append(arrayNum, cc)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if arrayNum == nil {
|
||||||
|
field.ArrayNumber = -1
|
||||||
|
} else {
|
||||||
|
num, err := strconv.Atoi(string(arrayNum))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
field.ArrayNumber = num
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
t.Error("错误")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
t.Error("错误")
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t.Error(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Error(field)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user