Skip to content

Commit

Permalink
compare dates and renamed
Browse files Browse the repository at this point in the history
  • Loading branch information
ax4w committed Nov 19, 2023
1 parent f8a8369 commit 767685c
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 74 deletions.
169 changes: 134 additions & 35 deletions eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package Gorage
import (
"strconv"
"strings"
"time"
)

const (
Expand All @@ -11,6 +12,7 @@ const (
tokenTypeFloat = 3
tokenTypeBoolean = 4
tokenTypeChar = 5
tokenTypeDate = 6
)

type token struct {
Expand All @@ -25,6 +27,14 @@ var (
strongSplit = []string{"&&", "!&", "||", "!|"}
)

func validateDate(d string) bool {
_, err := time.Parse("2006-01-02", d)
if err != nil {
return false
}
return true
}

func compareByteArray(b1, b2 []byte) bool {
if len(b1) != len(b2) {
return false
Expand All @@ -50,6 +60,37 @@ func convertBytesToFloat(v []byte) float64 {
return r
}

// -2 d1 is greater
// -1 d1 is greater than
// 0 equal
// 1 d2 is greater than
// 2 d2 is greater
func compareDates(d1, d2 string) int {
t1, err := time.Parse("2006-01-02", d1)
if err != nil {
panic("Error parsing dates")
}
td1 := t1.Unix()
t2, err := time.Parse("2006-01-02", d2)
if err != nil {
panic("Error parsing dates")
}
td2 := t2.Unix()
switch {
case td1 > td2:
return -2
case td1 == td2:
return 0
case td1 >= td2:
return -1
case td2 >= td1:
return 1
case td2 > td1:
return 2
}
return 0
}

func evaluate(f *token) *token {
if f.left == nil && f.right == nil {
return f
Expand All @@ -62,74 +103,130 @@ func evaluate(f *token) *token {
if !(r.tokenType == tokenTypeInt && l.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeInt && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt) {
panic("<= is only supported for int and float")
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate) {
panic("< is only supported for int, float and date")
}
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv < rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
if l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate {
i := compareDates(string(l.value), string(r.value))
if i == -2 {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
} else {
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv < rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}

case ">":
if !(r.tokenType == tokenTypeInt && l.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeInt && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt) {
panic("<= is only supported for int and float")
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate) {
panic("<= is only supported for int, float and date")
}
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv > rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
if l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate {
i := compareDates(string(l.value), string(r.value))
if i == 2 {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
} else {
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv > rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}

case ">=":
if !(r.tokenType == tokenTypeInt && l.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeInt && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt) {
panic("<= is only supported for int and float")
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate) {
panic("<= is only supported for int, float and date")
}
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv >= rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
if l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate {
i := compareDates(string(l.value), string(r.value))
if i == 1 {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
} else {
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv >= rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}

case "<=":
if !(r.tokenType == tokenTypeInt && l.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeInt && r.tokenType == tokenTypeFloat ||
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt) {
panic("<= is only supported for int and float")
l.tokenType == tokenTypeFloat && r.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate) {
panic("<= is only supported for int, float and date")
}
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv <= rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
if l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate {
i := compareDates(string(l.value), string(r.value))
if i == -1 {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
} else {
lv := convertBytesToFloat(l.value)
rv := convertBytesToFloat(r.value)
if lv <= rv {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
case "==":
if !(l.tokenType == r.tokenType ||
l.tokenType == tokenTypeChar && r.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeInt && r.tokenType == tokenTypeChar) {
panic("mismatching == types")
}
if compareByteArray(l.value, r.value) {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
if l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate {
i := compareDates(string(l.value), string(r.value))
if i == 0 {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
} else {
if compareByteArray(l.value, r.value) {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}

case "!=":
if !(l.tokenType == r.tokenType ||
l.tokenType == tokenTypeChar && r.tokenType == tokenTypeInt ||
l.tokenType == tokenTypeInt && r.tokenType == tokenTypeChar) {
panic("mismatching == types")
}
if !compareByteArray(l.value, r.value) {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
if l.tokenType == tokenTypeDate && r.tokenType == tokenTypeDate {
i := compareDates(string(l.value), string(r.value))
if i != 0 {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
} else {
if !compareByteArray(l.value, r.value) {
return &token{value: []byte("t"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
}
return &token{value: []byte("f"), tokenType: tokenTypeBoolean}
case "&&":
if !(l.tokenType == tokenTypeBoolean && r.tokenType == tokenTypeBoolean) {
panic("&& expects both sides to be a boolean")
Expand Down Expand Up @@ -311,7 +408,9 @@ func parse(f string) []*token {
tokenType = tokenTypeBoolean
break
default:
if _, err := strconv.Atoi(k); err == nil {
if validateDate(k) {
tokenType = tokenTypeDate
} else if _, err := strconv.Atoi(k); err == nil {
tokenType = tokenTypeInt
} else if _, err = strconv.ParseFloat(k, 64); err == nil {
tokenType = tokenTypeFloat
Expand Down
12 changes: 6 additions & 6 deletions eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import (
//

func TestEval(t *testing.T) {
//println(float64(int(rune('a'))))
//f := fmt.Sprintf("'%s' = 'hallo welt' & %d = 3 & %d = 4", "hallo welt", 3, 4)
if eval("( 'William' == 'William' && 2 == 2 ) || 85.5 >= 90.0") != "t" {
t.Fatalf("Should return true")
}
Expand All @@ -28,8 +26,10 @@ func TestEval(t *testing.T) {
if eval("( 'Hi' == 'hi' ) || ( 1 == 1 && ( 5 != 5 !& ( t == f ) ) ) && 1.0 < 1.1") != "t" {
t.Fatalf("Should be true")
}
//traverseTree(tr[0])

//_printTree(&tr[0])
//_printTree(&tr[0])
if eval("2023-11-19 == 2023-11-19") != "t" {
t.Fatalf("Should be true")
}
if eval("2023-11-19 == 2023-11-19") != "t" {
t.Fatalf("Should be true")
}
}
19 changes: 6 additions & 13 deletions gorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ type Gorage struct {
AllowDuplicated bool
Log bool
Path string
Tables []GorageTable
Tables []Table
}

/*
Select a table from the loaded Gorage
*/

func (g *Gorage) FromTable(name string) *GorageTable {
func (g *Gorage) FromTable(name string) *Table {
k := -1
for i, v := range g.Tables {
if v.Name == name {
Expand Down Expand Up @@ -60,17 +60,17 @@ Create a table.
Two tables with the same name in the same gorage are NOT possible
*/

func (g *Gorage) CreateTable(name string) *GorageTable {
func (g *Gorage) CreateTable(name string) *Table {
if g.TableExists(name) {
if g.Log {
gprint("CreateTable", "Table already exists")
}
return nil
}
t := GorageTable{
t := Table{
Name: name,
host: g,
Columns: []GorageColumn{},
Columns: []Column{},
Rows: [][]interface{}{},
}
g.Tables = append(g.Tables, t)
Expand Down Expand Up @@ -111,13 +111,6 @@ func Open(path string) *Gorage {
for i, _ := range g.Tables {
g.Tables[i].host = &g
}
go func() {
for _, v := range g.Tables {
if c := v.getColByType(TIMEOUT); c != nil {

}
}
}()
return &g
}

Expand All @@ -144,7 +137,7 @@ func Create(path string, allowDuplicates, log bool) *Gorage {
Log: log,
AllowDuplicated: allowDuplicates,
Path: path,
Tables: []GorageTable{},
Tables: []Table{},
}
file, _ := json.MarshalIndent(g, "", " ")
err = os.WriteFile(path, file, 0644)
Expand Down
Loading

0 comments on commit 767685c

Please sign in to comment.