Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Introduce Callsite#augmented_columns && Callsite#augmented_columns?; …

…cleanup association optimizations
  • Loading branch information...
commit 3104c60b0febd1719cd4e8b2a459c84daa2fa0e5 1 parent 7f1f56b
Lourens Naudé authored
15 lib/callsite.rb
View
@@ -15,7 +15,8 @@ class Callsite
def initialize( klass, signature )
@klass = klass
@signature = signature
- @columns = setup_columns
+ @default_columns = setup_columns
+ @columns = @default_columns.dup
@associations = setup_associations
end
@@ -27,6 +28,18 @@ def column!( column )
end
end
+ # Has any columns other than the primary key or possible inheritance column been generated
+ #
+ def augmented_columns?
+ !augmented_columns.empty?
+ end
+
+ # Return all augmented ( excluding primary key or inheritance column ) columns
+ #
+ def augmented_columns
+ @columns - @default_columns
+ end
+
# Diff known associations with given includes
#
def preload( includes )
49 lib/optimizations/associations/macro.rb
View
@@ -27,7 +27,7 @@ def scrooge_installable?
module SingletonMethods
@@preloadable_associations = {}
- FindAssociatedRegex = /preload_associations|preload_one_association|find_associated_records/
+ FindAssociatedRegex = /preload_associations|preload_one_association/
def self.extended( base )
eigen = class << base; self; end
@@ -49,10 +49,7 @@ def find_with_scrooge(*args)
validate_find_options(options)
set_readonly_option!(options)
- options[:scrooge_callsite] = callsite_signature( (_caller = caller), options.except(:conditions, :limit, :offset) )
- if _caller.grep( FindAssociatedRegex ).empty?
- options[:include] = scrooge_callsite(options[:scrooge_callsite]).preload( options[:include] )
- end
+ options = scrooge_optimize_preloading!( options )
case args.first
when :first then find_initial(options)
@@ -70,7 +67,7 @@ def find_every_with_scrooge(options)
if include_associations.any? && references_eager_loaded_tables?(options)
records = find_with_associations(options)
else
- records = find_by_sql(construct_finder_sql(options), options[:scrooge_callsite])
+ records = find_by_sql(construct_finder_sql(options), options[:scrooge_callsite]) #scrooged_records_for_find_every( options )
if include_associations.any?
preload_associations(records, include_associations)
end
@@ -86,6 +83,46 @@ def find_every_with_scrooge(options)
def preloadable_associations
@@preloadable_associations[self.name] ||= reflect_on_all_associations.reject{|a| a.options[:polymorphic] || a.macro == :has_many }.map{|a| a.name }
end
+
+ private
+
+ def scrooge_optimize_preloading!( options )
+ options[:scrooge_callsite] = callsite_signature( (_caller = caller), options.except(:conditions, :limit, :offset) )
+ if should_optimize_preloading?( _caller )
+ options[:include] = scrooge_callsite(options[:scrooge_callsite]).preload( options[:include] )
+ end
+
+ if should_augment_select_options?( options )
+ options[:select] = augment_given_select_option( options )
+ end
+ options
+ end
+
+ # Should a given :select option be optimized ?
+ #
+ def should_augment_select_options?( options )
+ options[:select] && scrooge_callsite(options[:scrooge_callsite]).augmented_columns?
+ end
+
+ # Should preloading be optimized ( ignore recursion via association_preload.rb ) ?
+ #
+ def should_optimize_preloading?( call_tree )
+ call_tree.grep( FindAssociatedRegex ).empty?
+ end
+
+ # Ensure a scrooged instance for custom :select options
+ #
+ def scrooged_records_for_find_every( options )
+ if options[:select]
+ find_by_sql_with_scrooge(construct_finder_sql(options.merge!( :select => augment_given_select_option( options ) ) ), options[:scrooge_callsite])
+ else
+ find_by_sql(construct_finder_sql(options), options[:scrooge_callsite])
+ end
+ end
+
+ def augment_given_select_option( options )
+ "#{options[:select]}, #{scrooge_select_sql( scrooge_callsite( options[:scrooge_callsite] ).columns )}"
+ end
end
12 test/callsite_test.rb
View
@@ -16,6 +16,18 @@ def setup
assert_equal Scrooge::Callsite.new( MysqlUser, 123456 ).columns, Set["User","inheritance"]
end
+ test "should be able to return all augmented columns" do
+ assert_equal @callsite.augmented_columns, Set.new
+ @callsite.column! :Db
+ assert_equal @callsite.augmented_columns, Set[:Db]
+ end
+
+ test "should be able to determine if any columns has been augmented" do
+ assert !@callsite.augmented_columns?
+ @callsite.column! :Db
+ assert @callsite.augmented_columns?
+ end
+
test "should be inspectable" do
@callsite.association! :mysql_user
@callsite.column! :db
1  test/helper.rb
View
@@ -2,6 +2,7 @@
require 'rubygems'
require 'mocha'
require 'active_support/test_case'
+ENV["BACKTRACE"] = "1"
module Scrooge
class Test
4 test/optimizations/associations/macro_test.rb
View
@@ -7,6 +7,10 @@ class OptimizationsAssociationsMacroTest < ActiveSupport::TestCase
test "should flag a record as being scrooged when found through a supported SQL query" do
assert MysqlUser.find(:first).scrooged?
end
+
+ test "should always flag records via Model.find with a custom :select requirement as scrooged" do
+ assert MysqlUser.find(:first, :select => 'user.Password' ).scrooged?
+ end
test "should be able to flag any associations instantiated from a record" do
@user = MysqlUser.find(:first)
Please sign in to comment.
Something went wrong with that request. Please try again.