rroonga 3.0.6-x86-mingw32 → 3.0.7-x86-mingw32

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
3
  #
4
- # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
4
+ # Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
5
5
  #
6
6
  # This library is free software; you can redistribute it and/or
7
7
  # modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,11 @@
16
16
  # License along with this library; if not, write to the Free Software
17
17
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
 
19
- require 'ostruct'
20
- require 'optparse'
21
- require 'pathname'
19
+ require "ostruct"
20
+ require "optparse"
21
+ require "pathname"
22
22
 
23
- require 'groonga'
23
+ require "groonga"
24
24
 
25
25
  options = OpenStruct.new
26
26
  options.output_directory = "index-dump"
@@ -1,5 +1,27 @@
1
1
  h1. NEWS
2
2
 
3
+ h2(#3-0-7). 3.0.7: 2013-09-19
4
+
5
+ h3. Improvements
6
+
7
+ * Added {Groonga::TableKeySupport#tokenize}. It requires groonga
8
+ 3.0.8. Groonga 3.0.8 is not released yet.
9
+ * Changed return object of {Groonga::Context#select} to groonga-client gem's
10
+ return object. It is a backward imcompatible change. Some APIs are changed.
11
+ For example, @drill_down@ is renamed to @drilldowns@. See
12
+ "Groonga::Client::Response::Select":http://rubydoc.info/gems/groonga-client/Groonga/Client/Response/Select
13
+ about rerturn object details.
14
+ ** Added groonga-client gem, groogna-command gem, gqtp gem dependencies.
15
+
16
+ h3. Fixes
17
+
18
+ * Fixed a bug that auto groonga installation is failed.
19
+ [GitHub#12][Patch by Keita Haga]
20
+
21
+ h3. Thanks
22
+
23
+ * Keita Haga
24
+
3
25
  h2(#3-0-6). 3.0.6: 2013-09-13
4
26
 
5
27
  h3. Improvements
@@ -232,8 +232,8 @@ end
232
232
  unless PKGConfig.have_package(package_name, major, minor, micro)
233
233
  unless have_local_groonga?(package_name, major, minor, micro)
234
234
  required_version = [major, minor, micro]
235
- if (required_version <=> LatestGroongaVersion::VERSISON) > 0
236
- target_version = LatestGroongaVersion::VERSISON
235
+ if (required_version <=> LatestGroongaVersion::VERSION) > 0
236
+ target_version = LatestGroongaVersion::VERSION
237
237
  else
238
238
  target_version = required_version
239
239
  end
@@ -258,6 +258,8 @@ have_header("ruby/st.h") unless have_macro("HAVE_RUBY_ST_H", "ruby.h")
258
258
  have_func("rb_errinfo", "ruby.h")
259
259
  have_type("enum ruby_value_type", "ruby.h")
260
260
 
261
+ have_func("grn_table_tokenize", "groonga.h")
262
+
261
263
  checking_for(checking_message("--enable-debug-log option")) do
262
264
  enable_debug_log = enable_config("debug-log", false)
263
265
  if enable_debug_log
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
2
  /*
3
- Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 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
@@ -877,6 +877,61 @@ rb_grn_table_key_support_support_key_p (VALUE self)
877
877
  return table->header.domain == GRN_ID_NIL ? Qfalse : Qtrue;
878
878
  }
879
879
 
880
+ #ifdef HAVE_GRN_TABLE_TOKENIZE
881
+ /*
882
+ * Tokenize a string using the table as lexicon.
883
+ *
884
+ * @overload tokenize(string, options={})
885
+ * @param [String] string The string to be tokenized.
886
+ * @param [::Hash] options
887
+ * @option options [Bool] :add (true) Adds a new token to the table if true.
888
+ * Returned tokens include the new token. Otherwise, a new token is
889
+ * just ignored.
890
+ * @return [::Array<Groonga::Record>] Tokenized tokens.
891
+ */
892
+ static VALUE
893
+ rb_grn_table_key_support_tokenize (int argc, VALUE *argv, VALUE self)
894
+ {
895
+ VALUE rb_string, rb_add_p;
896
+ VALUE rb_options;
897
+ VALUE rb_tokens = Qnil;
898
+ grn_ctx *context;
899
+ grn_obj *table;
900
+ char *string;
901
+ int string_size;
902
+ grn_bool add_p;
903
+ grn_obj tokens;
904
+
905
+ rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
906
+ rb_grn_scan_options(rb_options,
907
+ "add", &rb_add_p,
908
+ NULL);
909
+ if (NIL_P(rb_add_p)) {
910
+ rb_add_p = Qtrue;
911
+ }
912
+
913
+ rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
914
+ NULL, NULL, NULL,
915
+ NULL, NULL, NULL,
916
+ NULL);
917
+
918
+ string = StringValueCStr(rb_string);
919
+ string_size = RSTRING_LEN(rb_string);
920
+
921
+ add_p = RVAL2CBOOL(rb_add_p);
922
+
923
+ GRN_RECORD_INIT(&tokens, GRN_OBJ_VECTOR, grn_obj_id(context, table));
924
+ grn_table_tokenize(context, table, string, string_size, &tokens, add_p);
925
+ if (context->rc == GRN_SUCCESS) {
926
+ rb_tokens = GRNUVECTOR2RVAL(context, &tokens, table, self);
927
+ }
928
+ grn_obj_unlink(context, &tokens);
929
+ rb_grn_context_check(context, self);
930
+
931
+ return rb_tokens;
932
+ }
933
+ #endif
934
+
880
935
  void
881
936
  rb_grn_init_table_key_support (VALUE mGrn)
882
937
  {
@@ -928,4 +983,9 @@ rb_grn_init_table_key_support (VALUE mGrn)
928
983
 
929
984
  rb_define_method(rb_mGrnTableKeySupport, "support_key?",
930
985
  rb_grn_table_key_support_support_key_p, 0);
986
+
987
+ #ifdef HAVE_GRN_TABLE_TOKENIZE
988
+ rb_define_method(rb_mGrnTableKeySupport, "tokenize",
989
+ rb_grn_table_key_support_tokenize, -1);
990
+ #endif
931
991
  }
data/ext/groonga/rb-grn.h CHANGED
@@ -84,7 +84,7 @@ RB_GRN_BEGIN_DECLS
84
84
 
85
85
  #define RB_GRN_MAJOR_VERSION 3
86
86
  #define RB_GRN_MINOR_VERSION 0
87
- #define RB_GRN_MICRO_VERSION 6
87
+ #define RB_GRN_MICRO_VERSION 7
88
88
 
89
89
  #define RB_GRN_QUERY_DEFAULT_MAX_EXPRESSIONS 32
90
90
 
data/lib/1.9/groonga.so CHANGED
Binary file
data/lib/2.0/groonga.so CHANGED
Binary file
@@ -0,0 +1,100 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "groonga/command"
19
+ require "groonga/client/response"
20
+
21
+ module Groonga
22
+ class Context
23
+ class CommandExecutor
24
+ def initialize(context)
25
+ @context = context
26
+ end
27
+
28
+ def execute(name, parameters={})
29
+ parameters = normalize_parameters(name, parameters)
30
+ command_class = Command.find(name)
31
+ command = command_class.new(name, parameters)
32
+ request_id = @context.send(command.to_command_format)
33
+ loop do
34
+ response_id, raw_response = @context.receive
35
+ if request_id == response_id
36
+ response_class = Client::Response.find(command.name)
37
+ header = [0, 0, 0]
38
+ case command.output_type
39
+ when :json
40
+ body = JSON.parse(raw_response)
41
+ else
42
+ body = raw_response
43
+ end
44
+ response = response_class.new(command, header, body)
45
+ response.raw = raw_response
46
+ return response
47
+ end
48
+ # raise if request_id < response_id
49
+ end
50
+ end
51
+
52
+ private
53
+ def normalize_parameters(name, parameters)
54
+ case name
55
+ when "select"
56
+ normalize_select_parameters(parameters)
57
+ else
58
+ parameters
59
+ end
60
+ end
61
+
62
+ def normalize_select_parameters(parameters)
63
+ table = parameters[:table]
64
+ parameters[:table] = table.name if table.is_a?(Table)
65
+
66
+ normalize_key(parameters, :drilldown, :drill_down)
67
+ normalize_key(parameters,
68
+ :drilldown_output_columns,
69
+ :drill_down_output_columns)
70
+ normalize_key(parameters, :drilldown_limit, :drill_down_limit)
71
+
72
+ normalize_array_value(parameters, :output_columns)
73
+ normalize_array_value(parameters, :drilldown)
74
+ normalize_array_value(parameters, :drilldown_output_columns)
75
+
76
+ normalize_integer_value(parameters, :limit)
77
+ normalize_integer_value(parameters, :drilldown_limit)
78
+
79
+ parameters
80
+ end
81
+
82
+ def normalize_key(parameters, real_key, alias_key)
83
+ return unless parameters.has_key?(alias_key)
84
+ parameters[real_key] ||= parameters.delete(alias_key)
85
+ end
86
+
87
+ def normalize_array_value(parameters, key)
88
+ if parameters[key].is_a?(::Array)
89
+ parameters[key] = parameters[key].join(", ")
90
+ end
91
+ end
92
+
93
+ def normalize_integer_value(parameters, key)
94
+ if parameters[key].is_a?(Integer)
95
+ parameters[key] = parameters[key].to_s
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -15,9 +15,8 @@
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
- require "groonga/command"
19
-
20
18
  require "groonga/memory-pool"
19
+ require "groonga/context/command-executor"
21
20
 
22
21
  module Groonga
23
22
  class Context
@@ -133,8 +132,12 @@ module Groonga
133
132
  # @option options [Array] XXX TODO
134
133
  # TODO
135
134
  def select(table, options={})
136
- select = Command::Select.new(self, table, options)
137
- select.exec
135
+ execute_command("select", {:table => table}.merge(options))
136
+ end
137
+
138
+ def execute_command(name, parameters={})
139
+ executor = CommandExecutor.new(self)
140
+ executor.execute(name, parameters)
138
141
  end
139
142
 
140
143
  # Restore commands dumped by "grndump" command.
data/rroonga.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- mode: ruby; coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2012-2013 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
@@ -70,7 +70,7 @@ Gem::Specification.new do |s|
70
70
  s.extra_rdoc_files = ["README.textile"]
71
71
  s.test_files = Dir.glob("test/**/*.rb")
72
72
  Dir.chdir("bin") do
73
- s.executables = Dir.glob("*")
73
+ s.executables = Dir.glob("*") - ["groonga-index-validate"]
74
74
  end
75
75
  end
76
76
 
@@ -82,6 +82,7 @@ Gem::Specification.new do |s|
82
82
  s.required_ruby_version = ">= 1.9.3"
83
83
 
84
84
  s.add_runtime_dependency("pkg-config")
85
+ s.add_runtime_dependency("groonga-client", ">= 0.0.3")
85
86
  s.add_runtime_dependency("json")
86
87
  s.add_runtime_dependency("archive-zip")
87
88
  s.add_development_dependency("test-unit", [">= 2.4.6"])
data/test/run-test.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2009-2013 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
@@ -41,18 +41,30 @@ require "test/unit/notify"
41
41
 
42
42
  Test::Unit::Priority.enable
43
43
 
44
+
45
+ groonga_command_dir = File.join(base_dir, "..", "groonga-command")
46
+ if File.exist?(groonga_command_dir)
47
+ $LOAD_PATH.unshift(File.join(groonga_command_dir, "lib"))
48
+ end
49
+
50
+ groonga_client_dir = File.join(base_dir, "..", "groonga-client")
51
+ if File.exist?(groonga_client_dir)
52
+ $LOAD_PATH.unshift(File.join(groonga_client_dir, "lib"))
53
+ end
54
+
55
+
44
56
  $LOAD_PATH.unshift(ext_dir)
45
57
  $LOAD_PATH.unshift(lib_dir)
46
58
  $LOAD_PATH.unshift(base_dir)
47
59
 
48
60
  $LOAD_PATH.unshift(test_dir)
49
- require 'groonga-test-utils'
61
+ require "groonga-test-utils"
50
62
 
51
63
  pkg_config = File.join(base_dir, "vendor", "local", "lib", "pkgconfig")
52
64
  PKGConfig.add_path(pkg_config)
53
65
 
54
66
  Dir.glob("#{base_dir}/test/**/test{_,-}*.rb") do |file|
55
- require file.sub(/\.rb$/, '')
67
+ require file.sub(/\.rb$/, "")
56
68
  end
57
69
 
58
70
  ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] ||= "5000"
@@ -76,45 +76,37 @@ class CommandSelectTest < Test::Unit::TestCase
76
76
  [result.n_hits, result.records])
77
77
  end
78
78
 
79
- def test_drill_down
79
+ def test_drilldowns
80
80
  result = context.select(@users,
81
81
  :output_columns => ["_key"],
82
82
  :drill_down => ["_key", "book"],
83
83
  :drill_down_output_columns => "_key",
84
84
  :drill_down_limit => 10)
85
- drill_down = normalize_drill_down(result.drill_down)
86
- assert_equal([4,
87
- [{"_key" => "morita"},
88
- {"_key" => "gunyara-kun"},
89
- {"_key" => "yu"},
90
- {"_key" => "ryoqun"}],
91
- {
85
+ drilldowns = normalize_drilldowns(result.drilldowns)
86
+ assert_equal({
92
87
  "_key" => [4, [{"_key" => "morita"},
93
88
  {"_key" => "gunyara-kun"},
94
89
  {"_key" => "yu"},
95
90
  {"_key" => "ryoqun"}]],
96
91
  "book" => [2, [{"_key" => "the groonga book"},
97
92
  {"_key" => "the groonga book (2)"}]],
98
- },
99
- ],
100
- [result.n_hits, result.records, drill_down])
93
+ },
94
+ drilldowns)
101
95
  end
102
96
 
103
- def test_drill_down_with_no_hit
97
+ def test_drilldowns_with_no_hit
104
98
  result = context.select(@users,
105
99
  :filter => "_key == \"no\\ hit\"",
106
100
  :output_columns => ["_key"],
107
101
  :drill_down => ["_key", "book"],
108
102
  :drill_down_output_columns => "_key",
109
103
  :drill_down_limit => 10)
110
- drill_down = normalize_drill_down(result.drill_down)
111
- assert_equal([0, [],
112
- {
113
- "_key" => [0, []],
114
- "book" => [0, []],
115
- },
116
- ],
117
- [result.n_hits, result.records, drill_down])
104
+ drilldowns = normalize_drilldowns(result.drilldowns)
105
+ assert_equal({
106
+ "_key" => [0, []],
107
+ "book" => [0, []],
108
+ },
109
+ drilldowns)
118
110
  end
119
111
 
120
112
  def test_time
@@ -201,12 +193,12 @@ class CommandSelectTest < Test::Unit::TestCase
201
193
  end
202
194
 
203
195
  private
204
- def normalize_drill_down(drill_down)
205
- normalized_drill_down = {}
206
- drill_down.each do |key, drill|
207
- normalized_drill_down[key] = [drill.n_hits, drill.records]
196
+ def normalize_drilldowns(drilldowns)
197
+ normalized_drilldowns = {}
198
+ drilldowns.each do |drilldown|
199
+ normalized_drilldowns[drilldown.key] = [drilldown.n_hits, drilldown.items]
208
200
  end
209
- normalized_drill_down
201
+ normalized_drilldowns
210
202
  end
211
203
 
212
204
  class EscapeTest < self
@@ -75,4 +75,66 @@ class TableKeySupportTest < Test::Unit::TestCase
75
75
  assert_equal(key, id.key)
76
76
  end
77
77
  end
78
+
79
+ class TokenizeTest < self
80
+ class TableTypeTest < self
81
+ def test_hash
82
+ Groonga::Schema.create_table("Terms",
83
+ :type => :hash,
84
+ :key_type => "ShortText",
85
+ :default_tokenizer => "TokenBigram",
86
+ :normalizer => "NormalizerAuto")
87
+ terms = Groonga["Terms"]
88
+ tokens = terms.tokenize("Hello World!")
89
+ assert_equal(["!", "hello", "world"],
90
+ tokens.collect(&:key).sort)
91
+ end
92
+
93
+ def test_patricia_trie
94
+ Groonga::Schema.create_table("Terms",
95
+ :type => :patricia_trie,
96
+ :key_type => "ShortText",
97
+ :default_tokenizer => "TokenBigram",
98
+ :normalizer => "NormalizerAuto")
99
+ terms = Groonga["Terms"]
100
+ tokens = terms.tokenize("Hello World!")
101
+ assert_equal(["!", "hello", "world"],
102
+ tokens.collect(&:key).sort)
103
+ end
104
+ end
105
+
106
+ class AddOptionTest < self
107
+ setup
108
+ def setup_lexicon
109
+ Groonga::Schema.create_table("Terms",
110
+ :type => :patricia_trie,
111
+ :key_type => "ShortText",
112
+ :default_tokenizer => "TokenBigram",
113
+ :normalizer => "NormalizerAuto")
114
+ @lexicon = Groonga["Terms"]
115
+ end
116
+
117
+ def test_default
118
+ tokens = @lexicon.tokenize("Hello World!")
119
+ assert_equal(["!", "hello", "world"],
120
+ tokens.collect(&:key).sort)
121
+ end
122
+
123
+ def test_true
124
+ tokens = @lexicon.tokenize("Hello World!", :add => true)
125
+ assert_equal(["!", "hello", "world"],
126
+ tokens.collect(&:key).sort)
127
+ end
128
+
129
+ def test_false
130
+ tokens = @lexicon.tokenize("Hello groonga!", :add => true)
131
+ assert_equal(["!", "groonga", "hello"],
132
+ tokens.collect(&:key).sort)
133
+
134
+ tokens = @lexicon.tokenize("Hello World!", :add => false)
135
+ assert_equal(["!", "hello"],
136
+ tokens.collect(&:key).sort)
137
+ end
138
+ end
139
+ end
78
140
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rroonga
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.6
4
+ version: 3.0.7
5
5
  prerelease:
6
6
  platform: x86-mingw32
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-09-14 00:00:00.000000000 Z
16
+ date: 2013-09-19 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: pkg-config
@@ -31,6 +31,22 @@ dependencies:
31
31
  - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
+ - !ruby/object:Gem::Dependency
35
+ name: groonga-client
36
+ requirement: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: 0.0.3
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: 0.0.3
34
50
  - !ruby/object:Gem::Dependency
35
51
  name: json
36
52
  requirement: !ruby/object:Gem::Requirement
@@ -234,10 +250,10 @@ files:
234
250
  - lib/groonga/pagination.rb
235
251
  - lib/groonga/database.rb
236
252
  - lib/groonga/schema.rb
237
- - lib/groonga/command.rb
238
253
  - lib/groonga/posting.rb
239
254
  - lib/groonga/patricia-trie.rb
240
255
  - lib/groonga/expression-builder.rb
256
+ - lib/groonga/context/command-executor.rb
241
257
  - lib/groonga/dumper.rb
242
258
  - lib/groonga/query-logger.rb
243
259
  - lib/groonga/expression-builder-19.rb
@@ -1,171 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License version 2.1 as published by the Free Software Foundation.
8
- #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
-
18
- module Groonga
19
- module Command
20
- class Builder
21
- class << self
22
- def escape_value(value)
23
- escaped_value = value.to_s.gsub(/[\\"]/) do |matched|
24
- "\\#{matched}"
25
- end
26
- "\"#{escaped_value}\""
27
- end
28
- end
29
-
30
- attr_reader :command, :arguments
31
- def initialize(command, arguments={})
32
- @command = command
33
- @arguments = arguments
34
- end
35
-
36
- def [](key)
37
- @arguments[key]
38
- end
39
-
40
- def []=(key, value)
41
- @arguments[key] = value
42
- end
43
-
44
- def build
45
- query = "#{@command} "
46
- @arguments.each do |key, value|
47
- value = value.join(", ") if value.is_a?(::Array)
48
- escaped_value = self.class.escape_value(value)
49
- query << " --#{key} #{escaped_value}"
50
- end
51
- query
52
- end
53
- end
54
-
55
- class Select
56
- def initialize(context, table, options)
57
- @context = context
58
- @table = table
59
- @options = normalize_options(options)
60
- end
61
-
62
- def exec
63
- request_id = @context.send(query)
64
- loop do
65
- response_id, result = @context.receive
66
- if request_id == response_id
67
- drill_down_keys = @options["drilldown"]
68
- if drill_down_keys.is_a?(String)
69
- drill_down_keys = drill_down_keys.split(/(?:\s+|\s*,\s*)/)
70
- end
71
- return Result.parse(result, drill_down_keys)
72
- end
73
- # raise if request_id < response_id
74
- end
75
- end
76
-
77
- private
78
- def normalize_options(options)
79
- normalized_options = {}
80
- options.each do |key, value|
81
- normalized_options[normalize_option_name(key)] = value
82
- end
83
- normalized_options
84
- end
85
-
86
- def normalize_option_name(name)
87
- name = name.to_s.gsub(/-/, "_").gsub(/drill_down/, "drilldown")
88
- name.gsub(/sort_by/, 'sortby')
89
- end
90
-
91
- def query
92
- if @table.is_a?(String)
93
- table_name = @table
94
- else
95
- table_name = @table.name
96
- end
97
- builder = Builder.new("select", @options.merge(:table => table_name))
98
- builder.build
99
- end
100
-
101
- class Result < Struct.new(:n_hits, :columns, :values, :drill_down)
102
- class << self
103
- def parse(json, drill_down_keys)
104
- select_result, *drill_down_results = JSON.parse(json)
105
- result = new
106
- n_hits, columns, values = extract_result(select_result)
107
- result.n_hits = n_hits
108
- result.columns = columns
109
- result.values = values
110
- if drill_down_results
111
- result.drill_down = parse_drill_down_results(drill_down_results,
112
- drill_down_keys)
113
- end
114
- result
115
- end
116
-
117
- def create_records(columns, values)
118
- records = []
119
- values.each do |value|
120
- record = {}
121
- columns.each_with_index do |(name, type), i|
122
- record[name] = convert_value(value[i], type)
123
- end
124
- records << record
125
- end
126
- records
127
- end
128
-
129
- private
130
- def parse_drill_down_results(results, keys)
131
- named_results = {}
132
- results.each_with_index do |drill_down, i|
133
- n_hits, columns, values = extract_result(drill_down)
134
- drill_down_result = DrillDownResult.new
135
- drill_down_result.n_hits = n_hits
136
- drill_down_result.columns = columns
137
- drill_down_result.values = values
138
- named_results[keys[i]] = drill_down_result
139
- end
140
- named_results
141
- end
142
-
143
- def extract_result(result)
144
- meta_data, columns, *values = result
145
- n_hits, = meta_data
146
- [n_hits, columns, values]
147
- end
148
-
149
- def convert_value(value, type)
150
- case type
151
- when "Time"
152
- Time.at(value)
153
- else
154
- value
155
- end
156
- end
157
- end
158
-
159
- def records
160
- @records ||= self.class.create_records(columns, values)
161
- end
162
-
163
- class DrillDownResult < Struct.new(:n_hits, :columns, :values)
164
- def records
165
- @records ||= Result.create_records(columns, values)
166
- end
167
- end
168
- end
169
- end
170
- end
171
- end