hstore_accessor 0.9.3 → 1.0.0
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 +4 -4
- data/hstore_accessor.gemspec +1 -1
- data/lib/hstore_accessor.rb +2 -2
- data/lib/hstore_accessor/active_record_4.2/type_helpers.rb +1 -1
- data/lib/hstore_accessor/{active_record_pre_4.2 → active_record_<_4.2}/time_helper.rb +0 -0
- data/lib/hstore_accessor/{active_record_pre_4.2 → active_record_<_4.2}/type_helpers.rb +1 -1
- data/lib/hstore_accessor/macro.rb +3 -6
- data/lib/hstore_accessor/serialization.rb +0 -8
- data/lib/hstore_accessor/version.rb +1 -1
- data/spec/hstore_accessor_spec.rb +6 -104
- data/spec/spec_helper.rb +0 -8
- metadata +6 -7
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3b755ac2d804d78400da381e4cad63a68647145
|
4
|
+
data.tar.gz: 7737c2ce560de5ab95fd750234bd7293386b1ab6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 099b5d22584a1734c72760a026dd42898be87ed7d0df5bd2abc0be60d742df11efa341cb6596c3618524db9bf6d0fd5358a98d1d29fed9429d5fb47c2b5da2e2
|
7
|
+
data.tar.gz: eb978d8c446b53413fd04737a920e7961d61481687cf2de0235c588fc22469c0db949ee4e55e901ef1e388fec2baf8e16d7ae7a96d149696ede082027189e6e6
|
data/hstore_accessor.gemspec
CHANGED
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency "rubocop"
|
32
32
|
spec.add_development_dependency "shoulda-matchers"
|
33
33
|
|
34
|
-
spec.post_install_message = "Please note that the `array` and `hash` types
|
34
|
+
spec.post_install_message = "Please note that the `array` and `hash` types are no longer supported in version 1.0.0"
|
35
35
|
end
|
data/lib/hstore_accessor.rb
CHANGED
@@ -5,8 +5,8 @@ require "hstore_accessor/version"
|
|
5
5
|
if ::ActiveRecord::VERSION::STRING.to_f >= 4.2
|
6
6
|
require "hstore_accessor/active_record_4.2/type_helpers"
|
7
7
|
else
|
8
|
-
require "hstore_accessor/
|
9
|
-
require "hstore_accessor/
|
8
|
+
require "hstore_accessor/active_record_<_4.2/type_helpers"
|
9
|
+
require "hstore_accessor/active_record_<_4.2/time_helper"
|
10
10
|
end
|
11
11
|
|
12
12
|
require "hstore_accessor/serialization"
|
File without changes
|
@@ -92,7 +92,7 @@ module HstoreAccessor
|
|
92
92
|
hstore_changes = send("#{hstore_attribute}_change")
|
93
93
|
return if hstore_changes.nil?
|
94
94
|
attribute_changes = hstore_changes.map { |change| change.try(:[], store_key.to_s) }
|
95
|
-
attribute_changes.
|
95
|
+
attribute_changes.compact.present? ? attribute_changes : nil
|
96
96
|
end
|
97
97
|
|
98
98
|
define_method("restore_#{key}!") do
|
@@ -115,8 +115,8 @@ module HstoreAccessor
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
query_field = "#{
|
119
|
-
eq_query_field = "#{
|
118
|
+
query_field = "#{hstore_attribute} -> '#{store_key}'"
|
119
|
+
eq_query_field = "#{hstore_attribute} @> hstore('#{store_key}', ?)"
|
120
120
|
|
121
121
|
case data_type
|
122
122
|
when :string
|
@@ -144,9 +144,6 @@ module HstoreAccessor
|
|
144
144
|
when :boolean
|
145
145
|
send(:scope, "is_#{key}", -> { where(eq_query_field, "true") })
|
146
146
|
send(:scope, "not_#{key}", -> { where(eq_query_field, "false") })
|
147
|
-
when :array
|
148
|
-
send(:scope, "#{key}_eq", -> value { where("#{query_field} = ?", value.join(Serialization::SEPARATOR)) })
|
149
|
-
send(:scope, "#{key}_contains", -> value { where("string_to_array(#{query_field}, '#{Serialization::SEPARATOR}') @> string_to_array(?, '#{Serialization::SEPARATOR}')", Array[value].flatten.join(Serialization::SEPARATOR)) })
|
150
147
|
end
|
151
148
|
end
|
152
149
|
|
@@ -3,13 +3,11 @@ module HstoreAccessor
|
|
3
3
|
InvalidDataTypeError = Class.new(StandardError)
|
4
4
|
|
5
5
|
VALID_TYPES = [
|
6
|
-
:array,
|
7
6
|
:boolean,
|
8
7
|
:date,
|
9
8
|
:datetime,
|
10
9
|
:decimal,
|
11
10
|
:float,
|
12
|
-
:hash,
|
13
11
|
:integer,
|
14
12
|
:string
|
15
13
|
]
|
@@ -17,24 +15,18 @@ module HstoreAccessor
|
|
17
15
|
DEFAULT_SERIALIZER = ->(value) { value.to_s }
|
18
16
|
DEFAULT_DESERIALIZER = DEFAULT_SERIALIZER
|
19
17
|
|
20
|
-
SEPARATOR = "||;||"
|
21
|
-
|
22
18
|
SERIALIZERS = {
|
23
|
-
array: -> value { (value && value.join(SEPARATOR)) || nil },
|
24
19
|
boolean: -> value { (value.to_s == "true").to_s },
|
25
20
|
date: -> value { value && value.to_s },
|
26
|
-
hash: -> value { (value && value.to_json) || nil },
|
27
21
|
datetime: -> value { value && value.to_i }
|
28
22
|
}
|
29
23
|
SERIALIZERS.default = DEFAULT_SERIALIZER
|
30
24
|
|
31
25
|
DESERIALIZERS = {
|
32
|
-
array: -> value { (value && value.split(SEPARATOR)) || nil },
|
33
26
|
boolean: -> value { TypeHelpers.cast(:boolean, value) },
|
34
27
|
date: -> value { value && Date.parse(value) },
|
35
28
|
decimal: -> value { value && BigDecimal.new(value) },
|
36
29
|
float: -> value { value && value.to_f },
|
37
|
-
hash: -> value { (value && JSON.parse(value)) || nil },
|
38
30
|
integer: -> value { value && value.to_i },
|
39
31
|
datetime: -> value { value && Time.at(value.to_i).in_time_zone }
|
40
32
|
}
|
@@ -2,17 +2,13 @@ require "spec_helper"
|
|
2
2
|
require "active_support/all"
|
3
3
|
|
4
4
|
FIELDS = {
|
5
|
-
name: :string,
|
6
5
|
color: :string,
|
7
6
|
price: :integer,
|
8
7
|
published: { data_type: :boolean, store_key: "p" },
|
9
8
|
weight: { data_type: :float, store_key: "w" },
|
10
9
|
popular: :boolean,
|
11
10
|
build_timestamp: :datetime,
|
12
|
-
tags: :array,
|
13
|
-
reviews: :hash,
|
14
11
|
released_at: :date,
|
15
|
-
likes: :integer,
|
16
12
|
miles: :decimal
|
17
13
|
}
|
18
14
|
|
@@ -20,15 +16,9 @@ DATA_FIELDS = {
|
|
20
16
|
color_data: :string
|
21
17
|
}
|
22
18
|
|
23
|
-
class ProductCategory < ActiveRecord::Base
|
24
|
-
hstore_accessor :options, name: :string, likes: :integer
|
25
|
-
has_many :products
|
26
|
-
end
|
27
|
-
|
28
19
|
class Product < ActiveRecord::Base
|
29
20
|
hstore_accessor :options, FIELDS
|
30
21
|
hstore_accessor :data, DATA_FIELDS
|
31
|
-
belongs_to :product_category
|
32
22
|
end
|
33
23
|
|
34
24
|
class SuperProduct < Product
|
@@ -85,7 +75,7 @@ describe HstoreAccessor do
|
|
85
75
|
let!(:timestamp) { Time.now }
|
86
76
|
let!(:datestamp) { Date.today }
|
87
77
|
let(:product) { Product.new }
|
88
|
-
let(:persisted_product) { Product.create!(color: "green", price: 10, weight: 10.1,
|
78
|
+
let(:persisted_product) { Product.create!(color: "green", price: 10, weight: 10.1, popular: true, build_timestamp: (timestamp - 10.days), released_at: (datestamp - 8.days), miles: BigDecimal.new("9.133790001")) }
|
89
79
|
|
90
80
|
FIELDS.keys.each do |field|
|
91
81
|
it "responds with nil when #{field} is not set" do
|
@@ -155,35 +145,9 @@ describe HstoreAccessor do
|
|
155
145
|
describe "scopes" do
|
156
146
|
let!(:timestamp) { Time.now }
|
157
147
|
let!(:datestamp) { Date.today }
|
158
|
-
let!(:product_a) { Product.create(
|
159
|
-
let!(:product_b) { Product.create(color: "orange", price: 20, weight: 20.2,
|
160
|
-
let!(:product_c) { Product.create(color: "blue", price: 30, weight: 30.3,
|
161
|
-
|
162
|
-
context "ambiguous column names" do
|
163
|
-
let!(:product_category) { ProductCategory.create!(name: "widget", likes: 2) }
|
164
|
-
|
165
|
-
before do
|
166
|
-
Product.all.to_a.each do |product|
|
167
|
-
product_category.products << product
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
context "eq query" do
|
172
|
-
let!(:query) { Product.all.joins(:product_category).merge(ProductCategory.with_name("widget")).with_name("widget") }
|
173
|
-
|
174
|
-
it "qualifies the table name to prevent ambiguous column name references" do
|
175
|
-
expect { query.to_a }.to_not raise_error
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
context "query" do
|
180
|
-
let!(:query) { Product.all.joins(:product_category).merge(ProductCategory.likes_lt(4)).likes_lt(4) }
|
181
|
-
|
182
|
-
it "qualifies the table name to prevent ambiguous column name references" do
|
183
|
-
expect { query.to_a }.to_not raise_error
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
148
|
+
let!(:product_a) { Product.create(color: "green", price: 10, weight: 10.1, popular: true, build_timestamp: (timestamp - 10.days), released_at: (datestamp - 8.days), miles: BigDecimal.new("10.113379001")) }
|
149
|
+
let!(:product_b) { Product.create(color: "orange", price: 20, weight: 20.2, popular: false, build_timestamp: (timestamp - 5.days), released_at: (datestamp - 4.days), miles: BigDecimal.new("20.213379001")) }
|
150
|
+
let!(:product_c) { Product.create(color: "blue", price: 30, weight: 30.3, popular: true, build_timestamp: timestamp, released_at: datestamp, miles: BigDecimal.new("30.313379001")) }
|
187
151
|
|
188
152
|
context "for string fields support" do
|
189
153
|
it "equality" do
|
@@ -257,20 +221,7 @@ describe HstoreAccessor do
|
|
257
221
|
end
|
258
222
|
end
|
259
223
|
|
260
|
-
context "for
|
261
|
-
it "equality" do
|
262
|
-
expect(Product.tags_eq(%w(tag1 tag2 tag3)).to_a).to eq [product_a]
|
263
|
-
end
|
264
|
-
|
265
|
-
it "contains" do
|
266
|
-
expect(Product.tags_contains("tag2").to_a).to eq [product_a, product_b]
|
267
|
-
expect(Product.tags_contains(%w(tag2 tag3)).to_a).to eq [product_a, product_b]
|
268
|
-
expect(Product.tags_contains(%w(tag1 tag2 tag3)).to_a).to eq [product_a]
|
269
|
-
expect(Product.tags_contains(%w(tag1 tag2 tag3 tag4)).to_a).to eq []
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
context "for time fields support" do
|
224
|
+
context "for datetime fields support" do
|
274
225
|
it "before" do
|
275
226
|
expect(Product.build_timestamp_before(timestamp)).to eq [product_a, product_b]
|
276
227
|
end
|
@@ -357,8 +308,6 @@ describe HstoreAccessor do
|
|
357
308
|
it_returns_the_properly_typed_column :datetime, :build_timestamp, ActiveRecord::Type::DateTime
|
358
309
|
it_returns_the_properly_typed_column :date, :released_at, ActiveRecord::Type::Date
|
359
310
|
it_returns_the_properly_typed_column :decimal, :miles, ActiveRecord::Type::Decimal
|
360
|
-
it_returns_the_properly_typed_column :array, :tags, ActiveRecord::Type::Value
|
361
|
-
it_returns_the_properly_typed_column :hash, :reviews, ActiveRecord::Type::Value
|
362
311
|
else
|
363
312
|
def self.it_returns_the_properly_typed_column(hstore_type, attribute_name, active_record_type)
|
364
313
|
context "#{hstore_type}" do
|
@@ -422,39 +371,6 @@ describe HstoreAccessor do
|
|
422
371
|
expect(product.weight).to eq 93.45
|
423
372
|
end
|
424
373
|
|
425
|
-
context "array values" do
|
426
|
-
it "correctly stores nothing" do
|
427
|
-
product.tags = nil
|
428
|
-
product.save
|
429
|
-
product.reload
|
430
|
-
expect(product.tags).to be_nil
|
431
|
-
end
|
432
|
-
|
433
|
-
it "correctly stores strings" do
|
434
|
-
product.tags = ["household", "living room", "kitchen"]
|
435
|
-
product.save
|
436
|
-
product.reload
|
437
|
-
expect(product.tags).to eq ["household", "living room", "kitchen"]
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
context "hash values" do
|
442
|
-
it "correctly stores nothing" do
|
443
|
-
product.reviews = nil
|
444
|
-
product.save
|
445
|
-
product.reload
|
446
|
-
expect(product.reviews).to be_nil
|
447
|
-
end
|
448
|
-
|
449
|
-
it "correctly stores hash values as json" do
|
450
|
-
hash = product.reviews = { "user_123" => "4 stars", "user_994" => "3 stars" }
|
451
|
-
product.save
|
452
|
-
product.reload
|
453
|
-
expect(product.reviews).to eq("user_123" => "4 stars", "user_994" => "3 stars")
|
454
|
-
expect(product.options["reviews"]).to eq(hash.to_json)
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
374
|
context "multipart values" do
|
459
375
|
it "stores multipart dates correctly" do
|
460
376
|
product.update_attributes!(
|
@@ -493,7 +409,7 @@ describe HstoreAccessor do
|
|
493
409
|
product.save!
|
494
410
|
product.reload
|
495
411
|
Time.use_zone(new_york_timezone) do
|
496
|
-
expect(product.build_timestamp.
|
412
|
+
expect(product.build_timestamp.utc_offset).to eq new_york_timezone.utc_offset
|
497
413
|
end
|
498
414
|
end
|
499
415
|
end
|
@@ -676,14 +592,12 @@ describe HstoreAccessor do
|
|
676
592
|
product.color = "GREEN"
|
677
593
|
expect(product.color_change).to eq %w(ORANGE GREEN)
|
678
594
|
end
|
679
|
-
|
680
595
|
context "when store_key differs from key" do
|
681
596
|
it "returns the old and new values" do
|
682
597
|
product.weight = 100.01
|
683
598
|
expect(product.weight_change[1]).to eq "100.01"
|
684
599
|
end
|
685
600
|
end
|
686
|
-
|
687
601
|
context "hstore attribute was nil" do
|
688
602
|
it "returns old and new values" do
|
689
603
|
product.options = nil
|
@@ -700,18 +614,6 @@ describe HstoreAccessor do
|
|
700
614
|
product.price = 6
|
701
615
|
expect(product.color_change).to be_nil
|
702
616
|
end
|
703
|
-
|
704
|
-
it "returns nil when other attributes were changed" do
|
705
|
-
product.price = 5
|
706
|
-
product.save!
|
707
|
-
product = Product.first
|
708
|
-
|
709
|
-
expect(product.price_change).to be_nil
|
710
|
-
|
711
|
-
product.color = "red"
|
712
|
-
|
713
|
-
expect(product.price_change).to be_nil
|
714
|
-
end
|
715
617
|
end
|
716
618
|
|
717
619
|
context "not persisted" do
|
data/spec/spec_helper.rb
CHANGED
@@ -26,7 +26,6 @@ def create_database
|
|
26
26
|
|
27
27
|
ActiveRecord::Base.connection.execute("CREATE EXTENSION hstore;") rescue ActiveRecord::StatementInvalid
|
28
28
|
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS products;")
|
29
|
-
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS product_categories;")
|
30
29
|
|
31
30
|
ActiveRecord::Base.connection.create_table(:products) do |t|
|
32
31
|
t.hstore :options
|
@@ -34,18 +33,11 @@ def create_database
|
|
34
33
|
|
35
34
|
t.string :string_type
|
36
35
|
t.integer :integer_type
|
37
|
-
t.integer :product_category_id
|
38
36
|
t.boolean :boolean_type
|
39
37
|
t.float :float_type
|
40
38
|
t.time :time_type
|
41
|
-
t.string :array_type, array: true
|
42
39
|
t.date :date_type
|
43
40
|
t.datetime :datetime_type
|
44
41
|
t.decimal :decimal_type
|
45
|
-
t.hstore :hash_type
|
46
|
-
end
|
47
|
-
|
48
|
-
ActiveRecord::Base.connection.create_table(:product_categories) do |t|
|
49
|
-
t.hstore :options
|
50
42
|
end
|
51
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hstore_accessor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Hirn
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2015-
|
15
|
+
date: 2015-02-10 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activerecord
|
@@ -181,7 +181,6 @@ extra_rdoc_files: []
|
|
181
181
|
files:
|
182
182
|
- ".gitignore"
|
183
183
|
- ".rubocop.yml"
|
184
|
-
- ".ruby-version"
|
185
184
|
- Appraisals
|
186
185
|
- Gemfile
|
187
186
|
- LICENSE.txt
|
@@ -193,8 +192,8 @@ files:
|
|
193
192
|
- hstore_accessor.gemspec
|
194
193
|
- lib/hstore_accessor.rb
|
195
194
|
- lib/hstore_accessor/active_record_4.2/type_helpers.rb
|
196
|
-
- lib/hstore_accessor/
|
197
|
-
- lib/hstore_accessor/
|
195
|
+
- lib/hstore_accessor/active_record_<_4.2/time_helper.rb
|
196
|
+
- lib/hstore_accessor/active_record_<_4.2/type_helpers.rb
|
198
197
|
- lib/hstore_accessor/macro.rb
|
199
198
|
- lib/hstore_accessor/serialization.rb
|
200
199
|
- lib/hstore_accessor/version.rb
|
@@ -204,8 +203,8 @@ homepage: http://github.com/devmynd/hstore_accessor
|
|
204
203
|
licenses:
|
205
204
|
- MIT
|
206
205
|
metadata: {}
|
207
|
-
post_install_message: Please note that the `array` and `hash` types
|
208
|
-
|
206
|
+
post_install_message: Please note that the `array` and `hash` types are no longer
|
207
|
+
supported in version 1.0.0
|
209
208
|
rdoc_options: []
|
210
209
|
require_paths:
|
211
210
|
- lib
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.1.5
|