...
1 package graphb
2
3 import (
4 "github.com/pkg/errors"
5 )
6
7
8 type Field struct {
9 Name string
10 Alias string
11 Arguments []Argument
12 Fields []*Field
13 E error
14 }
15
16
17 func (f *Field) getFields() []*Field {
18 return f.Fields
19 }
20
21 func (f *Field) setFields(fs []*Field) {
22 f.Fields = fs
23 }
24
25
26
27 func (f *Field) StringChan() (<-chan string, error) {
28
29 if err := f.check(); err != nil {
30
31 ch := make(chan string)
32 close(ch)
33 return ch, errors.WithStack(err)
34 }
35 return f.stringChan(), nil
36 }
37
38
39
40
41 func (f *Field) stringChan() <-chan string {
42
43 tokenChan := make(chan string)
44
45 go func() {
46
47 if f.Alias != "" {
48 tokenChan <- f.Alias
49 tokenChan <- tokenColumn
50 }
51 tokenChan <- f.Name
52
53
54 if len(f.Arguments) > 0 {
55 tokenChan <- tokenLP
56 for i := range f.Arguments {
57 if i != 0 {
58 tokenChan <- tokenComma
59 }
60 for str := range f.Arguments[i].stringChan() {
61 tokenChan <- str
62 }
63 }
64 tokenChan <- tokenRP
65 }
66
67
68 if len(f.Fields) > 0 {
69 tokenChan <- tokenLB
70 for i, field := range f.Fields {
71 if field != nil {
72 if i != 0 {
73 tokenChan <- tokenComma
74 }
75 for str := range field.stringChan() {
76 tokenChan <- str
77 }
78 }
79 }
80 tokenChan <- tokenRB
81 }
82 close(tokenChan)
83 }()
84 return tokenChan
85 }
86
87 func (f *Field) check() error {
88 if err := f.checkCycle(); err != nil {
89 return errors.WithStack(err)
90 }
91 if err := f.checkOther(); err != nil {
92 return errors.WithStack(err)
93 }
94 return nil
95 }
96
97
98 func (f *Field) checkOther() error {
99
100 if !validName.MatchString(f.Name) {
101 return errors.WithStack(InvalidNameErr{fieldName, f.Name})
102 }
103 if err := f.checkAlias(); err != nil {
104 return errors.WithStack(err)
105 }
106 for _, arg := range f.Arguments {
107 if !validName.MatchString(arg.Name) {
108 return errors.WithStack(InvalidNameErr{argumentName, arg.Name})
109 }
110 }
111
112
113 for _, subF := range f.Fields {
114 if err := subF.checkOther(); err != nil {
115 return errors.WithStack(err)
116 }
117 }
118 return nil
119 }
120
121 func (f *Field) checkAlias() error {
122 if f.Alias != "" && !validName.MatchString(f.Alias) {
123 return errors.WithStack(InvalidNameErr{aliasName, f.Alias})
124 }
125 return nil
126 }
127
128
129 func (f *Field) checkCycle() error {
130 if err := reach(f, f); err != nil {
131 return errors.WithStack(err)
132 }
133 return nil
134 }
135
136
137
138
139
140
141 func MakeField(name string) *Field {
142 return &Field{Name: name}
143 }
144
145
146 func (f *Field) SetArguments(arguments ...Argument) *Field {
147 f.Arguments = arguments
148 return f
149 }
150
151 func (f *Field) AddArguments(argument ...Argument) *Field {
152 f.Arguments = append(f.Arguments, argument...)
153 return f
154 }
155
156
157 func (f *Field) SetFields(fs ...*Field) *Field {
158 f.Fields = fs
159 return f
160 }
161
162
163 func (f *Field) SetAlias(alias string) *Field {
164 f.Alias = alias
165 return f
166 }
167
168
169
170
171
172 func reach(f1, f2 *Field) error {
173 if f1 == nil || f2 == nil {
174 return errors.WithStack(NilFieldErr{})
175 }
176 for _, field := range f2.Fields {
177 if f1 == field {
178 return errors.WithStack(CyclicFieldErr{*f1})
179 }
180 if err := reach(f1, field); err != nil {
181 return errors.WithStack(err)
182 }
183 }
184 return nil
185 }
186
View as plain text