gql 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +60 -60
- data/lib/gql/call.rb +46 -7
- data/lib/gql/config.rb +23 -0
- data/lib/gql/connection.rb +22 -22
- data/lib/gql/errors.rb +15 -11
- data/lib/gql/executor.rb +8 -7
- data/lib/gql/field.rb +26 -2
- data/lib/gql/fields/connection.rb +26 -12
- data/lib/gql/fields/object.rb +28 -8
- data/lib/gql/node.rb +75 -90
- data/lib/gql/parser.rb +214 -284
- data/lib/gql/parser.y +40 -110
- data/lib/gql/version.rb +1 -1
- data/lib/gql.rb +33 -16
- metadata +3 -3
- data/lib/gql/schema.rb +0 -21
data/lib/gql/parser.y
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
class GQL::Parser
|
2
2
|
token STRING NUMBER TRUE FALSE NULL AS IDENT
|
3
3
|
rule
|
4
|
-
|
5
|
-
: variables
|
4
|
+
root
|
5
|
+
: variables node variables { result = Root.new(val[1], val[0].merge(val[2])) }
|
6
|
+
| variables { result = Root.new(Node.new(nil, nil), val[0] ) }
|
6
7
|
;
|
7
8
|
|
8
|
-
|
9
|
-
:
|
10
|
-
|
|
11
|
-
| identifier arguments { result = CallNode.new(val[0], val[1], nil, nil) }
|
9
|
+
node
|
10
|
+
: call { result = Node.new(val[0], nil ) }
|
11
|
+
| fields { result = Node.new(nil, val[0].presence) }
|
12
12
|
;
|
13
13
|
|
14
|
-
|
15
|
-
:
|
14
|
+
call
|
15
|
+
: identifier arguments fields { result = Call.new(val[0], val[1], nil, val[2].presence) }
|
16
|
+
| identifier arguments '.' call { result = Call.new(val[0], val[1], val[3], nil ) }
|
17
|
+
| identifier arguments { result = Call.new(val[0], val[1], nil, nil ) }
|
16
18
|
;
|
17
19
|
|
18
20
|
arguments
|
@@ -28,7 +30,7 @@ rule
|
|
28
30
|
|
29
31
|
argument
|
30
32
|
: variable_identifier
|
31
|
-
|
|
33
|
+
| json_value
|
32
34
|
;
|
33
35
|
|
34
36
|
fields
|
@@ -42,30 +44,30 @@ rule
|
|
42
44
|
;
|
43
45
|
|
44
46
|
field
|
45
|
-
: identifier fields alias_identifier { result =
|
46
|
-
| identifier
|
47
|
-
| identifier alias_identifier { result =
|
48
|
-
| identifier fields { result =
|
49
|
-
| identifier
|
50
|
-
| identifier { result =
|
47
|
+
: identifier fields alias_identifier { result = Field.new(val[0], val[2], nil, val[1].presence) }
|
48
|
+
| identifier '.' call alias_identifier { result = Field.new(val[0], val[3], val[2], nil ) }
|
49
|
+
| identifier alias_identifier { result = Field.new(val[0], val[1], nil, nil ) }
|
50
|
+
| identifier fields { result = Field.new(val[0], nil, nil, val[1].presence) }
|
51
|
+
| identifier '.' call { result = Field.new(val[0], nil, val[2], nil ) }
|
52
|
+
| identifier { result = Field.new(val[0], nil, nil, nil ) }
|
51
53
|
;
|
52
54
|
|
53
55
|
alias_identifier
|
54
|
-
: AS identifier { result = val[1]
|
56
|
+
: AS identifier { result = val[1] }
|
55
57
|
;
|
56
58
|
|
57
59
|
variables
|
58
|
-
: /* empty */ { result =
|
59
|
-
| variable_list
|
60
|
+
: /* empty */ { result = {} }
|
61
|
+
| variable_list
|
60
62
|
;
|
61
63
|
|
62
64
|
variable_list
|
63
|
-
: variable
|
64
|
-
| variable_list variable { result.
|
65
|
+
: variable
|
66
|
+
| variable_list variable { result.update val[1] }
|
65
67
|
;
|
66
68
|
|
67
69
|
variable
|
68
|
-
: variable_identifier '=' variable_value { result =
|
70
|
+
: variable_identifier '=' variable_value { result = { val[0] => val[2] } }
|
69
71
|
;
|
70
72
|
|
71
73
|
variable_identifier
|
@@ -73,12 +75,9 @@ rule
|
|
73
75
|
;
|
74
76
|
|
75
77
|
variable_value
|
76
|
-
:
|
78
|
+
: json_value
|
77
79
|
;
|
78
80
|
|
79
|
-
json_text
|
80
|
-
: json_value { result = @json.result }
|
81
|
-
|
82
81
|
json_value
|
83
82
|
: object
|
84
83
|
| array
|
@@ -86,51 +85,40 @@ rule
|
|
86
85
|
;
|
87
86
|
|
88
87
|
object
|
89
|
-
:
|
90
|
-
|
|
88
|
+
: '{' '}' { result = {} }
|
89
|
+
| '{' pairs '}' { result = val[1] }
|
91
90
|
;
|
92
91
|
|
93
|
-
start_object : '{' { @json.start_object } ;
|
94
|
-
end_object : '}' { @json.end_object } ;
|
95
|
-
|
96
92
|
pairs
|
97
|
-
: pairs ',' pair
|
93
|
+
: pairs ',' pair { result.update val[2] }
|
98
94
|
| pair
|
99
95
|
;
|
100
96
|
|
101
97
|
pair
|
102
|
-
: string ':' json_value
|
98
|
+
: string ':' json_value { result = { val[0] => val[2] } }
|
103
99
|
;
|
104
100
|
|
105
101
|
array
|
106
|
-
:
|
107
|
-
|
|
102
|
+
: '[' ']' { result = [] }
|
103
|
+
| '[' values ']' { result = val[1] }
|
108
104
|
;
|
109
105
|
|
110
|
-
start_array : '[' { @json.start_array } ;
|
111
|
-
end_array : ']' { @json.end_array } ;
|
112
|
-
|
113
106
|
values
|
114
|
-
: values ',' json_value
|
115
|
-
| json_value
|
107
|
+
: values ',' json_value { result.push val[2] }
|
108
|
+
| json_value { result = val }
|
116
109
|
;
|
117
110
|
|
118
111
|
scalar
|
119
112
|
: string
|
120
|
-
|
|
121
|
-
;
|
122
|
-
|
123
|
-
string
|
124
|
-
: STRING { @json.scalar unescape_string(val[0]) }
|
125
|
-
;
|
126
|
-
|
127
|
-
literal
|
128
|
-
: NUMBER { result = convert_number(val[0]) }
|
113
|
+
| NUMBER { result = convert_number(val[0]) }
|
129
114
|
| TRUE { result = true }
|
130
115
|
| FALSE { result = false }
|
131
116
|
| NULL { result = nil }
|
132
117
|
;
|
133
118
|
|
119
|
+
string
|
120
|
+
: STRING { result = unescape_string(val[0]) }
|
121
|
+
|
134
122
|
identifier
|
135
123
|
: IDENT { result = val[0].to_sym }
|
136
124
|
;
|
@@ -143,69 +131,16 @@ require 'active_support/core_ext/object/blank'
|
|
143
131
|
|
144
132
|
---- inner
|
145
133
|
|
146
|
-
class
|
134
|
+
class Root < Struct.new(:node, :variables)
|
147
135
|
end
|
148
136
|
|
149
|
-
class
|
137
|
+
class Node < Struct.new(:call, :fields)
|
150
138
|
end
|
151
139
|
|
152
|
-
class
|
140
|
+
class Field < Struct.new(:name, :alias_name, :call, :fields)
|
153
141
|
end
|
154
142
|
|
155
|
-
class
|
156
|
-
attr_reader :stack
|
157
|
-
|
158
|
-
def initialize
|
159
|
-
clear
|
160
|
-
end
|
161
|
-
|
162
|
-
def start_object
|
163
|
-
push [:hash]
|
164
|
-
end
|
165
|
-
|
166
|
-
def start_array
|
167
|
-
push [:array]
|
168
|
-
end
|
169
|
-
|
170
|
-
def end_array
|
171
|
-
@stack.pop
|
172
|
-
end
|
173
|
-
|
174
|
-
alias :end_object :end_array
|
175
|
-
|
176
|
-
def scalar(s)
|
177
|
-
@stack.last << [:scalar, s]
|
178
|
-
end
|
179
|
-
|
180
|
-
def push(o)
|
181
|
-
@stack.last << o
|
182
|
-
@stack << o
|
183
|
-
end
|
184
|
-
|
185
|
-
def result
|
186
|
-
root = @stack.first.last
|
187
|
-
value = process(root.first, root.drop(1))
|
188
|
-
clear
|
189
|
-
value
|
190
|
-
end
|
191
|
-
|
192
|
-
private
|
193
|
-
def clear
|
194
|
-
@stack = [[:json]]
|
195
|
-
end
|
196
|
-
|
197
|
-
def process(type, rest)
|
198
|
-
case type
|
199
|
-
when :array
|
200
|
-
rest.map { |x| process(x.first, x.drop(1)) }
|
201
|
-
when :hash
|
202
|
-
Hash[rest.map { |x|
|
203
|
-
process(x.first, x.drop(1))
|
204
|
-
}.each_slice(2).to_a]
|
205
|
-
when :scalar
|
206
|
-
rest.first
|
207
|
-
end
|
208
|
-
end
|
143
|
+
class Call < Struct.new(:name, :arguments, :call, :fields)
|
209
144
|
end
|
210
145
|
|
211
146
|
UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
|
@@ -239,7 +174,6 @@ require 'active_support/core_ext/object/blank'
|
|
239
174
|
end
|
240
175
|
|
241
176
|
def parse
|
242
|
-
@json = JSONHandler.new
|
243
177
|
do_parse
|
244
178
|
end
|
245
179
|
|
@@ -275,7 +209,3 @@ require 'active_support/core_ext/object/blank'
|
|
275
209
|
def convert_number(str)
|
276
210
|
str.count('.') > 0 ? str.to_f : str.to_i
|
277
211
|
end
|
278
|
-
|
279
|
-
def convert_variables(arr1, arr2)
|
280
|
-
Hash[*arr1.flatten(1)].merge Hash[*arr2.flatten(1)]
|
281
|
-
end
|
data/lib/gql/version.rb
CHANGED
data/lib/gql.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
module GQL
|
2
2
|
autoload :Call, 'gql/call'
|
3
|
+
autoload :Config, 'gql/config'
|
3
4
|
autoload :Connection, 'gql/connection'
|
4
5
|
autoload :Executor, 'gql/executor'
|
5
6
|
autoload :Field, 'gql/field'
|
6
7
|
autoload :Node, 'gql/node'
|
7
8
|
autoload :Parser, 'gql/parser'
|
8
|
-
autoload :Schema, 'gql/schema'
|
9
9
|
autoload :Tokenizer, 'gql/tokenizer'
|
10
10
|
autoload :VERSION, 'gql/version'
|
11
11
|
|
12
12
|
module Errors
|
13
|
-
autoload :InvalidNodeClass,
|
14
|
-
autoload :ParseError,
|
15
|
-
autoload :UndefinedCall,
|
16
|
-
autoload :UndefinedField,
|
17
|
-
autoload :
|
18
|
-
autoload :
|
13
|
+
autoload :InvalidNodeClass, 'gql/errors'
|
14
|
+
autoload :ParseError, 'gql/errors'
|
15
|
+
autoload :UndefinedCall, 'gql/errors'
|
16
|
+
autoload :UndefinedField, 'gql/errors'
|
17
|
+
autoload :UndefinedNodeClass, 'gql/errors'
|
18
|
+
autoload :UndefinedRoot, 'gql/errors'
|
19
|
+
autoload :UndefinedFieldType, 'gql/errors'
|
19
20
|
end
|
20
21
|
|
21
22
|
module Fields
|
@@ -27,16 +28,23 @@ module GQL
|
|
27
28
|
autoload :String, 'gql/fields/string'
|
28
29
|
end
|
29
30
|
|
30
|
-
Schema.fields.update(
|
31
|
-
boolean: Fields::Boolean,
|
32
|
-
connection: Fields::Connection,
|
33
|
-
float: Fields::Float,
|
34
|
-
integer: Fields::Integer,
|
35
|
-
object: Fields::Object,
|
36
|
-
string: Fields::String
|
37
|
-
)
|
38
|
-
|
39
31
|
extend(Module.new {
|
32
|
+
def config
|
33
|
+
Thread.current[:gql_config] ||= Config.new
|
34
|
+
end
|
35
|
+
|
36
|
+
%w(root_node_class field_types).each do |method|
|
37
|
+
module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1
|
38
|
+
def #{method}
|
39
|
+
config.#{method}
|
40
|
+
end
|
41
|
+
|
42
|
+
def #{method}=(value)
|
43
|
+
config.#{method} = (value)
|
44
|
+
end
|
45
|
+
DELEGATORS
|
46
|
+
end
|
47
|
+
|
40
48
|
def execute(input, context = {})
|
41
49
|
ast = parse(input)
|
42
50
|
|
@@ -65,4 +73,13 @@ module GQL
|
|
65
73
|
end
|
66
74
|
end
|
67
75
|
})
|
76
|
+
|
77
|
+
self.field_types.update(
|
78
|
+
boolean: Fields::Boolean,
|
79
|
+
connection: Fields::Connection,
|
80
|
+
float: Fields::Float,
|
81
|
+
integer: Fields::Integer,
|
82
|
+
object: Fields::Object,
|
83
|
+
string: Fields::String
|
84
|
+
)
|
68
85
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Andert
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- gql.gemspec
|
112
112
|
- lib/gql.rb
|
113
113
|
- lib/gql/call.rb
|
114
|
+
- lib/gql/config.rb
|
114
115
|
- lib/gql/connection.rb
|
115
116
|
- lib/gql/errors.rb
|
116
117
|
- lib/gql/executor.rb
|
@@ -124,7 +125,6 @@ files:
|
|
124
125
|
- lib/gql/node.rb
|
125
126
|
- lib/gql/parser.rb
|
126
127
|
- lib/gql/parser.y
|
127
|
-
- lib/gql/schema.rb
|
128
128
|
- lib/gql/tokenizer.rb
|
129
129
|
- lib/gql/tokenizer.rex
|
130
130
|
- lib/gql/version.rb
|
data/lib/gql/schema.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
require 'forwardable'
|
3
|
-
|
4
|
-
module GQL
|
5
|
-
class Schema
|
6
|
-
include Singleton
|
7
|
-
|
8
|
-
class << self
|
9
|
-
extend Forwardable
|
10
|
-
|
11
|
-
delegate [:root, :root=, :fields] => :instance
|
12
|
-
end
|
13
|
-
|
14
|
-
attr_accessor :root
|
15
|
-
attr_reader :fields
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
@fields = {}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|