SQLite3: Make fixture loading to bulk statements
This commit is contained in:
parent
c852eda542
commit
d8d6bd5e63
|
@ -353,39 +353,12 @@ module ActiveRecord
|
|||
# We keep this method to provide fallback
|
||||
# for databases like sqlite that do not support bulk inserts.
|
||||
def insert_fixture(fixture, table_name)
|
||||
fixture = fixture.stringify_keys
|
||||
|
||||
columns = schema_cache.columns_hash(table_name)
|
||||
binds = fixture.map do |name, value|
|
||||
if column = columns[name]
|
||||
type = lookup_cast_type_from_column(column)
|
||||
Relation::QueryAttribute.new(name, value, type)
|
||||
else
|
||||
raise Fixture::FixtureError, %(table "#{table_name}" has no column named #{name.inspect}.)
|
||||
end
|
||||
end
|
||||
|
||||
table = Arel::Table.new(table_name)
|
||||
|
||||
values = binds.map do |bind|
|
||||
value = with_yaml_fallback(bind.value_for_database)
|
||||
[table[bind.name], value]
|
||||
end
|
||||
|
||||
manager = Arel::InsertManager.new
|
||||
manager.into(table)
|
||||
manager.insert(values)
|
||||
execute manager.to_sql, "Fixture Insert"
|
||||
execute(build_fixture_sql(Array.wrap(fixture), table_name), "Fixture Insert")
|
||||
end
|
||||
|
||||
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
||||
fixture_inserts = fixture_set.map do |table_name, fixtures|
|
||||
next if fixtures.empty?
|
||||
|
||||
build_fixture_sql(fixtures, table_name)
|
||||
end.compact
|
||||
|
||||
table_deletes = tables_to_delete.map { |table| +"DELETE FROM #{quote_table_name table}" }
|
||||
fixture_inserts = build_fixture_statements(fixture_set)
|
||||
table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
|
||||
total_sql = Array(combine_multi_statements(table_deletes + fixture_inserts))
|
||||
|
||||
with_multi_statements do
|
||||
|
@ -433,14 +406,17 @@ module ActiveRecord
|
|||
execute(sql, name)
|
||||
end
|
||||
|
||||
DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
|
||||
private_constant :DEFAULT_INSERT_VALUE
|
||||
|
||||
def default_insert_value(column)
|
||||
Arel.sql("DEFAULT")
|
||||
DEFAULT_INSERT_VALUE
|
||||
end
|
||||
|
||||
def build_fixture_sql(fixtures, table_name)
|
||||
columns = schema_cache.columns_hash(table_name)
|
||||
|
||||
values = fixtures.map do |fixture|
|
||||
values_list = fixtures.map do |fixture|
|
||||
fixture = fixture.stringify_keys
|
||||
|
||||
unknown_columns = fixture.keys - columns.keys
|
||||
|
@ -462,12 +438,32 @@ module ActiveRecord
|
|||
table = Arel::Table.new(table_name)
|
||||
manager = Arel::InsertManager.new
|
||||
manager.into(table)
|
||||
columns.each_key { |column| manager.columns << table[column] }
|
||||
manager.values = manager.create_values_list(values)
|
||||
|
||||
if values_list.size == 1
|
||||
values = values_list.shift
|
||||
new_values = []
|
||||
columns.each_key.with_index { |column, i|
|
||||
unless values[i].equal?(DEFAULT_INSERT_VALUE)
|
||||
new_values << values[i]
|
||||
manager.columns << table[column]
|
||||
end
|
||||
}
|
||||
values_list << new_values
|
||||
else
|
||||
columns.each_key { |column| manager.columns << table[column] }
|
||||
end
|
||||
|
||||
manager.values = manager.create_values_list(values_list)
|
||||
manager.to_sql
|
||||
end
|
||||
|
||||
def build_fixture_statements(fixture_set)
|
||||
fixture_set.map do |table_name, fixtures|
|
||||
next if fixtures.empty?
|
||||
build_fixture_sql(fixtures, table_name)
|
||||
end.compact
|
||||
end
|
||||
|
||||
def build_truncate_statements(*table_names)
|
||||
truncate_tables = table_names.map do |table_name|
|
||||
"TRUNCATE TABLE #{quote_table_name(table_name)}"
|
||||
|
|
|
@ -75,7 +75,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def default_insert_value(column)
|
||||
Arel.sql("DEFAULT") unless column.auto_increment?
|
||||
super unless column.auto_increment?
|
||||
end
|
||||
|
||||
def last_inserted_id(result)
|
||||
|
|
|
@ -19,6 +19,13 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def build_fixture_statements(fixture_set)
|
||||
fixture_set.flat_map do |table_name, fixtures|
|
||||
next if fixtures.empty?
|
||||
fixtures.map { |fixture| build_fixture_sql([fixture], table_name) }
|
||||
end.compact
|
||||
end
|
||||
|
||||
def build_truncate_statements(*table_names)
|
||||
truncate_tables = table_names.map do |table_name|
|
||||
"DELETE FROM #{quote_table_name(table_name)}"
|
||||
|
|
|
@ -384,18 +384,6 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
||||
disable_referential_integrity do
|
||||
transaction(requires_new: true) do
|
||||
tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
|
||||
|
||||
fixture_set.each do |table_name, rows|
|
||||
rows.each { |row| insert_fixture(row, table_name) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_insert_sql(insert) # :nodoc:
|
||||
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ class FixturesTest < ActiveRecord::TestCase
|
|||
conn = ActiveRecord::Base.connection
|
||||
mysql_margin = 2
|
||||
packet_size = 1024
|
||||
bytes_needed_to_have_a_1024_bytes_fixture = 860
|
||||
bytes_needed_to_have_a_1024_bytes_fixture = 906
|
||||
fixtures = {
|
||||
"traffic_lights" => [
|
||||
{ "location" => "US", "state" => ["NY"], "long_state" => ["a" * bytes_needed_to_have_a_1024_bytes_fixture] },
|
||||
|
@ -496,11 +496,7 @@ class FixturesTest < ActiveRecord::TestCase
|
|||
ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT + "/naked/yml", "parrots")
|
||||
end
|
||||
|
||||
if current_adapter?(:SQLite3Adapter)
|
||||
assert_equal(%(table "parrots" has no column named "arrr".), e.message)
|
||||
else
|
||||
assert_equal(%(table "parrots" has no columns named "arrr", "foobar".), e.message)
|
||||
end
|
||||
assert_equal(%(table "parrots" has no columns named "arrr", "foobar".), e.message)
|
||||
end
|
||||
|
||||
def test_yaml_file_with_symbol_columns
|
||||
|
|
Loading…
Reference in New Issue