eload_select 0.0.1
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.
- data/LICENSE +20 -0
- data/README +13 -0
- data/Rakefile +71 -0
- data/init.rb +1 -0
- data/lib/eload_select.rb +132 -0
- metadata +58 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Blythe Dunham
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#this is based on
|
2
|
+
#http://dev.rubyonrails.org/ticket/5371
|
3
|
+
#and the patch 7147
|
4
|
+
#http://dev.rubyonrails.org/attachment/ticket/7147/options_select_working_with_eager_loading.diff
|
5
|
+
#
|
6
|
+
#Enhanced to let you apply database functions to columns. These columns will be placed in the attributes of the base class
|
7
|
+
#
|
8
|
+
# ex. Contact.find :first, :include => :account, :select => 'now(), account.name, 123, "YOUR MOM" as blah'
|
9
|
+
# returns a record where the now(), 123, and YOUR MOM is placed in contact['now()'] => "12007-07-09 blah', contact['123'] => '123', contact['blah'] => "YOUR MOM"
|
10
|
+
# contact.account.name will return the account name
|
11
|
+
#
|
12
|
+
# Also adding support for pre_sql, post_sql, keywords
|
13
|
+
#
|
data/Rakefile
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/contrib/sshpublisher'
|
5
|
+
|
6
|
+
PKG_NAME = "eload_select"
|
7
|
+
PKG_VERSION = "0.0.1"
|
8
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
9
|
+
RUBY_FORGE_PROJECT = "eload_select"
|
10
|
+
|
11
|
+
spec = Gem::Specification.new do |s|
|
12
|
+
s.name = PKG_NAME
|
13
|
+
s.version = PKG_VERSION
|
14
|
+
s.platform = Gem::Platform::RUBY
|
15
|
+
s.summary = "Eager Loader Select Supporter forces :select to play nice with :include when eagerly loading ActiveRecord data with associations."
|
16
|
+
s.files = FileList["{lib,tasks}/**/*"].to_a + %w(init.rb LICENSE Rakefile README)
|
17
|
+
s.require_path = "lib"
|
18
|
+
s.autorequire = PKG_NAME
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.test_files = nil
|
21
|
+
s.add_dependency "rails", ">= 1.2.0"
|
22
|
+
|
23
|
+
s.author = "Blythe Dunham"
|
24
|
+
s.email = "blythe@spongecell.com"
|
25
|
+
s.homepage = "http://spongetech.wordpress.com/"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Default: run unit tests.'
|
29
|
+
task :default => :test
|
30
|
+
|
31
|
+
desc 'Test the ar_test plugin.'
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << '.\lib'
|
34
|
+
t.pattern = 'test/**/*_test.rb'
|
35
|
+
t.verbose = true
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'Generate documentation for the ar_test plugin.'
|
39
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
40
|
+
rdoc.rdoc_dir = 'rdoc'
|
41
|
+
rdoc.title = 'ArP'
|
42
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
43
|
+
rdoc.rdoc_files.include('README')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
46
|
+
|
47
|
+
Rake::GemPackageTask.new(spec) do |p|
|
48
|
+
p.gem_spec = spec
|
49
|
+
p.need_tar = true
|
50
|
+
p.need_zip = true
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Publish the API docs and gem"
|
54
|
+
task :publish => [:pdoc, :release]
|
55
|
+
|
56
|
+
desc "Publish the release files to RubyForge."
|
57
|
+
task :release => [:gem, :package] do
|
58
|
+
require 'rubyforge'
|
59
|
+
|
60
|
+
options = {"cookie_jar" => RubyForge::COOKIE_F}
|
61
|
+
options["password"] = ENV["RUBY_FORGE_PASSWORD"] if ENV["RUBY_FORGE_PASSWORD"]
|
62
|
+
ruby_forge = RubyForge.new
|
63
|
+
ruby_forge.login
|
64
|
+
|
65
|
+
%w( gem tgz zip ).each do |ext|
|
66
|
+
file = "pkg/#{PKG_FILE_NAME}.#{ext}"
|
67
|
+
puts "Releasing #{File.basename(file)}..."
|
68
|
+
|
69
|
+
ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
|
70
|
+
end
|
71
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'eload_select'
|
data/lib/eload_select.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
#this is based on
|
2
|
+
#http://dev.rubyonrails.org/ticket/5371
|
3
|
+
#and the patch 7147
|
4
|
+
#http://dev.rubyonrails.org/attachment/ticket/7147/options_select_working_with_eager_loading.diff
|
5
|
+
#
|
6
|
+
#Enhanced to let you apply database functions to columns. These columns will be placed in the attributes of the base class
|
7
|
+
#
|
8
|
+
# ex. Contact.find :first, :include => :account, :select => 'now(), account.name, 123, "YOUR MOM" as blah'
|
9
|
+
# returns a record where the now(), 123, and YOUR MOM is placed in contact['now()'] => "12007-07-09 blah', contact['123'] => '123', contact['blah'] => "YOUR MOM"
|
10
|
+
# contact.account.name will return the account name
|
11
|
+
#
|
12
|
+
# Also adding support for pre_sql, post_sql, keywords
|
13
|
+
#
|
14
|
+
|
15
|
+
module ActiveRecord
|
16
|
+
module Associations
|
17
|
+
class HasManyThroughAssociation < AssociationProxy #:nodoc:
|
18
|
+
def find(*args)
|
19
|
+
options = Base.send(:extract_options_from_args!, args)
|
20
|
+
|
21
|
+
conditions = "#{@finder_sql}"
|
22
|
+
if sanitized_conditions = sanitize_sql(options[:conditions])
|
23
|
+
conditions << " AND (#{sanitized_conditions})"
|
24
|
+
end
|
25
|
+
options[:conditions] = conditions
|
26
|
+
|
27
|
+
if options[:order] && @reflection.options[:order]
|
28
|
+
options[:order] = "#{options[:order]}, #{@reflection.options[:order]}"
|
29
|
+
elsif @reflection.options[:order]
|
30
|
+
options[:order] = @reflection.options[:order]
|
31
|
+
end
|
32
|
+
|
33
|
+
options[:from] ||= construct_from
|
34
|
+
options[:joins] = construct_joins(options[:joins])
|
35
|
+
options[:include] = @reflection.source_reflection.options[:include] if options[:include].nil?
|
36
|
+
options[:select]||= @reflection.options[:select]||("#{@reflection.table_name}.*" unless options[:include])
|
37
|
+
|
38
|
+
merge_options_from_reflection!(options)
|
39
|
+
|
40
|
+
# Pass through args exactly as we received them.
|
41
|
+
args << options
|
42
|
+
@reflection.klass.find(*args)
|
43
|
+
end
|
44
|
+
end #HasManyThroughAssociation
|
45
|
+
|
46
|
+
|
47
|
+
module ClassMethods
|
48
|
+
|
49
|
+
def construct_finder_sql_with_included_associations_with_eager_select(options, join_dependency)
|
50
|
+
scope = scope(:find)
|
51
|
+
sql = "SELECT "
|
52
|
+
sql << construct_select_sql((scope && scope[:select]) || options[:select], join_dependency)
|
53
|
+
sql << " FROM #{(scope && scope[:from]) || options[:from] || table_name} "
|
54
|
+
sql << join_dependency.join_associations.collect{|join| join.association_join }.join
|
55
|
+
|
56
|
+
add_joins!(sql, options, scope)
|
57
|
+
add_conditions!(sql, options[:conditions], scope)
|
58
|
+
add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit])
|
59
|
+
|
60
|
+
sql << "GROUP BY #{options[:group]} " if options[:group]
|
61
|
+
|
62
|
+
add_order!(sql, options[:order], scope)
|
63
|
+
add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections)
|
64
|
+
add_lock!(sql, options, scope)
|
65
|
+
|
66
|
+
return sanitize_sql(sql)
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :construct_finder_sql_with_included_associations, :construct_finder_sql_with_included_associations_with_eager_select
|
70
|
+
|
71
|
+
def columns_for_eager_loading(select_options, join_dependency)
|
72
|
+
additional_columns = []
|
73
|
+
selected_column_map = select_options.split(',').inject({}) {|selected_column_map, column|
|
74
|
+
column.scan(/^\s*((\S+)\.)?(\S+)(\s+AS\s+(\S+))?\s*$/i) do
|
75
|
+
if ($5 || $2.nil?)
|
76
|
+
additional_columns << [$3, $5, column.strip]
|
77
|
+
else
|
78
|
+
selected_column_map[$2]||= []
|
79
|
+
selected_column_map[$2] << $3
|
80
|
+
end
|
81
|
+
end
|
82
|
+
selected_column_map
|
83
|
+
}
|
84
|
+
|
85
|
+
join_dependency.joins.each{|join|
|
86
|
+
join.column_names_with_alias(selected_column_map.delete(join.aliased_table_name) || [])
|
87
|
+
}
|
88
|
+
|
89
|
+
standard_columns = column_aliases(join_dependency)
|
90
|
+
additional_columns.concat(selected_column_map.values) unless selected_column_map.blank?
|
91
|
+
|
92
|
+
join_dependency.join_base.additional_aliased_columns(additional_columns)
|
93
|
+
|
94
|
+
additional_columns << [standard_columns] unless standard_columns.blank?
|
95
|
+
additional_columns.collect{|column_name| column_name.last}.join(', ')
|
96
|
+
end
|
97
|
+
|
98
|
+
def construct_select_sql(selected, join_dependency)
|
99
|
+
select_sql = (selected && selected.strip != '*' ?
|
100
|
+
columns_for_eager_loading(selected, join_dependency) :
|
101
|
+
column_aliases(join_dependency))
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
class JoinDependency
|
107
|
+
class JoinBase
|
108
|
+
def additional_aliased_columns(additional_columns=[])
|
109
|
+
additional_columns.each {|(column, alias_name, full_data)| @column_names_with_alias << [alias_name || column, alias_name || column] }
|
110
|
+
end
|
111
|
+
|
112
|
+
def column_names_with_alias(eager_loaded_columns=nil)
|
113
|
+
|
114
|
+
unless @column_names_with_alias
|
115
|
+
eager_loaded_columns = column_names if eager_loaded_columns.nil? || eager_loaded_columns.include?('*')
|
116
|
+
eager_loaded_columns = ([primary_key] + (eager_loaded_columns - [primary_key]))
|
117
|
+
@column_names_with_alias = []
|
118
|
+
eager_loaded_columns.each_with_index do |column_name, i|
|
119
|
+
@column_names_with_alias << [column_name, "#{ aliased_prefix }_r#{ i }"]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
return @column_names_with_alias
|
123
|
+
end
|
124
|
+
end#JoinBase
|
125
|
+
end#JoinDependency
|
126
|
+
end#ClassMethods
|
127
|
+
end#Associations
|
128
|
+
end#ActiveRecord
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: eload_select
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-08-09 00:00:00 -07:00
|
8
|
+
summary: Eager Loader Select Supporter forces :select to play nice with :include when eagerly loading ActiveRecord data with associations.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: blythe@spongecell.com
|
12
|
+
homepage: http://spongetech.wordpress.com/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: eload_select
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Blythe Dunham
|
31
|
+
files:
|
32
|
+
- lib/eload_select.rb
|
33
|
+
- init.rb
|
34
|
+
- LICENSE
|
35
|
+
- Rakefile
|
36
|
+
- README
|
37
|
+
test_files: []
|
38
|
+
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
dependencies:
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rails
|
52
|
+
version_requirement:
|
53
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 1.2.0
|
58
|
+
version:
|