groonga-client 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/README.md +1 -0
- data/doc/text/news.md +16 -3
- data/groonga-client.gemspec +1 -1
- data/lib/groonga/client.rb +69 -7
- data/lib/groonga/client/command.rb +1 -2
- data/lib/groonga/client/connection/error.rb +31 -0
- data/lib/groonga/client/{protocol → connection}/gqtp.rb +41 -1
- data/lib/groonga/client/connection/http.rb +83 -0
- data/lib/groonga/client/{protocol/http.rb → connection/request.rb} +5 -18
- data/lib/groonga/client/response/base.rb +38 -8
- data/lib/groonga/client/response/column_list.rb +3 -2
- data/lib/groonga/client/response/select.rb +46 -14
- data/lib/groonga/client/response/table_create.rb +12 -0
- data/lib/groonga/client/response/table_list.rb +3 -2
- data/lib/groonga/client/version.rb +1 -1
- data/test/connection/test-gqtp.rb +105 -0
- data/test/connection/test-http.rb +97 -0
- data/test/response/helper.rb +4 -0
- data/test/response/test-column-list.rb +2 -11
- data/test/response/test-select.rb +127 -12
- data/test/response/test-table-list.rb +2 -11
- data/test/results/test-column-list.rb +2 -1
- data/test/results/test-table-list.rb +2 -1
- data/test/test-client.rb +43 -27
- data/test/test-command.rb +36 -3
- metadata +36 -31
- data/test/results/test-select.rb +0 -63
data/.yardopts
CHANGED
data/README.md
CHANGED
data/doc/text/news.md
CHANGED
@@ -1,12 +1,25 @@
|
|
1
1
|
# NEWS
|
2
2
|
|
3
|
+
## 0.0.3 - 2013-09-18
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* Supported "table_create" command.
|
8
|
+
* {Groonga::Client.open} returns block value.
|
9
|
+
* Supported {Groonga::Client#close}.
|
10
|
+
* select: Supported auto time value conversion.
|
11
|
+
* select: Renamed to {Groonga::Client::Response::Select#n_hits}
|
12
|
+
from #n_records. It is a backward incompatible change.
|
13
|
+
* Added {Groonga::Client::Connection::Error} as an abstracted error.
|
14
|
+
* Required groonga-command 1.0.4 or later.
|
15
|
+
|
3
16
|
## 0.0.2 - 2013-07-08
|
4
17
|
|
5
18
|
### Improvements
|
6
19
|
|
7
|
-
* Supported "select" command.
|
8
|
-
* Supported Enumerable type interface in
|
9
|
-
|
20
|
+
* Supported "select" command.
|
21
|
+
* Supported Enumerable type interface in
|
22
|
+
Response::TableList and Response::ColumnList
|
10
23
|
|
11
24
|
## 0.0.1 - 2013-06-27
|
12
25
|
|
data/groonga-client.gemspec
CHANGED
@@ -47,7 +47,7 @@ Gem::Specification.new do |spec|
|
|
47
47
|
# end
|
48
48
|
|
49
49
|
spec.add_runtime_dependency("gqtp", ">= 1.0.4")
|
50
|
-
spec.add_runtime_dependency("groonga-command", ">= 1.0.
|
50
|
+
spec.add_runtime_dependency("groonga-command", ">= 1.0.4")
|
51
51
|
|
52
52
|
spec.add_development_dependency("bundler")
|
53
53
|
spec.add_development_dependency("rake")
|
data/lib/groonga/client.rb
CHANGED
@@ -18,17 +18,41 @@
|
|
18
18
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
19
|
|
20
20
|
require "groonga/client/command"
|
21
|
-
require "groonga/client/
|
22
|
-
require "groonga/client/
|
21
|
+
require "groonga/client/connection/gqtp"
|
22
|
+
require "groonga/client/connection/http"
|
23
23
|
|
24
24
|
module Groonga
|
25
25
|
class Client
|
26
26
|
class << self
|
27
|
+
# @!macro [new] initialize_options
|
28
|
+
# @param [Hash] options The options.
|
29
|
+
# @option options [:gqtp or :http] :protocol The protocol that is
|
30
|
+
# used by the client.
|
31
|
+
#
|
32
|
+
# @overload open(options={})
|
33
|
+
# Opens a new client connection.
|
34
|
+
#
|
35
|
+
# @macro initialize_options
|
36
|
+
# @return [Client] The opened client.
|
37
|
+
#
|
38
|
+
# @overload open(options={}) {|client| }
|
39
|
+
# Opens a new client connection while the block is evaluated.
|
40
|
+
# The block is finished the opened client is closed.
|
41
|
+
#
|
42
|
+
# @macro initialize_options
|
43
|
+
# @yield [client] Gives a opened client to the block. The opened
|
44
|
+
# client is closed automatically when the block is finished.
|
45
|
+
# @yieldparam client [Client] The opened client.
|
46
|
+
# @yieldreturn [Object] Any object.
|
47
|
+
# @return [Object] Any object that is returned by the block.
|
27
48
|
def open(options={}, &block)
|
28
49
|
client = new(options)
|
29
50
|
if block_given?
|
30
|
-
|
31
|
-
|
51
|
+
begin
|
52
|
+
yield(client)
|
53
|
+
ensure
|
54
|
+
client.close
|
55
|
+
end
|
32
56
|
else
|
33
57
|
client
|
34
58
|
end
|
@@ -38,18 +62,55 @@ module Groonga
|
|
38
62
|
attr_reader :protocol
|
39
63
|
attr_reader :connection
|
40
64
|
|
65
|
+
# @macro initialize_options
|
41
66
|
def initialize(options)
|
42
67
|
@protocol = options.delete(:protocol) || :gqtp
|
43
68
|
|
44
69
|
@connection = nil
|
45
70
|
if @protocol == :gqtp
|
46
|
-
@connection = Groonga::Client::
|
71
|
+
@connection = Groonga::Client::Connection::GQTP.new(options)
|
47
72
|
else
|
48
|
-
@connection = Groonga::Client::
|
73
|
+
@connection = Groonga::Client::Connection::HTTP.new(options)
|
49
74
|
end
|
50
75
|
end
|
51
76
|
|
52
|
-
|
77
|
+
# Closes the opened client connection if the current connection is
|
78
|
+
# still opened. You can't send a new command after you call this
|
79
|
+
# method.
|
80
|
+
#
|
81
|
+
# @overload close
|
82
|
+
# Closes synchronously.
|
83
|
+
#
|
84
|
+
# @return [Boolean] true when the opened connection is closed.
|
85
|
+
# false when there is no connection.
|
86
|
+
#
|
87
|
+
# @overload close {}
|
88
|
+
# Closes asynchronously.
|
89
|
+
#
|
90
|
+
# @yield [] Calls the block when the opened connection is closed.
|
91
|
+
# @return [#wait] The request object. If you want to wait until
|
92
|
+
# the request is processed. You can send #wait message to the
|
93
|
+
# request.
|
94
|
+
def close(&block)
|
95
|
+
sync = !block_given?
|
96
|
+
if @connection
|
97
|
+
close_request = @connection.close do
|
98
|
+
yield unless sync
|
99
|
+
@connection = nil
|
100
|
+
end
|
101
|
+
if sync
|
102
|
+
close_request.wait
|
103
|
+
true
|
104
|
+
else
|
105
|
+
close_request
|
106
|
+
end
|
107
|
+
else
|
108
|
+
if sync
|
109
|
+
false
|
110
|
+
else
|
111
|
+
Connection::EmptryReqest.new
|
112
|
+
end
|
113
|
+
end
|
53
114
|
end
|
54
115
|
|
55
116
|
def cache_limit(parameters)
|
@@ -128,6 +189,7 @@ module Groonga
|
|
128
189
|
end
|
129
190
|
|
130
191
|
def table_create(parameters)
|
192
|
+
execute_command("table_create", parameters)
|
131
193
|
end
|
132
194
|
|
133
195
|
def table_list(parameters={})
|
@@ -46,8 +46,7 @@ module Groonga
|
|
46
46
|
|
47
47
|
private
|
48
48
|
def parse_raw_response(raw_response)
|
49
|
-
|
50
|
-
response_class.parse(raw_response, @command.output_type)
|
49
|
+
Groonga::Client::Response.parse(@command, raw_response)
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 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 as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
|
19
|
+
module Groonga
|
20
|
+
class Client
|
21
|
+
module Connection
|
22
|
+
class Error < StandardError
|
23
|
+
attr_reader :raw_error
|
24
|
+
def initialize(raw_error)
|
25
|
+
@raw_error = raw_error
|
26
|
+
super(raw_error.message)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -22,9 +22,11 @@ require "erb"
|
|
22
22
|
require "gqtp"
|
23
23
|
require "json"
|
24
24
|
|
25
|
+
require "groonga/client/connection/request"
|
26
|
+
|
25
27
|
module Groonga
|
26
28
|
class Client
|
27
|
-
module
|
29
|
+
module Connection
|
28
30
|
class GQTP
|
29
31
|
def initialize(options)
|
30
32
|
@client = ::GQTP::Client.new(options)
|
@@ -41,6 +43,44 @@ module Groonga
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
46
|
+
# @return [Boolean] true if the current connection is opened,
|
47
|
+
# false otherwise.
|
48
|
+
def connected?
|
49
|
+
not @client.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Closes the opened connection if the current connection is
|
53
|
+
# still opened. You can't send a new command after you call
|
54
|
+
# this method.
|
55
|
+
#
|
56
|
+
# @overload close
|
57
|
+
# Closes synchronously.
|
58
|
+
#
|
59
|
+
# @return [Boolean] true when the opened connection is closed.
|
60
|
+
# false when there is no connection.
|
61
|
+
#
|
62
|
+
# @overload close {}
|
63
|
+
# Closes asynchronously.
|
64
|
+
#
|
65
|
+
# @yield [] Calls the block when the opened connection is closed.
|
66
|
+
# @return [#wait] The request object. If you want to wait until
|
67
|
+
# the request is processed. You can send #wait message to the
|
68
|
+
# request.
|
69
|
+
def close(&block)
|
70
|
+
sync = !block_given?
|
71
|
+
if connected?
|
72
|
+
return_value = @client.close(&block)
|
73
|
+
@client = nil
|
74
|
+
return_value
|
75
|
+
else
|
76
|
+
if sync
|
77
|
+
false
|
78
|
+
else
|
79
|
+
EmptyRequest.new
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
44
84
|
class RawResponse
|
45
85
|
include ERB::Util
|
46
86
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
|
+
# Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
|
5
|
+
#
|
6
|
+
# This library is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
8
|
+
# License as published by the Free Software Foundation; either
|
9
|
+
# version 2.1 of the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
|
20
|
+
require "open-uri"
|
21
|
+
|
22
|
+
require "groonga/client/connection/request"
|
23
|
+
require "groonga/client/connection/error"
|
24
|
+
|
25
|
+
module Groonga
|
26
|
+
class Client
|
27
|
+
module Connection
|
28
|
+
class HTTP
|
29
|
+
def initialize(options)
|
30
|
+
@host = options[:host] || "127.0.0.1"
|
31
|
+
@port = options[:port] || 10041
|
32
|
+
end
|
33
|
+
|
34
|
+
def send(command)
|
35
|
+
url = "http://#{@host}:#{@port}#{command.to_uri_format}"
|
36
|
+
thread = Thread.new do
|
37
|
+
begin
|
38
|
+
open(url) do |response|
|
39
|
+
body = response.read
|
40
|
+
yield(body)
|
41
|
+
end
|
42
|
+
rescue OpenURI::HTTPError
|
43
|
+
raise Error.new($!)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
ThreadRequest.new(thread)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [false] Always returns false because the current
|
50
|
+
# implementation doesn't support keep-alive.
|
51
|
+
def connected?
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
# Does nothing because the current implementation doesn't
|
56
|
+
# support keep-alive. If the implementation supports
|
57
|
+
# keep-alive, it close the opend connection.
|
58
|
+
#
|
59
|
+
# @overload close
|
60
|
+
# Closes synchronously.
|
61
|
+
#
|
62
|
+
# @return [false] It always returns false because there is always
|
63
|
+
# no connectin.
|
64
|
+
#
|
65
|
+
# @overload close {}
|
66
|
+
# Closes asynchronously.
|
67
|
+
#
|
68
|
+
# @yield [] Calls the block when the opened connection is closed.
|
69
|
+
# @return [#wait] The request object. If you want to wait until
|
70
|
+
# the request is processed. You can send #wait message to the
|
71
|
+
# request.
|
72
|
+
def close(&block)
|
73
|
+
sync = !block_given?
|
74
|
+
if sync
|
75
|
+
false
|
76
|
+
else
|
77
|
+
EmptyRequest.new
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
3
|
# Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
|
5
4
|
#
|
6
5
|
# This library is free software; you can redistribute it and/or
|
@@ -17,12 +16,10 @@
|
|
17
16
|
# License along with this library; if not, write to the Free Software
|
18
17
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
18
|
|
20
|
-
require "open-uri"
|
21
|
-
|
22
19
|
module Groonga
|
23
20
|
class Client
|
24
|
-
module
|
25
|
-
class
|
21
|
+
module Connection
|
22
|
+
class ThreadRequest
|
26
23
|
def initialize(thread)
|
27
24
|
@thread = thread
|
28
25
|
end
|
@@ -32,21 +29,11 @@ module Groonga
|
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
35
|
-
class
|
36
|
-
def initialize
|
37
|
-
@host = options[:host] || "127.0.0.1"
|
38
|
-
@port = options[:port] || 10041
|
32
|
+
class EmptyRequest
|
33
|
+
def initialize
|
39
34
|
end
|
40
35
|
|
41
|
-
def
|
42
|
-
url = "http://#{@host}:#{@port}#{command.to_uri_format}"
|
43
|
-
thread = Thread.new do
|
44
|
-
open(url) do |response|
|
45
|
-
body = response.read
|
46
|
-
yield(body)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
Request.new(thread)
|
36
|
+
def wait
|
50
37
|
end
|
51
38
|
end
|
52
39
|
end
|
@@ -33,12 +33,24 @@ module Groonga
|
|
33
33
|
def find(name)
|
34
34
|
@@registered_commands[name] || Base
|
35
35
|
end
|
36
|
+
|
37
|
+
# Parses the response for the request of the command and returns
|
38
|
+
# response object.
|
39
|
+
#
|
40
|
+
# @param [Groonga::Command::Base] The command of the request.
|
41
|
+
# @param [String] The raw (not parsed) response returned by groonga
|
42
|
+
# server.
|
43
|
+
# @return [Base]
|
44
|
+
def parse(command, raw_response)
|
45
|
+
klass = find(command.name)
|
46
|
+
klass.parse(command, raw_response)
|
47
|
+
end
|
36
48
|
end
|
37
49
|
|
38
50
|
class Base
|
39
51
|
class << self
|
40
|
-
def parse(
|
41
|
-
case
|
52
|
+
def parse(command, raw_response)
|
53
|
+
case command.output_type
|
42
54
|
when :json
|
43
55
|
header, body = JSON.parse(raw_response)
|
44
56
|
when :xml
|
@@ -47,7 +59,7 @@ module Groonga
|
|
47
59
|
header = nil
|
48
60
|
body = raw_response
|
49
61
|
end
|
50
|
-
response = new(header, body)
|
62
|
+
response = new(command, header, body)
|
51
63
|
response.raw = raw_response
|
52
64
|
response
|
53
65
|
end
|
@@ -100,13 +112,31 @@ module Groonga
|
|
100
112
|
end
|
101
113
|
end
|
102
114
|
|
103
|
-
|
115
|
+
# @return [Groonga::Command] The command for the request.
|
116
|
+
attr_accessor :command
|
117
|
+
# @return [::Array<Integer, Float, Float>] The header of response.
|
118
|
+
# It consists of `[return_code, start_time, elapsed_time_in_seconds]`
|
119
|
+
# for success case.
|
120
|
+
# It consists of
|
121
|
+
# `[return_code, start_time, elapsed_time_in_seconds, error_message, error_location]`
|
122
|
+
# for error case.
|
123
|
+
# @see http://groonga.org/docs/reference/command/output_format.html#header
|
124
|
+
# Defails for header format.
|
125
|
+
attr_accessor :header
|
126
|
+
# @return [::Hash] The body of response. Its content is depends on
|
127
|
+
# command.
|
128
|
+
# @see http://groonga.org/docs/reference/command.html
|
129
|
+
# The list of built-in commands.
|
130
|
+
attr_accessor :body
|
131
|
+
# @return [String] The unparsed response. It may be JSON, XML or
|
132
|
+
# groonga command format.
|
104
133
|
attr_accessor :raw
|
105
134
|
|
106
|
-
def initialize(header, body)
|
107
|
-
|
108
|
-
|
109
|
-
|
135
|
+
def initialize(command, header, body)
|
136
|
+
self.command = command
|
137
|
+
self.header = header
|
138
|
+
self.body = body
|
139
|
+
self.raw = nil
|
110
140
|
end
|
111
141
|
end
|
112
142
|
end
|