slim_scrooge 1.0.12 → 1.0.14
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 +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
|