columns_on_demand 4.1.1 → 4.2.0

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: c360d877be5435f7217a91ab76ba418c519d9585
4
- data.tar.gz: 968eb4b78136d091e6a60de3f6277e8ca6d41607
3
+ metadata.gz: 0e2af8b1aaf2ba19e065727ca50a8340e15ae2da
4
+ data.tar.gz: 42febaa5ebfdbf3ad1cbee5b6263ddc9593cfa18
5
5
  SHA512:
6
- metadata.gz: 01a5390f5cd9a6ccfd8ee59bf5113b66c7babe1b03bbc5ea937ec027b210e6c45a2e7e00ba87a7646b469ea549688df36e40a2f0646e0e8cf73aac196b16fcc1
7
- data.tar.gz: 94c39a5b6e1e2f64665d1e41f7092283efa4720b0ed324cd27ee9f6be4a98704e772eec835ce941b0953cc51871fc9534db0ebbabfc5c72a83640efc33e9f6fb
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.13 and 3.1.8, on Ruby 1.8.7 and 2.0.0p0.
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-2013 Will Bryant, Sekuda Ltd, released under the MIT license
47
+ Copyright (c) 2008-2014 Will Bryant, Sekuda Ltd, released under the MIT license
@@ -8,9 +8,10 @@ module ColumnsOnDemand
8
8
  include InstanceMethods
9
9
 
10
10
  class <<self
11
- unless ActiveRecord.const_defined?(:AttributeMethods) &&
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) || !@attributes[attr_name].nil? || new_record? || columns_loaded.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
- @attributes[attr_name] = row[i]
88
+ value = row[i]
85
89
 
86
- if coder = self.class.serialized_attributes[attr_name]
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, @attributes[attr_name], :serialized)
107
+ @attributes[attr_name] = ActiveRecord::AttributeMethods::Serialization::Attribute.new(coder, value, :serialized)
99
108
  elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 1
100
- # in 2.3 an 3.0, @attributes has the serialized form; from 3.1 it has the deserialized form
101
- @attributes[attr_name] = coder.load @attributes[attr_name]
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 {|attr_name| @attributes.delete(attr_name)}
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
@@ -1,3 +1,3 @@
1
1
  module ColumnsOnDemand
2
- VERSION = '4.1.1'
2
+ VERSION = '4.2.0'
3
3
  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.1.1
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-07-16 00:00:00.000000000 Z
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.2.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.