groonga-client-model 0.9.8 → 0.9.9

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.
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