gql 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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/node.rb
CHANGED
@@ -3,138 +3,123 @@ require 'active_support/core_ext/string/inflections'
|
|
3
3
|
|
4
4
|
module GQL
|
5
5
|
class Node
|
6
|
-
class_attribute :call_classes
|
7
|
-
self.call_classes = {}
|
6
|
+
class_attribute :call_classes, :field_classes, instance_accessor: false, instance_predicate: false
|
8
7
|
|
9
|
-
|
8
|
+
self.call_classes = {}
|
10
9
|
self.field_classes = {}
|
11
10
|
|
12
11
|
class << self
|
13
12
|
def cursor(method_name)
|
14
13
|
define_method :cursor do
|
15
|
-
|
14
|
+
target.send(method_name).to_s
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
|
-
def call(
|
20
|
-
|
21
|
-
function = block || lambda { |*args| target.public_send(name, *args) }
|
22
|
-
|
23
|
-
if result_class.is_a? Array
|
24
|
-
result_class.unshift Connection if result_class.size == 1
|
25
|
-
result_class.unshift Fields::Connection if result_class.size == 2
|
26
|
-
|
27
|
-
field_class, connection_class, node_class = result_class
|
18
|
+
def call(*names, &block)
|
19
|
+
names_with_result_class = names.extract_options!
|
28
20
|
|
29
|
-
|
30
|
-
|
31
|
-
result_class = Class.new(field_class)
|
32
|
-
result_class.const_set :NODE_CLASS, node_class
|
33
|
-
result_class.const_set :CONNECTION_CLASS, connection_class
|
34
|
-
else
|
35
|
-
raise Errors::InvalidNodeClass.new(result_class, Node) unless result_class.nil? || result_class < Node
|
21
|
+
names.each do |name|
|
22
|
+
names_with_result_class[name] = nil
|
36
23
|
end
|
37
24
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
self.const_set "#{name.to_s.camelize}Call", call_class
|
43
|
-
self.call_classes = call_classes.merge(name => call_class)
|
44
|
-
end
|
25
|
+
names_with_result_class.each do |name, result_class|
|
26
|
+
method = block || lambda { |*args| target.public_send(name, *args) }
|
27
|
+
call_class = Call.build_class(result_class, method)
|
45
28
|
|
46
|
-
|
47
|
-
|
29
|
+
self.const_set "#{name.to_s.camelize}Call", call_class
|
30
|
+
self.call_classes = call_classes.merge(name => call_class)
|
31
|
+
end
|
48
32
|
end
|
49
33
|
|
50
|
-
def field(*names,
|
51
|
-
|
52
|
-
|
34
|
+
def field(*names, field_type_class: nil, connection_class: nil, node_class: nil, &block)
|
35
|
+
names.each do |name|
|
36
|
+
method = block || lambda { target.public_send(name) }
|
37
|
+
field_type_class ||= Field
|
53
38
|
|
54
|
-
|
39
|
+
unless field_type_class <= Field
|
40
|
+
raise Errors::InvalidNodeClass.new(field_type_class, Field)
|
41
|
+
end
|
55
42
|
|
56
|
-
field_class =
|
57
|
-
|
58
|
-
field_class.const_set :NODE_CLASS, node_class
|
59
|
-
field_class.const_set :CONNECTION_CLASS, connection_class
|
43
|
+
field_class = field_type_class.build_class(method, connection_class, node_class)
|
60
44
|
|
61
45
|
self.const_set "#{name.to_s.camelize}Field", field_class
|
62
|
-
|
63
|
-
result.merge name => field_class
|
46
|
+
self.field_classes = field_classes.merge(name => field_class)
|
64
47
|
end
|
65
|
-
|
66
|
-
self.field_classes = field_classes.merge(classes)
|
67
48
|
end
|
68
49
|
|
69
|
-
def method_missing(method, *
|
70
|
-
if
|
71
|
-
options =
|
50
|
+
def method_missing(method, *names, &block)
|
51
|
+
if field_type_class = GQL.field_types[method]
|
52
|
+
options = names.extract_options!
|
72
53
|
|
73
|
-
field(*
|
54
|
+
field(*names, options.merge(field_type_class: field_type_class), &block)
|
74
55
|
else
|
75
56
|
super
|
76
57
|
end
|
77
58
|
rescue NoMethodError => exc
|
78
|
-
raise Errors::
|
59
|
+
raise Errors::UndefinedFieldType, method
|
79
60
|
end
|
80
61
|
end
|
81
62
|
|
82
|
-
attr_reader :
|
63
|
+
attr_reader :ast_node, :target, :variables, :context
|
83
64
|
|
84
65
|
def initialize(ast_node, target, variables, context)
|
85
|
-
@ast_node, @
|
86
|
-
@variables, @
|
66
|
+
@ast_node, @target = ast_node, target
|
67
|
+
@variables, @context = variables, context
|
87
68
|
end
|
88
69
|
|
89
|
-
def
|
90
|
-
if ast_call =
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
call = call_class.new(self, ast_call, __target, @variables, __context)
|
96
|
-
call.execute
|
97
|
-
elsif ast_fields = @ast_node.fields
|
98
|
-
ast_fields.reduce({}) do |memo, ast_field|
|
99
|
-
key = ast_field.alias_name || ast_field.name
|
100
|
-
|
101
|
-
val =
|
102
|
-
case key
|
103
|
-
when :node
|
104
|
-
field = self.class.new(ast_field, __target, @variables, __context)
|
105
|
-
field.__value
|
106
|
-
when :cursor
|
107
|
-
cursor
|
108
|
-
else
|
109
|
-
target = public_send(ast_field.name)
|
110
|
-
field_class = self.class.field_classes[ast_field.name]
|
111
|
-
|
112
|
-
raise Errors::UndefinedField.new(ast_field.name, self.class) if field_class.nil?
|
113
|
-
raise Errors::InvalidNodeClass.new(field_class.superclass, Field) unless field_class <= Field
|
114
|
-
|
115
|
-
field = field_class.new(ast_field, target, @variables, __context)
|
116
|
-
field.__value
|
117
|
-
end
|
118
|
-
|
119
|
-
memo.merge key => val
|
120
|
-
end
|
70
|
+
def value
|
71
|
+
if ast_call = ast_node.call
|
72
|
+
value_of_call ast_call
|
73
|
+
elsif ast_fields = ast_node.fields
|
74
|
+
value_of_fields ast_fields
|
121
75
|
else
|
122
|
-
|
76
|
+
raw_value
|
123
77
|
end
|
124
78
|
end
|
125
79
|
|
126
|
-
def
|
127
|
-
|
80
|
+
def value_of_call(ast_call)
|
81
|
+
call_class = self.class.call_classes[ast_call.name]
|
82
|
+
|
83
|
+
if call_class.nil?
|
84
|
+
raise Errors::UndefinedCall.new(ast_call.name, self.class.superclass)
|
85
|
+
end
|
86
|
+
|
87
|
+
call = call_class.new(self, ast_call, target, variables, context)
|
88
|
+
call.execute
|
89
|
+
end
|
90
|
+
|
91
|
+
def value_of_fields(ast_fields)
|
92
|
+
ast_fields.reduce({}) do |memo, ast_field|
|
93
|
+
key = ast_field.alias_name || ast_field.name
|
94
|
+
|
95
|
+
memo.merge key => value_of_field(ast_field)
|
96
|
+
end
|
128
97
|
end
|
129
98
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
99
|
+
def value_of_field(ast_field)
|
100
|
+
case ast_field.name
|
101
|
+
when :node
|
102
|
+
field = self.class.new(ast_field, target, variables, context)
|
103
|
+
field.value
|
104
|
+
when :cursor
|
105
|
+
cursor
|
133
106
|
else
|
134
|
-
|
107
|
+
method = Field::Method.new(target, context)
|
108
|
+
field_class = self.class.field_classes[ast_field.name]
|
109
|
+
|
110
|
+
if field_class.nil?
|
111
|
+
raise Errors::UndefinedField.new(ast_field.name, self.class)
|
112
|
+
end
|
113
|
+
|
114
|
+
next_target = method.execute(field_class.method)
|
115
|
+
|
116
|
+
field = field_class.new(ast_field, next_target, variables, context)
|
117
|
+
field.value
|
135
118
|
end
|
136
|
-
|
137
|
-
|
119
|
+
end
|
120
|
+
|
121
|
+
def raw_value
|
122
|
+
nil
|
138
123
|
end
|
139
124
|
end
|
140
125
|
end
|