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 CHANGED
@@ -1,4 +1,5 @@
1
1
  --output-dir doc/reference/en
2
+ --markup markdown
2
3
  lib/**/*.rb
3
4
  -
4
5
  doc/text/**/*
data/README.md CHANGED
@@ -57,6 +57,7 @@ TODO: use commands with parameters for examples
57
57
  ## Authors
58
58
 
59
59
  * Haruka Yoshihara \<yoshihara@clear-code.com\>
60
+ * Kouhei Sutou \<kou@clear-code.com\>
60
61
 
61
62
  ## License
62
63
 
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
- Response::TableList and Response::ColumnList
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
 
@@ -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.2")
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")
@@ -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/protocol/gqtp"
22
- require "groonga/client/protocol/http"
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
- yield(client)
31
- client.close
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::Protocol::GQTP.new(options)
71
+ @connection = Groonga::Client::Connection::GQTP.new(options)
47
72
  else
48
- @connection = Groonga::Client::Protocol::HTTP.new(options)
73
+ @connection = Groonga::Client::Connection::HTTP.new(options)
49
74
  end
50
75
  end
51
76
 
52
- def close
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
- response_class = Groonga::Client::Response.find(@command.name)
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 Protocol
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 Protocol
25
- class Request
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 HTTP
36
- def initialize(options)
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 send(command)
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(raw_response, type)
41
- case type
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
- attr_accessor :header, :body
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
- @header = header
108
- @body = body
109
- @raw = nil
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