Skip to content

Commit 23f6802

Browse files
committed
[experimental] Typesafe semi-generated engine
* query language parser almost from scratch via `goyacc` * new query abstract syntax tree with transformation support * added `Dataset` wrapper generator
1 parent 2001ea4 commit 23f6802

20 files changed

+2497
-20
lines changed

.github/workflows/push.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ jobs:
1919
- run: npm --prefix ui install
2020
- run: make build-ui
2121
- run: make test
22-
- uses: codecov/codecov-action@v1
22+
- uses: codecov/codecov-action@v1
23+
if: always()

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ config.yml
1212
dist/
1313

1414
coverage.txt
15-
.DS_Store
15+
.DS_Store
16+
17+
*.output

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44
"editor.codeActionsOnSave": [
55
"editor.action.organizeImports",
66
],
7+
"emeraldwalk.runonsave": {
8+
"commands": []
9+
}
710
}

go.mod

+8-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ module github.com/nfx/slrp
22

33
go 1.18
44

5-
// direct
65
require (
76
github.com/Bogdan-D/go-socks4 v1.0.0
87
github.com/PuerkitoBio/goquery v1.8.0
@@ -11,43 +10,34 @@ require (
1110
github.com/dop251/goja v0.0.0-20220124171016-cfb079cdc7b4
1211
github.com/ghodss/yaml v1.0.0
1312
github.com/gorilla/mux v1.8.0
13+
github.com/maxmind/mmdbwriter v0.0.0-20220606140952-b99976ab4826
1414
github.com/microcosm-cc/bluemonday v1.0.19
1515
github.com/oschwald/maxminddb-golang v1.9.0
1616
github.com/rs/zerolog v1.27.0
17+
github.com/stretchr/testify v1.8.0
1718
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4
19+
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
1820
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f
1921
gopkg.in/natefinch/lumberjack.v2 v2.0.0
2022
)
2123

22-
// test
23-
require (
24-
github.com/maxmind/mmdbwriter v0.0.0-20220606140952-b99976ab4826
25-
github.com/stretchr/testify v1.8.0
26-
)
27-
28-
// indirect
2924
require (
25+
github.com/BurntSushi/toml v1.0.0 // indirect
3026
github.com/andybalholm/cascadia v1.3.1 // indirect
3127
github.com/aymerick/douceur v0.2.0 // indirect
3228
github.com/davecgh/go-spew v1.1.1 // indirect
3329
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
3430
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
3531
github.com/gorilla/css v1.0.0 // indirect
36-
github.com/pmezard/go-difflib v1.0.0 // indirect
37-
golang.org/x/text v0.3.6 // indirect
38-
gopkg.in/yaml.v3 v3.0.1 // indirect
39-
)
40-
41-
// TODO: fix yaml dependencies
42-
require gopkg.in/yaml.v2 v2.4.0 // indirect
43-
44-
require (
45-
github.com/BurntSushi/toml v1.0.0 // indirect
4632
github.com/mattn/go-colorable v0.1.12 // indirect
4733
github.com/mattn/go-isatty v0.0.14 // indirect
4834
github.com/pkg/errors v0.9.1 // indirect
35+
github.com/pmezard/go-difflib v1.0.0 // indirect
4936
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
5037
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect
5138
golang.org/x/sys v0.0.0-20220325203850-36772127a21f // indirect
39+
golang.org/x/text v0.3.6 // indirect
40+
gopkg.in/yaml.v2 v2.4.0 // indirect
41+
gopkg.in/yaml.v3 v3.0.1 // indirect
5242
inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 // indirect
5343
)

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:
7979
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
8080
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
8181
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
82+
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
83+
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
8284
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
8385
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
8486
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=

ql/ast/ast.go

+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
package ast
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"time"
7+
)
8+
9+
type Cb func(Node) Node
10+
11+
type Node interface {
12+
Transform(cb Cb) Node
13+
}
14+
15+
type Binary interface {
16+
LeftRight() (Node, Node)
17+
}
18+
19+
type Query struct {
20+
Filter Node
21+
Sort Sort
22+
Limit int
23+
}
24+
25+
func (n Query) Transform(cb Cb) Node {
26+
return cb(Query{
27+
Filter: cb(n.Filter.Transform(cb)),
28+
Sort: n.Sort,
29+
Limit: n.Limit,
30+
})
31+
}
32+
33+
type Bool bool
34+
35+
const True = Bool(true)
36+
const False = Bool(false)
37+
38+
func (n Bool) Transform(cb Cb) Node {
39+
return cb(n)
40+
}
41+
42+
func (n Bool) And(o Bool) Node {
43+
return n && o
44+
}
45+
46+
func (n Bool) String() string {
47+
return fmt.Sprintf("%t", n)
48+
}
49+
50+
type Ident string
51+
52+
func (n Ident) Transform(cb Cb) Node {
53+
return cb(n)
54+
}
55+
56+
func (n Ident) String() string {
57+
return string(n)
58+
}
59+
60+
61+
type String string
62+
63+
func (n String) Transform(cb Cb) Node {
64+
return cb(n)
65+
}
66+
67+
func (n String) String() string {
68+
return fmt.Sprintf(`"%s"`, string(n))
69+
}
70+
71+
type Number float64
72+
73+
func (n Number) Transform(cb Cb) Node {
74+
return cb(n)
75+
}
76+
77+
func (n Number) String() string {
78+
return strconv.FormatFloat(float64(n), 'f', -1, 64)
79+
}
80+
81+
type Duration time.Duration
82+
83+
func (n Duration) Transform(cb Cb) Node {
84+
return cb(n)
85+
}
86+
87+
type And struct {
88+
Left, Right Node
89+
}
90+
91+
func (n And) Transform(cb Cb) Node {
92+
return cb(And{cb(n.Left.Transform(cb)), cb(n.Right.Transform(cb))})
93+
}
94+
95+
func (n And) String() string {
96+
return fmt.Sprintf("(%s AND %s)", n.Left, n.Right)
97+
}
98+
99+
type Or struct {
100+
Left, Right Node
101+
}
102+
103+
func (n Or) Transform(cb Cb) Node {
104+
return cb(Or{cb(n.Left.Transform(cb)), cb(n.Right.Transform(cb))})
105+
}
106+
107+
func (n Or) String() string {
108+
return fmt.Sprintf("(%s OR %s)", n.Left, n.Right)
109+
}
110+
111+
type Not struct {
112+
Left Node
113+
}
114+
115+
func (n Not) Transform(cb Cb) Node {
116+
return cb(Not{cb(n.Left.Transform(cb))})
117+
}
118+
119+
func (n Not) String() string {
120+
return fmt.Sprintf("NOT %s", n.Left)
121+
}
122+
123+
type Equals struct {
124+
Left, Right Node
125+
}
126+
127+
func (n Equals) Transform(cb Cb) Node {
128+
return cb(Equals{cb(n.Left.Transform(cb)), cb(n.Right.Transform(cb))})
129+
}
130+
131+
func (n Equals) LeftRight() (Node, Node) {
132+
return n.Left, n.Right
133+
}
134+
135+
func (n Equals) String() string {
136+
return fmt.Sprintf("%s = %s", n.Left, n.Right)
137+
}
138+
139+
type Contains struct {
140+
Left, Right Node
141+
}
142+
143+
func (n Contains) Transform(cb Cb) Node {
144+
return cb(Contains{cb(n.Left.Transform(cb)), cb(n.Right.Transform(cb))})
145+
}
146+
147+
func (n Contains) LeftRight() (Node, Node) {
148+
return n.Left, n.Right
149+
}
150+
151+
func (n Contains) String() string {
152+
return fmt.Sprintf("%s ~ %s", n.Left, n.Right)
153+
}
154+
155+
type LessThan struct {
156+
Left, Right Node
157+
}
158+
159+
func (n LessThan) Transform(cb Cb) Node {
160+
return cb(LessThan{cb(n.Left.Transform(cb)), cb(n.Right.Transform(cb))})
161+
}
162+
163+
func (n LessThan) LeftRight() (Node, Node) {
164+
return n.Left, n.Right
165+
}
166+
167+
func (n LessThan) String() string {
168+
return fmt.Sprintf("%s < %s", n.Left, n.Right)
169+
}
170+
171+
type GreaterThan struct {
172+
Left, Right Node
173+
}
174+
175+
func (n GreaterThan) Transform(cb Cb) Node {
176+
return cb(GreaterThan{cb(n.Left.Transform(cb)), cb(n.Right.Transform(cb))})
177+
}
178+
179+
func (n GreaterThan) LeftRight() (Node, Node) {
180+
return n.Left, n.Right
181+
}
182+
183+
func (n GreaterThan) String() string {
184+
return fmt.Sprintf("%s > %s", n.Left, n.Right)
185+
}
186+
187+
type Sort []OrderBy
188+
189+
type OrderBy struct {
190+
Ident string
191+
Asc bool
192+
}

0 commit comments

Comments
 (0)