mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
formatting insert and update statements
- values need to be coerced to the type corresponding to the column
This commit is contained in:
parent
ed9c8d4d82
commit
af3d7c5193
8 changed files with 110 additions and 45 deletions
1
TODO
1
TODO
|
@ -1,5 +1,4 @@
|
|||
todo:
|
||||
- remove to_sql logic from array and hash, push it into a formatter
|
||||
- string passthrough:
|
||||
:joins=>"INNER JOIN posts ON comments.post_id = posts.id"
|
||||
:conditions=>"(`posts`.author_id = 1)",
|
||||
|
|
|
@ -3,7 +3,7 @@ class Array
|
|||
Hash[*flatten]
|
||||
end
|
||||
|
||||
def to_sql(formatter = Sql::SelectExpression.new)
|
||||
formatter.array self
|
||||
def to_sql(formatter = nil)
|
||||
"(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")"
|
||||
end
|
||||
end
|
|
@ -8,12 +8,4 @@ class Hash
|
|||
descendent.merge(yield(key) => yield(value))
|
||||
end
|
||||
end
|
||||
|
||||
def to_sql(formatter = nil)
|
||||
'(' +
|
||||
inject([]) do |values, (key, value)|
|
||||
values << key.format(value)
|
||||
end.join(', ') +
|
||||
')'
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@ module ActiveRelation
|
|||
"INSERT",
|
||||
"INTO #{table_sql}",
|
||||
"(#{record.keys.collect(&:to_sql)})",
|
||||
"VALUES #{record.to_sql}"
|
||||
"VALUES (#{record.collect { |key, value| key.format(value) }})"
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ module ActiveRelation
|
|||
def to_sql(formatter = nil)
|
||||
[
|
||||
"UPDATE #{table_sql} SET",
|
||||
assignments.inject("") do |assignments, (attribute, value)|
|
||||
assignments << " #{attribute.to_sql} = #{value.to_sql}"
|
||||
end,
|
||||
assignments.collect do |attribute, value|
|
||||
"#{value.format(attribute)} = #{attribute.format(value)}"
|
||||
end.join("\n"),
|
||||
("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?)
|
||||
].join("\n")
|
||||
end
|
||||
|
|
|
@ -54,19 +54,25 @@ module ActiveRelation
|
|||
end
|
||||
|
||||
describe 'when relating to an array' do
|
||||
describe 'when given an arry of elements of the same type of the attribute' do
|
||||
it 'manufactures sql with a list' do
|
||||
array = [1, 2, 3]
|
||||
ConcreteBinary.new(@attribute1, array.bind(@relation)).to_sql.should be_like("
|
||||
describe 'when the array\'s elements are the same type as the attribute' do
|
||||
before do
|
||||
@array = [1, 2, 3]
|
||||
end
|
||||
|
||||
it 'manufactures sql with a comma separated list' do
|
||||
ConcreteBinary.new(@attribute1, @array.bind(@relation)).to_sql.should be_like("
|
||||
`users`.`id` <=> (1, 2, 3)
|
||||
")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an array, the elements of which are not the same type as the attribute' do
|
||||
it 'formats values in the array in the type of the attribute' do
|
||||
array = ['1-asdf', 2, 3]
|
||||
ConcreteBinary.new(@attribute1, array.bind(@relation)).to_sql.should be_like("
|
||||
describe 'when the array\'s elements are not same type as the attribute' do
|
||||
before do
|
||||
@array = ['1-asdf', 2, 3]
|
||||
end
|
||||
|
||||
it 'formats values in the array as the type of the attribute' do
|
||||
ConcreteBinary.new(@attribute1, @array.bind(@relation)).to_sql.should be_like("
|
||||
`users`.`id` <=> (1, 2, 3)
|
||||
")
|
||||
end
|
||||
|
|
|
@ -4,20 +4,57 @@ module ActiveRelation
|
|||
describe Insertion do
|
||||
before do
|
||||
@relation = Table.new(:users)
|
||||
@insertion = Insertion.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
end
|
||||
|
||||
describe '#to_sql' do
|
||||
it 'manufactures sql inserting the data for one item' do
|
||||
@insertion.to_sql.should be_like("
|
||||
INSERT
|
||||
INTO `users`
|
||||
(`users`.`name`) VALUES ('nick')
|
||||
")
|
||||
describe 'when given values whose types correspond to the types of the attributes' do
|
||||
before do
|
||||
@insertion = Insertion.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
end
|
||||
|
||||
it 'manufactures sql inserting data' do
|
||||
@insertion.to_sql.should be_like("
|
||||
INSERT
|
||||
INTO `users`
|
||||
(`users`.`name`) VALUES ('nick')
|
||||
")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given values whose types differ from from the types of the attributes' do
|
||||
before do
|
||||
@insertion = Insertion.new(@relation, @relation[:id] => '1-asdf'.bind(@relation))
|
||||
end
|
||||
|
||||
it 'manufactures sql inserting data' do
|
||||
@insertion.to_sql.should be_like("
|
||||
INSERT
|
||||
INTO `users`
|
||||
(`users`.`id`) VALUES (1)
|
||||
")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given values whose types correspond to the type of the attribtues' do
|
||||
before do
|
||||
@insertion = Insertion.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
end
|
||||
|
||||
it 'manufactures sql inserting data' do
|
||||
@insertion.to_sql.should be_like("
|
||||
INSERT
|
||||
INTO `users`
|
||||
(`users`.`name`) VALUES ('nick')
|
||||
")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
before do
|
||||
@insertion = Insertion.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
end
|
||||
|
||||
it 'executes an insert on the connection' do
|
||||
mock(connection = Object.new).insert(@insertion.to_sql)
|
||||
@insertion.call(connection)
|
||||
|
|
|
@ -7,27 +7,58 @@ module ActiveRelation
|
|||
end
|
||||
|
||||
describe '#to_sql' do
|
||||
it 'manufactures sql updating attributes' do
|
||||
Update.new(@relation, @relation[:name] => "nick".bind(@relation)).to_sql.should be_like("
|
||||
UPDATE `users`
|
||||
SET `users`.`name` = 'nick'
|
||||
")
|
||||
describe 'when given values whose types correspond to the types of the attributes' do
|
||||
before do
|
||||
@update = Update.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
end
|
||||
|
||||
it 'manufactures sql updating attributes' do
|
||||
@update.to_sql.should be_like("
|
||||
UPDATE `users`
|
||||
SET `users`.`name` = 'nick'
|
||||
")
|
||||
end
|
||||
end
|
||||
|
||||
it 'manufactures sql updating a selection relation' do
|
||||
Update.new(@relation.select(@relation[:id].equals(1)), @relation[:name] => "nick".bind(@relation)).to_sql.should be_like("
|
||||
UPDATE `users`
|
||||
SET `users`.`name` = 'nick'
|
||||
WHERE `users`.`id` = 1
|
||||
")
|
||||
|
||||
describe 'when given values whose types differ from from the types of the attributes' do
|
||||
before do
|
||||
@update = Update.new(@relation, @relation[:id] => '1-asdf'.bind(@relation))
|
||||
end
|
||||
|
||||
it 'manufactures sql updating attributes' do
|
||||
@update.to_sql.should be_like("
|
||||
UPDATE `users`
|
||||
SET `users`.`id` = 1
|
||||
")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when the relation is a selection' do
|
||||
before do
|
||||
@update = Update.new(
|
||||
@relation.select(@relation[:id].equals(1)),
|
||||
@relation[:name] => "nick".bind(@relation)
|
||||
)
|
||||
end
|
||||
|
||||
it 'manufactures sql updating a selection relation' do
|
||||
@update.to_sql.should be_like("
|
||||
UPDATE `users`
|
||||
SET `users`.`name` = 'nick'
|
||||
WHERE `users`.`id` = 1
|
||||
")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
before do
|
||||
@update = Update.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
end
|
||||
|
||||
it 'executes an update on the connection' do
|
||||
update = Update.new(@relation, @relation[:name] => "nick".bind(@relation))
|
||||
mock(connection = Object.new).update(update.to_sql)
|
||||
update.call(connection)
|
||||
mock(connection = Object.new).update(@update.to_sql)
|
||||
@update.call(connection)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue