ghazel-ar-extensions 0.9.3
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 +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,146 @@
|
|
1
|
+
module ActiveRecord # :nodoc:
|
2
|
+
module ConnectionAdapters # :nodoc:
|
3
|
+
class AbstractAdapter # :nodoc:
|
4
|
+
NO_MAX_PACKET = 0
|
5
|
+
QUERY_OVERHEAD = 8 #This was shown to be true for MySQL, but it's not clear where the overhead is from.
|
6
|
+
|
7
|
+
def next_value_for_sequence(sequence_name)
|
8
|
+
%{#{sequence_name}.nextval}
|
9
|
+
end
|
10
|
+
|
11
|
+
# +sql+ can be a single string or an array. If it is an array all
|
12
|
+
# elements that are in position >= 1 will be appended to the final SQL.
|
13
|
+
def insert_many( sql, values, *args ) # :nodoc:
|
14
|
+
# the number of inserts default
|
15
|
+
number_of_inserts = 0
|
16
|
+
|
17
|
+
base_sql,post_sql = if sql.is_a?( String )
|
18
|
+
[ sql, '' ]
|
19
|
+
elsif sql.is_a?( Array )
|
20
|
+
[ sql.shift, sql.join( ' ' ) ]
|
21
|
+
end
|
22
|
+
|
23
|
+
sql_size = QUERY_OVERHEAD + base_sql.size + post_sql.size
|
24
|
+
|
25
|
+
# the number of bytes the requested insert statement values will take up
|
26
|
+
values_in_bytes = self.class.sum_sizes( *values )
|
27
|
+
|
28
|
+
# the number of bytes (commas) it will take to comma separate our values
|
29
|
+
comma_separated_bytes = values.size-1
|
30
|
+
|
31
|
+
# the total number of bytes required if this statement is one statement
|
32
|
+
total_bytes = sql_size + values_in_bytes + comma_separated_bytes
|
33
|
+
|
34
|
+
max = max_allowed_packet
|
35
|
+
|
36
|
+
# if we can insert it all as one statement
|
37
|
+
if NO_MAX_PACKET == max or total_bytes < max
|
38
|
+
number_of_inserts += 1
|
39
|
+
sql2insert = base_sql + values.join( ',' ) + post_sql
|
40
|
+
insert( sql2insert, *args )
|
41
|
+
else
|
42
|
+
value_sets = self.class.get_insert_value_sets( values, sql_size, max )
|
43
|
+
value_sets.each do |values|
|
44
|
+
number_of_inserts += 1
|
45
|
+
sql2insert = base_sql + values.join( ',' ) + post_sql
|
46
|
+
insert( sql2insert, *args )
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
number_of_inserts
|
51
|
+
end
|
52
|
+
|
53
|
+
def pre_sql_statements(options)
|
54
|
+
sql = []
|
55
|
+
sql << options[:pre_sql] if options[:pre_sql]
|
56
|
+
sql << options[:command] if options[:command]
|
57
|
+
sql << "IGNORE" if options[:ignore]
|
58
|
+
|
59
|
+
#add keywords like IGNORE or DELAYED
|
60
|
+
if options[:keywords].is_a?(Array)
|
61
|
+
sql.concat(options[:keywords])
|
62
|
+
elsif options[:keywords]
|
63
|
+
sql << options[:keywords].to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
sql
|
67
|
+
end
|
68
|
+
|
69
|
+
# Synchronizes the passed in ActiveRecord instances with the records in
|
70
|
+
# the database by calling +reload+ on each instance.
|
71
|
+
def after_import_synchronize( instances )
|
72
|
+
instances.each { |e| e.reload }
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns an array of post SQL statements given the passed in options.
|
76
|
+
def post_sql_statements( table_name, options ) # :nodoc:
|
77
|
+
post_sql_statements = []
|
78
|
+
if options[:on_duplicate_key_update]
|
79
|
+
post_sql_statements << sql_for_on_duplicate_key_update( table_name, options[:on_duplicate_key_update] )
|
80
|
+
end
|
81
|
+
|
82
|
+
#custom user post_sql
|
83
|
+
post_sql_statements << options[:post_sql] if options[:post_sql]
|
84
|
+
|
85
|
+
#with rollup
|
86
|
+
post_sql_statements << rollup_sql if options[:rollup]
|
87
|
+
|
88
|
+
post_sql_statements
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# Generates the INSERT statement used in insert multiple value sets.
|
93
|
+
def multiple_value_sets_insert_sql(table_name, column_names, options) # :nodoc:
|
94
|
+
"INSERT #{options[:ignore] ? 'IGNORE ':''}INTO #{table_name} (#{column_names.join(',')}) VALUES "
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns SQL the VALUES for an INSERT statement given the passed in +columns+
|
98
|
+
# and +array_of_attributes+.
|
99
|
+
def values_sql_for_column_names_and_attributes( columns, array_of_attributes ) # :nodoc:
|
100
|
+
values = []
|
101
|
+
array_of_attributes.each do |arr|
|
102
|
+
my_values = []
|
103
|
+
arr.each_with_index do |val,j|
|
104
|
+
my_values << quote( val, columns[j] )
|
105
|
+
end
|
106
|
+
values << my_values
|
107
|
+
end
|
108
|
+
values_arr = values.map{ |arr| '(' + arr.join( ',' ) + ')' }
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns the sum of the sizes of the passed in objects. This should
|
112
|
+
# probably be moved outside this class, but to where?
|
113
|
+
def self.sum_sizes( *objects ) # :nodoc:
|
114
|
+
objects.inject( 0 ){|sum,o| sum += o.size }
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns the maximum number of bytes that the server will allow
|
118
|
+
# in a single packet
|
119
|
+
def max_allowed_packet
|
120
|
+
NO_MAX_PACKET
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.get_insert_value_sets( values, sql_size, max_bytes ) # :nodoc:
|
124
|
+
value_sets = []
|
125
|
+
arr, current_arr_values_size, current_size = [], 0, 0
|
126
|
+
values.each_with_index do |val,i|
|
127
|
+
comma_bytes = arr.size
|
128
|
+
sql_size_thus_far = sql_size + current_size + val.size + comma_bytes
|
129
|
+
if NO_MAX_PACKET == max_bytes or sql_size_thus_far <= max_bytes
|
130
|
+
current_size += val.size
|
131
|
+
arr << val
|
132
|
+
else
|
133
|
+
value_sets << arr
|
134
|
+
arr = [ val ]
|
135
|
+
current_size = val.size
|
136
|
+
end
|
137
|
+
|
138
|
+
# if we're on the last iteration push whatever we have in arr to value_sets
|
139
|
+
value_sets << arr if i == (values.size-1)
|
140
|
+
end
|
141
|
+
[ *value_sets ]
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
|
2
|
+
# Returns the maximum number of bytes that the server will allow
|
3
|
+
# in a single packet
|
4
|
+
def max_allowed_packet # :nodoc:
|
5
|
+
result = execute( "SHOW VARIABLES like 'max_allowed_packet';" )
|
6
|
+
result.fetch_row[1].to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def rollup_sql; " WITH ROLLUP "; end
|
10
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Although the finder options actually override ActiveRecord::Base functionality instead of
|
2
|
+
# connector functionality, the methods are included here to keep the syntax of 0.8.0 intact
|
3
|
+
#
|
4
|
+
# To include finder options, use:
|
5
|
+
# require 'ar-extensions/create_and_update/mysql.rb'
|
6
|
+
|
7
|
+
ActiveRecord::Base.send :include, ActiveRecord::Extensions::CreateAndUpdate
|