forked from xo/usql
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.go
213 lines (197 loc) · 5.61 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package metacmd
import (
"context"
"database/sql"
"io"
"os/user"
"strings"
"time"
"github.com/xo/dburl"
"github.com/xo/usql/drivers"
"github.com/xo/usql/drivers/metadata"
"github.com/xo/usql/env"
"github.com/xo/usql/rline"
"github.com/xo/usql/stmt"
"github.com/xo/usql/text"
)
// Handler is the shared interface for a command handler.
type Handler interface {
// IO handles the handler's IO.
IO() rline.IO
// User returns the current user.
User() *user.User
// URL returns the current database URL.
URL() *dburl.URL
// DB returns the current database connection.
DB() drivers.DB
// Last returns the last executed query.
Last() string
// LastRaw returns the last raw (non-interpolated) query.
LastRaw() string
// Buf returns the current query buffer.
Buf() *stmt.Stmt
// Reset resets the last and current query buffer.
Reset([]rune)
// Open opens a database connection.
Open(context.Context, ...string) error
// Close closes the current database connection.
Close() error
// ChangePassword changes the password for a user.
ChangePassword(string) (string, error)
// ReadVar reads a variable of a specified type.
ReadVar(string, string) (string, error)
// Include includes a file.
Include(string, bool) error
// Begin begins a transaction.
Begin(*sql.TxOptions) error
// Commit commits the current transaction.
Commit() error
// Rollback aborts the current transaction.
Rollback() error
// Highlight highlights the statement.
Highlight(io.Writer, string) error
// GetTiming mode.
GetTiming() bool
// SetTiming mode.
SetTiming(bool)
// GetOutput writer.
GetOutput() io.Writer
// SetOutput writer.
SetOutput(io.WriteCloser)
// MetadataWriter retrieves the metadata writer for the handler.
MetadataWriter(context.Context) (metadata.Writer, error)
// Print formats according to a format specifier and writes to handler's standard output.
Print(string, ...interface{})
}
// Runner is a runner interface type.
type Runner interface {
Run(Handler) (Option, error)
}
// RunnerFunc is a type wrapper for a single func satisfying Runner.Run.
type RunnerFunc func(Handler) (Option, error)
// Run satisfies the Runner interface.
func (f RunnerFunc) Run(h Handler) (Option, error) {
return f(h)
}
// ExecType represents the type of execution requested.
type ExecType int
const (
// ExecNone indicates no execution.
ExecNone ExecType = iota
// ExecOnly indicates plain execution only (\g).
ExecOnly
// ExecPipe indicates execution and piping results (\g |file)
ExecPipe
// ExecSet indicates execution and setting the resulting columns as
// variables (\gset).
ExecSet
// ExecExec indicates execution and executing the resulting rows (\gexec).
ExecExec
// ExecCrosstab indicates execution using crosstabview (\crosstabview).
ExecCrosstab
// ExecWatch indicates repeated execution with a fixed time interval.
ExecWatch
)
// Option contains parsed result options of a metacmd.
type Option struct {
// Quit instructs the handling code to quit.
Quit bool
// Exec informs the handling code of the type of execution.
Exec ExecType
// Params are accompanying string parameters for execution.
Params map[string]string
// Crosstab are the crosstab column parameters.
Crosstab []string
// Watch is the watch duration interval.
Watch time.Duration
}
func (opt *Option) ParseParams(params []string, defaultKey string) error {
if opt.Params == nil {
opt.Params = make(map[string]string, len(params))
}
formatOptions := false
for i, param := range params {
if len(param) == 0 {
continue
}
if !formatOptions {
if param[0] == '(' {
formatOptions = true
} else {
opt.Params[defaultKey] = strings.Join(params[i:], " ")
return nil
}
}
parts := strings.SplitN(param, "=", 2)
if len(parts) == 1 {
return text.ErrInvalidFormatOption
}
opt.Params[strings.TrimLeft(parts[0], "(")] = strings.TrimRight(parts[1], ")")
if formatOptions && param[len(param)-1] == ')' {
formatOptions = false
}
}
return nil
}
// Params wraps metacmd parameters.
type Params struct {
// Handler is the process handler.
Handler Handler
// Name is the name of the metacmd.
Name string
// Params are the actual statement parameters.
Params *stmt.Params
// Option contains resulting command execution options.
Option Option
}
// Get returns the next command parameter, using env.Unquote to decode quoted
// strings.
func (p *Params) Get(exec bool) (string, error) {
_, v, err := p.Params.Get(env.Unquote(
p.Handler.User(),
exec,
env.All(),
))
if err != nil {
return "", err
}
return v, nil
}
// GetOK returns the next command parameter, using env.Unquote to decode quoted
// strings.
func (p *Params) GetOK(exec bool) (bool, string, error) {
return p.Params.Get(env.Unquote(
p.Handler.User(),
exec,
env.All(),
))
}
// GetOptional returns the next command parameter, using env.Unquote to decode
// quoted strings, returns true when the value is prefixed with a "-", along
// with the value sans the "-" prefix. Otherwise returns false and the value.
func (p *Params) GetOptional(exec bool) (bool, string, error) {
v, err := p.Get(exec)
if err != nil {
return false, "", err
}
if len(v) > 0 && v[0] == '-' {
return true, v[1:], nil
}
return false, v, nil
}
// GetAll gets all remaining command parameters using env.Unquote to decode
// quoted strings.
func (p *Params) GetAll(exec bool) ([]string, error) {
return p.Params.GetAll(env.Unquote(
p.Handler.User(),
exec,
env.All(),
))
}
// GetRaw gets the remaining command parameters as a raw string.
//
// Note: no other processing is done to interpolate variables or to decode
// string values.
func (p *Params) GetRaw() string {
return p.Params.GetRaw()
}