ghazel-ar-extensions 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/ChangeLog +145 -0
  2. data/README +169 -0
  3. data/Rakefile +61 -0
  4. data/config/database.yml +7 -0
  5. data/config/database.yml.template +7 -0
  6. data/config/mysql.schema +72 -0
  7. data/config/postgresql.schema +39 -0
  8. data/db/migrate/generic_schema.rb +97 -0
  9. data/db/migrate/mysql_schema.rb +32 -0
  10. data/db/migrate/oracle_schema.rb +5 -0
  11. data/db/migrate/version.rb +4 -0
  12. data/init.rb +31 -0
  13. data/lib/ar-extensions/adapters/abstract_adapter.rb +146 -0
  14. data/lib/ar-extensions/adapters/mysql.rb +10 -0
  15. data/lib/ar-extensions/adapters/oracle.rb +14 -0
  16. data/lib/ar-extensions/adapters/postgresql.rb +9 -0
  17. data/lib/ar-extensions/adapters/sqlite.rb +7 -0
  18. data/lib/ar-extensions/create_and_update/mysql.rb +7 -0
  19. data/lib/ar-extensions/create_and_update.rb +509 -0
  20. data/lib/ar-extensions/csv.rb +309 -0
  21. data/lib/ar-extensions/delete/mysql.rb +3 -0
  22. data/lib/ar-extensions/delete.rb +143 -0
  23. data/lib/ar-extensions/extensions.rb +513 -0
  24. data/lib/ar-extensions/finder_options/mysql.rb +6 -0
  25. data/lib/ar-extensions/finder_options.rb +275 -0
  26. data/lib/ar-extensions/finders.rb +94 -0
  27. data/lib/ar-extensions/foreign_keys.rb +70 -0
  28. data/lib/ar-extensions/fulltext/mysql.rb +44 -0
  29. data/lib/ar-extensions/fulltext.rb +62 -0
  30. data/lib/ar-extensions/import/mysql.rb +50 -0
  31. data/lib/ar-extensions/import/postgresql.rb +0 -0
  32. data/lib/ar-extensions/import/sqlite.rb +22 -0
  33. data/lib/ar-extensions/import.rb +348 -0
  34. data/lib/ar-extensions/insert_select/mysql.rb +7 -0
  35. data/lib/ar-extensions/insert_select.rb +178 -0
  36. data/lib/ar-extensions/synchronize.rb +30 -0
  37. data/lib/ar-extensions/temporary_table/mysql.rb +3 -0
  38. data/lib/ar-extensions/temporary_table.rb +131 -0
  39. data/lib/ar-extensions/union/mysql.rb +6 -0
  40. data/lib/ar-extensions/union.rb +204 -0
  41. data/lib/ar-extensions/util/sql_generation.rb +27 -0
  42. data/lib/ar-extensions/util/support_methods.rb +32 -0
  43. data/lib/ar-extensions/version.rb +9 -0
  44. data/lib/ar-extensions.rb +5 -0
  45. 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,14 @@
1
+ module ActiveRecord # :nodoc:
2
+ module ConnectionAdapters # :nodoc:
3
+ class OracleAdapter # :nodoc:
4
+
5
+ def next_value_for_sequence(sequence_name)
6
+ %{#{sequence_name}.nextval}
7
+ end
8
+
9
+ def supports_import?
10
+ true
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord # :nodoc:
2
+ module ConnectionAdapters # :nodoc:
3
+ class PostgreSQLAdapter # :nodoc:
4
+ def next_value_for_sequence(sequence_name)
5
+ %{nextval('#{sequence_name}')}
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveRecord # :nodoc:
2
+ module ConnectionAdapters # :nodoc:
3
+ class SqliteAdapter # :nodoc:
4
+
5
+ end
6
+ end
7
+ 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