Class: SlimScrooge::Callsite
- Inherits:
-
Object
- Object
- SlimScrooge::Callsite
- Defined in:
- lib/slim_scrooge/callsite.rb
Overview
A Callsite contains the list of columns that are accessed when an SQL query is made from a particular place in the app
Constant Summary collapse
- ScroogeComma =
",".freeze
- ScroogeRegexJoin =
/(?:LEFT|INNER|OUTER|CROSS)*\s*(?:STRAIGHT_JOIN|JOIN)/i
Instance Attribute Summary collapse
-
#columns_hash ⇒ Object
readonly
Returns the value of attribute columns_hash.
-
#model_class ⇒ Object
readonly
Returns the value of attribute model_class.
-
#primary_key ⇒ Object
readonly
Returns the value of attribute primary_key.
-
#seen_columns ⇒ Object
Returns the value of attribute seen_columns.
Class Method Summary collapse
-
.make_callsite(model_class, original_sql) ⇒ Object
Make a callsite if the query is of the right type for us to optimise.
-
.select_regexp(table_name) ⇒ Object
The regexp that enables us to replace the * from SELECT * with the list of columns we actually need.
-
.use_scrooge?(model_class, original_sql) ⇒ Boolean
Check if query can be optimised.
Instance Method Summary collapse
-
#essential_columns ⇒ Object
List of columns that should always be fetched no matter what.
-
#initialize(model_class) ⇒ Callsite
constructor
A new instance of Callsite.
-
#missing_columns(fetched_columns) ⇒ Object
List if columns what were not fetched.
-
#reload_sql(primary_keys, fetched_columns) ⇒ Object
Returns sql for fetching the unfetched columns for all the rows in the result set, specified by primary_keys.
-
#scrooge_select_sql(set) ⇒ Object
Change a set of columns into a correctly quoted comma separated list.
-
#scrooged_sql(seen_columns, sql) ⇒ Object
Returns suitable sql given a list of columns and the original query.
Constructor Details
#initialize(model_class) ⇒ Callsite
Returns a new instance of Callsite.
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/slim_scrooge/callsite.rb', line 41 def initialize(model_class) @all_columns = SimpleSet.new(model_class.column_names) @model_class = model_class @quoted_table_name = model_class.quoted_table_name @primary_key = model_class.primary_key @quoted_primary_key = model_class.connection.quote_column_name(@primary_key) @columns_hash = model_class.columns_hash @select_regexp = self.class.select_regexp(model_class.table_name) @seen_columns = SimpleSet.new(essential_columns) end |
Instance Attribute Details
#columns_hash ⇒ Object (readonly)
Returns the value of attribute columns_hash.
12 13 14 |
# File 'lib/slim_scrooge/callsite.rb', line 12 def columns_hash @columns_hash end |
#model_class ⇒ Object (readonly)
Returns the value of attribute model_class.
12 13 14 |
# File 'lib/slim_scrooge/callsite.rb', line 12 def model_class @model_class end |
#primary_key ⇒ Object (readonly)
Returns the value of attribute primary_key.
12 13 14 |
# File 'lib/slim_scrooge/callsite.rb', line 12 def primary_key @primary_key end |
#seen_columns ⇒ Object
Returns the value of attribute seen_columns.
11 12 13 |
# File 'lib/slim_scrooge/callsite.rb', line 11 def seen_columns @seen_columns end |
Class Method Details
.make_callsite(model_class, original_sql) ⇒ Object
Make a callsite if the query is of the right type for us to optimise
17 18 19 20 21 22 23 |
# File 'lib/slim_scrooge/callsite.rb', line 17 def make_callsite(model_class, original_sql) if use_scrooge?(model_class, original_sql) new(model_class) else nil end end |
.select_regexp(table_name) ⇒ Object
The regexp that enables us to replace the * from SELECT * with the list of columns we actually need
36 37 38 |
# File 'lib/slim_scrooge/callsite.rb', line 36 def select_regexp(table_name) %r{SELECT (`?(?:#{table_name})?`?.?\\*) FROM} end |
.use_scrooge?(model_class, original_sql) ⇒ Boolean
Check if query can be optimised
27 28 29 30 31 |
# File 'lib/slim_scrooge/callsite.rb', line 27 def use_scrooge?(model_class, original_sql) original_sql =~ select_regexp(model_class.table_name) && model_class.columns_hash.has_key?(model_class.primary_key) && original_sql !~ ScroogeRegexJoin end |
Instance Method Details
#essential_columns ⇒ Object
List of columns that should always be fetched no matter what
54 55 56 57 58 59 60 61 |
# File 'lib/slim_scrooge/callsite.rb', line 54 def essential_columns @model_class.reflect_on_all_associations.inject([@primary_key]) do |arr, assoc| if assoc.[:dependent] && assoc.macro == :belongs_to arr << assoc.association_foreign_key end arr end end |
#missing_columns(fetched_columns) ⇒ Object
List if columns what were not fetched
71 72 73 |
# File 'lib/slim_scrooge/callsite.rb', line 71 def missing_columns(fetched_columns) (@all_columns - SimpleSet.new(fetched_columns)) << @primary_key end |
#reload_sql(primary_keys, fetched_columns) ⇒ Object
Returns sql for fetching the unfetched columns for all the rows in the result set, specified by primary_keys
78 79 80 81 82 |
# File 'lib/slim_scrooge/callsite.rb', line 78 def reload_sql(primary_keys, fetched_columns) sql_keys = primary_keys.collect{|pk| "'#{pk}'"}.join(ScroogeComma) cols = scrooge_select_sql(missing_columns(fetched_columns)) "SELECT #{cols} FROM #{@quoted_table_name} WHERE #{@quoted_primary_key} IN (#{sql_keys})" end |
#scrooge_select_sql(set) ⇒ Object
Change a set of columns into a correctly quoted comma separated list
86 87 88 89 90 |
# File 'lib/slim_scrooge/callsite.rb', line 86 def scrooge_select_sql(set) set.collect do |name| "#{@quoted_table_name}.#{@model_class.connection.quote_column_name(name)}" end.join(ScroogeComma) end |
#scrooged_sql(seen_columns, sql) ⇒ Object
Returns suitable sql given a list of columns and the original query
65 66 67 |
# File 'lib/slim_scrooge/callsite.rb', line 65 def scrooged_sql(seen_columns, sql) sql.gsub(@select_regexp, "SELECT #{scrooge_select_sql(seen_columns)} FROM") end |