methodmissing-scrooge 2.2.1 → 2.2.2
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.
- data/VERSION.yml +2 -2
- data/lib/optimizations/columns/attributes_proxy.rb +26 -19
- data/lib/optimizations/columns/macro.rb +24 -3
- data/lib/scrooge.rb +0 -1
- data/test/models/mysql_user.rb +4 -0
- data/test/scrooge_test.rb +5 -0
- metadata +5 -4
data/VERSION.yml
CHANGED
@@ -1,21 +1,30 @@
|
|
1
|
-
class Hash
|
2
|
-
|
3
|
-
# TODO: Circumvent this hack
|
4
|
-
alias_method :update_without_scrooge, :update
|
5
|
-
def update(other)
|
6
|
-
update_without_scrooge(other.to_hash)
|
7
|
-
end
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
1
|
module Scrooge
|
12
2
|
module Optimizations
|
13
3
|
module Columns
|
14
|
-
class
|
15
|
-
|
16
|
-
# Hash
|
4
|
+
class UnscroogedAttributes < Hash
|
5
|
+
|
6
|
+
# Hash container for attributes when scrooge is not used
|
17
7
|
#
|
8
|
+
|
9
|
+
def self.setup(record)
|
10
|
+
new.replace(record)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Must call to_hash - other hash may be ScroogedAttributes and
|
14
|
+
# must be fully fetched if so
|
15
|
+
#
|
16
|
+
def update(hash)
|
17
|
+
super(hash.to_hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :merge!, :update
|
21
|
+
end
|
22
|
+
|
23
|
+
class ScroogedAttributes < Hash
|
18
24
|
|
25
|
+
# Hash container for attributes with scrooge monitoring of attribute access
|
26
|
+
#
|
27
|
+
|
19
28
|
attr_accessor :callsite_signature, :scrooge_columns, :fully_fetched, :klass
|
20
29
|
|
21
30
|
def self.setup(record, scrooge_columns, klass, callsite_signature)
|
@@ -88,7 +97,7 @@ module Scrooge
|
|
88
97
|
|
89
98
|
def update(hash)
|
90
99
|
@fully_fetched = true
|
91
|
-
super
|
100
|
+
super(hash.to_hash)
|
92
101
|
end
|
93
102
|
|
94
103
|
alias_method :merge!, :update
|
@@ -107,17 +116,15 @@ module Scrooge
|
|
107
116
|
|
108
117
|
def fetch_remaining!( columns_to_fetch )
|
109
118
|
begin
|
110
|
-
|
119
|
+
remaining_attributes = fetch_record_with_remaining_columns( columns_to_fetch )
|
111
120
|
rescue ActiveRecord::RecordNotFound
|
112
121
|
raise ActiveRecord::MissingAttributeError, "scrooge cannot fetch missing attribute(s) #{columns_to_fetch.to_a.join(', ')} because record went away"
|
113
122
|
end
|
114
|
-
replace(
|
123
|
+
replace(remaining_attributes.merge(self))
|
115
124
|
end
|
116
125
|
|
117
126
|
def fetch_record_with_remaining_columns( columns_to_fetch )
|
118
|
-
@klass.
|
119
|
-
@klass.find(self[@klass.primary_key], :select=>@klass.scrooge_select_sql(columns_to_fetch))
|
120
|
-
end
|
127
|
+
@klass.scrooge_reload(self[@klass.primary_key], columns_to_fetch)
|
121
128
|
end
|
122
129
|
|
123
130
|
def interesting_for_scrooge?( attr_s )
|
@@ -51,6 +51,14 @@ module Scrooge
|
|
51
51
|
Marshal.load(str)
|
52
52
|
end
|
53
53
|
|
54
|
+
# Efficient reloading - get the hash with missing attributes directly from the
|
55
|
+
# underlying connection.
|
56
|
+
#
|
57
|
+
def scrooge_reload( p_key, missing_columns )
|
58
|
+
attributes = connection.send( :select, "SELECT #{scrooge_select_sql(missing_columns)} FROM #{quoted_table_name} WHERE #{quoted_table_name}.#{primary_key} = '#{p_key}'" ).first
|
59
|
+
attributes ? attributes : raise( ActiveRecord::RecordNotFound )
|
60
|
+
end
|
61
|
+
|
54
62
|
private
|
55
63
|
|
56
64
|
# Only scope n-1 rows by default.
|
@@ -68,10 +76,16 @@ module Scrooge
|
|
68
76
|
callsite_set = scrooge_callsite(callsite_signature).columns
|
69
77
|
sql = sql.gsub(scrooge_select_regex, "SELECT #{scrooge_select_sql(callsite_set)} FROM")
|
70
78
|
result = connection.select_all(sanitize_sql(sql), "#{name} Load Scrooged").collect! do |record|
|
71
|
-
instantiate( Scrooge::Optimizations::Columns::
|
79
|
+
instantiate( Scrooge::Optimizations::Columns::ScroogedAttributes.setup(record, callsite_set, self, callsite_signature) )
|
72
80
|
end
|
73
81
|
end
|
74
82
|
|
83
|
+
def find_by_sql_without_scrooge( sql )
|
84
|
+
result = connection.select_all(sanitize_sql(sql), "#{name} Load").collect! do |record|
|
85
|
+
instantiate( Scrooge::Optimizations::Columns::UnscroogedAttributes.setup(record) )
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
75
89
|
# Generate a regex that respects the table name as well to catch
|
76
90
|
# verbose SQL from JOINS etc.
|
77
91
|
#
|
@@ -88,17 +102,18 @@ module Scrooge
|
|
88
102
|
end
|
89
103
|
|
90
104
|
module InstanceMethods
|
91
|
-
|
105
|
+
|
92
106
|
def self.included( base )
|
93
107
|
base.alias_method_chain :delete, :scrooge
|
94
108
|
base.alias_method_chain :destroy, :scrooge
|
95
109
|
base.alias_method_chain :respond_to?, :scrooge
|
110
|
+
base.alias_method_chain :attributes_from_column_definition, :scrooge
|
96
111
|
end
|
97
112
|
|
98
113
|
# Is this instance being handled by scrooge?
|
99
114
|
#
|
100
115
|
def scrooged?
|
101
|
-
@attributes.is_a?(Scrooge::Optimizations::Columns::
|
116
|
+
@attributes.is_a?(Scrooge::Optimizations::Columns::ScroogedAttributes)
|
102
117
|
end
|
103
118
|
|
104
119
|
# Delete should fully load all the attributes before the @attributes hash is frozen
|
@@ -178,6 +193,12 @@ module Scrooge
|
|
178
193
|
def scrooge_fetch_remaining
|
179
194
|
@attributes.fetch_remaining if scrooged?
|
180
195
|
end
|
196
|
+
|
197
|
+
# New objects should get an UnscroogedAttributes as their @attributes hash
|
198
|
+
#
|
199
|
+
def attributes_from_column_definition_with_scrooge
|
200
|
+
UnscroogedAttributes.setup(attributes_from_column_definition_without_scrooge)
|
201
|
+
end
|
181
202
|
|
182
203
|
end
|
183
204
|
|
data/lib/scrooge.rb
CHANGED
data/test/models/mysql_user.rb
CHANGED
data/test/scrooge_test.rb
CHANGED
@@ -63,6 +63,11 @@ class ScroogeTest < ActiveSupport::TestCase
|
|
63
63
|
user.User
|
64
64
|
end
|
65
65
|
|
66
|
+
test "should only fire after_initialize once" do
|
67
|
+
# should not raise ActiveRecord::MissingAttributeError
|
68
|
+
[:max_connections, :max_user_connections].each {|f| MysqlUser.find(:first).read_attribute(f)}
|
69
|
+
end
|
70
|
+
|
66
71
|
def first_callsite
|
67
72
|
MysqlUser.scrooge_callsites.to_a.flatten.first
|
68
73
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: methodmissing-scrooge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Lourens Naud\xC3\xA9"
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-03-
|
13
|
+
date: 2009-03-16 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -20,8 +20,9 @@ executables: []
|
|
20
20
|
|
21
21
|
extensions: []
|
22
22
|
|
23
|
-
extra_rdoc_files:
|
24
|
-
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README
|
25
|
+
- README.textile
|
25
26
|
files:
|
26
27
|
- Rakefile
|
27
28
|
- README
|