slim_scrooge 1.0.12 → 1.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.textile +4 -1
- data/ext/callsite_hash.c +23 -5
- data/lib/slim_scrooge.rb +3 -2
- data/lib/slim_scrooge/callsite.rb +17 -3
- data/lib/slim_scrooge/slim_scrooge.rb +32 -8
- metadata +25 -44
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4673f9a5113c3c55c2bb9bbcb2b7a3253290f23a
|
4
|
+
data.tar.gz: d2ef07ca8b1c3f1746731132db5782dbfbe93d86
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef68a0f3a7a6b9514b2a87a6daadb65a08ca7c5d479b7ee88db9d0de48c2006809ceaeb81148daa9b3607a95418726eafb1ea45d9a55bd69f5bc294c9094acea
|
7
|
+
data.tar.gz: 6cbb4b9a9c149a7327df03c78f0b748e8264375571a34c194d7d8d3b98093f889ff98311deb2582478de4b0aa934d0b448411091def26f890749d9b28a2dec88
|
data/README.textile
CHANGED
@@ -21,12 +21,13 @@ In future releases I expect further gains.
|
|
21
21
|
h2. Installation
|
22
22
|
|
23
23
|
Requirements: Rails 2.2 or above, Ruby 1.8.6 or above.
|
24
|
+
It should work ok in Rails 3.x, but please check issues. Rails 4.x untested.
|
24
25
|
|
25
26
|
h3. Gem
|
26
27
|
|
27
28
|
<pre>
|
28
29
|
# install slim_scrooge
|
29
|
-
|
30
|
+
gem install slim_scrooge
|
30
31
|
</pre>
|
31
32
|
|
32
33
|
Note that the C extension will only build in MRI Ruby 1.8 on non-windows at present, but do not worry, for other platforms the backup callsite mechanism is used.
|
@@ -115,3 +116,5 @@ h2. Authors
|
|
115
116
|
* Special thanks to Lourens Naudé (methodmissing) for the original idea, and the C implementation of callsite_hash as well as some other bits of code that I borrowed from the original project.
|
116
117
|
* Thanks to Steve Purcell for fixes and help
|
117
118
|
* Thanks to Adam Holt
|
119
|
+
* Thanks to Vitaly Kosenko
|
120
|
+
|
data/ext/callsite_hash.c
CHANGED
@@ -6,12 +6,26 @@
|
|
6
6
|
|
7
7
|
static int strhash(register const char *string) {
|
8
8
|
register int c;
|
9
|
-
register int val
|
9
|
+
register int val;
|
10
|
+
register const char* s1 = string;
|
11
|
+
register const char* s2 = string;
|
10
12
|
|
11
13
|
while ((c = *string++) != '\0') {
|
14
|
+
if (c == '/') {
|
15
|
+
if (val)
|
16
|
+
s1 = string;
|
17
|
+
else
|
18
|
+
s2 = string;
|
19
|
+
val = !val;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
if (s1 > s2) {
|
23
|
+
s1 = s2;
|
24
|
+
}
|
25
|
+
val = 0;
|
26
|
+
while ((c = *s1++) != '\0') {
|
12
27
|
val = val*997 + c;
|
13
28
|
}
|
14
|
-
|
15
29
|
return val + (val>>5);
|
16
30
|
}
|
17
31
|
|
@@ -19,6 +33,7 @@ static VALUE rb_f_callsite(VALUE obj) {
|
|
19
33
|
struct FRAME *frame = ruby_frame;
|
20
34
|
NODE *n;
|
21
35
|
int csite = 0;
|
36
|
+
int files = 0;
|
22
37
|
|
23
38
|
if (frame->last_func == ID_ALLOCATOR) frame = frame->prev;
|
24
39
|
|
@@ -26,14 +41,17 @@ static VALUE rb_f_callsite(VALUE obj) {
|
|
26
41
|
if (ruby_sourcefile) csite += strhash(ruby_sourcefile);
|
27
42
|
csite += frame->last_func + ruby_sourceline;
|
28
43
|
|
29
|
-
for (; frame && (n = frame->node); frame = frame->prev) {
|
44
|
+
for (; frame && (n = frame->node) && files < 10; frame = frame->prev) {
|
30
45
|
if (frame->prev && frame->prev->last_func) {
|
31
46
|
if (frame->prev->node == n) {
|
32
47
|
if (frame->prev->last_func == frame->last_func) continue;
|
33
48
|
}
|
34
49
|
csite += frame->prev->last_func;
|
35
50
|
}
|
36
|
-
if (n->nd_file)
|
51
|
+
if (n->nd_file) {
|
52
|
+
csite += strhash(n->nd_file);
|
53
|
+
files++;
|
54
|
+
}
|
37
55
|
csite += nd_line(n);
|
38
56
|
}
|
39
57
|
|
@@ -42,4 +60,4 @@ static VALUE rb_f_callsite(VALUE obj) {
|
|
42
60
|
|
43
61
|
void Init_callsite_hash() {
|
44
62
|
rb_define_global_function("callsite_hash", rb_f_callsite, 0);
|
45
|
-
}
|
63
|
+
}
|
data/lib/slim_scrooge.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# Author: Stephen Sykes
|
2
2
|
begin
|
3
3
|
unless File.exists?(File.join(File.dirname(__FILE__), "../", "ext", "Makefile"))
|
4
|
-
Dir.chdir(File.join(File.dirname(__FILE__), "../", "ext"))
|
5
|
-
|
4
|
+
Dir.chdir(File.join(File.dirname(__FILE__), "../", "ext")) do
|
5
|
+
`rake`
|
6
|
+
end
|
6
7
|
end
|
7
8
|
rescue Exception
|
8
9
|
end
|
@@ -25,6 +25,8 @@ module SlimScrooge
|
|
25
25
|
# Check if query can be optimised
|
26
26
|
#
|
27
27
|
def use_scrooge?(model_class, original_sql)
|
28
|
+
original_sql = original_sql.to_sql if original_sql.respond_to?(:to_sql)
|
29
|
+
|
28
30
|
original_sql =~ select_regexp(model_class.table_name) &&
|
29
31
|
model_class.columns_hash.has_key?(model_class.primary_key) &&
|
30
32
|
original_sql !~ ScroogeRegexJoin
|
@@ -54,7 +56,7 @@ module SlimScrooge
|
|
54
56
|
def essential_columns(model_class)
|
55
57
|
model_class.reflect_on_all_associations.inject([@primary_key]) do |arr, assoc|
|
56
58
|
if assoc.options[:dependent] && assoc.macro == :belongs_to
|
57
|
-
arr << assoc.primary_key_name
|
59
|
+
arr << assoc.respond_to?(:foreign_key) ? assoc.foreign_key : assoc.primary_key_name
|
58
60
|
end
|
59
61
|
arr
|
60
62
|
end
|
@@ -63,7 +65,19 @@ module SlimScrooge
|
|
63
65
|
# Returns suitable sql given a list of columns and the original query
|
64
66
|
#
|
65
67
|
def scrooged_sql(seen_columns, sql)
|
66
|
-
sql.
|
68
|
+
if sql.respond_to?(:project)
|
69
|
+
# modify the query - this is a hack that needs to be fixed
|
70
|
+
projections = sql.instance_variable_get(:@ctx).projections
|
71
|
+
select_cols = seen_columns.collect do |name|
|
72
|
+
arel_attr = projections[0].dup
|
73
|
+
arel_attr.name = name
|
74
|
+
arel_attr
|
75
|
+
end
|
76
|
+
projections.replace(select_cols)
|
77
|
+
sql
|
78
|
+
else
|
79
|
+
sql.gsub(@select_regexp, "SELECT #{scrooge_select_sql(seen_columns)} FROM")
|
80
|
+
end
|
67
81
|
end
|
68
82
|
|
69
83
|
# List if columns what were not fetched
|
@@ -76,7 +90,7 @@ module SlimScrooge
|
|
76
90
|
# in the result set, specified by primary_keys
|
77
91
|
#
|
78
92
|
def reload_sql(primary_keys, fetched_columns)
|
79
|
-
sql_keys = primary_keys.collect{|pk| "
|
93
|
+
sql_keys = primary_keys.collect{|pk| "#{connection.quote_column_name(pk)}"}.join(ScroogeComma)
|
80
94
|
cols = scrooge_select_sql(missing_columns(fetched_columns))
|
81
95
|
"SELECT #{cols} FROM #{@quoted_table_name} WHERE #{@quoted_primary_key} IN (#{sql_keys})"
|
82
96
|
end
|
@@ -4,20 +4,40 @@ module SlimScrooge
|
|
4
4
|
module FindBySql
|
5
5
|
def self.included(base)
|
6
6
|
ActiveRecord::Base.extend ClassMethods
|
7
|
+
ClassMethods.class_variable_set(:@@slim_use_arel, (base.method(:find_by_sql).arity != 1))
|
7
8
|
class << base
|
8
9
|
alias_method_chain :find_by_sql, :slim_scrooge
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
12
13
|
module ClassMethods
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
def find_by_sql_with_slim_scrooge(sql, binds = [])
|
16
|
+
return find_by_sql_with_or_without_arel(sql, binds) if sql.is_a?(Array) # don't mess with user's custom query
|
17
|
+
|
18
|
+
if @@slim_use_arel
|
19
|
+
callsite_key = SlimScrooge::Callsites.callsite_key(sql.froms.map(&:name).join)
|
20
|
+
else
|
21
|
+
callsite_key = SlimScrooge::Callsites.callsite_key(sql)
|
22
|
+
end
|
23
|
+
|
16
24
|
if SlimScrooge::Callsites.has_key?(callsite_key)
|
17
|
-
find_with_callsite_key(sql, callsite_key)
|
25
|
+
find_with_callsite_key(sql, callsite_key, binds)
|
18
26
|
elsif callsite = SlimScrooge::Callsites.create(sql, callsite_key, name) # new site that is scroogeable
|
19
|
-
|
27
|
+
if @@slim_use_arel
|
28
|
+
rows = connection.select_all(sanitize_sql(sql), "#{name} Load SlimScrooged 1st time", binds)
|
29
|
+
else
|
30
|
+
rows = connection.select_all(sql, "#{name} Load SlimScrooged 1st time")
|
31
|
+
end
|
20
32
|
rows.collect! {|row| instantiate(MonitoredHash[row, {}, callsite])}
|
33
|
+
else
|
34
|
+
find_by_sql_with_or_without_arel(sql, binds)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_by_sql_with_or_without_arel(sql, binds)
|
39
|
+
if @@slim_use_arel
|
40
|
+
find_by_sql_without_slim_scrooge(sql, binds)
|
21
41
|
else
|
22
42
|
find_by_sql_without_slim_scrooge(sql)
|
23
43
|
end
|
@@ -25,10 +45,14 @@ module SlimScrooge
|
|
25
45
|
|
26
46
|
private
|
27
47
|
|
28
|
-
def find_with_callsite_key(sql, callsite_key)
|
48
|
+
def find_with_callsite_key(sql, callsite_key, binds)
|
29
49
|
if callsite = SlimScrooge::Callsites[callsite_key]
|
30
50
|
seen_columns = callsite.seen_columns.dup # dup so cols aren't changed underneath us
|
31
|
-
|
51
|
+
if @@slim_use_arel
|
52
|
+
rows = connection.select_all(callsite.scrooged_sql(seen_columns, sql), "#{name} Load SlimScrooged", binds)
|
53
|
+
else
|
54
|
+
rows = connection.select_all(callsite.scrooged_sql(seen_columns, sql), "#{name} Load SlimScrooged")
|
55
|
+
end
|
32
56
|
rows.collect! {|row| MonitoredHash[{}, row, callsite]}
|
33
57
|
result_set = SlimScrooge::ResultSet.new(rows.dup, callsite_key, seen_columns)
|
34
58
|
rows.collect! do |row|
|
@@ -36,7 +60,7 @@ module SlimScrooge
|
|
36
60
|
instantiate(row)
|
37
61
|
end
|
38
62
|
else
|
39
|
-
|
63
|
+
find_by_sql_with_or_without_arel(sql, binds)
|
40
64
|
end
|
41
65
|
end
|
42
66
|
end
|
metadata
CHANGED
@@ -1,33 +1,24 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: slim_scrooge
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease: false
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 12
|
10
|
-
version: 1.0.12
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.14
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Stephen Sykes
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2011-09-29 00:00:00 +03:00
|
19
|
-
default_executable:
|
11
|
+
date: 2013-12-23 00:00:00.000000000 Z
|
20
12
|
dependencies: []
|
21
|
-
|
22
|
-
|
13
|
+
description: Slim scrooge boosts speed in Rails ActiveRecord Models by only querying
|
14
|
+
the database for what is needed.
|
23
15
|
email: sdsykes@gmail.com
|
24
16
|
executables: []
|
25
|
-
|
26
|
-
extensions:
|
17
|
+
extensions:
|
27
18
|
- ext/Rakefile
|
28
|
-
extra_rdoc_files:
|
19
|
+
extra_rdoc_files:
|
29
20
|
- README.textile
|
30
|
-
files:
|
21
|
+
files:
|
31
22
|
- README.textile
|
32
23
|
- Rakefile
|
33
24
|
- VERSION.yml
|
@@ -46,41 +37,31 @@ files:
|
|
46
37
|
- test/models/course.rb
|
47
38
|
- test/schema/schema.rb
|
48
39
|
- test/setup.rb
|
49
|
-
has_rdoc: true
|
50
40
|
homepage: http://github.com/sdsykes/slim_scrooge
|
51
41
|
licenses: []
|
52
|
-
|
42
|
+
metadata: {}
|
53
43
|
post_install_message:
|
54
|
-
rdoc_options:
|
44
|
+
rdoc_options:
|
55
45
|
- --charset=UTF-8
|
56
|
-
require_paths:
|
46
|
+
require_paths:
|
57
47
|
- lib
|
58
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
none: false
|
69
|
-
requirements:
|
70
|
-
- - ">="
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
hash: 3
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
version: "0"
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
76
58
|
requirements: []
|
77
|
-
|
78
59
|
rubyforge_project:
|
79
|
-
rubygems_version:
|
60
|
+
rubygems_version: 2.0.3
|
80
61
|
signing_key:
|
81
62
|
specification_version: 3
|
82
63
|
summary: Slim_scrooge - serious optimisation for ActiveRecord
|
83
|
-
test_files:
|
64
|
+
test_files:
|
84
65
|
- test/active_record_setup.rb
|
85
66
|
- test/helper.rb
|
86
67
|
- test/models/course.rb
|