ar-extensions 0.5.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/ChangeLog +97 -0
- data/README +123 -0
- data/Rakefile +97 -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 +59 -0
- data/db/migrate/mysql_schema.rb +26 -0
- data/db/migrate/version.rb +4 -0
- data/init.rb +32 -0
- data/lib/ar-extensions.rb +4 -0
- data/lib/ar-extensions/adapters/abstract_adapter.rb +83 -0
- data/lib/ar-extensions/adapters/mysql_adapter.rb +14 -0
- data/lib/ar-extensions/adapters/postgresql.rb +7 -0
- data/lib/ar-extensions/csv.rb +302 -0
- data/lib/ar-extensions/extensions.rb +474 -0
- data/lib/ar-extensions/finders.rb +76 -0
- data/lib/ar-extensions/foreign_keys.rb +70 -0
- data/lib/ar-extensions/fulltext.rb +63 -0
- data/lib/ar-extensions/fulltext/mysql.rb +44 -0
- data/lib/ar-extensions/import.rb +254 -0
- data/lib/ar-extensions/import/mysql.rb +70 -0
- data/lib/ar-extensions/import/postgresql.rb +0 -0
- data/lib/ar-extensions/temporary_table.rb +124 -0
- data/lib/ar-extensions/temporary_table/mysql.rb +3 -0
- data/lib/ar-extensions/version.rb +8 -0
- metadata +83 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
module ActiveRecord::ConnectionAdapters::Quoting
|
2
|
+
|
3
|
+
alias :quote_orig :quote
|
4
|
+
def quote( value, column=nil ) # :nodoc:
|
5
|
+
if value.is_a?( Regexp )
|
6
|
+
"'#{value.inspect[1...-1]}'"
|
7
|
+
else
|
8
|
+
quote_orig( value, column )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
class ActiveRecord::Base
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
alias :sanitize_sql_orig :sanitize_sql
|
21
|
+
def sanitize_sql( arg ) # :nodoc:
|
22
|
+
return sanitize_sql_orig( arg ) if arg.nil?
|
23
|
+
if arg.respond_to?( :to_sql )
|
24
|
+
arg = sanitize_sql_by_way_of_duck_typing( arg ) #if arg.respond_to?( :to_sql )
|
25
|
+
elsif arg.is_a?( Hash )
|
26
|
+
arg = sanitize_sql_from_hash( arg ) #if arg.is_a?( Hash )
|
27
|
+
elsif arg.size == 2 and arg.first.is_a?( String ) and arg.last.is_a?( Hash )
|
28
|
+
arg = sanitize_sql_from_string_and_hash( arg ) # if arg.size == 2 and arg.first.is_a?( String ) and arg.last.is_a?( Hash )
|
29
|
+
end
|
30
|
+
sanitize_sql_orig( arg )
|
31
|
+
end
|
32
|
+
|
33
|
+
def sanitize_sql_by_way_of_duck_typing( arg ) #: nodoc:
|
34
|
+
arg.to_sql( caller )
|
35
|
+
end
|
36
|
+
|
37
|
+
def sanitize_sql_from_string_and_hash( arr ) # :nodoc:
|
38
|
+
return arr if arr.first =~ /\:[\w]+/
|
39
|
+
arr2 = sanitize_sql_from_hash( arr.last )
|
40
|
+
if arr2.empty?
|
41
|
+
conditions = arr.first
|
42
|
+
else
|
43
|
+
conditions = [ arr.first << " AND (#{arr2.first})" ]
|
44
|
+
conditions.push( *arr2[1..-1] )
|
45
|
+
end
|
46
|
+
conditions
|
47
|
+
end
|
48
|
+
|
49
|
+
def sanitize_sql_from_hash( hsh ) #:nodoc:
|
50
|
+
conditions, values = [], []
|
51
|
+
|
52
|
+
hsh.each_pair do |key,val|
|
53
|
+
if val.respond_to?( :to_sql )
|
54
|
+
conditions << sanitize_sql_by_way_of_duck_typing( val )
|
55
|
+
next
|
56
|
+
else
|
57
|
+
sql = nil
|
58
|
+
result = ActiveRecord::Extensions.process( key, val, self )
|
59
|
+
if result
|
60
|
+
conditions << result.sql if result.sql
|
61
|
+
values.push( result.value ) if result.value
|
62
|
+
else
|
63
|
+
conditions << "#{table_name}.#{connection.quote_column_name(key.to_s)} #{attribute_condition( val )} "
|
64
|
+
values << val
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
conditions = conditions.join( ' AND ' )
|
70
|
+
return [] if conditions.size == 1 and conditions.first.empty?
|
71
|
+
[ conditions, *values ]
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Enables support for enabling and disabling foreign keys
|
2
|
+
# for the underlyig database connection for ActiveRecord.
|
3
|
+
#
|
4
|
+
# This can be used with or without block form. This also
|
5
|
+
# uses the connection attached to the model.
|
6
|
+
#
|
7
|
+
# ==== Example 1, without block form
|
8
|
+
# Project.foreign_keys.disable
|
9
|
+
# Project.foreign_keys.enable
|
10
|
+
#
|
11
|
+
# If you use this form you have to manually re-enable the foreign
|
12
|
+
# keys.
|
13
|
+
#
|
14
|
+
# ==== Example 2, with block form
|
15
|
+
# Project.foreign_keys.disable do
|
16
|
+
# # ...
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Project.foreign_keys.enable do
|
20
|
+
# # ...
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# If you use the block form the foreign keys are automatically
|
24
|
+
# enabled or disabled when the block exits. This currently
|
25
|
+
# does not restore the state of foreign keys to the state before
|
26
|
+
# the block was entered.
|
27
|
+
#
|
28
|
+
# Note: If you use the disable block foreign keys
|
29
|
+
# will be enabled after the block exits. If you use the enable block foreign keys
|
30
|
+
# will be disabled after the block exits.
|
31
|
+
#
|
32
|
+
# TODO: check the external state and restore that state when using block form.
|
33
|
+
module ActiveRecord::Extensions::ForeignKeys
|
34
|
+
|
35
|
+
class ForeignKeyController # :nodoc:
|
36
|
+
attr_reader :clazz
|
37
|
+
|
38
|
+
def initialize( clazz )
|
39
|
+
@clazz = clazz
|
40
|
+
end
|
41
|
+
|
42
|
+
def disable # :nodoc:
|
43
|
+
if block_given?
|
44
|
+
disable
|
45
|
+
yield
|
46
|
+
enable
|
47
|
+
else
|
48
|
+
clazz.connection.execute "set foreign_key_checks = 0"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def enable #:nodoc:
|
53
|
+
if block_given?
|
54
|
+
enable
|
55
|
+
yield
|
56
|
+
disable
|
57
|
+
else
|
58
|
+
clazz.connection.execute "set foreign_key_checks = 1"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end #end ForeignKeyController
|
63
|
+
|
64
|
+
def foreign_keys # :nodoc:
|
65
|
+
ForeignKeyController.new( self )
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
ActiveRecord::Base.extend( ActiveRecord::Extensions::ForeignKeys )
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
# FullTextSearching provides fulltext searching capabilities
|
4
|
+
# if the underlying database adapter supports it. Currently
|
5
|
+
# only MySQL is supported.
|
6
|
+
module ActiveRecord::Extensions::FullTextSearching
|
7
|
+
|
8
|
+
module FullTextSupport # :nodoc:
|
9
|
+
def supports_full_text_searching? #:nodoc:
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class ActiveRecord::Base
|
17
|
+
class FullTextSearchingNotSupported < StandardError ; end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
# Adds fulltext searching capabilities to the current model
|
22
|
+
# for the given fulltext key and option hash.
|
23
|
+
#
|
24
|
+
# == Parameters
|
25
|
+
# * +fulltext_key+ - the key/attribute to be used to as the fulltext index
|
26
|
+
# * +options+ - the options hash.
|
27
|
+
#
|
28
|
+
# ==== Options
|
29
|
+
# * +fields+ - an array of field names to be used in the fulltext search
|
30
|
+
#
|
31
|
+
# == Example
|
32
|
+
#
|
33
|
+
# class Book < ActiveRecord::Base
|
34
|
+
# fulltext :title, :fields=>%W( title publisher author_name )
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # To use the fulltext index
|
38
|
+
# Book.find :all, :conditions=>{ :match_title => 'Zach' }
|
39
|
+
#
|
40
|
+
def fulltext( fulltext_key, options )
|
41
|
+
connection.register_fulltext_extension( fulltext_key, options )
|
42
|
+
rescue NoMethodError
|
43
|
+
logger.warn "FullTextSearching is not supported for adapter!"
|
44
|
+
raise FullTextSearchingNotSupported.new
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns true if the current connection adapter supports full
|
48
|
+
# text searching, otherwise returns false.
|
49
|
+
def supports_full_text_searching?
|
50
|
+
connection.supports_full_text_searching?
|
51
|
+
rescue NoMethodError
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# This adds FullText searching functionality for the MySQLAdapter.
|
2
|
+
class ActiveRecord::Extensions::FullTextSearching::MySQLFullTextExtension
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
class << self
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def register( fulltext_key, options ) # :nodoc:
|
9
|
+
@fulltext_registry ||= ActiveRecord::Extensions::Registry.new
|
10
|
+
@fulltext_registry.register( fulltext_key, options )
|
11
|
+
end
|
12
|
+
|
13
|
+
def registry # :nodoc:
|
14
|
+
@fulltext_registry
|
15
|
+
end
|
16
|
+
|
17
|
+
def_delegator :@fulltext_registry, :registers?, :registers?
|
18
|
+
end
|
19
|
+
|
20
|
+
RGX = /^match_(.+)/
|
21
|
+
|
22
|
+
def process( key, val, caller ) # :nodoc:
|
23
|
+
match_data = key.to_s.match( RGX )
|
24
|
+
return nil unless match_data
|
25
|
+
fulltext_identifier = match_data.captures[0].to_sym
|
26
|
+
if self.class.registers?( fulltext_identifier )
|
27
|
+
fields = self.class.registry.options( fulltext_identifier )[:fields]
|
28
|
+
str = "MATCH ( #{fields.join( ',' )} ) AGAINST (#{caller.connection.quote(val)})"
|
29
|
+
return ActiveRecord::Extensions::Result.new( str, nil )
|
30
|
+
end
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def_delegator 'ActiveRecord::Extensions::FullTextSupport::MySQLFullTextExtension', :register
|
35
|
+
end
|
36
|
+
ActiveRecord::Extensions.register ActiveRecord::Extensions::FullTextSearching::MySQLFullTextExtension.new, :adapters=>[:mysql]
|
37
|
+
|
38
|
+
class ActiveRecord::ConnectionAdapters::MysqlAdapter # :nodoc:
|
39
|
+
include ActiveRecord::Extensions::FullTextSearching::FullTextSupport
|
40
|
+
|
41
|
+
def register_fulltext_extension( fulltext_key, options ) # :nodoc:
|
42
|
+
ActiveRecord::Extensions::FullTextSearching::MySQLFullTextExtension.register( fulltext_key, options )
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
module ActiveRecord::Extensions::ConnectionAdapters ; end
|
2
|
+
|
3
|
+
module ActiveRecord::Extensions::Import #:nodoc:
|
4
|
+
|
5
|
+
module ImportSupport #:nodoc:
|
6
|
+
def supports_import? #:nodoc:
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module OnDuplicateKeyUpdateSupport #:nodoc:
|
12
|
+
def supports_on_duplicate_key_update? #:nodoc:
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class ActiveRecord::Base
|
20
|
+
class << self
|
21
|
+
|
22
|
+
# Returns true if the current database connection adapter
|
23
|
+
# supports import functionality, otherwise returns false.
|
24
|
+
def supports_import?
|
25
|
+
connection.supports_import?
|
26
|
+
rescue NoMethodError
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns true if the current database connection adapter
|
31
|
+
# supports on duplicate key update functionality, otherwise
|
32
|
+
# returns false.
|
33
|
+
def supports_on_duplicate_key_update?
|
34
|
+
connection.supports_on_duplicate_key_update?
|
35
|
+
rescue NoMethodError
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
39
|
+
# Imports a collection of values to the database.
|
40
|
+
#
|
41
|
+
# This is more efficient than using ActiveRecord::Base#create or
|
42
|
+
# ActiveRecord::Base#save multiple times. This method works well if
|
43
|
+
# you want to create more than one record at a time and do not care
|
44
|
+
# about having ActiveRecord objects returned for each record
|
45
|
+
# inserted.
|
46
|
+
#
|
47
|
+
# This can be used with or without validations. It does not utilize
|
48
|
+
# the ActiveRecord::Callbacks during creation/modification while
|
49
|
+
# performing the import.
|
50
|
+
#
|
51
|
+
# == Usage
|
52
|
+
# Model.import array_of_models
|
53
|
+
# Model.import column_names, array_of_values
|
54
|
+
# Model.import column_names, array_of_values, options
|
55
|
+
#
|
56
|
+
# ==== Model.import array_of_models
|
57
|
+
#
|
58
|
+
# With this form you can call _import_ passing in an array of model
|
59
|
+
# objects that you want updated.
|
60
|
+
#
|
61
|
+
# ==== Model.import column_names, array_of_values
|
62
|
+
#
|
63
|
+
# The first parameter +column_names+ is an array of symbols or
|
64
|
+
# strings which specify the columns that you want to update.
|
65
|
+
#
|
66
|
+
# The second parameter, +array_of_values+, is an array of
|
67
|
+
# arrays. Each subarray is a single set of values for a new
|
68
|
+
# record. The order of values in each subarray should match up to
|
69
|
+
# the order of the +column_names+.
|
70
|
+
#
|
71
|
+
# ==== Model.import column_names, array_of_values, options
|
72
|
+
#
|
73
|
+
# The first two parameters are the same as the above form. The third
|
74
|
+
# parameter, +options+, is a hash. This is optional. Please see
|
75
|
+
# below for what +options+ are available.
|
76
|
+
#
|
77
|
+
# == Options
|
78
|
+
# * +validate+ - true|false, tells import whether or not to use \
|
79
|
+
# ActiveRecord validations. Validations are enforced by default.
|
80
|
+
# * +on_duplicate_key_update+ - an Array or Hash, tells import to \
|
81
|
+
# use MySQL's ON DUPLICATE KEY UPDATE ability. See On Duplicate\
|
82
|
+
# Key Update below.
|
83
|
+
#
|
84
|
+
# == Examples
|
85
|
+
# class BlogPost < ActiveRecord::Base ; end
|
86
|
+
#
|
87
|
+
# # Example using array of model objects
|
88
|
+
# posts = [ BlogPost.new :author_name=>'Zach Dennis', :title=>'AREXT',
|
89
|
+
# BlogPost.new :author_name=>'Zach Dennis', :title=>'AREXT2',
|
90
|
+
# BlogPost.new :author_name=>'Zach Dennis', :title=>'AREXT3' ]
|
91
|
+
# BlogPost.import posts
|
92
|
+
#
|
93
|
+
# # Example using column_names and array_of_values
|
94
|
+
# columns = [ :author_name, :title ]
|
95
|
+
# values = [ [ 'zdennis', 'test post' ], [ 'jdoe', 'another test post' ] ]
|
96
|
+
# BlogPost.import columns, values
|
97
|
+
#
|
98
|
+
# # Example using column_names, array_of_value and options
|
99
|
+
# columns = [ :author_name, :title ]
|
100
|
+
# values = [ [ 'zdennis', 'test post' ], [ 'jdoe', 'another test post' ] ]
|
101
|
+
# BlogPost.import( columns, values, :validate => false )
|
102
|
+
#
|
103
|
+
# == On Duplicate Key Update (MySQL only)
|
104
|
+
#
|
105
|
+
# The :on_duplicate_key_update option can be either an Array or a Hash.
|
106
|
+
#
|
107
|
+
# ==== Using an Array
|
108
|
+
#
|
109
|
+
# The :on_duplicate_key_update option can be an array of column
|
110
|
+
# names. The column names are the only fields that are updated if
|
111
|
+
# a duplicate record is found. Below is an example:
|
112
|
+
#
|
113
|
+
# BlogPost.import columns, values, :on_duplicate_key_update=>[ :date_modified, :content, :author ]
|
114
|
+
#
|
115
|
+
# ==== Using A Hash
|
116
|
+
#
|
117
|
+
# The :on_duplicate_key_update option can be a hash of column name
|
118
|
+
# to model attribute name mappings. This gives you finer grained
|
119
|
+
# control over what fields are updated with what attributes on your
|
120
|
+
# model. Below is an example:
|
121
|
+
#
|
122
|
+
# BlogPost.import columns, attributes, :on_duplicate_key_update=>{ :title => :title }
|
123
|
+
#
|
124
|
+
def import( *args )
|
125
|
+
options = { :validate=>true }
|
126
|
+
options.merge!( args.pop ) if args.last.is_a? Hash
|
127
|
+
|
128
|
+
# assume array of model objects
|
129
|
+
if args.last.is_a?( Array ) and args.last.first.is_a? ActiveRecord::Base
|
130
|
+
if args.length == 2
|
131
|
+
models = args.last
|
132
|
+
column_names = args.first
|
133
|
+
else
|
134
|
+
models = args.first
|
135
|
+
column_names = self.column_names.dup
|
136
|
+
column_names.delete( self.primary_key ) unless options[ :on_duplicate_key_update ]
|
137
|
+
end
|
138
|
+
|
139
|
+
array_of_attributes = models.inject( [] ) do |arr,model|
|
140
|
+
attributes = []
|
141
|
+
column_names.each do |name|
|
142
|
+
attributes << model.send( "#{name}_before_type_cast" )
|
143
|
+
end
|
144
|
+
arr << attributes
|
145
|
+
end
|
146
|
+
# supports 2-element array and array
|
147
|
+
elsif args.size == 2 and args.first.is_a?( Array ) and args.last.is_a?( Array )
|
148
|
+
column_names, array_of_attributes = args
|
149
|
+
else
|
150
|
+
raise ArgumentError.new( "Invalid arguments!" )
|
151
|
+
end
|
152
|
+
|
153
|
+
is_validating = options.delete( :validate )
|
154
|
+
|
155
|
+
# dup the passed in array so we don't modify it unintentionally
|
156
|
+
array_of_attributes = array_of_attributes.dup
|
157
|
+
if is_validating
|
158
|
+
import_with_validations( column_names, array_of_attributes, options )
|
159
|
+
else
|
160
|
+
import_without_validations_or_callbacks( column_names, array_of_attributes, options )
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# TODO import_from_table needs to be implemented.
|
165
|
+
def import_from_table( options ) # :nodoc:
|
166
|
+
end
|
167
|
+
|
168
|
+
# Imports the passed in +column_names+ and +array_of_attributes+
|
169
|
+
# given the passed in +options+ Hash with validations. Returns an
|
170
|
+
# array of instances that failed validations. See
|
171
|
+
# ActiveRecord::Base.import for more information on
|
172
|
+
# +column_names+, +array_of_attributes+ and +options+.
|
173
|
+
def import_with_validations( column_names, array_of_attributes, options={} )
|
174
|
+
failed_instances = []
|
175
|
+
|
176
|
+
# create instances for each of our column/value sets
|
177
|
+
arr = validations_array_for_column_names_and_attributes( column_names, array_of_attributes )
|
178
|
+
|
179
|
+
# keep track of the instance and the position it is currently at. if this fails
|
180
|
+
# validation we'll use the index to remove it from the array_of_attributes
|
181
|
+
arr.each_with_index do |hsh,i|
|
182
|
+
instance = new( hsh )
|
183
|
+
if not instance.valid?
|
184
|
+
array_of_attributes[ i ] = nil
|
185
|
+
failed_instances << instance
|
186
|
+
end
|
187
|
+
end
|
188
|
+
array_of_attributes.compact!
|
189
|
+
|
190
|
+
if not array_of_attributes.empty?
|
191
|
+
import_without_validations_or_callbacks( column_names, array_of_attributes, options )
|
192
|
+
end
|
193
|
+
failed_instances
|
194
|
+
end
|
195
|
+
|
196
|
+
# Imports the passed in +column_names+ and +array_of_attributes+
|
197
|
+
# given the passed in +options+ Hash. This will return the number
|
198
|
+
# of insert operations it took to create these records without
|
199
|
+
# validations or callbacks. See ActiveRecord::Base.import for more
|
200
|
+
# information on +column_names+, +array_of_attributes_ and
|
201
|
+
# +options+.
|
202
|
+
def import_without_validations_or_callbacks( column_names, array_of_attributes, options={} )
|
203
|
+
escaped_column_names = quote_column_names( column_names )
|
204
|
+
columns = []
|
205
|
+
array_of_attributes.first.each_with_index { |arr,i| columns << columns_hash[ column_names[i] ] }
|
206
|
+
|
207
|
+
if not supports_import?
|
208
|
+
columns_sql = "(" + escaped_column_names.join( ',' ) + ")"
|
209
|
+
insert_statements, values = [], []
|
210
|
+
array_of_attributes.each do |arr|
|
211
|
+
my_values = []
|
212
|
+
arr.each_with_index do |val,j|
|
213
|
+
my_values << connection.quote( val, columns[j] )
|
214
|
+
end
|
215
|
+
insert_statements << "INSERT INTO #{self.table_name} #{columns_sql} VALUES(" + my_values.join( ',' ) + ")"
|
216
|
+
connection.execute( insert_statements.last )
|
217
|
+
end
|
218
|
+
return
|
219
|
+
else
|
220
|
+
|
221
|
+
# generate the sql
|
222
|
+
insert_sql = connection.multiple_value_sets_insert_sql( table_name, escaped_column_names, options )
|
223
|
+
values_sql = connection.values_sql_for_column_names_and_attributes( columns, array_of_attributes )
|
224
|
+
post_sql_statements = connection.post_sql_statements( table_name, options )
|
225
|
+
|
226
|
+
# perform the inserts
|
227
|
+
number_of_inserts = connection.insert_many(
|
228
|
+
[ insert_sql, post_sql_statements ].flatten,
|
229
|
+
values_sql,
|
230
|
+
"#{self.class.name} Create Many Without Validations Or Callbacks" )
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# Returns an array of quoted column names
|
235
|
+
def quote_column_names( names )
|
236
|
+
names.map{ |name| connection.quote_column_name( name ) }
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
# Returns an Array of Hashes for the passed in +column_names+ and +array_of_attributes+.
|
243
|
+
def validations_array_for_column_names_and_attributes( column_names, array_of_attributes ) # :nodoc:
|
244
|
+
arr = []
|
245
|
+
array_of_attributes.each do |attributes|
|
246
|
+
c = 0
|
247
|
+
hsh = attributes.inject( {} ){|hsh,attr| hsh[ column_names[c] ] = attr ; c+=1 ; hsh }
|
248
|
+
arr << hsh
|
249
|
+
end
|
250
|
+
arr
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
end
|