refinerycms 0.9.6.22 → 0.9.6.23

Sign up to get free protection for your applications and to get access to all the features.
data/.yardopts CHANGED
@@ -7,7 +7,6 @@ vendor/plugins/images/**/*.rb
7
7
  vendor/plugins/authentication/**/*.rb
8
8
  vendor/plugins/dashboard/**/*.rb
9
9
  vendor/plugins/inquiries/**/*.rb
10
- vendor/plugins/news/**/*.rb
11
10
  vendor/plugins/pages/**/*.rb
12
11
  vendor/plugins/refinery/**/*.rb
13
12
  vendor/plugins/refinery_dialogs/**/*.rb
@@ -24,7 +23,6 @@ vendor/plugins/images/images.md
24
23
  vendor/plugins/authentication/authentication.md
25
24
  vendor/plugins/dashboard/dashboard.md
26
25
  vendor/plugins/inquiries/inquiries.md
27
- vendor/plugins/news/news.md
28
26
  vendor/plugins/resources/resources.md
29
27
  vendor/plugins/refinery_settings/settings.md
30
28
  license.md
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.6.22
1
+ 0.9.6.23
@@ -2,7 +2,7 @@
2
2
  RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
3
3
 
4
4
  # Specified gem version of Refinery to use when vendor/plugins/refinery/lib/refinery.rb is not present.
5
- REFINERY_GEM_VERSION = '0.9.6.22' unless defined? REFINERY_GEM_VERSION
5
+ REFINERY_GEM_VERSION = '0.9.6.23' unless defined? REFINERY_GEM_VERSION
6
6
 
7
7
  # Boot Rails
8
8
  require File.join(File.dirname(__FILE__), 'boot')
data/readme.md CHANGED
@@ -65,8 +65,7 @@ After your database exists, you'll need to install the gems that Refinery depend
65
65
 
66
66
  rake gems:install
67
67
 
68
- As of version 0.9.6.22, the news engine was extracted into a separate gem.
69
- This is found here:
68
+ Note: The news engine that was previously in Refinery's core was extracted into a separate gem / plugin to be found here:
70
69
 
71
70
  http://github.com/resolve/refinerycms-news
72
71
 
metadata CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
6
6
  - 0
7
7
  - 9
8
8
  - 6
9
- - 22
10
- version: 0.9.6.22
9
+ - 23
10
+ version: 0.9.6.23
11
11
  platform: ruby
12
12
  authors:
13
13
  - Resolve Digital
@@ -782,27 +782,6 @@ files:
782
782
  - vendor/plugins/resources/config/routes.rb
783
783
  - vendor/plugins/resources/rails/init.rb
784
784
  - vendor/plugins/resources/resources.md
785
- - vendor/plugins/slim_scrooge/README.textile
786
- - vendor/plugins/slim_scrooge/Rakefile
787
- - vendor/plugins/slim_scrooge/VERSION.yml
788
- - vendor/plugins/slim_scrooge/ext/Rakefile
789
- - vendor/plugins/slim_scrooge/ext/callsite_hash.c
790
- - vendor/plugins/slim_scrooge/ext/extconf.rb
791
- - vendor/plugins/slim_scrooge/lib/slim_scrooge.rb
792
- - vendor/plugins/slim_scrooge/lib/slim_scrooge/callsite.rb
793
- - vendor/plugins/slim_scrooge/lib/slim_scrooge/callsites.rb
794
- - vendor/plugins/slim_scrooge/lib/slim_scrooge/monitored_hash.rb
795
- - vendor/plugins/slim_scrooge/lib/slim_scrooge/result_set.rb
796
- - vendor/plugins/slim_scrooge/lib/slim_scrooge/simple_set.rb
797
- - vendor/plugins/slim_scrooge/lib/slim_scrooge/slim_scrooge.rb
798
- - vendor/plugins/slim_scrooge/rails/init.rb
799
- - vendor/plugins/slim_scrooge/slim_scrooge.gemspec
800
- - vendor/plugins/slim_scrooge/slim_scrooge_windows.gemspec
801
- - vendor/plugins/slim_scrooge/test/active_record_setup.rb
802
- - vendor/plugins/slim_scrooge/test/helper.rb
803
- - vendor/plugins/slim_scrooge/test/models/course.rb
804
- - vendor/plugins/slim_scrooge/test/schema/schema.rb
805
- - vendor/plugins/slim_scrooge/test/setup.rb
806
785
  - vendor/plugins/themes/app/helpers/themes_helper.rb
807
786
  - vendor/plugins/themes/lib/theme.rb
808
787
  - vendor/plugins/themes/lib/theme_server.rb
@@ -1,112 +0,0 @@
1
- h1. SlimScrooge - serious optimisation for activerecord
2
-
3
- h2. What is it?
4
-
5
- It's an optimization layer to ensure your application only fetches the database content needed to minimize wire traffic, excessive SQL queries and reduce conversion overheads to native Ruby types.
6
-
7
- SlimScrooge implements inline query optimisation, automatically restricting the columns fetched based on what was used during previous passes through the same part of your code.
8
-
9
- SlimScrooge is similar to (and is partly derived from) "Scrooge":http://github.com/methodmissing/scrooge but has many fewer lines of code and is faster.
10
-
11
- h2. Benchmark
12
-
13
- SlimScrooge performs best when the database is not on the same machine as your rails app. In this case the overhead of fetching unnecessary data from the database can become more important.
14
-
15
- I ran a benchmark that consisted of fetching 400 real urls (culled from the log file) from our complex web app. In this test I found a consistent *12% improvement* in performance over plain active record. Not earth-shattering, but worthwhile.
16
-
17
- Note that this result was for comparing the time taken for running complete requests through rails - of which database accesses are only one part. So the result is better than it at first sounds.
18
-
19
- In future releases I expect further gains.
20
-
21
- h2. Installation
22
-
23
- Requirements: Rails 2.2 or above, Ruby 1.8.6 or above.
24
-
25
- h3. Gem
26
-
27
- <pre>
28
- # if you haven't already, add gemcutter to your gem sources
29
- sudo gem install gemcutter
30
- gem tumble
31
- # install slim_scrooge
32
- sudo gem install slim_scrooge
33
- </pre>
34
-
35
- 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.
36
-
37
- Next add this to your Rails::Initializer section in environment.rb:
38
-
39
- <pre>
40
- config.gem 'slim_scrooge'
41
- </pre>
42
-
43
- h3. Plugin
44
-
45
- <pre>
46
- script/plugin install git://github.com/sdsykes/slim_scrooge.git
47
- </pre>
48
-
49
- h2. What it does
50
-
51
- <pre>
52
- # 1st request, sql is unchanged but columns accesses are recorded
53
- Brochure Load SlimScrooged 1st time (27.1ms) SELECT * FROM `brochures` WHERE (expires_at IS NULL)
54
-
55
- # 2nd request, only fetch columns that were used the first time
56
- Brochure Load SlimScrooged (4.5ms) SELECT `brochures`.expires_at,`brochures`.operator_id,`brochures`.id FROM
57
- `brochures` WHERE (expires_at IS NULL)
58
-
59
- # 2nd request, later in code we need another column which causes a reload of all remaining columns
60
- Brochure Reload SlimScrooged (0.6ms) `brochures`.name,`brochures`.comment,`brochures`.image_height,`brochures`.id,
61
- `brochures`.tel,`brochures`.long_comment,`brochures`.image_name,`brochures`.image_width FROM
62
- `brochures` WHERE `brochures`.id IN ('5646','5476','4562','3456','4567','7355')
63
-
64
- # 3rd request
65
- Brochure Load SlimScrooged (4.5ms) SELECT `brochures`.expires_at,`brochures`.operator_id,`brochures`.name,
66
- `brochures`.id FROM `brochures` WHERE (expires_at IS NULL)
67
- </pre>
68
-
69
- h2. Technical discussion
70
-
71
- SlimScrooge hooks in at just one particular place in ActiveRecord - and that place is the find_all_by_sql method. All select queries pass through this method.
72
-
73
- SlimScrooge is able to record each call (and where it came from in your code), and to modify queries that do SELECT * FROM en-route to the database so that they only select the rows that are actually used by that piece of code.
74
-
75
- How does SlimScrooge know which columns are actually used?
76
-
77
- It tracks them using a monitored hash - the hash is a subclass of Hash that has is instantiated with a proc for its default value. In this proc we handle any attributes that were not fetched from the DB - fetching the remaining columns as needed.
78
-
79
- In fact for efficiency, column accesses are only recorded when they are for newly accessed columns. Columns we already know about are accessed completely normally, and there is no additional overhead.
80
-
81
- h2. Caveats
82
-
83
- * It is possible to delete an object and then to try to use its attributes to access another object that perhaps must be also deleted (like the option :dependent=>:destroy in Rails associations).
84
-
85
- This situation is likely to be found rarely because SlimScrooge particularly checks for columns used by :dependent=>:destroy, but if you are doing something similar manually in your code then you may run into problems. Your attempt to access the key of the dependent object could cause a reload if the column is not already noted by SlimScrooge, and the reload will fail if you have already destroyed the parent object.
86
-
87
- * Some users have complained that running their test suite is slower when SlimScrooge is enabled. This is expected - it's doing a little more work for each query, and most queries in tests are only executed once.
88
-
89
- If it proves to be a problem, you can try this in environment.rb:
90
-
91
- <pre>
92
- config.gem 'slim_scrooge' unless Rails.env.test?
93
- </pre>
94
-
95
- I do recommend you test with SlimScrooge enabled at some point though, to make sure that everything is working as expected.
96
-
97
- h2. Tests
98
-
99
- SlimScrooge performs the full activerecord test suite without errors, except for a couple of tests that check the number of queries performed.
100
-
101
- To run the tests you need to set your database up with appropriate access for the rails user, and make activerecord_unittest and activerecord_unittest2 databases. Then run:
102
-
103
- <pre>
104
- rake test_with_active_record
105
- </pre>
106
-
107
- h2. References
108
- * "Scrooge":http://github.com/methodmissing/scrooge
109
-
110
- h2. Authors
111
- * Stephen Sykes (sdsykes)
112
- * 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.
@@ -1,29 +0,0 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'test/helper'
4
-
5
- Rake::TestTask.new(:test_with_active_record) do |t|
6
- t.libs << SlimScrooge::ActiveRecordTest::AR_TEST_SUITE
7
- t.libs << SlimScrooge::ActiveRecordTest.connection
8
- t.test_files = SlimScrooge::ActiveRecordTest.test_files
9
- t.ruby_opts = ["-r #{File.join(File.dirname(__FILE__), 'test', 'active_record_setup')}"]
10
- t.verbose = true
11
- end
12
-
13
- begin
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |s|
16
- s.name = "slim_scrooge"
17
- s.summary = "Slim_scrooge - serious optimisation for ActiveRecord"
18
- s.email = "sdsykes@gmail.com"
19
- s.homepage = "http://github.com/sdsykes/slim_scrooge"
20
- s.description = "Slim scrooge boosts speed in Rails ActiveRecord Models by only querying the database for what is needed."
21
- s.authors = ["Stephen Sykes"]
22
- s.files = FileList["[A-Z]*", "{ext,lib,test}/**/*"]
23
- s.extensions = "ext/Rakefile"
24
- end
25
- Jeweler::GemcutterTasks.new
26
- rescue LoadError
27
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://
28
- gems.github.com"
29
- end
@@ -1,5 +0,0 @@
1
- ---
2
- :patch: 5
3
- :major: 1
4
- :build:
5
- :minor: 0
@@ -1,42 +0,0 @@
1
- task :default=>[:build]
2
-
3
- task :build do
4
- # only try to install extension on non windows / MRI 1.8
5
- unless /mswin/ =~ RUBY_PLATFORM || RUBY_VERSION >= "1.9" || defined?(RUBY_ENGINE) && RUBY_ENGINE != "ruby"
6
- require 'rbconfig'
7
-
8
- ruby = File.join(Config::CONFIG["bindir"],
9
- Config::CONFIG["RUBY_INSTALL_NAME"])
10
- ruby << Config::CONFIG["EXEEXT"]
11
-
12
- # escape string in case path to ruby executable contain spaces.
13
- ruby.sub!(/.*\s.*/m, '"\&"')
14
-
15
- results = `#{ruby} extconf.rb`
16
-
17
- unless File.exist? 'Makefile'
18
- raise "Makefile not found:\n\n#{results.join "\n"}"
19
- end
20
-
21
- dest_path = ENV["RUBYARCHDIR"] || File.join(File.dirname(__FILE__), "..", "lib")
22
-
23
- mf = File.read('Makefile')
24
- mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$[^$]*/, "RUBYARCHDIR = #{dest_path}")
25
- mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$[^$]*/, "RUBYLIBDIR = #{dest_path}")
26
-
27
- File.open('Makefile', 'wb') {|f| f.print mf}
28
-
29
- make_program = ENV['make']
30
- unless make_program
31
- make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
32
- end
33
-
34
- ['', ' install'].each do |target|
35
- cmd = "#{make_program}#{target}"
36
- results << cmd + "\n"
37
- results << `#{cmd}`
38
-
39
- raise "make#{target} failed:\n\n#{results}" unless $?.success?
40
- end
41
- end
42
- end
@@ -1,5 +0,0 @@
1
- require 'mkmf'
2
-
3
- dir_config('callsite_hash')
4
-
5
- create_makefile('callsite_hash')
@@ -1,16 +0,0 @@
1
- # Author: Stephen Sykes
2
- begin
3
- unless File.exists?(File.join(File.dirname(__FILE__), "../", "ext", "Makefile"))
4
- Dir.chdir(File.join(File.dirname(__FILE__), "../", "ext"))
5
- `rake`
6
- end
7
- rescue Exception
8
- end
9
-
10
- begin; require 'callsite_hash'; rescue LoadError; end
11
- require 'slim_scrooge/simple_set'
12
- require 'slim_scrooge/callsites'
13
- require 'slim_scrooge/callsite'
14
- require 'slim_scrooge/result_set'
15
- require 'slim_scrooge/monitored_hash'
16
- require 'slim_scrooge/slim_scrooge'
@@ -1,96 +0,0 @@
1
- # Author: Stephen Sykes
2
-
3
- module SlimScrooge
4
- # A Callsite contains the list of columns that are accessed when an SQL
5
- # query is made from a particular place in the app
6
- #
7
- class Callsite
8
- ScroogeComma = ",".freeze
9
- ScroogeRegexJoin = /(?:LEFT|INNER|OUTER|CROSS)*\s*(?:STRAIGHT_JOIN|JOIN)/i
10
-
11
- attr_accessor :seen_columns
12
- attr_reader :columns_hash, :primary_key, :model_class_name
13
-
14
- class << self
15
- # Make a callsite if the query is of the right type for us to optimise
16
- #
17
- def make_callsite(model_class, original_sql)
18
- if use_scrooge?(model_class, original_sql)
19
- new(model_class)
20
- else
21
- nil
22
- end
23
- end
24
-
25
- # Check if query can be optimised
26
- #
27
- def use_scrooge?(model_class, original_sql)
28
- original_sql =~ select_regexp(model_class.table_name) &&
29
- model_class.columns_hash.has_key?(model_class.primary_key) &&
30
- original_sql !~ ScroogeRegexJoin
31
- end
32
-
33
- # The regexp that enables us to replace the * from SELECT * with
34
- # the list of columns we actually need
35
- #
36
- def select_regexp(table_name)
37
- %r{SELECT (`?(?:#{table_name})?`?.?\\*) FROM}
38
- end
39
- end
40
-
41
- def initialize(model_class)
42
- @all_columns = SimpleSet.new(model_class.column_names)
43
- @model_class_name = model_class.to_s
44
- @quoted_table_name = model_class.quoted_table_name
45
- @primary_key = model_class.primary_key
46
- @quoted_primary_key = model_class.connection.quote_column_name(@primary_key)
47
- @columns_hash = model_class.columns_hash
48
- @select_regexp = self.class.select_regexp(model_class.table_name)
49
- @seen_columns = SimpleSet.new(essential_columns(model_class))
50
- end
51
-
52
- # List of columns that should always be fetched no matter what
53
- #
54
- def essential_columns(model_class)
55
- model_class.reflect_on_all_associations.inject([@primary_key]) do |arr, assoc|
56
- if assoc.options[:dependent] && assoc.macro == :belongs_to
57
- arr << assoc.association_foreign_key
58
- end
59
- arr
60
- end
61
- end
62
-
63
- # Returns suitable sql given a list of columns and the original query
64
- #
65
- def scrooged_sql(seen_columns, sql)
66
- sql.gsub(@select_regexp, "SELECT #{scrooge_select_sql(seen_columns)} FROM")
67
- end
68
-
69
- # List if columns what were not fetched
70
- #
71
- def missing_columns(fetched_columns)
72
- (@all_columns - SimpleSet.new(fetched_columns)) << @primary_key
73
- end
74
-
75
- # Returns sql for fetching the unfetched columns for all the rows
76
- # in the result set, specified by primary_keys
77
- #
78
- def reload_sql(primary_keys, fetched_columns)
79
- sql_keys = primary_keys.collect{|pk| "'#{pk}'"}.join(ScroogeComma)
80
- cols = scrooge_select_sql(missing_columns(fetched_columns))
81
- "SELECT #{cols} FROM #{@quoted_table_name} WHERE #{@quoted_primary_key} IN (#{sql_keys})"
82
- end
83
-
84
- def connection
85
- @model_class_name.constantize.connection
86
- end
87
-
88
- # Change a set of columns into a correctly quoted comma separated list
89
- #
90
- def scrooge_select_sql(set)
91
- set.collect do |name|
92
- "#{@quoted_table_name}.#{connection.quote_column_name(name)}"
93
- end.join(ScroogeComma)
94
- end
95
- end
96
- end
@@ -1,70 +0,0 @@
1
- # Author: Stephen Sykes
2
-
3
- module SlimScrooge
4
- # Contains the complete list of callsites
5
- #
6
- class Callsites
7
- CallsitesMutex = Mutex.new
8
- @@callsites = {}
9
- ScroogeCallsiteSample = 1..16
10
-
11
- class << self
12
- # Whether we have encountered a callsite before
13
- #
14
- def has_key?(callsite_key)
15
- @@callsites.has_key?(callsite_key)
16
- end
17
-
18
- # Return the callsite for this key
19
- #
20
- def [](callsite_key)
21
- @@callsites[callsite_key]
22
- end
23
-
24
- # Fallback if you can't compile extension for some reason
25
- #
26
- begin
27
- callsite_hash
28
- rescue NameError
29
- def callsite_hash
30
- caller[ScroogeCallsiteSample].hash
31
- end
32
- end
33
-
34
- # Generate a key string - uses the portion of the query before the WHERE
35
- # together with the callsite_hash generated by callsite_hash.c
36
- #
37
- def callsite_key(sql)
38
- callsite_hash + sql.gsub(/\sWHERE.*/i, "").hash
39
- end
40
-
41
- # Create a new callsite
42
- #
43
- def create(sql, callsite_key, name)
44
- begin
45
- model_class = name.split.first.constantize
46
- rescue NameError, NoMethodError
47
- add_callsite(callsite_key, nil)
48
- else
49
- add_callsite(callsite_key, Callsite.make_callsite(model_class, sql))
50
- end
51
- end
52
-
53
- # Add a new callsite, wrap in a mutex for safety
54
- #
55
- def add_callsite(callsite_key, callsite)
56
- CallsitesMutex.synchronize do
57
- @@callsites[callsite_key] = callsite
58
- end
59
- end
60
-
61
- # Record that a column was accessed, wrap in a mutex for safety
62
- #
63
- def add_seen_column(callsite, seen_column)
64
- CallsitesMutex.synchronize do
65
- callsite.seen_columns << seen_column
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,103 +0,0 @@
1
- # Author: Stephen Sykes
2
-
3
- module SlimScrooge
4
- # A MonitoredHash allows us to return only some columns into the @attributes
5
- # of an ActiveRecord model object, but to notice when an attribute that
6
- # wasn't fetched is accessed.
7
- #
8
- # Also, when a result is first fetched for a particular callsite, we monitor
9
- # all the columns so that we can immediately learn which columns are needed.
10
- #
11
- class MonitoredHash < Hash
12
- attr_accessor :callsite, :result_set, :monitored_columns
13
-
14
- # Create a monitored hash. The unmonitored_columns are accessed like a regular
15
- # hash. The monitored columns kept separately, and new_column_access is called
16
- # before they are returned.
17
- #
18
- def self.[](monitored_columns, unmonitored_columns, callsite)
19
- hash = MonitoredHash.new {|hash, key| hash.new_column_access(key)}
20
- hash.monitored_columns = monitored_columns
21
- hash.merge!(unmonitored_columns)
22
- hash.callsite = callsite
23
- hash
24
- end
25
-
26
- # Called when an unknown column is requested, through the default proc.
27
- # If the column requested is valid, and the result set is not completely
28
- # loaded, then we reload. Otherwise just note the column with add_seen_column.
29
- #
30
- def new_column_access(name)
31
- if @callsite.columns_hash.has_key?(name)
32
- @result_set.reload! if @result_set && name != @callsite.primary_key
33
- Callsites.add_seen_column(@callsite, name)
34
- end
35
- @monitored_columns[name]
36
- end
37
-
38
- # Reload if needed before allowing assignment
39
- #
40
- def []=(name, value)
41
- if has_key?(name)
42
- return super
43
- elsif @result_set && @callsite.columns_hash.has_key?(name)
44
- @result_set.reload!
45
- Callsites.add_seen_column(@callsite, name)
46
- end
47
- @monitored_columns[name] = value
48
- end
49
-
50
- # Returns the column names
51
- #
52
- def keys
53
- @result_set ? @callsite.columns_hash.keys : super | @monitored_columns.keys
54
- end
55
-
56
- # Check for a column name
57
- #
58
- def has_key?(name)
59
- @result_set ? @callsite.columns_hash.has_key?(name) : super || @monitored_columns.has_key?(name)
60
- end
61
-
62
- alias_method :include?, :has_key?
63
-
64
- # Called by Hash#update when reload is called on an ActiveRecord object
65
- #
66
- def to_hash
67
- @result_set.reload! if @result_set
68
- @monitored_columns.merge(self)
69
- end
70
-
71
- def freeze
72
- @result_set.reload! if @result_set
73
- @monitored_columns.freeze
74
- super
75
- end
76
-
77
- # Marshal
78
- # Dump a real hash - can't dump a monitored hash due to default proc
79
- #
80
- def _dump(depth)
81
- Marshal.dump(to_hash)
82
- end
83
-
84
- def self._load(str)
85
- Marshal.load(str)
86
- end
87
- end
88
- end
89
-
90
- # We need to change the update method of Hash so that it *always* calls
91
- # to_hash. This is because it normally checks if other_hash is a kind of
92
- # Hash, and doesn't bother calling to_hash if so. But we need it to call
93
- # to_hash, because otherwise update will not get the complete columns
94
- # from a MonitoredHash
95
- #
96
- # This is not harmful - to_hash in a regular Hash just returns self.
97
- #
98
- class Hash
99
- alias_method :c_update, :update
100
- def update(other_hash, &block)
101
- c_update(other_hash.to_hash, &block)
102
- end
103
- end
@@ -1,38 +0,0 @@
1
- # Author: Stephen Sykes
2
-
3
- module SlimScrooge
4
- # A ResultSet contains all the rows found by an sql query
5
- # A call to reload! will cause all the rows in the set to be fully loaded
6
- # from the database - this should be called when a column access that hasn't previously
7
- # been seen by SlimScrooge is encountered
8
- #
9
- class ResultSet
10
- attr_reader :rows, :callsite_key
11
-
12
- def initialize(rows, callsite_key, fetched_columns)
13
- @rows = rows
14
- @callsite_key = callsite_key
15
- @fetched_columns = fetched_columns
16
- end
17
-
18
- def rows_by_key(key)
19
- @rows.inject({}) {|hash, row| hash[row[key]] = row; hash}
20
- end
21
-
22
- # Reload all the rows in the sql result at once
23
- # Reloads only those columns we didn't fetch the first time
24
- #
25
- def reload!
26
- callsite = Callsites[@callsite_key]
27
- rows_hash = rows_by_key(callsite.primary_key)
28
- sql = callsite.reload_sql(rows_hash.keys, @fetched_columns)
29
- new_rows = callsite.connection.send(:select, sql, "#{callsite.model_class_name} Reload SlimScrooged")
30
- new_rows.each do |row|
31
- if old_row = rows_hash[row[callsite.primary_key]]
32
- old_row.result_set = nil
33
- old_row.monitored_columns.merge!(row)
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,34 +0,0 @@
1
- module SlimScrooge
2
- class SimpleSet < Hash
3
- class << self
4
- # Creates a new set containing the given objects
5
- def [](*ary)
6
- new(ary)
7
- end
8
- end
9
-
10
- # Create a new SimpleSet containing the unique members of _arr_
11
- def initialize(arr = [])
12
- Array(arr).each {|x| self[x] = true}
13
- end
14
-
15
- # Add a value to the set, and return it
16
- def <<(value)
17
- self[value] = true
18
- self
19
- end
20
-
21
- # Invokes block once for each item in the set. Creates an array
22
- # containing the values returned by the block.
23
- def collect(&block)
24
- keys.collect(&block)
25
- end
26
-
27
- alias_method :to_a, :keys
28
-
29
- # Returns set after elements in other have been removed
30
- def -(other)
31
- SimpleSet.new(collect {|k| other[k] ? nil : k}.compact)
32
- end
33
- end
34
- end
@@ -1,46 +0,0 @@
1
- # Author: Stephen Sykes
2
-
3
- module SlimScrooge
4
- module FindBySql
5
- def self.included(base)
6
- ActiveRecord::Base.extend ClassMethods
7
- class << base
8
- alias_method_chain :find_by_sql, :slim_scrooge
9
- end
10
- end
11
-
12
- module ClassMethods
13
- def find_by_sql_with_slim_scrooge(sql)
14
- return find_by_sql_without_slim_scrooge(sql) if sql.is_a?(Array) # don't mess with user's custom query
15
- callsite_key = SlimScrooge::Callsites.callsite_key(sql)
16
- if SlimScrooge::Callsites.has_key?(callsite_key)
17
- find_with_callsite_key(sql, callsite_key)
18
- elsif callsite = SlimScrooge::Callsites.create(sql, callsite_key, name) # new site that is scroogeable
19
- rows = connection.select_all(sql, "#{name} Load SlimScrooged 1st time")
20
- rows.collect! {|row| instantiate(MonitoredHash[row, {}, callsite])}
21
- else
22
- find_by_sql_without_slim_scrooge(sql)
23
- end
24
- end
25
-
26
- private
27
-
28
- def find_with_callsite_key(sql, callsite_key)
29
- if callsite = SlimScrooge::Callsites[callsite_key]
30
- seen_columns = callsite.seen_columns.dup # dup so cols aren't changed underneath us
31
- rows = connection.select_all(callsite.scrooged_sql(seen_columns, sql), "#{name} Load SlimScrooged")
32
- rows.collect! {|row| MonitoredHash[{}, row, callsite]}
33
- result_set = SlimScrooge::ResultSet.new(rows.dup, callsite_key, seen_columns)
34
- rows.collect! do |row|
35
- row.result_set = result_set
36
- instantiate(row)
37
- end
38
- else
39
- find_by_sql_without_slim_scrooge(sql)
40
- end
41
- end
42
- end
43
- end
44
- end
45
-
46
- ActiveRecord::Base.send(:include, SlimScrooge::FindBySql)
@@ -1,8 +0,0 @@
1
- unless /mswin/ =~ RUBY_PLATFORM || RUBY_VERSION >= "1.9" || defined?(RUBY_ENGINE) && RUBY_ENGINE != "ruby"
2
- unless File.exists?(File.join(File.dirname(__FILE__), "..", "ext", "Makefile"))
3
- Dir.chdir(File.join(File.dirname(__FILE__), "..", "ext"))
4
- `rake`
5
- end
6
- end
7
-
8
- require 'slim_scrooge.rb'
@@ -1,62 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{slim_scrooge}
8
- s.version = "1.0.5"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Stephen Sykes"]
12
- s.date = %q{2010-02-15}
13
- s.description = %q{Slim scrooge boosts speed in Rails ActiveRecord Models by only querying the database for what is needed.}
14
- s.email = %q{sdsykes@gmail.com}
15
- s.extensions = ["ext/Rakefile"]
16
- s.extra_rdoc_files = [
17
- "README.textile"
18
- ]
19
- s.files = [
20
- "README.textile",
21
- "Rakefile",
22
- "VERSION.yml",
23
- "ext/Rakefile",
24
- "ext/callsite_hash.c",
25
- "ext/extconf.rb",
26
- "lib/slim_scrooge.rb",
27
- "lib/slim_scrooge/callsite.rb",
28
- "lib/slim_scrooge/callsites.rb",
29
- "lib/slim_scrooge/monitored_hash.rb",
30
- "lib/slim_scrooge/result_set.rb",
31
- "lib/slim_scrooge/simple_set.rb",
32
- "lib/slim_scrooge/slim_scrooge.rb",
33
- "test/active_record_setup.rb",
34
- "test/helper.rb",
35
- "test/models/course.rb",
36
- "test/schema/schema.rb",
37
- "test/setup.rb"
38
- ]
39
- s.homepage = %q{http://github.com/sdsykes/slim_scrooge}
40
- s.rdoc_options = ["--charset=UTF-8"]
41
- s.require_paths = ["lib"]
42
- s.rubygems_version = %q{1.3.5}
43
- s.summary = %q{Slim_scrooge - serious optimisation for ActiveRecord}
44
- s.test_files = [
45
- "test/active_record_setup.rb",
46
- "test/helper.rb",
47
- "test/models/course.rb",
48
- "test/schema/schema.rb",
49
- "test/setup.rb"
50
- ]
51
-
52
- if s.respond_to? :specification_version then
53
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
- s.specification_version = 3
55
-
56
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
57
- else
58
- end
59
- else
60
- end
61
- end
62
-
@@ -1,59 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{slim_scrooge}
8
- s.version = "1.0.4"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Stephen Sykes"]
12
- s.date = %q{2009-12-26}
13
- s.description = %q{Slim scrooge boosts speed in Rails ActiveRecord Models by only querying the database for what is needed.}
14
- s.email = %q{sdsykes@gmail.com}
15
-
16
- s.extra_rdoc_files = [
17
- "README.textile"
18
- ]
19
- s.files = [
20
- "README.textile",
21
- "Rakefile",
22
- "VERSION.yml",
23
- "lib/slim_scrooge.rb",
24
- "lib/slim_scrooge/callsite.rb",
25
- "lib/slim_scrooge/callsites.rb",
26
- "lib/slim_scrooge/monitored_hash.rb",
27
- "lib/slim_scrooge/result_set.rb",
28
- "lib/slim_scrooge/simple_set.rb",
29
- "lib/slim_scrooge/slim_scrooge.rb",
30
- "test/active_record_setup.rb",
31
- "test/helper.rb",
32
- "test/models/course.rb",
33
- "test/schema/schema.rb",
34
- "test/setup.rb"
35
- ]
36
- s.homepage = %q{http://github.com/sdsykes/slim_scrooge}
37
- s.rdoc_options = ["--charset=UTF-8"]
38
- s.require_paths = ["lib"]
39
- s.rubygems_version = %q{1.3.5}
40
- s.summary = %q{Slim_scrooge - serious optimisation for ActiveRecord}
41
- s.test_files = [
42
- "test/active_record_setup.rb",
43
- "test/helper.rb",
44
- "test/models/course.rb",
45
- "test/schema/schema.rb",
46
- "test/setup.rb"
47
- ]
48
-
49
- if s.respond_to? :specification_version then
50
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
- s.specification_version = 3
52
-
53
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
- else
55
- end
56
- else
57
- end
58
- end
59
-
@@ -1,3 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
2
-
3
- SlimScrooge::ActiveRecordTest.setup
@@ -1,91 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'setup')
2
- require 'active_support/test_case'
3
-
4
- module SlimScrooge
5
- class Test
6
- class << self
7
-
8
- def setup
9
- setup_constants
10
- make_sqlite_config
11
- make_sqlite_connection
12
- load_models
13
- load(SCHEMA_ROOT + "/schema.rb")
14
- require 'test/unit'
15
- end
16
-
17
- def test_files
18
- glob("#{File.dirname(__FILE__)}/**/*_test.rb")
19
- end
20
-
21
- def test_model_files
22
- %w{course}
23
- end
24
-
25
- private
26
-
27
- def setup_constants
28
- set_constant('TEST_ROOT') {File.expand_path(File.dirname(__FILE__))}
29
- set_constant('SCHEMA_ROOT') {TEST_ROOT + "/schema"}
30
- end
31
-
32
- def make_sqlite_config
33
- ActiveRecord::Base.configurations = {
34
- 'db' => {
35
- :adapter => 'sqlite3',
36
- :database => 'test_db',
37
- :timeout => 5000
38
- }
39
- }
40
- end
41
-
42
- def load_models
43
- test_model_files.each {|f| require File.join(File.dirname(__FILE__), "models", f)}
44
- end
45
-
46
- def make_sqlite_connection
47
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['db'])
48
- end
49
-
50
- def set_constant(constant)
51
- Object.const_set(constant, yield) unless Object.const_defined?(constant)
52
- end
53
-
54
- def glob(pattern)
55
- Dir.glob(pattern)
56
- end
57
- end
58
- end
59
-
60
- class ActiveRecordTest < Test
61
- class << self
62
- def setup
63
- setup_constants
64
- end
65
-
66
- def test_files
67
- glob("#{AR_TEST_SUITE}/cases/**/*_test.rb").sort
68
- end
69
-
70
- def connection
71
- File.join(AR_TEST_SUITE, 'connections', 'native_mysql')
72
- end
73
-
74
- private
75
-
76
- def setup_constants
77
- set_constant('MYSQL_DB_USER') {'rails'}
78
- set_constant('AR_TEST_SUITE') {find_active_record_test_suite}
79
- end
80
-
81
- def find_active_record_test_suite
82
- ts = ($:).grep(/activerecord/).last.split('/')
83
- ts.pop
84
- ts << 'test'
85
- ts.join('/')
86
- end
87
- end
88
-
89
- AR_TEST_SUITE = find_active_record_test_suite
90
- end
91
- end
@@ -1,2 +0,0 @@
1
- class Course < ActiveRecord::Base
2
- end
@@ -1,5 +0,0 @@
1
- ActiveRecord::Schema.define do
2
- create_table :courses, :force => true do |t|
3
- t.column :name, :string, :null => false
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- require 'rubygems'
2
- require 'active_record'
3
- require 'active_record/connection_adapters/mysql_adapter'
4
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
- require 'slim_scrooge'