groonga-command-parser 1.0.6 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/doc/text/news.md +7 -0
- data/groonga-command-parser.gemspec +1 -2
- data/lib/groonga/command/parser.rb +3 -1
- data/lib/groonga/command/parser/load-values-parser.rb +40 -126
- data/lib/groonga/command/parser/version.rb +2 -4
- data/test/run-test.rb +1 -8
- data/test/test-load-value-parser.rb +47 -3
- data/test/test-parser.rb +3 -5
- metadata +4 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a650d05617980af6af0e11548cf0938e8ed631a
|
4
|
+
data.tar.gz: 7aceca455972e4734e8029e966d501a8ba3e14db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a78f94997caa0239aca88c73b71fb22b9da213c40a48f60d8500e136299cf7e667af0b124d1ab5ea74a9f7ca2767a783ccb58152c6024836e4aa6b478ba7235b
|
7
|
+
data.tar.gz: e9a0427a34376d5e91f7f33a4aa0945457c5ac74bb1a4cc94e8abc5475a10e9ac940c3ab548e0bd9411c559411a22034479c54557bcdd76560b07b0d637fb43b
|
data/doc/text/news.md
CHANGED
@@ -53,8 +53,7 @@ Gem::Specification.new do |spec|
|
|
53
53
|
spec.require_paths = ["lib"]
|
54
54
|
|
55
55
|
spec.add_runtime_dependency("groonga-command", ">= 1.0.9")
|
56
|
-
spec.add_runtime_dependency("
|
57
|
-
spec.add_runtime_dependency("ffi-yajl")
|
56
|
+
spec.add_runtime_dependency("json-stream")
|
58
57
|
|
59
58
|
spec.add_development_dependency("test-unit")
|
60
59
|
spec.add_development_dependency("test-unit-notify")
|
@@ -122,7 +122,6 @@ module Groonga
|
|
122
122
|
def initialize
|
123
123
|
reset
|
124
124
|
initialize_hooks
|
125
|
-
initialize_load_values_parser
|
126
125
|
end
|
127
126
|
|
128
127
|
# Streaming parsing command.
|
@@ -262,6 +261,7 @@ module Groonga
|
|
262
261
|
on_load_columns(@command, @command.columns)
|
263
262
|
end
|
264
263
|
if @command[:values]
|
264
|
+
initialize_load_values_parser
|
265
265
|
@load_values_parser << @command[:values]
|
266
266
|
reset
|
267
267
|
else
|
@@ -271,6 +271,7 @@ module Groonga
|
|
271
271
|
else
|
272
272
|
@command.original_source << "\n"
|
273
273
|
@loading = true
|
274
|
+
initialize_load_values_parser
|
274
275
|
end
|
275
276
|
end
|
276
277
|
else
|
@@ -339,6 +340,7 @@ module Groonga
|
|
339
340
|
@command = nil
|
340
341
|
@loading = false
|
341
342
|
@buffer = "".force_encoding("ASCII-8BIT")
|
343
|
+
@load_values_parser = nil
|
342
344
|
end
|
343
345
|
|
344
346
|
def initialize_hooks
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Copyright (C) 2015 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
|
4
2
|
#
|
5
3
|
# This library is free software; you can redistribute it and/or
|
6
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -16,12 +14,7 @@
|
|
16
14
|
# License along with this library; if not, write to the Free Software
|
17
15
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
16
|
|
19
|
-
|
20
|
-
require "ffi_yajl"
|
21
|
-
|
22
|
-
module FFI_Yajl
|
23
|
-
attach_function :yajl_get_bytes_consumed, [:yajl_handle], :size_t
|
24
|
-
end
|
17
|
+
require "json/stream"
|
25
18
|
|
26
19
|
module Groonga
|
27
20
|
module Command
|
@@ -30,9 +23,7 @@ module Groonga
|
|
30
23
|
attr_writer :on_value
|
31
24
|
attr_writer :on_end
|
32
25
|
def initialize
|
33
|
-
|
34
|
-
@handle = nil
|
35
|
-
@callbacks_memory = nil
|
26
|
+
initialize_parser
|
36
27
|
@on_value = nil
|
37
28
|
@on_end = nil
|
38
29
|
@containers = []
|
@@ -43,39 +34,28 @@ module Groonga
|
|
43
34
|
data_size = data.bytesize
|
44
35
|
return self if data_size.zero?
|
45
36
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
if status != :yajl_status_ok
|
51
|
-
consumed = FFI_Yajl.yajl_get_bytes_consumed(@handle)
|
52
|
-
if consumed > 0
|
53
|
-
consumed -= 1
|
54
|
-
end
|
55
|
-
if @containers.empty?
|
56
|
-
message = "there are garbages before JSON"
|
57
|
-
else
|
58
|
-
message = FFI_Yajl.yajl_get_error(@handle, 0, nil, 0).chomp
|
59
|
-
end
|
37
|
+
before_pos = @parser.pos
|
38
|
+
status = catch do |tag|
|
39
|
+
@tag = tag
|
60
40
|
begin
|
61
|
-
|
41
|
+
@parser << data
|
42
|
+
rescue JSON::Stream::ParserError => error
|
43
|
+
pos = @parser.pos
|
44
|
+
consumed = pos - before_pos - 1
|
45
|
+
raise Error.new(error.message,
|
62
46
|
data[0, consumed],
|
63
47
|
data[consumed..-1])
|
64
|
-
ensure
|
65
|
-
finalize_handle
|
66
48
|
end
|
49
|
+
:continue
|
67
50
|
end
|
68
51
|
|
69
|
-
if
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
ensure
|
78
|
-
finalize_handle
|
52
|
+
if status == :done
|
53
|
+
pos = @parser.pos
|
54
|
+
consumed = pos - before_pos
|
55
|
+
if consumed < data_size
|
56
|
+
@on_end.call(data[consumed..-1])
|
57
|
+
else
|
58
|
+
@on_end.call(nil)
|
79
59
|
end
|
80
60
|
end
|
81
61
|
|
@@ -83,51 +63,30 @@ module Groonga
|
|
83
63
|
end
|
84
64
|
|
85
65
|
private
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
def initialize_callbacks
|
94
|
-
@null_callback = callback do
|
95
|
-
push_value(nil)
|
96
|
-
end
|
97
|
-
@boolean_callback = callback(:int) do |c_boolean|
|
98
|
-
push_value(c_boolean != 0)
|
99
|
-
end
|
100
|
-
@number_callback = callback(:string, :size_t) do |data, size|
|
101
|
-
number_data = data.slice(0, size)
|
102
|
-
if /[\.eE]/ =~ number_data
|
103
|
-
number = number_data.to_f
|
104
|
-
else
|
105
|
-
number = number_data.to_i
|
106
|
-
end
|
107
|
-
push_value(number)
|
108
|
-
end
|
109
|
-
@string_callback = callback(:string, :size_t) do |data, size|
|
110
|
-
string = data.slice(0, size)
|
111
|
-
string.force_encoding(Encoding::UTF_8)
|
112
|
-
push_value(string)
|
66
|
+
def initialize_parser
|
67
|
+
@parser = JSON::Stream::Parser.new
|
68
|
+
@parser.singleton_class.__send__(:attr_reader, :pos)
|
69
|
+
@parser.end_document do
|
70
|
+
throw(@tag, :done)
|
113
71
|
end
|
114
|
-
@
|
72
|
+
@parser.start_object do
|
115
73
|
push_container({})
|
116
74
|
end
|
117
|
-
@
|
118
|
-
key = data.slice(0, size)
|
119
|
-
key.force_encoding(Encoding::UTF_8)
|
120
|
-
@keys.push(key)
|
121
|
-
end
|
122
|
-
@end_map_callback = callback do
|
75
|
+
@parser.end_object do
|
123
76
|
pop_container
|
124
77
|
end
|
125
|
-
@
|
78
|
+
@parser.start_array do
|
126
79
|
push_container([])
|
127
80
|
end
|
128
|
-
@
|
81
|
+
@parser.end_array do
|
129
82
|
pop_container
|
130
83
|
end
|
84
|
+
@parser.key do |key|
|
85
|
+
push_key(key)
|
86
|
+
end
|
87
|
+
@parser.value do |value|
|
88
|
+
push_value(value)
|
89
|
+
end
|
131
90
|
end
|
132
91
|
|
133
92
|
def push_container(container)
|
@@ -143,64 +102,19 @@ module Groonga
|
|
143
102
|
end
|
144
103
|
end
|
145
104
|
|
105
|
+
def push_key(key)
|
106
|
+
@keys.push(key)
|
107
|
+
end
|
108
|
+
|
146
109
|
def push_value(value)
|
147
110
|
container = @containers.last
|
148
111
|
case container
|
149
|
-
when Hash
|
112
|
+
when ::Hash
|
150
113
|
container[@keys.pop] = value
|
151
|
-
when Array
|
114
|
+
when ::Array
|
152
115
|
container.push(value)
|
153
116
|
end
|
154
117
|
end
|
155
|
-
|
156
|
-
def ensure_handle
|
157
|
-
return if @handle
|
158
|
-
initialize_handle
|
159
|
-
end
|
160
|
-
|
161
|
-
def initialize_handle
|
162
|
-
@callbacks_memory = FFI::MemoryPointer.new(FFI_Yajl::YajlCallbacks)
|
163
|
-
callbacks = FFI_Yajl::YajlCallbacks.new(@callbacks_memory)
|
164
|
-
callbacks[:yajl_null] = @null_callback
|
165
|
-
callbacks[:yajl_boolean] = @boolean_callback
|
166
|
-
callbacks[:yajl_integer] = nil
|
167
|
-
callbacks[:yajl_double] = nil
|
168
|
-
callbacks[:yajl_number] = @number_callback
|
169
|
-
callbacks[:yajl_string] = @string_callback
|
170
|
-
callbacks[:yajl_start_map] = @start_map_callback
|
171
|
-
callbacks[:yajl_map_key] = @map_key_callback
|
172
|
-
callbacks[:yajl_end_map] = @end_map_callback
|
173
|
-
callbacks[:yajl_start_array] = @start_array_callback
|
174
|
-
callbacks[:yajl_end_array] = @end_array_callback
|
175
|
-
|
176
|
-
@handle = FFI_Yajl.yajl_alloc(@callbacks_memory, nil, nil)
|
177
|
-
FFI_Yajl.yajl_config(@handle,
|
178
|
-
:yajl_allow_trailing_garbage,
|
179
|
-
:int,
|
180
|
-
1)
|
181
|
-
@finalizer = Finalizer.new(@handle)
|
182
|
-
ObjectSpace.define_finalizer(self, @finalizer)
|
183
|
-
end
|
184
|
-
|
185
|
-
def finalize_handle
|
186
|
-
@callbacks_memory = nil
|
187
|
-
@finalizer.call(object_id)
|
188
|
-
ObjectSpace.undefine_finalizer(self)
|
189
|
-
@finalizer = nil
|
190
|
-
@handle = nil
|
191
|
-
end
|
192
|
-
|
193
|
-
class Finalizer
|
194
|
-
def initialize(handle)
|
195
|
-
@handle = handle
|
196
|
-
end
|
197
|
-
|
198
|
-
def call(object_id)
|
199
|
-
return if @handle.nil?
|
200
|
-
FFI_Yajl.yajl_free(@handle)
|
201
|
-
@handle = nil
|
202
|
-
end
|
203
|
-
end
|
204
118
|
end
|
205
119
|
end
|
206
120
|
end
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Copyright (C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
|
4
2
|
#
|
5
3
|
# This library is free software; you can redistribute it and/or
|
6
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -19,7 +17,7 @@
|
|
19
17
|
module Groonga
|
20
18
|
module Command
|
21
19
|
class Parser
|
22
|
-
VERSION = "1.0.
|
20
|
+
VERSION = "1.0.7"
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
data/test/run-test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#
|
3
|
-
# Copyright (C) 2012-
|
3
|
+
# Copyright (C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -36,13 +36,6 @@ end
|
|
36
36
|
$LOAD_PATH.unshift(lib_dir)
|
37
37
|
$LOAD_PATH.unshift(test_dir)
|
38
38
|
|
39
|
-
# TODO: Remove me when suppress warnings patches are merged int
|
40
|
-
# ffi_yajl.
|
41
|
-
require "stringio"
|
42
|
-
$VERBOSE = false
|
43
|
-
require "ffi_yajl/ffi"
|
44
|
-
$VERBOSE = true
|
45
|
-
|
46
39
|
require "groonga-command-parser-test-utils"
|
47
40
|
|
48
41
|
ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] ||= "5000"
|
@@ -21,13 +21,17 @@ class LoadValuesParserTest < Test::Unit::TestCase
|
|
21
21
|
@parser.on_value = lambda do |value|
|
22
22
|
@values << value
|
23
23
|
end
|
24
|
+
@parse_done = false
|
24
25
|
@parser.on_end = lambda do |rest|
|
26
|
+
@parse_done = true
|
27
|
+
@parse_rest = rest
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
31
|
def parse(data)
|
29
32
|
data.each_line do |line|
|
30
|
-
|
33
|
+
@parser << line
|
34
|
+
break if @parse_done
|
31
35
|
end
|
32
36
|
@values
|
33
37
|
end
|
@@ -140,10 +144,50 @@ class LoadValuesParserTest < Test::Unit::TestCase
|
|
140
144
|
}
|
141
145
|
}
|
142
146
|
]
|
147
|
+
JSON
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
sub_test_case "error" do
|
152
|
+
test "unfinished" do
|
153
|
+
assert_equal([
|
154
|
+
{
|
155
|
+
"object" => {
|
156
|
+
"string" => "abc",
|
157
|
+
},
|
158
|
+
},
|
159
|
+
],
|
160
|
+
parse(<<-JSON))
|
143
161
|
[
|
144
|
-
|
145
|
-
|
162
|
+
{
|
163
|
+
"object": {
|
164
|
+
"string": "abc"
|
165
|
+
}
|
166
|
+
},
|
167
|
+
{
|
168
|
+
JSON
|
169
|
+
assert_false(@parse_done)
|
170
|
+
end
|
171
|
+
|
172
|
+
test "too much" do
|
173
|
+
assert_equal([
|
174
|
+
{
|
175
|
+
"object" => {
|
176
|
+
"string" => "abc",
|
177
|
+
},
|
178
|
+
},
|
179
|
+
],
|
180
|
+
parse(<<-JSON))
|
181
|
+
[
|
182
|
+
{
|
183
|
+
"object": {
|
184
|
+
"string": "abc"
|
185
|
+
}
|
186
|
+
}
|
187
|
+
]garbage
|
146
188
|
JSON
|
189
|
+
assert_equal([true, "garbage\n"],
|
190
|
+
[@parse_done, @parse_rest])
|
147
191
|
end
|
148
192
|
end
|
149
193
|
end
|
data/test/test-parser.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Copyright (C) 2011-2014 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
|
4
2
|
#
|
5
3
|
# This library is free software; you can redistribute it and/or
|
6
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -374,7 +372,7 @@ EOS
|
|
374
372
|
end
|
375
373
|
|
376
374
|
def test_no_record_separate_comma
|
377
|
-
message = "
|
375
|
+
message = "Expected comma or object or array close: char 37"
|
378
376
|
before = <<-BEFORE
|
379
377
|
[
|
380
378
|
{"_key": "alice", "name": "Alice"}
|
@@ -394,7 +392,7 @@ EOC
|
|
394
392
|
end
|
395
393
|
|
396
394
|
def test_garbage_before_json
|
397
|
-
message = "
|
395
|
+
message = "Expected value: char 0"
|
398
396
|
before = ""
|
399
397
|
after = <<-AFTER
|
400
398
|
XXX
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groonga-command-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: groonga-command
|
@@ -25,21 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.0.9
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: ffi-yajl
|
28
|
+
name: json-stream
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
@@ -200,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
186
|
version: '0'
|
201
187
|
requirements: []
|
202
188
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.5.
|
189
|
+
rubygems_version: 2.5.2
|
204
190
|
signing_key:
|
205
191
|
specification_version: 4
|
206
192
|
summary: Groonga-command-parser is a Ruby library to parses [groonga](http://groonga.org/)'s
|
@@ -211,4 +197,3 @@ test_files:
|
|
211
197
|
- test/test-load-value-parser.rb
|
212
198
|
- test/test-command-line-splitter.rb
|
213
199
|
- test/groonga-command-parser-test-utils.rb
|
214
|
-
has_rdoc:
|