groonga-client-model 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a4687e8ec94929e2474ebe8205dc7f9ced8eb07
4
- data.tar.gz: 8f374d746774e4673fac9aaf3a1697587f3c0e6e
3
+ metadata.gz: 0f62905cc625bbbe0a0a44b163ef75a1a176ea21
4
+ data.tar.gz: 70ca5ad3240f79c26eb581f16fbcabba4b8a8b66
5
5
  SHA512:
6
- metadata.gz: 320533d1264b86925dc04f4e9913f77d5e049608b0ba5e8ce2334212f841dc1b3abf045b50d6b465fd84c38a8f05aa7205741ec0a12b9618f9f026bc7e325017
7
- data.tar.gz: b0f9aadce06abd75c79fa79b3d58aa32fb5dc4d216fb79c983dde8e76126caa8699bf1654d90923744153b7522ad6f97151fdcd7b7c5facc162a0555994f635b
6
+ metadata.gz: 246eb7a6cfe6c03df9dc51aabc135cb1801cac43de8a6f9185ad493cad7ea3e7a17cc0616fb1f802851124849151d96d71801ef96ab5b2c1f11ec4ba29399c4c
7
+ data.tar.gz: 0a22d63d2a9b0500c3b8c273828157216bdfcb69b43ada31800cf5dae7fe5ac9a5b1df818db6f319799de98f68b6d7290a76e28ee78b0f3151f70e843541273e
data/doc/text/news.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # NEWS
2
2
 
3
+ ## 0.9.9 - 2016-02-07
4
+
5
+ ### Improvements
6
+
7
+ * {GroongaClientModel::Record}: Added `_key` validation by default.
8
+
9
+ * {GroongaClientModel::Record}: Supported `load --output_errors yes
10
+ --command_version 3` introduced since Groonga 7.0.0.
11
+
12
+ * Required groonga-client gem 0.4.1 or later.
13
+
14
+ * Supported i18n.
15
+
3
16
  ## 0.9.8 - 2016-01-27
4
17
 
5
18
  ### Improvements
@@ -1,6 +1,6 @@
1
1
  # -*- ruby -*-
2
2
  #
3
- # Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2016-2017 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
@@ -39,11 +39,11 @@ Gem::Specification.new do |spec|
39
39
  spec.license = "LGPL-2.1+"
40
40
  spec.files = ["README.md", "Rakefile", "Gemfile", "#{spec.name}.gemspec"]
41
41
  spec.files += [".yardopts"]
42
- spec.files += Dir.glob("lib/**/*.{rb,rake}")
42
+ spec.files += Dir.glob("lib/**/*.{rb,rake,yml}")
43
43
  spec.files += Dir.glob("doc/text/*")
44
44
  spec.test_files += Dir.glob("test/**/*")
45
45
 
46
- spec.add_runtime_dependency("groonga-client", ">= 0.3.7")
46
+ spec.add_runtime_dependency("groonga-client", ">= 0.4.1")
47
47
  spec.add_runtime_dependency("groonga-command-parser")
48
48
  spec.add_runtime_dependency("activemodel")
49
49
 
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -27,9 +27,11 @@ require "groonga_client_model/error"
27
27
  require "groonga_client_model/load_value_generator"
28
28
  require "groonga_client_model/modelizable"
29
29
  require "groonga_client_model/modelize"
30
- require "groonga_client_model/record"
31
30
  require "groonga_client_model/schema"
32
31
  require "groonga_client_model/schema_loader"
32
+ require "groonga_client_model/validations/type_validator"
33
+
34
+ require "groonga_client_model/record"
33
35
 
34
36
  module GroongaClientModel
35
37
  extend ActiveSupport::Autoload
@@ -42,3 +44,8 @@ ActiveSupport.run_load_hooks(:groonga_client_model, GroongaClientModel)
42
44
  if defined?(Rails)
43
45
  require "groonga_client_model/railtie"
44
46
  end
47
+
48
+ ActiveSupport.on_load(:i18n) do
49
+ I18n.load_path << "#{__dir__}/groonga_client_model/locale/en.yml"
50
+ I18n.load_path << "#{__dir__}/groonga_client_model/locale/ja.yml"
51
+ end
@@ -0,0 +1,23 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ not_a_positive_integer:
5
+ "must be a positive integer: %{inspected_value}"
6
+ invalid_uint8:
7
+ "must be less than 2 ** 8: %{inspected_value}"
8
+ invalid_uint16:
9
+ "must be less than 2 ** 16: %{inspected_value}"
10
+ invalid_uint32:
11
+ "must be less than 2 ** 32: %{inspected_value}"
12
+ invalid_uint64:
13
+ "must be less than 2 ** 64: %{inspected_value}"
14
+ invalid_int8:
15
+ "must be between -(2 ** 7) and (2 ** 7) - 1: %{inspected_value}"
16
+ invalid_int16:
17
+ "must be between -(2 ** 15) and (2 ** 15) - 1: %{inspected_value}"
18
+ invalid_int32:
19
+ "must be between -(2 ** 31) and (2 ** 31) - 1: %{inspected_value}"
20
+ invalid_int64:
21
+ "must be between -(2 ** 63) and (2 ** 63) - 1: %{inspected_value}"
22
+ not_a_time:
23
+ "must be a time: %{inspected_value}"
@@ -0,0 +1,23 @@
1
+ ja:
2
+ errors:
3
+ messages:
4
+ not_a_positive_integer:
5
+ "正の整数ではありません:%{inspected_value}"
6
+ invalid_uint8:
7
+ "2 ** 8より大きいです:%{inspected_value}"
8
+ invalid_uint16:
9
+ "2 ** 16より大きいです:%{inspected_value}"
10
+ invalid_uint32:
11
+ "2 ** 32より大きいです:%{inspected_value}"
12
+ invalid_uint64:
13
+ "2 ** 64より大きいです:%{inspected_value}"
14
+ invalid_int8:
15
+ "-(2 ** 7)以上(2 ** 7) - 1以下の範囲外です:%{inspected_value}"
16
+ invalid_int16:
17
+ "-(2 ** 15)以上(2 ** 15) - 1以下の範囲外です:%{inspected_value}"
18
+ invalid_int32:
19
+ "-(2 ** 31)以上(2 ** 31) - 1以下の範囲外:%{inspected_value}"
20
+ invalid_int64:
21
+ "-(2 ** 63)以上(2 ** 63) - 1以下の範囲外です:%{inspected_value}"
22
+ not_a_time:
23
+ "時刻を表す値ではありません:%{inspected_value}"
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -138,7 +138,13 @@ module GroongaClientModel
138
138
 
139
139
  attr_reader :attributes
140
140
 
141
- validates :_key, presence: true, if: ->(record) {record.class.have_key?}
141
+ validates(:_key,
142
+ presence: true,
143
+ if: ->(record) {record.class.have_key?})
144
+ validates(:_key,
145
+ "groonga_client_model/validations/type": true,
146
+ if: ->(record) {record.class.have_key?},
147
+ allow_blank: true)
142
148
 
143
149
  def initialize(attributes=nil)
144
150
  @attributes = {}
@@ -265,6 +271,7 @@ module GroongaClientModel
265
271
  response = client.load(table: table.name,
266
272
  values: [value],
267
273
  output_ids: "yes",
274
+ output_errors: "yes",
268
275
  command_version: "3")
269
276
  unless response.success?
270
277
  message = "Failed to save: "
@@ -272,7 +279,12 @@ module GroongaClientModel
272
279
  raise RecordNotSaved.new(message, self)
273
280
  end
274
281
  if response.n_loaded_records.zero?
275
- message = "Failed to save: #{value.inspect}"
282
+ message = "Failed to save"
283
+ error = response.errors[0]
284
+ if error and !error.return_code.zero?
285
+ message << ": #{error.return_code}: #{error.message}: "
286
+ end
287
+ message << ": #{value.inspect}"
276
288
  raise RecordNotSaved.new(message, self)
277
289
  end
278
290
  if @new_record
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2016-2017 Kouhei Sutou <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -62,18 +62,20 @@ module GroongaClientModel
62
62
 
63
63
  def columns
64
64
  raw_columns = {}
65
- raw_columns["_id"] = create_pseudo_column("_id")
66
- if @raw_table.key_type
67
- raw_columns["_key"] = create_pseudo_column("_key")
65
+ raw_columns["_id"] = create_pseudo_column("_id", {"name" => "UInt32"})
66
+ key_type = @raw_table.key_type
67
+ if key_type
68
+ raw_columns["_key"] = create_pseudo_column("_key", key_type)
68
69
  end
69
70
  Columns.new(@raw_schema, @raw_table.columns.merge(raw_columns))
70
71
  end
71
72
 
72
73
  private
73
- def create_pseudo_column(name)
74
+ def create_pseudo_column(name, value_type)
74
75
  raw_column = {
75
76
  "name" => name,
76
77
  "indexes" => [],
78
+ "value_type" => value_type,
77
79
  }
78
80
  Groonga::Client::Response::Schema::Column.new(@raw_schema, raw_column)
79
81
  end
@@ -88,7 +90,7 @@ module GroongaClientModel
88
90
  end
89
91
 
90
92
  def exist?(name)
91
- @raw_columns.key?(name)
93
+ @raw_columns.key?(normalize_name(name))
92
94
  end
93
95
 
94
96
  def names
@@ -96,7 +98,7 @@ module GroongaClientModel
96
98
  end
97
99
 
98
100
  def [](name)
99
- @raw_columns[name]
101
+ @raw_columns[normalize_name(name)]
100
102
  end
101
103
 
102
104
  def each
@@ -104,6 +106,11 @@ module GroongaClientModel
104
106
  yield(name, column)
105
107
  end
106
108
  end
109
+
110
+ private
111
+ def normalize_name(name)
112
+ name.to_s
113
+ end
107
114
  end
108
115
  end
109
116
  end
@@ -0,0 +1,143 @@
1
+ # Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ module GroongaClientModel
18
+ module Validations
19
+ class TypeValidator < ActiveModel::EachValidator
20
+ def validate_each(record, attribute, value)
21
+ column = record.class.columns[attribute]
22
+ return if column.nil?
23
+ value_type = column["value_type"]
24
+ return if value_type.nil?
25
+
26
+ case value_type["name"]
27
+ when "UInt8"
28
+ validate_uint(record, attribute, value, 8)
29
+ when "UInt16"
30
+ validate_uint(record, attribute, value, 16)
31
+ when "UInt32"
32
+ validate_uint(record, attribute, value, 32)
33
+ when "UInt64"
34
+ validate_uint(record, attribute, value, 64)
35
+ when "Int8"
36
+ validate_int(record, attribute, value, 8)
37
+ when "Int16"
38
+ validate_int(record, attribute, value, 16)
39
+ when "Int32"
40
+ validate_int(record, attribute, value, 32)
41
+ when "Int64"
42
+ validate_int(record, attribute, value, 64)
43
+ when "Float"
44
+ validate_float(record, attribute, value)
45
+ when "Time"
46
+ validate_time(record, attribute, value)
47
+ end
48
+ end
49
+
50
+ private
51
+ def validate_uint(record, attribute, value, n_bits)
52
+ if value.is_a?(String)
53
+ begin
54
+ value = Integer(value)
55
+ rescue ArgumentError
56
+ end
57
+ end
58
+
59
+ case value
60
+ when Numeric
61
+ if value < 0
62
+ record.errors.add(attribute,
63
+ :not_a_positive_integer,
64
+ options.merge(inspected_value: value.inspect))
65
+ return
66
+ end
67
+ if value > ((2 ** n_bits) - 1)
68
+ record.errors.add(attribute,
69
+ :"invalid_uint#{n_bits}",
70
+ options.merge(inspected_value: value.inspect))
71
+ return
72
+ end
73
+ else
74
+ record.errors.add(attribute,
75
+ :not_a_positive_integer,
76
+ options.merge(inspected_value: value.inspect))
77
+ end
78
+ end
79
+
80
+ def validate_int(record, attribute, value, n_bits)
81
+ if value.is_a?(String)
82
+ begin
83
+ value = Integer(value)
84
+ rescue ArgumentError
85
+ end
86
+ end
87
+
88
+ case value
89
+ when Numeric
90
+ min = -(2 ** (n_bits - 1))
91
+ max = ((2 ** (n_bits - 1)) - 1)
92
+ if value < min or value > max
93
+ record.errors.add(attribute,
94
+ :"invalid_int#{n_bits}",
95
+ options.merge(inspected_value: value.inspect))
96
+ return
97
+ end
98
+ else
99
+ record.errors.add(attribute, :not_an_integer)
100
+ end
101
+ end
102
+
103
+ def validate_float(record, attribute, value)
104
+ if value.is_a?(String)
105
+ begin
106
+ value = Float(value)
107
+ rescue ArgumentError
108
+ end
109
+ end
110
+
111
+ case value
112
+ when Numeric
113
+ else
114
+ record.errors.add(attribute, :not_a_number)
115
+ end
116
+ end
117
+
118
+ def validate_time(record, attribute, value)
119
+ if value.is_a?(String)
120
+ begin
121
+ value = Float(value)
122
+ rescue ArgumentError
123
+ begin
124
+ value = Time.strptime(value, "%Y-%m-%d %H:%M:%S.%N")
125
+ rescue ArgumentError
126
+ begin
127
+ value = Time.strptime(value, "%Y-%m-%d %H:%M:%S")
128
+ rescue ArgumentError
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ case value
135
+ when Date, Time, Numeric
136
+ else
137
+ record.errors.add(attribute, :not_a_time,
138
+ options.merge(inspected_value: value.inspect))
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -15,5 +15,5 @@
15
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
  module GroongaClientModel
18
- VERSION = "0.9.8"
18
+ VERSION = "0.9.9"
19
19
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../../../../groonga-client
3
3
  specs:
4
- groonga-client (0.4.0)
4
+ groonga-client (0.4.1)
5
5
  gqtp (>= 1.0.4)
6
6
  groonga-command (>= 1.2.8)
7
7
  groonga-command-parser (>= 1.0.7)
@@ -10,9 +10,9 @@ PATH
10
10
  PATH
11
11
  remote: ../../../
12
12
  specs:
13
- groonga-client-model (0.9.5)
13
+ groonga-client-model (0.9.9)
14
14
  activemodel
15
- groonga-client (>= 0.3.7)
15
+ groonga-client (>= 0.4.1)
16
16
  groonga-command-parser
17
17
 
18
18
  GEM
@@ -78,10 +78,10 @@ GEM
78
78
  globalid (0.3.7)
79
79
  activesupport (>= 4.1.0)
80
80
  gqtp (1.0.6)
81
- groonga-command (1.3.1)
81
+ groonga-command (1.3.2)
82
82
  json
83
- groonga-command-parser (1.0.7)
84
- groonga-command (>= 1.0.9)
83
+ groonga-command-parser (1.0.9)
84
+ groonga-command (>= 1.3.2)
85
85
  json-stream
86
86
  hashie (3.4.6)
87
87
  i18n (0.7.0)
@@ -92,7 +92,7 @@ GEM
92
92
  rails-dom-testing (>= 1, < 3)
93
93
  railties (>= 4.2.0)
94
94
  thor (>= 0.14, < 2.0)
95
- json (2.0.2)
95
+ json (2.0.3)
96
96
  json-stream (0.2.1)
97
97
  listen (3.0.8)
98
98
  rb-fsevent (~> 0.9, >= 0.9.4)
@@ -205,3 +205,59 @@ Processing by PostsController#show as HTML
205
205
  Rendering posts/show.html.erb within layouts/application
206
206
  Rendered posts/show.html.erb within layouts/application (0.9ms)
207
207
  Completed 200 OK in 36ms (Views: 3.9ms)
208
+ --------------------------------------------
209
+ PostsControllerTest: test_should_create_post
210
+ --------------------------------------------
211
+ table_create (0.7ms) table_create --flags "TABLE_NO_KEY" --name "posts"
212
+ -----------------------------------------
213
+ PostsControllerTest: test_should_get_edit
214
+ -----------------------------------------
215
+ table_create (0.4ms) table_create --flags "TABLE_NO_KEY" --name "posts"
216
+ ------------------------------------------
217
+ PostsControllerTest: test_should_show_post
218
+ ------------------------------------------
219
+ table_create (0.3ms) table_create --flags "TABLE_NO_KEY" --name "posts"
220
+ ---------------------------------------------
221
+ PostsControllerTest: test_should_destroy_post
222
+ ---------------------------------------------
223
+ table_create (0.5ms) table_create --flags "TABLE_NO_KEY" --name "posts"
224
+ ----------------------------------------
225
+ PostsControllerTest: test_should_get_new
226
+ ----------------------------------------
227
+ table_create (0.5ms) table_create --flags "TABLE_NO_KEY" --name "posts"
228
+ ------------------------------------------
229
+ PostsControllerTest: test_should_get_index
230
+ ------------------------------------------
231
+ table_create (0.5ms) table_create --flags "TABLE_NO_KEY" --name "posts"
232
+ --------------------------------------------
233
+ PostsControllerTest: test_should_update_post
234
+ --------------------------------------------
235
+ table_create (0.4ms) table_create --flags "TABLE_NO_KEY" --name "posts"
236
+ ------------------------------------------
237
+ PostsControllerTest: test_should_show_post
238
+ ------------------------------------------
239
+ table_create (0.6ms) table_create --flags "TABLE_NO_KEY" --name "posts"
240
+ --------------------------------------------
241
+ PostsControllerTest: test_should_update_post
242
+ --------------------------------------------
243
+ table_create (0.3ms) table_create --flags "TABLE_NO_KEY" --name "posts"
244
+ --------------------------------------------
245
+ PostsControllerTest: test_should_create_post
246
+ --------------------------------------------
247
+ table_create (0.3ms) table_create --flags "TABLE_NO_KEY" --name "posts"
248
+ ----------------------------------------
249
+ PostsControllerTest: test_should_get_new
250
+ ----------------------------------------
251
+ table_create (0.3ms) table_create --flags "TABLE_NO_KEY" --name "posts"
252
+ ---------------------------------------------
253
+ PostsControllerTest: test_should_destroy_post
254
+ ---------------------------------------------
255
+ table_create (0.3ms) table_create --flags "TABLE_NO_KEY" --name "posts"
256
+ -----------------------------------------
257
+ PostsControllerTest: test_should_get_edit
258
+ -----------------------------------------
259
+ table_create (0.3ms) table_create --flags "TABLE_NO_KEY" --name "posts"
260
+ ------------------------------------------
261
+ PostsControllerTest: test_should_get_index
262
+ ------------------------------------------
263
+ table_create (0.5ms) table_create --flags "TABLE_NO_KEY" --name "posts"
@@ -10,9 +10,9 @@ PATH
10
10
  PATH
11
11
  remote: ../../../
12
12
  specs:
13
- groonga-client-model (0.9.8)
13
+ groonga-client-model (0.9.9)
14
14
  activemodel
15
- groonga-client (>= 0.3.7)
15
+ groonga-client (>= 0.4.1)
16
16
  groonga-command-parser
17
17
 
18
18
  GEM
@@ -0,0 +1,2 @@
1
+ class Age < ApplicationGroongaRecord
2
+ end
@@ -7,3 +7,5 @@ table_create terms TABLE_PAT_KEY ShortText \
7
7
  --default_tokenizer TokenBigram \
8
8
  --normalizer NormalizerAuto
9
9
  column_create terms posts_body COLUMN_INDEX|WITH_POSITION posts body
10
+
11
+ table_create ages TABLE_HASH_KEY UInt32