ghazel-ar-extensions 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +145 -0
- data/README +169 -0
- data/Rakefile +61 -0
- data/config/database.yml +7 -0
- data/config/database.yml.template +7 -0
- data/config/mysql.schema +72 -0
- data/config/postgresql.schema +39 -0
- data/db/migrate/generic_schema.rb +97 -0
- data/db/migrate/mysql_schema.rb +32 -0
- data/db/migrate/oracle_schema.rb +5 -0
- data/db/migrate/version.rb +4 -0
- data/init.rb +31 -0
- data/lib/ar-extensions/adapters/abstract_adapter.rb +146 -0
- data/lib/ar-extensions/adapters/mysql.rb +10 -0
- data/lib/ar-extensions/adapters/oracle.rb +14 -0
- data/lib/ar-extensions/adapters/postgresql.rb +9 -0
- data/lib/ar-extensions/adapters/sqlite.rb +7 -0
- data/lib/ar-extensions/create_and_update/mysql.rb +7 -0
- data/lib/ar-extensions/create_and_update.rb +509 -0
- data/lib/ar-extensions/csv.rb +309 -0
- data/lib/ar-extensions/delete/mysql.rb +3 -0
- data/lib/ar-extensions/delete.rb +143 -0
- data/lib/ar-extensions/extensions.rb +513 -0
- data/lib/ar-extensions/finder_options/mysql.rb +6 -0
- data/lib/ar-extensions/finder_options.rb +275 -0
- data/lib/ar-extensions/finders.rb +94 -0
- data/lib/ar-extensions/foreign_keys.rb +70 -0
- data/lib/ar-extensions/fulltext/mysql.rb +44 -0
- data/lib/ar-extensions/fulltext.rb +62 -0
- data/lib/ar-extensions/import/mysql.rb +50 -0
- data/lib/ar-extensions/import/postgresql.rb +0 -0
- data/lib/ar-extensions/import/sqlite.rb +22 -0
- data/lib/ar-extensions/import.rb +348 -0
- data/lib/ar-extensions/insert_select/mysql.rb +7 -0
- data/lib/ar-extensions/insert_select.rb +178 -0
- data/lib/ar-extensions/synchronize.rb +30 -0
- data/lib/ar-extensions/temporary_table/mysql.rb +3 -0
- data/lib/ar-extensions/temporary_table.rb +131 -0
- data/lib/ar-extensions/union/mysql.rb +6 -0
- data/lib/ar-extensions/union.rb +204 -0
- data/lib/ar-extensions/util/sql_generation.rb +27 -0
- data/lib/ar-extensions/util/support_methods.rb +32 -0
- data/lib/ar-extensions/version.rb +9 -0
- data/lib/ar-extensions.rb +5 -0
- metadata +110 -0
@@ -0,0 +1,131 @@
|
|
1
|
+
module ActiveRecord::Extensions::TemporaryTableSupport # :nodoc:
|
2
|
+
def supports_temporary_tables? #:nodoc:
|
3
|
+
true
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class ActiveRecord::Base
|
8
|
+
# Returns true if the underlying database connection supports temporary tables
|
9
|
+
def self.supports_temporary_tables?
|
10
|
+
connection.supports_temporary_tables?
|
11
|
+
rescue NoMethodError
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
######################################################################
|
16
|
+
# Creates a temporary table given the passed in options hash. The
|
17
|
+
# temporary table is created based off from another table the
|
18
|
+
# current model class. This method returns the constant for the new
|
19
|
+
# new model. This can also be used with block form (see below).
|
20
|
+
#
|
21
|
+
# == Parameters
|
22
|
+
# * options - the options hash used to define the temporary table.
|
23
|
+
#
|
24
|
+
# ==== Options
|
25
|
+
# <tt>:table_name</tt>::the desired name of the temporary table. If not supplied
|
26
|
+
# then a name of "temp_" + the current table_name of the current model
|
27
|
+
# will be used.
|
28
|
+
# <tt>:like</tt>:: the table model you want to base the temporary tables
|
29
|
+
# structure off from. If this is not supplied then the table_name of the
|
30
|
+
# current model will be used.
|
31
|
+
# <tt>:model_name</tt>:: the name of the model you want to use for the temporary
|
32
|
+
# table. This must be compliant with Ruby's naming conventions for
|
33
|
+
# constants. If this is not supplied a rails-generated table name will
|
34
|
+
# be created which is based off from the table_name of the temporary table.
|
35
|
+
# IE: Account.create_temporary_table creates the TempAccount model class
|
36
|
+
#
|
37
|
+
# ==== Example 1, using defaults
|
38
|
+
#
|
39
|
+
# class Project < ActiveRecord::Base
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# > t = Project.create_temporary_table
|
43
|
+
# > t.class
|
44
|
+
# => "TempProject"
|
45
|
+
# > t.superclass
|
46
|
+
# => Project
|
47
|
+
#
|
48
|
+
# This creates a temporary table named 'temp_projects' and creates a constant
|
49
|
+
# name TempProject. The table structure is copied from the 'projects' table.
|
50
|
+
# TempProject is a subclass of Project as you would expect.
|
51
|
+
#
|
52
|
+
# ==== Example 2, using <tt>:table_name</tt> and <tt>:model options</tt>
|
53
|
+
#
|
54
|
+
# Project.create_temporary_table :table_name => 'my_projects', :model => 'MyProject'
|
55
|
+
#
|
56
|
+
# This creates a temporary table named 'my_projects' and creates a constant named
|
57
|
+
# MyProject. The table structure is copied from the 'projects' table.
|
58
|
+
#
|
59
|
+
# ==== Example 3, using <tt>:like</tt>
|
60
|
+
#
|
61
|
+
# ActiveRecord::Base.create_temporary_table :like => Project
|
62
|
+
#
|
63
|
+
# This is the same as calling Project.create_temporary_table.
|
64
|
+
#
|
65
|
+
# ==== Example 4, using block form
|
66
|
+
#
|
67
|
+
# Project.create_temporary_table do |t|
|
68
|
+
# # ...
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# Using the block form will automatically drop the temporary table
|
72
|
+
# when the block exits. +t+ which is passed into the block is the temporary
|
73
|
+
# table class. In the above example +t+ equals TempProject. The block form
|
74
|
+
# can be used with all of the available options.
|
75
|
+
#
|
76
|
+
# === See
|
77
|
+
#
|
78
|
+
# * +drop+
|
79
|
+
#
|
80
|
+
######################################################################
|
81
|
+
def self.create_temporary_table(opts={})
|
82
|
+
opts[:temporary] ||= !opts[:permanent]
|
83
|
+
opts[:like] ||= self
|
84
|
+
opts[:table_name] ||= "temp_#{self.table_name}"
|
85
|
+
opts[:model_name] ||= ActiveSupport::Inflector.classify(opts[:table_name])
|
86
|
+
|
87
|
+
if Object.const_defined?(opts[:model_name])
|
88
|
+
raise Exception, "Model #{opts[:model_name]} already exists!"
|
89
|
+
end
|
90
|
+
|
91
|
+
like_table_name = opts[:like].table_name || self.table_name
|
92
|
+
|
93
|
+
connection.execute <<-SQL
|
94
|
+
CREATE #{opts[:temporary] ? 'TEMPORARY' : ''} TABLE #{opts[:table_name]}
|
95
|
+
LIKE #{like_table_name}
|
96
|
+
SQL
|
97
|
+
|
98
|
+
# Sample evaluation:
|
99
|
+
#
|
100
|
+
# class ::TempFood < Food
|
101
|
+
# set_table_name :temp_food
|
102
|
+
#
|
103
|
+
# def self.drop
|
104
|
+
# connection.execute "DROP TABLE temp_foo"
|
105
|
+
# Object.send(:remove_const, self.name.to_sym)
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
class_eval(<<-RUBY, __FILE__, __LINE__)
|
109
|
+
class ::#{opts[:model_name]} < #{self.name}
|
110
|
+
set_table_name :#{opts[:table_name]}
|
111
|
+
|
112
|
+
def self.drop
|
113
|
+
connection.execute "DROP TABLE #{opts[:table_name]};"
|
114
|
+
Object.send(:remove_const, self.name.to_sym)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
RUBY
|
118
|
+
|
119
|
+
model = Object.const_get(opts[:model_name])
|
120
|
+
|
121
|
+
if block_given?
|
122
|
+
begin
|
123
|
+
yield(model)
|
124
|
+
ensure
|
125
|
+
model.drop
|
126
|
+
end
|
127
|
+
else
|
128
|
+
return model
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
module ActiveRecord::Extensions::Union#:nodoc:
|
2
|
+
module UnionSupport #:nodoc:
|
3
|
+
def supports_union? #:nodoc:
|
4
|
+
true
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ActiveRecord::Base
|
10
|
+
supports_extension :union
|
11
|
+
|
12
|
+
extend ActiveRecord::Extensions::SqlGeneration
|
13
|
+
class << self
|
14
|
+
# Find a union of two or more queries
|
15
|
+
# === Args
|
16
|
+
# Each argument is a hash map of options sent to <tt>:find :all</tt>
|
17
|
+
# including <tt>:conditions</tt>, <tt>:join</tt>, <tt>:group</tt>,
|
18
|
+
# <tt>:having</tt>, and <tt>:limit</tt>
|
19
|
+
#
|
20
|
+
# In addition the following options are accepted
|
21
|
+
# * <tt>:pre_sql</tt> inserts SQL before the SELECT statement of this protion of the +union+
|
22
|
+
# * <tt>:post_sql</tt> appends additional SQL to the end of the statement
|
23
|
+
# * <tt>:override_select</tt> is used to override the <tt>SELECT</tt> clause of eager loaded associations
|
24
|
+
#
|
25
|
+
# == Examples
|
26
|
+
# Find the union of a San Fran zipcode with a Seattle zipcode
|
27
|
+
# union_args1 = {:conditions => ['zip_id = ?', 94010], :select => :phone_number_id}
|
28
|
+
# union_args2 = {:conditions => ['zip_id = ?', 98102], :select => :phone_number_id}
|
29
|
+
# Contact.find_union(union_args1, union_args2, ...)
|
30
|
+
#
|
31
|
+
# SQL> (SELECT phone_number_id FROM contacts WHERE zip_id = 94010) UNION
|
32
|
+
# (SELECT phone_number_id FROM contacts WHERE zip_id = 98102) UNION ...
|
33
|
+
#
|
34
|
+
# == Global Options
|
35
|
+
# To specify global options that apply to the entire union, specify a hash as the
|
36
|
+
# first parameter with a key <tt>:union_options</tt>. Valid options include
|
37
|
+
# <tt>:group</tt>, <tt>:having</tt>, <tt>:order</tt>, and <tt>:limit</tt>
|
38
|
+
#
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
# Contact.find_union(:union_options => {:limit => 10, :order => 'created_on'},
|
42
|
+
# union_args1, union_args2, ...)
|
43
|
+
#
|
44
|
+
# SQL> ((select phone_number_id from contacts ...) UNION (select phone_number_id from contacts ...)) order by created_on limit 10
|
45
|
+
#
|
46
|
+
def find_union(*args)
|
47
|
+
supports_union!
|
48
|
+
find_by_sql(find_union_sql(*args))
|
49
|
+
end
|
50
|
+
|
51
|
+
# Count across a union of two or more queries
|
52
|
+
# === Args
|
53
|
+
# * +column_name+ - The column to count. Defaults to all ('*')
|
54
|
+
# * <tt>*args</tt> - Each additional argument is a hash map of options used by <tt>:find :all</tt>
|
55
|
+
# including <tt>:conditions</tt>, <tt>:join</tt>, <tt>:group</tt>,
|
56
|
+
# <tt>:having</tt>, and <tt>:limit</tt>
|
57
|
+
#
|
58
|
+
# In addition the following options are accepted
|
59
|
+
# * <tt>:pre_sql</tt> inserts SQL before the SELECT statement of this protion of the +union+
|
60
|
+
# * <tt>:post_sql</tt> appends additional SQL to the end of the statement
|
61
|
+
# * <tt>:override_select</tt> is used to override the <tt>SELECT</tt> clause of eager loaded associations
|
62
|
+
#
|
63
|
+
# Note that distinct is implied so a record that matches more than one
|
64
|
+
# portion of the union is counted only once.
|
65
|
+
#
|
66
|
+
# == Global Options
|
67
|
+
# To specify global options that apply to the entire union, specify a hash as the
|
68
|
+
# first parameter with a key <tt>:union_options</tt>. Valid options include
|
69
|
+
# <tt>:group</tt>, <tt>:having</tt>, <tt>:order</tt>, and <tt>:limit</tt>
|
70
|
+
#
|
71
|
+
# == Examples
|
72
|
+
# Count the number of people who live in Seattle and San Francisco
|
73
|
+
# Contact.count_union(:phone_number_id,
|
74
|
+
# {:conditions => ['zip_id = ?, 94010]'},
|
75
|
+
# {:conditions => ['zip_id = ?', 98102]})
|
76
|
+
# SQL> select count(*) from ((select phone_number_id from contacts ...) UNION (select phone_number_id from contacts ...)) as counter_tbl;
|
77
|
+
def count_union(column_name, *args)
|
78
|
+
supports_union!
|
79
|
+
count_val = calculate_union(:count, column_name, *args)
|
80
|
+
(args.length == 1 && args.first[:limit] && args.first[:limit].to_i < count_val) ? args.first[:limit].to_i : count_val
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
#do a union of specified calculation. Only for simple calculations
|
86
|
+
def calculate_union(operation, column_name, *args)#:nodoc:
|
87
|
+
union_options = remove_union_options(args)
|
88
|
+
|
89
|
+
|
90
|
+
if args.length == 1
|
91
|
+
column_name = '*' if column_name == :all
|
92
|
+
calculate(operation, column_name, args.first.update(union_options))
|
93
|
+
|
94
|
+
# For more than one map of options, count off the subquery of all the column_name fields unioned together
|
95
|
+
# For example, if column_name is phone_number_id the generated query is
|
96
|
+
# Contact.calculate_union(:count, :phone_number_id, args)
|
97
|
+
# SQL> select count(*) from
|
98
|
+
# ((select phone_number_id from contacts ...)
|
99
|
+
# UNION
|
100
|
+
# (select phone_number_id from contacts ...)) as counter_tbl
|
101
|
+
else
|
102
|
+
column_name = primary_key if column_name == :all
|
103
|
+
column = column_for column_name
|
104
|
+
column_name = "#{table_name}.#{column_name}" unless column_name.to_s.include?('.')
|
105
|
+
|
106
|
+
group_by = union_options.delete(:group)
|
107
|
+
having = union_options.delete(:having)
|
108
|
+
query_alias = union_options.delete(:query_alias)||"#{operation}_giraffe"
|
109
|
+
|
110
|
+
|
111
|
+
#aggregate_alias should be table_name_id
|
112
|
+
aggregate_alias = column_alias_for('', column_name)
|
113
|
+
#main alias is operation_table_name_id
|
114
|
+
main_aggregate_alias = column_alias_for(operation, column_name)
|
115
|
+
|
116
|
+
sql = "SELECT "
|
117
|
+
sql << (group_by ? "#{group_by}, #{operation}(#{aggregate_alias})" : "#{operation}(*)")
|
118
|
+
sql << " AS #{main_aggregate_alias}"
|
119
|
+
sql << " FROM ("
|
120
|
+
|
121
|
+
#by nature of the union the results will always be distinct, so remove distinct column here
|
122
|
+
sql << args.inject([]){|l, a|
|
123
|
+
calc = "(#{construct_calculation_sql_with_extension('', column_name, a)})"
|
124
|
+
#for group by we need to select the group by column also
|
125
|
+
calc.gsub!(" AS #{aggregate_alias}", " AS #{aggregate_alias}, #{group_by} ") if group_by
|
126
|
+
l << calc
|
127
|
+
}.join(" UNION ")
|
128
|
+
|
129
|
+
add_union_options!(sql, union_options)
|
130
|
+
|
131
|
+
sql << ") as #{query_alias}"
|
132
|
+
|
133
|
+
if group_by
|
134
|
+
#add groupings
|
135
|
+
sql << " GROUP BY #{group_by}"
|
136
|
+
sql << " HAVING #{having}" if having
|
137
|
+
|
138
|
+
calculated_data = connection.select_all(sql)
|
139
|
+
|
140
|
+
calculated_data.inject(ActiveSupport::OrderedHash.new) do |all, row|
|
141
|
+
key = type_cast_calculated_value(row[group_by], column_for(group_by.to_s))
|
142
|
+
value = row[main_aggregate_alias]
|
143
|
+
all << [key, type_cast_calculated_value(value, column_for(column), operation)]
|
144
|
+
end
|
145
|
+
|
146
|
+
else
|
147
|
+
count_by_sql(sql)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
#Add Global Union options
|
154
|
+
def add_union_options!(sql, options)#:nodoc:
|
155
|
+
sql << " GROUP BY #{options[:group]} " if options[:group]
|
156
|
+
|
157
|
+
if options[:order] || options[:limit]
|
158
|
+
scope = scope(:find)
|
159
|
+
add_order!(sql, options[:order], scope)
|
160
|
+
add_limit!(sql, options, scope)
|
161
|
+
end
|
162
|
+
sql
|
163
|
+
end
|
164
|
+
|
165
|
+
#Remove the global union options
|
166
|
+
def remove_union_options(args)#:nodoc:
|
167
|
+
args.first.is_a?(Hash) && args.first.has_key?(:union_options) ? (args.shift)[:union_options] : {}
|
168
|
+
end
|
169
|
+
|
170
|
+
def construct_calculation_sql_with_extension(operation, column_name, options)
|
171
|
+
construct_ar_extension_sql(options.merge(:command => '', :keywords => nil, :distinct => nil)) {|sql, o|
|
172
|
+
calc_sql = construct_calculation_sql(operation, column_name, options)
|
173
|
+
|
174
|
+
#this is really gross but prevents us from rewriting construct_calculation_sql
|
175
|
+
calc_sql.gsub!(/^SELECT\s/, "SELECT #{options[:keywords]} ") if options[:keywords]
|
176
|
+
|
177
|
+
sql << calc_sql
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
# Return the sql for union of the query options specified on the command line
|
182
|
+
# If the first parameter is a map containing :union_options, use these
|
183
|
+
def find_union_sql(*args)#:nodoc:
|
184
|
+
options = remove_union_options(args)
|
185
|
+
|
186
|
+
if args.length == 1
|
187
|
+
return finder_sql_to_string(args.first.update(options))
|
188
|
+
end
|
189
|
+
|
190
|
+
sql = args.inject([]) do |sql_list, union_args|
|
191
|
+
part = union_args.merge(:force_eager_load => true,
|
192
|
+
:override_select => union_args[:select]||"#{quoted_table_name}.*",
|
193
|
+
:select => nil)
|
194
|
+
sql_list << "(#{finder_sql_to_string(part)})"
|
195
|
+
sql_list
|
196
|
+
end.join(" UNION ")
|
197
|
+
|
198
|
+
|
199
|
+
add_union_options!(sql, options)
|
200
|
+
sql
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
#Extend this module on ActiveRecord to access global functions
|
3
|
+
module ActiveRecord
|
4
|
+
module Extensions
|
5
|
+
module SqlGeneration#:nodoc:
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def post_sql_statements(options)#:nodoc:
|
10
|
+
connection.post_sql_statements(quoted_table_name, options).join(' ')
|
11
|
+
end
|
12
|
+
|
13
|
+
def pre_sql_statements(options)#:nodoc:
|
14
|
+
connection.pre_sql_statements({:command => 'SELECT'}.merge(options)).join(' ').strip + " "
|
15
|
+
end
|
16
|
+
|
17
|
+
def construct_ar_extension_sql(options={}, valid_options = [], &block)#:nodoc:
|
18
|
+
options.assert_valid_keys(valid_options)if valid_options.any?
|
19
|
+
|
20
|
+
sql = pre_sql_statements(options)
|
21
|
+
yield sql, options
|
22
|
+
sql << post_sql_statements(options)
|
23
|
+
sql
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#Extend this module on ActiveRecord to access global functions
|
2
|
+
class ExtensionNotSupported < Exception; end;
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module Extensions
|
6
|
+
module SupportMethods#:nodoc:
|
7
|
+
def supports_extension(name)
|
8
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
9
|
+
def self.supports_#{name}?#:nodoc:
|
10
|
+
connection.supports_#{name}?
|
11
|
+
rescue NoMethodError
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def supports_#{name}?#:nodoc:
|
16
|
+
self.class.supports_#{name}?
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.supports_#{name}!#:nodoc:
|
20
|
+
supports_#{name}? or raise ExtensionNotSupported.new("#{name} extension is not supported. Please require the adapter file.")
|
21
|
+
end
|
22
|
+
|
23
|
+
def supports_#{name}!#:nodoc:
|
24
|
+
self.class.supports_#{name}!
|
25
|
+
end
|
26
|
+
EOS
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
ActiveRecord::Base.send :extend, ActiveRecord::Extensions::SupportMethods
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ghazel-ar-extensions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zach Dennis
|
8
|
+
- Mark Van Holstyn
|
9
|
+
- Blythe Dunham
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2010-10-28 00:00:00 -07:00
|
15
|
+
default_executable:
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: activerecord
|
19
|
+
type: :runtime
|
20
|
+
version_requirement:
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ~>
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: "2.1"
|
26
|
+
version:
|
27
|
+
description: Extends ActiveRecord functionality by adding better finder/query support, as well as supporting mass data import, foreign key, CSV and temporary tables
|
28
|
+
email: zach.dennis@gmail.com
|
29
|
+
executables: []
|
30
|
+
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files:
|
34
|
+
- README
|
35
|
+
files:
|
36
|
+
- init.rb
|
37
|
+
- db/migrate/generic_schema.rb
|
38
|
+
- db/migrate/mysql_schema.rb
|
39
|
+
- db/migrate/oracle_schema.rb
|
40
|
+
- db/migrate/version.rb
|
41
|
+
- Rakefile
|
42
|
+
- ChangeLog
|
43
|
+
- README
|
44
|
+
- config/database.yml
|
45
|
+
- config/database.yml.template
|
46
|
+
- config/mysql.schema
|
47
|
+
- config/postgresql.schema
|
48
|
+
- lib/ar-extensions/adapters/abstract_adapter.rb
|
49
|
+
- lib/ar-extensions/adapters/mysql.rb
|
50
|
+
- lib/ar-extensions/adapters/oracle.rb
|
51
|
+
- lib/ar-extensions/adapters/postgresql.rb
|
52
|
+
- lib/ar-extensions/adapters/sqlite.rb
|
53
|
+
- lib/ar-extensions/create_and_update/mysql.rb
|
54
|
+
- lib/ar-extensions/create_and_update.rb
|
55
|
+
- lib/ar-extensions/csv.rb
|
56
|
+
- lib/ar-extensions/delete/mysql.rb
|
57
|
+
- lib/ar-extensions/delete.rb
|
58
|
+
- lib/ar-extensions/extensions.rb
|
59
|
+
- lib/ar-extensions/finders.rb
|
60
|
+
- lib/ar-extensions/finder_options/mysql.rb
|
61
|
+
- lib/ar-extensions/finder_options.rb
|
62
|
+
- lib/ar-extensions/foreign_keys.rb
|
63
|
+
- lib/ar-extensions/fulltext/mysql.rb
|
64
|
+
- lib/ar-extensions/fulltext.rb
|
65
|
+
- lib/ar-extensions/import/mysql.rb
|
66
|
+
- lib/ar-extensions/import/postgresql.rb
|
67
|
+
- lib/ar-extensions/import/sqlite.rb
|
68
|
+
- lib/ar-extensions/import.rb
|
69
|
+
- lib/ar-extensions/insert_select/mysql.rb
|
70
|
+
- lib/ar-extensions/insert_select.rb
|
71
|
+
- lib/ar-extensions/synchronize.rb
|
72
|
+
- lib/ar-extensions/temporary_table/mysql.rb
|
73
|
+
- lib/ar-extensions/temporary_table.rb
|
74
|
+
- lib/ar-extensions/union/mysql.rb
|
75
|
+
- lib/ar-extensions/union.rb
|
76
|
+
- lib/ar-extensions/util/sql_generation.rb
|
77
|
+
- lib/ar-extensions/util/support_methods.rb
|
78
|
+
- lib/ar-extensions/version.rb
|
79
|
+
- lib/ar-extensions.rb
|
80
|
+
has_rdoc: true
|
81
|
+
homepage: http://www.continuousthinking.com/tags/arext
|
82
|
+
licenses: []
|
83
|
+
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options:
|
86
|
+
- --main
|
87
|
+
- README
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: "0"
|
95
|
+
version:
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: "0"
|
101
|
+
version:
|
102
|
+
requirements: []
|
103
|
+
|
104
|
+
rubyforge_project: arext
|
105
|
+
rubygems_version: 1.3.5
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: Extends ActiveRecord functionality.
|
109
|
+
test_files: []
|
110
|
+
|