-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathclient.go
105 lines (93 loc) · 2.21 KB
/
client.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
//
// Copyright (c) 2021 Markku Rossi
//
// All rights reserved.
//
package iql
import (
"fmt"
"io"
"github.com/markkurossi/iql/lang"
"github.com/markkurossi/iql/types"
"github.com/markkurossi/tabulate"
)
// Client implements the IQL client.
type Client struct {
global *lang.Scope
out io.Writer
}
// NewClient creates a new IQL client.
func NewClient(out io.Writer) *Client {
global := lang.NewScope(nil)
lang.InitSystemVariables(global)
return &Client{
global: global,
out: out,
}
}
// SetString assigns the string value to the global variable. The
// global variable must have been declared and its type must be
// VARCHAR.
func (c *Client) SetString(name, value string) error {
return c.global.Set(name, types.StringValue(value))
}
// SetStringArray assings the string array value to the global
// variable. The global variable must have been declared and its type
// must be []VARCHAR.
func (c *Client) SetStringArray(name string, value []string) error {
var arr []types.Value
for _, v := range value {
arr = append(arr, types.StringValue(v))
}
return c.global.Set(name, types.NewArray(types.String, arr))
}
// Write implements io.Write().
func (c *Client) Write(p []byte) (n int, err error) {
if c.SysTermOut() {
return c.out.Write(p)
}
return len(p), nil
}
// Parse parses the IQL file.
func (c *Client) Parse(input io.Reader, source string) error {
parser := lang.NewParser(c.global, input, source, c)
for {
q, err := parser.Parse()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
tab, err := types.Tabulate(q, c.SysTableFmt())
if err != nil {
return err
}
tab.Print(c)
}
}
// SysTableFmt returns the table formatting style.
func (c *Client) SysTableFmt() (style tabulate.Style) {
style = tabulate.Unicode
b := c.global.Get(lang.SysTableFmt)
if b == nil {
return
}
s, ok := tabulate.Styles[b.Value.String()]
if ok {
style = s
}
return
}
// SysTermOut describes if terminal output is enabled.
func (c *Client) SysTermOut() bool {
b := c.global.Get(lang.SysTermOut)
if b == nil {
panic("system variable TERMOUT not set")
}
v, err := b.Value.Bool()
if err != nil {
panic(fmt.Sprintf("invalid system variable value: %s", err))
}
return v
}