Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/active_record/connection_adapters/sqlserver/quoting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ def quoted_false

def quoted_datetime(value)
if value.acts_like?(:time)
value.is_a?(Date) ? quoted_value_acts_like_time_filter(value).to_time.xmlschema.to(18) : quoted_value_acts_like_time_filter(value).iso8601(3).to(22)
time_zone_qualified_value = quoted_value_acts_like_time_filter(value)
if value.is_a?(Date)
time_zone_qualified_value.to_time.xmlschema.to(18)
else
if value.is_a?(ActiveSupport::TimeWithZone)
time_zone_qualified_value = time_zone_qualified_value.to_time
end
time_zone_qualified_value.iso8601(3).to(22)
end
else
quoted_date(value)
end
Expand Down
265 changes: 263 additions & 2 deletions test/cases/adapter_test_sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def setup
end

context 'For Quoting' do

should 'return 1 for #quoted_true' do
assert_equal '1', @connection.quoted_true
end
Expand Down Expand Up @@ -366,7 +366,268 @@ def setup
assert_equal '[foo].[bar]', @connection.quote_column_name('foo.bar')
assert_equal '[foo].[bar].[baz]', @connection.quote_column_name('foo.bar.baz')
end


context "#quote" do

context "string and multibyte values" do

context "on an activerecord :integer column" do

setup do
@column = stub("column", :type => :integer)
end

should "return null for empty string" do
assert_nil @connection.quote('', @column)
end

end

context "on an activerecord :binary column" do

setup do
@column = stub("column", :type => :binary)
end

should "ask the column class to convert the value" do
value = "value"
result = stub("result")
@column.class.stubs(:string_to_binary).with(value).returns(result)
assert_equal result, @connection.quote(value, @column)
end

end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will be removing this section. We already have a quote data for sqlserver with literal 0x prefix test in the column test file. BTW, before you say that the tests are spread out all over the place, remember that in many cases we mirror the test setup and organization of how ActiveRecord base is done. Another good example, the test_column_names_are_escaped in base_test_sqlserver.rb file. Either way, removing this.


context "on an activerecord :string column or with any value that is_utf8?" do

should "surround it when N'...'" do
assert_equal "N'foo'", @connection.quote("foo")
end

should "escape all single quotes by repeating them" do
assert_equal "N'''quotation''s'''", @connection.quote("'quotation's'")
end

end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll be removing this one too. We always quote using N' prefixing. Before you ask, should we, yes! There is a long story to this, browse issues if your interested.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, gonna keep these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just removing the comment about only when utf8.


context "with a value that's not is_utf8?" do

setup do
@value = "value"
@value.stubs(:is_utf8? => false)
end

should_eventually "call super"

end

end

context "date and time values" do

setup do
@value = Date.today
end

context "on a sql datetime column" do

setup do
@column = stub("column", :sql_type => 'datetime')
end

should "call quoted_datetime and surrounds its result with single quotes" do
@connection.stubs(:quoted_datetime).with(@value).returns("2000-01-01")
assert_equal "'2000-01-01'", @connection.quote(@value, @column)
end

end

context "on a sql datetimeoffset column" do

setup do
@column = stub("column", :sql_type => 'datetimeoffset')
end

should "call quoted_full_iso8601 and surrounds its result with single quotes" do
@connection.stubs(:quoted_full_iso8601).with(@value).returns("2000-01-01")
assert_equal "'2000-01-01'", @connection.quote(@value, @column)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without stubbing, you actually find this test is wrong. The true parse returns '01-01-2000'"

end

end

context "on a sql time column" do

setup do
@column = stub("column", :sql_type => 'time')
end

should "call quoted_full_iso8601 and surrounds its result with single quotes" do
@connection.stubs(:quoted_full_iso8601).with(@value).returns("2000-01-01")
assert_equal "'2000-01-01'", @connection.quote(@value, @column)
end

end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to remove the datetimeoffset and time data type assertions. I have no idea if these are even correct and until FreeTDS supports them, I do not want to canonize tests for them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This decision makes more sense too when you consider that I am refactoring to use real columns vs stubs. Since we have so many available :)


context "with another sql column" do

setup do
@column = stub("column", :sql_type => 'foo')
end

should_eventually "call super"

end

context "with no column" do

should_eventually "call super"

end

end

context "nil values" do

context "on a sql timestamp column" do

setup do
@column = stub("column", :sql_type => 'timestamp')
end

should "return DEFAULT" do
assert_equal "DEFAULT", @connection.quote(nil, @column)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one fails too when not using stubs. Returns NULL. I am removing this test too. This data type is not what you think it is. There is no such thing as an inserted value for it.

end

end

context "with another sql column" do

setup do
@column = stub("column", :sql_type => 'foo')
end

should_eventually "call super"

end

end

context "other values" do

setup do
@value = stub("value")
end

should_eventually "call super"

end

end

context "#quoted_datetime" do

context "with a Date" do

setup do
@value = Date.parse('2001-02-03T04:05:06-0700')
assert @value.is_a?(Date)
end

should "return a dd-mm-yyyy date string" do
assert_equal '02-03-2001', @connection.quoted_datetime(@value)
end

end

context "when the ActiveRecord default timezone is UTC" do

setup do
@old_activerecord_timezone = ActiveRecord::Base.default_timezone
ActiveRecord::Base.default_timezone = :utc
end

teardown do
ActiveRecord::Base.default_timezone = @old_activerecord_timezone
@old_activerecord_timezone = nil
end

context "with a Time" do

setup do
@value = Time.parse('2001-02-03T04:05:06-0700')
assert @value.is_a?(Time)
end

should "return an ISO 8601 datetime string" do
assert_equal '2001-02-03T11:05:06.000', @connection.quoted_datetime(@value)
end

end

context "with a DateTime" do

setup do
@value = DateTime.parse('2001-02-03T04:05:06-0700')
assert @value.is_a?(DateTime)
end

should "return an ISO 8601 datetime string" do
assert_equal '2001-02-03T11:05:06', @connection.quoted_datetime(@value)
end

end

context "with an ActiveSupport::TimeWithZone" do

setup do
require 'tzinfo'
@old_zone = Time.zone
Time.zone = 'Eastern Time (US & Canada)'
end

teardown do
Time.zone = @old_zone
@old_zone = nil
end

context "wrapping a datetime" do

setup do
@value = DateTime.parse('2001-02-03T04:05:06-0700').in_time_zone
assert @value.is_a?(ActiveSupport::TimeWithZone)
end

should "return an ISO 8601 datetime string with milliseconds" do
assert_equal '2001-02-03T11:05:06.000', @connection.quoted_datetime(@value)
end

end

context "wrapping a time" do

setup do
@value = Time.parse('2001-02-03T04:05:06-0700').in_time_zone
assert @value.is_a?(ActiveSupport::TimeWithZone)
end

should "return an ISO 8601 datetime string with milliseconds" do
assert_equal '2001-02-03T11:05:06.000', @connection.quoted_datetime(@value)
end

end

end

context "with a String" do

should_eventually "call quoted_date on super"

end

end

end

end

context 'When disabling referential integrity' do
Expand Down