diff --git a/base.go b/base.go new file mode 100644 index 0000000..8bfd4a9 --- /dev/null +++ b/base.go @@ -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 + } + } +} diff --git a/field.go b/field.go new file mode 100644 index 0000000..3db37f0 --- /dev/null +++ b/field.go @@ -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]) +} diff --git a/rocksdb.go b/rocksdb.go index d323064..513b0d9 100644 --- a/rocksdb.go +++ b/rocksdb.go @@ -4,10 +4,6 @@ import ( "fmt" "log" "os" - "regexp" - "strings" - "sync" - "sync/atomic" "time" "github.com/tecbot/gorocksdb" @@ -31,128 +27,6 @@ func init() { 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} func OpenDataBase() (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle) { diff --git a/table.go b/table.go new file mode 100644 index 0000000..a260681 --- /dev/null +++ b/table.go @@ -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") + } + +} diff --git a/table_test.go b/table_test.go index 4618d3c..a7bbc46 100644 --- a/table_test.go +++ b/table_test.go @@ -2,6 +2,7 @@ package main import ( "regexp" + "strconv" "strings" "testing" ) @@ -18,30 +19,104 @@ func TestParseRe(t *testing.T) { var parseCollection []parseTest parseCollection = append(parseCollection, 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"}, }, 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"}, }, 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"}, }, 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"}, }, ) + field := &Field{} + for _, parse := range parseCollection { codes := strings.Split(parse.PS, ";") - result := ReKeyDefined.FindStringSubmatch(codes[0]) - if len(result) >= 3 && !(result[1] == parse.Result[0] && result[2] == parse.Result[1]) { - t.Error(result) + definestr := codes[0] + i := 0 + + // 检查定义头是否存在 + 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) + }