Skip to content

Commit a0c8c0f

Browse files
committed
add begin parsing and handling
1 parent aa0c9a0 commit a0c8c0f

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

atlas/socket/begin.go

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* This file is part of Atlas-DB.
3+
*
4+
* Atlas-DB is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of
7+
* the License, or (at your option) any later version.
8+
*
9+
* Atlas-DB is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with Atlas-DB. If not, see <https://www.gnu.org/licenses/>.
16+
*
17+
*/
18+
19+
package socket
20+
21+
import (
22+
"errors"
23+
"github.com/bottledcode/atlas-db/atlas/commands"
24+
"strings"
25+
)
26+
27+
type Begin struct {
28+
isReadonly bool
29+
tables []string
30+
views []string
31+
triggers []string
32+
}
33+
34+
func sanitizeBegin(cmd commands.Command) (tables, views, triggers []string, err error) {
35+
extractList := func() (list []string, err error) {
36+
var rip []string
37+
n := 4
38+
expectingFirst := true
39+
expectingLast := true
40+
for {
41+
first, _ := cmd.SelectNormalizedCommand(n)
42+
rip = append(rip, first)
43+
n++
44+
isLast := false
45+
first = strings.TrimSuffix(first, ",")
46+
if first == "" {
47+
break
48+
}
49+
if first == "(" {
50+
expectingFirst = false
51+
continue
52+
}
53+
if first == ")" {
54+
expectingLast = false
55+
break
56+
}
57+
if strings.HasPrefix(first, "(") {
58+
first = strings.TrimPrefix(first, "(")
59+
expectingFirst = false
60+
}
61+
if strings.HasSuffix(first, ")") {
62+
expectingLast = false
63+
first = strings.TrimSuffix(first, ")")
64+
isLast = true
65+
}
66+
if expectingFirst {
67+
err = errors.New("expected table name in parentheses")
68+
return
69+
}
70+
71+
if first == "," {
72+
continue
73+
}
74+
75+
list = append(list, cmd.NormalizeName(first))
76+
if isLast {
77+
break
78+
}
79+
}
80+
if expectingFirst || expectingLast {
81+
err = errors.New("expected table name in parentheses")
82+
return
83+
}
84+
cmd = cmd.ReplaceCommand(strings.Join(rip, " "), "BEGIN IMMEDIATE WITH")
85+
return
86+
}
87+
88+
if t, ok := cmd.SelectNormalizedCommand(1); ok && t == "IMMEDIATE" {
89+
if err = cmd.CheckMinLen(3); err != nil {
90+
return
91+
}
92+
for {
93+
switch t, _ = cmd.SelectNormalizedCommand(3); t {
94+
case "TABLE":
95+
if err = cmd.CheckMinLen(4); err != nil {
96+
return
97+
}
98+
tables, err = extractList()
99+
if err != nil {
100+
return
101+
}
102+
case "VIEW":
103+
if err = cmd.CheckMinLen(4); err != nil {
104+
return
105+
}
106+
views, err = extractList()
107+
if err != nil {
108+
return
109+
}
110+
case "TRIGGER":
111+
if err = cmd.CheckMinLen(4); err != nil {
112+
return
113+
}
114+
triggers, err = extractList()
115+
if err != nil {
116+
return
117+
}
118+
case "":
119+
return
120+
default:
121+
err = errors.New("expected TABLE, VIEW, or TRIGGER")
122+
return
123+
}
124+
}
125+
}
126+
return
127+
}
128+
129+
func ParseBegin(cmd commands.Command) (*Begin, error) {
130+
if t, ok := cmd.SelectNormalizedCommand(1); ok && t == "IMMEDIATE" {
131+
tables, views, triggers, err := sanitizeBegin(cmd)
132+
if err != nil {
133+
return nil, err
134+
}
135+
136+
return &Begin{
137+
isReadonly: false,
138+
tables: tables,
139+
views: views,
140+
triggers: triggers,
141+
}, nil
142+
}
143+
return &Begin{
144+
isReadonly: true,
145+
}, nil
146+
}
147+
148+
func (b *Begin) Handle(s *Socket) error {
149+
s.authorizer.Reset()
150+
s.authorizer.ForceReadonly = b.isReadonly
151+
152+
// todo: capture tables, views, and triggers
153+
154+
return nil
155+
}

0 commit comments

Comments
 (0)