columns_on_demand 4.1.1 → 4.2.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/README +2 -2
- data/lib/columns_on_demand.rb +37 -10
- data/lib/columns_on_demand/version.rb +1 -1
- data/test/columns_on_demand_test.rb +6 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e2af8b1aaf2ba19e065727ca50a8340e15ae2da
|
4
|
+
data.tar.gz: 42febaa5ebfdbf3ad1cbee5b6263ddc9593cfa18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 319c73384f3d7738430c69a5ca2c5c21c48f9c75ed1253e75c3b509b7793996607e383aaaecc9fb929dd3f3d9cd70a7f30f46b77412e93c7b392601943a51883
|
7
|
+
data.tar.gz: 392e3d12c891be2a2181994c50e53eb9c1d450f47f84c97f0ef7a65ca0a0ae8ebf9decce40029228e46265372d702e729b1d854468dcbb9f9420de148a69cbd5
|
data/README
CHANGED
@@ -21,7 +21,7 @@ Compatibility
|
|
21
21
|
|
22
22
|
Supports mysql, mysql2, postgresql, and sqlite3.
|
23
23
|
|
24
|
-
Currently tested against Rails 3.2.
|
24
|
+
Currently tested against Rails 4.2.0, 4.1.5, 4.0.9, 3.2.18 and 3.1.8, on Ruby 2.0.0.
|
25
25
|
Was also tested compatible with 2.3.14, 3.0.17.
|
26
26
|
|
27
27
|
Note that 3.0 and 3.1 have ActiveRecord regressions that will affect sqlite users.
|
@@ -44,4 +44,4 @@ class Example
|
|
44
44
|
end
|
45
45
|
|
46
46
|
|
47
|
-
Copyright (c) 2008-
|
47
|
+
Copyright (c) 2008-2014 Will Bryant, Sekuda Ltd, released under the MIT license
|
data/lib/columns_on_demand.rb
CHANGED
@@ -8,9 +8,10 @@ module ColumnsOnDemand
|
|
8
8
|
include InstanceMethods
|
9
9
|
|
10
10
|
class <<self
|
11
|
-
unless ActiveRecord
|
11
|
+
unless ActiveRecord::VERSION::MAJOR > 3 ||
|
12
|
+
(ActiveRecord.const_defined?(:AttributeMethods) &&
|
12
13
|
ActiveRecord::AttributeMethods::const_defined?(:Serialization) &&
|
13
|
-
ActiveRecord::AttributeMethods::Serialization::Attribute
|
14
|
+
ActiveRecord::AttributeMethods::Serialization::const_defined?(:Attribute))
|
14
15
|
alias_method_chain :define_read_method_for_serialized_attribute, :columns_on_demand
|
15
16
|
end
|
16
17
|
alias_method_chain :reset_column_information, :columns_on_demand
|
@@ -21,6 +22,7 @@ module ColumnsOnDemand
|
|
21
22
|
alias_method_chain :read_attribute_before_type_cast, :columns_on_demand
|
22
23
|
alias_method_chain :missing_attribute, :columns_on_demand
|
23
24
|
alias_method_chain :reload, :columns_on_demand
|
25
|
+
alias_method_chain :changed_in_place?, :columns_on_demand if ActiveRecord::AttributeMethods::Dirty.instance_methods.include?(:changed_attributes)
|
24
26
|
end
|
25
27
|
|
26
28
|
def reset_column_information_with_columns_on_demand
|
@@ -60,7 +62,7 @@ module ColumnsOnDemand
|
|
60
62
|
end
|
61
63
|
|
62
64
|
def column_loaded?(attr_name)
|
63
|
-
!columns_to_load_on_demand.include?(attr_name) ||
|
65
|
+
!columns_to_load_on_demand.include?(attr_name) || @attributes.key?(attr_name) || new_record? || columns_loaded.include?(attr_name)
|
64
66
|
end
|
65
67
|
|
66
68
|
def attributes_with_columns_on_demand
|
@@ -74,16 +76,23 @@ module ColumnsOnDemand
|
|
74
76
|
|
75
77
|
def load_attributes(*attr_names)
|
76
78
|
return if attr_names.blank?
|
79
|
+
|
77
80
|
values = self.class.connection.select_rows(
|
78
81
|
"SELECT #{attr_names.collect {|attr_name| self.class.connection.quote_column_name(attr_name)}.join(", ")}" +
|
79
82
|
" FROM #{self.class.quoted_table_name}" +
|
80
83
|
" WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{self.class.quote_value(id, self.class.columns_hash[self.class.primary_key])}")
|
81
84
|
row = values.first || raise(ActiveRecord::RecordNotFound, "Couldn't find #{self.class.name} with ID=#{id}")
|
85
|
+
|
82
86
|
attr_names.each_with_index do |attr_name, i|
|
83
87
|
columns_loaded << attr_name
|
84
|
-
|
88
|
+
value = row[i]
|
85
89
|
|
86
|
-
if
|
90
|
+
if @attributes.respond_to?(:write_from_database)
|
91
|
+
# activerecord 4.2 or later, which make it easy to replicate the normal typecasting and deserialization logic
|
92
|
+
@attributes.write_from_database(attr_name, value)
|
93
|
+
|
94
|
+
elsif coder = self.class.serialized_attributes[attr_name]
|
95
|
+
# activerecord 4.1 or earlier, with a serialized column
|
87
96
|
# for some database adapters, @column_types_override gets populated with type data from query used to load the record originally.
|
88
97
|
# this is fine, but unfortunately some special-case "decorate_columns" code in ActiveRecord will wrap those types in serialization
|
89
98
|
# objects, and it does this for each column listed in @serialized_column_names *even if they are not present in the query results*.
|
@@ -93,13 +102,19 @@ module ColumnsOnDemand
|
|
93
102
|
|
94
103
|
if ActiveRecord.const_defined?(:AttributeMethods) &&
|
95
104
|
ActiveRecord::AttributeMethods::const_defined?(:Serialization) &&
|
96
|
-
ActiveRecord::AttributeMethods::Serialization::Attribute
|
105
|
+
ActiveRecord::AttributeMethods::Serialization::const_defined?(:Attribute)
|
97
106
|
# in 3.2 @attributes has a special Attribute struct to help cache both serialized and unserialized forms
|
98
|
-
@attributes[attr_name] = ActiveRecord::AttributeMethods::Serialization::Attribute.new(coder,
|
107
|
+
@attributes[attr_name] = ActiveRecord::AttributeMethods::Serialization::Attribute.new(coder, value, :serialized)
|
99
108
|
elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 1
|
100
|
-
#
|
101
|
-
@attributes[attr_name] = coder.load
|
109
|
+
# from 3.1 it has the deserialized form
|
110
|
+
@attributes[attr_name] = coder.load value
|
111
|
+
else
|
112
|
+
# in 2.3 an 3.0, @attributes has the serialized form
|
113
|
+
@attributes[attr_name] = value
|
102
114
|
end
|
115
|
+
else
|
116
|
+
# activerecord 4.1 or earlier, with a regular unserialized column
|
117
|
+
@attributes[attr_name] = value
|
103
118
|
end
|
104
119
|
end
|
105
120
|
end
|
@@ -108,6 +123,10 @@ module ColumnsOnDemand
|
|
108
123
|
load_attributes(attr_name.to_s) unless column_loaded?(attr_name.to_s)
|
109
124
|
end
|
110
125
|
|
126
|
+
def changed_in_place_with_columns_on_demand?(attr_name)
|
127
|
+
column_loaded?(attr_name) && changed_in_place_without_columns_on_demand?(attr_name)
|
128
|
+
end
|
129
|
+
|
111
130
|
def read_attribute_with_columns_on_demand(attr_name, &block)
|
112
131
|
ensure_loaded(attr_name)
|
113
132
|
read_attribute_without_columns_on_demand(attr_name, &block)
|
@@ -129,7 +148,15 @@ module ColumnsOnDemand
|
|
129
148
|
def reload_with_columns_on_demand(*args)
|
130
149
|
reload_without_columns_on_demand(*args).tap do
|
131
150
|
columns_loaded.clear
|
132
|
-
columns_to_load_on_demand.each
|
151
|
+
columns_to_load_on_demand.each do |attr_name|
|
152
|
+
if @attributes.respond_to?(:reset)
|
153
|
+
# 4.2 and above
|
154
|
+
@attributes.reset(attr_name)
|
155
|
+
else
|
156
|
+
# 4.1 and earlier
|
157
|
+
@attributes.delete(attr_name)
|
158
|
+
end
|
159
|
+
end
|
133
160
|
end
|
134
161
|
end
|
135
162
|
end
|
@@ -24,11 +24,11 @@ end
|
|
24
24
|
|
25
25
|
class ColumnsOnDemandTest < ActiveSupport::TestCase
|
26
26
|
def assert_not_loaded(record, attr_name)
|
27
|
-
assert !record.column_loaded?(attr_name.to_s)
|
27
|
+
assert !record.column_loaded?(attr_name.to_s), "Record should not have the #{attr_name} column loaded, but did"
|
28
28
|
end
|
29
29
|
|
30
30
|
def assert_loaded(record, attr_name)
|
31
|
-
assert record.column_loaded?(attr_name.to_s)
|
31
|
+
assert record.column_loaded?(attr_name.to_s), "Record should have the #{attr_name} column loaded, but didn't"
|
32
32
|
end
|
33
33
|
|
34
34
|
def assert_queries(num = 1)
|
@@ -271,11 +271,15 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
|
|
271
271
|
assert_equal data, original_record.data
|
272
272
|
|
273
273
|
record = Serializing.first
|
274
|
+
assert_not_loaded record, "data"
|
275
|
+
assert_equal false, record.data_changed?
|
276
|
+
|
274
277
|
assert_not_loaded record, "data"
|
275
278
|
assert_equal data, record.data
|
276
279
|
assert_equal false, record.data_changed?
|
277
280
|
assert_equal false, record.changed?
|
278
281
|
assert_equal data, record.data
|
282
|
+
assert_equal data, record.data_was
|
279
283
|
|
280
284
|
record.data = "replacement"
|
281
285
|
assert_equal true, record.data_changed?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: columns_on_demand
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Will Bryant
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
version: '0'
|
158
158
|
requirements: []
|
159
159
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.
|
160
|
+
rubygems_version: 2.0.14
|
161
161
|
signing_key:
|
162
162
|
specification_version: 4
|
163
163
|
summary: Lazily loads large columns on demand.
|