Skip to content

Commit 2247bd5

Browse files
committed
Finished version 1.0.0
1 parent a9d8d24 commit 2247bd5

File tree

12 files changed

+213
-152
lines changed

12 files changed

+213
-152
lines changed

engine/store/store.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// package store provides APIs for low level
1+
// Package store provides APIs for low level
22
// interaction with the key-value data store.
33
package store
44

@@ -31,16 +31,16 @@ func Init() *Store {
3131
// Del performs a thread safe delete over keys provided and
3232
// returns a slice of Booleans (BaseType implement) signifying
3333
// successful deletion if key was found.
34-
func (s *Store) Del(keys []string) []types.Boolean {
34+
func (s *Store) Del(keys []string) []types.BaseType {
3535
s.mutex.Lock()
3636
defer s.mutex.Unlock()
37-
var statuses []types.Boolean
37+
var statuses []types.BaseType
3838
for _, key := range keys {
3939
if _, ok := s.pairs[key]; ok {
4040
delete(s.pairs, key)
41-
statuses = append(statuses, *types.NewBoolean(true))
41+
statuses = append(statuses, types.NewBoolean(true))
4242
} else {
43-
statuses = append(statuses, *types.NewBoolean(false))
43+
statuses = append(statuses, types.NewBoolean(false))
4444
}
4545
}
4646
return statuses

engine/types/types.go

Lines changed: 68 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -7,147 +7,114 @@ import (
77
"unsafe"
88
)
99

10+
// BaseType makes up the most basic building blocks of all
11+
// primitive data types for HellDB. There is no differentiation
12+
// between composite or self sufficient types.
13+
//
14+
// The Name function is a meta function that returns the string
15+
// identifier for a type - in case we need a strongly typed interpreter
16+
// that supports operations for reducing or mapping over keys.
17+
//
18+
// SizeOf returns an unsigned integer for the number of bytes taken
19+
// up by a data member - it's statically defined for some types (ex. Boolean),
20+
// grows with size for some (ex. String, Collection) and is platform dependent
21+
// for others (ex. Int).
22+
//
23+
// String is another meta function returns a native string
24+
// representation for a type useful for taking snapshots (currently
25+
// unsupported) before shutdown or at random intervals.
26+
//
27+
// Native returns a native Go type representation for a BaseType. Compound
28+
// data types can also be represented such as heterogeneous arrays (Collection)
29+
// since they all implement the BaseType interface and required methods.
1030
type BaseType interface {
1131
Name() string
1232
SizeOf() uint
1333
String() string
1434
Native() interface{}
1535
}
1636

37+
// Int is a struct that implements BaseType for signed 64
38+
// bit integers.
1739
type Int struct {
18-
data int64
40+
Data int64 `json:"int"`
1941
}
2042

21-
type String struct {
22-
data string
23-
}
24-
25-
type Boolean struct {
26-
data bool
27-
}
28-
29-
type Collection struct {
30-
data []BaseType
31-
}
32-
33-
/* -----------------int------------------ */
34-
35-
func (i *Int) Name() string {
36-
return "integer"
37-
}
38-
39-
func (i *Int) SizeOf() uint {
40-
return uint(unsafe.Sizeof(i.data))
41-
}
42-
43-
func (i *Int) String() string {
44-
return strconv.FormatInt(i.data, 10)
45-
}
46-
47-
func (i *Int) Native() interface{} {
48-
return i.data
49-
}
43+
func (i *Int) Native() interface{} { return i.Data }
44+
func (i *Int) Name() string { return "integer" }
45+
func NewInt(data int64) *Int { return &Int{Data: data} }
46+
func (i *Int) SizeOf() uint { return uint(unsafe.Sizeof(i.Data)) }
47+
func (i *Int) String() string { return strconv.FormatInt(i.Data, 10) }
5048

51-
func NewInt(data int64) *Int {
52-
return &Int{data: data}
49+
type String struct {
50+
Data string `json:"string"`
5351
}
5452

55-
/* -----------------str----------------- */
56-
57-
func (s *String) Name() string {
58-
return "str"
59-
}
53+
func (s *String) Name() string { return "str" }
54+
func (s *String) String() string { return s.Data }
55+
func (s *String) Native() interface{} { return s.Data }
56+
func (s *String) SizeOf() uint { return uint(len(s.Data)) }
57+
func NewString(data string) *String { return &String{Data: data} }
6058

61-
func (s *String) SizeOf() uint {
62-
return uint(len(s.data))
59+
type Boolean struct {
60+
Data bool `json:"bool"`
6361
}
6462

65-
func (s *String) String() string {
66-
return s.data
67-
}
63+
func (b *Boolean) SizeOf() uint { return 1 }
64+
func (b *Boolean) Native() interface{} { return b.Data }
65+
func (b *Boolean) Name() string { return "boolean" }
66+
func NewBoolean(data bool) *Boolean { return &Boolean{Data: data} }
6867

69-
func (s *String) Native() interface{} {
70-
return s.data
68+
func (b *Boolean) String() string {
69+
if b.Data {
70+
return "true"
71+
} else {
72+
return "false"
73+
}
7174
}
7275

73-
func NewString(data string) *String {
74-
return &String{data: data}
76+
type Collection struct {
77+
Data []BaseType `json:"collection"`
7578
}
7679

77-
/* ----------------collection---------------- */
80+
func (c *Collection) Name() string { return "collection" }
81+
func (c *Collection) Native() interface{} { return serializeCollection(c) }
82+
func NewCollection(data []BaseType) *Collection { return &Collection{Data: data} }
7883

79-
func (c *Collection) Name() string {
80-
return "collection"
84+
func serializeCollection(collection *Collection) []interface{} {
85+
var list []interface{}
86+
for _, val := range collection.Data {
87+
if c, ok := val.(*Collection); ok {
88+
list = append(list, serializeCollection(c))
89+
} else {
90+
list = append(list, val.Native())
91+
}
92+
}
93+
return list
8194
}
8295

8396
func (c *Collection) SizeOf() uint {
84-
if l := uint(len(c.data)); l == 0 {
97+
if l := uint(len(c.Data)); l == 0 {
8598
return 0
8699
} else {
87100
var total uint = 0
88-
for _, item := range c.data {
101+
for _, item := range c.Data {
89102
total += item.SizeOf()
90103
}
91104
return total
92105
}
93106
}
94107

95108
func (c *Collection) String() string {
96-
if len(c.data) == 0 {
109+
if len(c.Data) == 0 {
97110
return "[]"
98111
} else {
99112
var b strings.Builder
100113
b.WriteString("[ ")
101-
for i := 0; i < len(c.data)-1; i++ {
102-
_, _ = fmt.Fprintf(&b, "%s, ", c.data[i].String())
114+
for i := 0; i < len(c.Data)-1; i++ {
115+
_, _ = fmt.Fprintf(&b, "%s, ", c.Data[i].String())
103116
}
104-
_, _ = fmt.Fprintf(&b, "%s ]", c.data[len(c.data)-1].String())
117+
_, _ = fmt.Fprintf(&b, "%s ]", c.Data[len(c.Data)-1].String())
105118
return b.String()
106119
}
107120
}
108-
109-
func serializeCollection(collection *Collection) []interface{} {
110-
var list []interface{}
111-
for _, val := range collection.data {
112-
if c, ok := val.(*Collection); ok {
113-
list = append(list, serializeCollection(c))
114-
} else {
115-
list = append(list, val.Native())
116-
}
117-
}
118-
return list
119-
}
120-
121-
func (c *Collection) Native() interface{} {
122-
return serializeCollection(c)
123-
}
124-
125-
func NewCollection(data []BaseType) *Collection {
126-
return &Collection{data: data}
127-
}
128-
129-
/* ----------------boolean---------------- */
130-
131-
func (b *Boolean) Name() string {
132-
return "boolean"
133-
}
134-
135-
func (b *Boolean) SizeOf() uint {
136-
return 1
137-
}
138-
139-
func (b *Boolean) String() string {
140-
if b.data {
141-
return "true"
142-
} else {
143-
return "false"
144-
}
145-
}
146-
147-
func (b *Boolean) Native() interface{} {
148-
return b.data
149-
}
150-
151-
func NewBoolean(data bool) *Boolean {
152-
return &Boolean{data: data}
153-
}

main.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,35 @@ import (
1111

1212
func main() {
1313

14-
clientFlag := flag.NewFlagSet("client", flag.ExitOnError)
15-
serverFlag := flag.NewFlagSet("server", flag.ExitOnError)
14+
const (
15+
version = "1.0.0"
16+
debugStr = "debug"
17+
serverStr = "server"
18+
)
19+
20+
debugFlag := flag.NewFlagSet(debugStr, flag.ExitOnError)
21+
serverFlag := flag.NewFlagSet(serverStr, flag.ExitOnError)
22+
versionPtr := flag.Bool("v", false, "displays current database version")
1623

1724
serverPortPtr := serverFlag.Uint("port", 8080, "port to run helldb on")
18-
clientPromptPtr := clientFlag.String("prompt", ">>> ", "prompt to use for client")
25+
debugPromptPtr := debugFlag.String("prompt", ">>> ", "prompt to use for client")
1926

2027
flag.Parse()
2128

29+
if *versionPtr {
30+
println(version)
31+
os.Exit(0)
32+
}
33+
2234
if len(os.Args) <= 1 {
2335
server.Serve(strconv.Itoa(int(*serverPortPtr)))
2436
}
2537

2638
switch os.Args[1] {
27-
case "server":
39+
case debugStr:
40+
evaluator.REPL(*debugPromptPtr)
41+
case serverStr:
2842
server.Serve(strconv.Itoa(int(*serverPortPtr)))
29-
case "client":
30-
evaluator.REPL(*clientPromptPtr)
3143
}
3244

3345
}

portal/evaluator/evaluator.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package evaluator
33
import (
44
"bufio"
55
"fmt"
6+
"helldb/engine/types"
67
"os"
78

89
s "helldb/engine/store"
@@ -19,7 +20,7 @@ func REPL(prompt string) {
1920
fmt.Print(prompt)
2021
for scanner.Scan() {
2122
input := scanner.Text()
22-
if input == "json" {
23+
if input == "dumb" {
2324
fmt.Println(store.JSON())
2425
fmt.Print(prompt)
2526
continue
@@ -39,32 +40,25 @@ func Eval(input string) Response {
3940
p := parser.New(l)
4041
query := p.ParseQuery()
4142
if len(p.Errors()) == 0 {
42-
for _, statement := range query.Statements {
43+
results := make([][]types.BaseType, len(query.Statements))
44+
for i, statement := range query.Statements {
4345
if valid, isGet := isGetOrDelStatement(statement); valid {
4446
var keys []string
4547
if isGet {
4648
keys = keysFromGetStatement(statement)
49+
results[i] = store.Get(keys)
4750
} else {
4851
keys = keysFromDelStatement(statement)
52+
results[i] = store.Del(keys)
4953
}
50-
return Response{Errors: nil, Results: store.Get(keys)}
5154
} else {
5255
putStatement := statement.(*ast.PutStatement)
53-
key := putStatement.Key.String()
54-
element := putStatement.Value
55-
switch element.(type) {
56-
case *ast.IntegerLiteral:
57-
store.Put(key, element.(*ast.IntegerLiteral).ToBaseType())
58-
case *ast.StringLiteral:
59-
store.Put(key, element.(*ast.StringLiteral).ToBaseType())
60-
case *ast.BooleanLiteral:
61-
store.Put(key, element.(*ast.BooleanLiteral).ToBaseType())
62-
case *ast.CollectionLiteral:
63-
store.Put(key, element.(*ast.CollectionLiteral).ToBaseType())
64-
}
65-
return Response{Errors: nil, Results: nil}
56+
key, value := putStatement.Key.String(), putStatement.Value
57+
store.Put(key, ast.ExtractToBaseType(value))
58+
results[i] = nil
6659
}
6760
}
61+
return Response{Errors: p.Errors(), Results: results}
6862
}
6963
return Response{Errors: p.Errors(), Results: nil}
7064
}

portal/evaluator/responses.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
package evaluator
22

3-
import "helldb/engine/types"
3+
import (
4+
"encoding/json"
5+
6+
"helldb/engine/types"
7+
)
8+
9+
func toJson(data interface{}) string {
10+
b, _ := json.Marshal(data)
11+
return string(b)
12+
}
413

514
type Response struct {
6-
Errors []string `json:"errors"`
7-
Results []types.BaseType `json:"results"`
15+
Errors []string `json:"errors"`
16+
Results [][]types.BaseType `json:"results"`
817
}

portal/evaluator/utils.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,24 @@ package evaluator
33
import (
44
"encoding/json"
55
"fmt"
6+
67
"helldb/engine/types"
78
"helldb/query/ast"
89
"helldb/query/token"
910
)
1011

11-
func showResults(results []types.BaseType) {
12+
func showResults(results [][]types.BaseType) {
1213
for _, result := range results {
13-
var res interface{}
14-
if result != nil {
15-
res = result.Native()
16-
} else {
17-
res = nil
14+
for _, retValue := range result {
15+
var res interface{}
16+
if retValue != nil {
17+
res = retValue.Native()
18+
} else {
19+
res = nil
20+
}
21+
str, _ := json.MarshalIndent(res, "", " ")
22+
fmt.Println(string(str))
1823
}
19-
str, _ := json.MarshalIndent(res, "", " ")
20-
fmt.Println(string(str))
2124
}
2225
}
2326

0 commit comments

Comments
 (0)