activerecord-sqlserver-adapter-odbc-extended 8.0.10
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.
- checksums.yaml +7 -0
- data/.github/issue_template.md +22 -0
- data/.github/workflows/ci.yml +32 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +69 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/Dockerfile.ci +14 -0
- data/Gemfile +26 -0
- data/LICENSE.txt +21 -0
- data/README.md +104 -0
- data/RUNNING_UNIT_TESTS.md +38 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/activerecord-sqlserver-adapter-odbc-extended.gemspec +34 -0
- data/compose.ci.yaml +15 -0
- data/lib/active_record/connection_adapters/extended_sqlserver_adapter.rb +204 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +41 -0
- data/lib/active_record/connection_adapters/sqlserver/odbc_database_statements.rb +234 -0
- data/lib/active_record/connection_adapters/sqlserver/type/binary_ext.rb +25 -0
- data/lib/activerecord-sqlserver-adapter-odbc-extended.rb +12 -0
- data/test/appveyor/dbsetup.ps1 +27 -0
- data/test/appveyor/dbsetup.sql +11 -0
- data/test/cases/active_schema_test_sqlserver.rb +127 -0
- data/test/cases/adapter_test_sqlserver.rb +648 -0
- data/test/cases/change_column_collation_test_sqlserver.rb +33 -0
- data/test/cases/change_column_null_test_sqlserver.rb +44 -0
- data/test/cases/coerced_tests.rb +2796 -0
- data/test/cases/column_test_sqlserver.rb +848 -0
- data/test/cases/connection_test_sqlserver.rb +138 -0
- data/test/cases/dbconsole.rb +19 -0
- data/test/cases/disconnected_test_sqlserver.rb +42 -0
- data/test/cases/eager_load_too_many_ids_test_sqlserver.rb +18 -0
- data/test/cases/enum_test_sqlserver.rb +49 -0
- data/test/cases/execute_procedure_test_sqlserver.rb +57 -0
- data/test/cases/fetch_test_sqlserver.rb +88 -0
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +72 -0
- data/test/cases/helper_sqlserver.rb +61 -0
- data/test/cases/migration_test_sqlserver.rb +144 -0
- data/test/cases/order_test_sqlserver.rb +153 -0
- data/test/cases/pessimistic_locking_test_sqlserver.rb +102 -0
- data/test/cases/primary_keys_test_sqlserver.rb +103 -0
- data/test/cases/rake_test_sqlserver.rb +198 -0
- data/test/cases/schema_dumper_test_sqlserver.rb +296 -0
- data/test/cases/schema_test_sqlserver.rb +111 -0
- data/test/cases/trigger_test_sqlserver.rb +51 -0
- data/test/cases/utils_test_sqlserver.rb +129 -0
- data/test/cases/uuid_test_sqlserver.rb +54 -0
- data/test/cases/view_test_sqlserver.rb +58 -0
- data/test/config.yml +38 -0
- data/test/debug.rb +16 -0
- data/test/fixtures/1px.gif +0 -0
- data/test/migrations/create_clients_and_change_column_collation.rb +19 -0
- data/test/migrations/create_clients_and_change_column_null.rb +25 -0
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +11 -0
- data/test/models/sqlserver/alien.rb +5 -0
- data/test/models/sqlserver/booking.rb +5 -0
- data/test/models/sqlserver/composite_pk.rb +9 -0
- data/test/models/sqlserver/customers_view.rb +5 -0
- data/test/models/sqlserver/datatype.rb +5 -0
- data/test/models/sqlserver/datatype_migration.rb +10 -0
- data/test/models/sqlserver/dollar_table_name.rb +5 -0
- data/test/models/sqlserver/edge_schema.rb +13 -0
- data/test/models/sqlserver/fk_has_fk.rb +5 -0
- data/test/models/sqlserver/fk_has_pk.rb +5 -0
- data/test/models/sqlserver/natural_pk_data.rb +6 -0
- data/test/models/sqlserver/natural_pk_int_data.rb +5 -0
- data/test/models/sqlserver/no_pk_data.rb +5 -0
- data/test/models/sqlserver/object_default.rb +5 -0
- data/test/models/sqlserver/quoted_table.rb +9 -0
- data/test/models/sqlserver/quoted_view_1.rb +5 -0
- data/test/models/sqlserver/quoted_view_2.rb +5 -0
- data/test/models/sqlserver/sst_memory.rb +5 -0
- data/test/models/sqlserver/sst_string_collation.rb +3 -0
- data/test/models/sqlserver/string_default.rb +5 -0
- data/test/models/sqlserver/string_defaults_big_view.rb +5 -0
- data/test/models/sqlserver/string_defaults_view.rb +5 -0
- data/test/models/sqlserver/table_with_spaces.rb +5 -0
- data/test/models/sqlserver/tinyint_pk.rb +5 -0
- data/test/models/sqlserver/trigger.rb +17 -0
- data/test/models/sqlserver/trigger_history.rb +5 -0
- data/test/models/sqlserver/upper.rb +5 -0
- data/test/models/sqlserver/uppered.rb +5 -0
- data/test/models/sqlserver/uuid.rb +5 -0
- data/test/schema/datatypes/2012.sql +56 -0
- data/test/schema/enable-in-memory-oltp.sql +81 -0
- data/test/schema/sqlserver_specific_schema.rb +363 -0
- data/test/support/coerceable_test_sqlserver.rb +55 -0
- data/test/support/connection_reflection.rb +32 -0
- data/test/support/core_ext/query_cache.rb +38 -0
- data/test/support/load_schema_sqlserver.rb +29 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic_associations.dump +0 -0
- data/test/support/minitest_sqlserver.rb +3 -0
- data/test/support/paths_sqlserver.rb +50 -0
- data/test/support/query_assertions.rb +49 -0
- data/test/support/rake_helpers.rb +46 -0
- data/test/support/table_definition_sqlserver.rb +24 -0
- data/test/support/test_in_memory_oltp.rb +17 -0
- metadata +240 -0
|
@@ -0,0 +1,848 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/helper_sqlserver"
|
|
4
|
+
|
|
5
|
+
class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
6
|
+
it "#table_name" do
|
|
7
|
+
assert SSTestDatatype.columns.all? { |c| c.table_name == "sst_datatypes" }
|
|
8
|
+
assert SSTestCustomersView.columns.all? { |c| c.table_name == "customers" }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "ActiveRecord::ConnectionAdapters::SQLServer::Type" do
|
|
12
|
+
let(:obj) { SSTestDatatype.new }
|
|
13
|
+
|
|
14
|
+
Type = ActiveRecord::ConnectionAdapters::SQLServer::Type
|
|
15
|
+
|
|
16
|
+
def new_obj; SSTestDatatype.new; end
|
|
17
|
+
|
|
18
|
+
def column(name); SSTestDatatype.columns_hash[name]; end
|
|
19
|
+
|
|
20
|
+
def assert_obj_set_and_save(attribute, value)
|
|
21
|
+
obj.send :"#{attribute}=", value
|
|
22
|
+
_(obj.send(attribute)).must_equal value
|
|
23
|
+
obj.save!
|
|
24
|
+
_(obj.reload.send(attribute)).must_equal value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# http://msdn.microsoft.com/en-us/library/ms187752.aspx
|
|
28
|
+
|
|
29
|
+
# Exact Numerics
|
|
30
|
+
|
|
31
|
+
it "int(4) PRIMARY KEY" do
|
|
32
|
+
col = column("id")
|
|
33
|
+
_(col.sql_type).must_equal "int(4)"
|
|
34
|
+
_(col.null).must_equal false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "bigint(8)" do
|
|
38
|
+
col = column("bigint")
|
|
39
|
+
_(col.sql_type).must_equal "bigint(8)"
|
|
40
|
+
_(col.type).must_equal :integer
|
|
41
|
+
_(col.null).must_equal true
|
|
42
|
+
_(col.default).must_equal 42
|
|
43
|
+
_(obj.bigint).must_equal 42
|
|
44
|
+
_(col.default_function).must_be_nil
|
|
45
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
46
|
+
_(type).must_be_instance_of Type::BigInteger
|
|
47
|
+
_(type.limit).must_equal 8
|
|
48
|
+
assert_obj_set_and_save :bigint, -9_223_372_036_854_775_808
|
|
49
|
+
assert_obj_set_and_save :bigint, 9_223_372_036_854_775_807
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "int(4)" do
|
|
53
|
+
col = column("int")
|
|
54
|
+
_(col.sql_type).must_equal "int(4)"
|
|
55
|
+
_(col.type).must_equal :integer
|
|
56
|
+
_(col.null).must_equal true
|
|
57
|
+
_(col.default).must_equal 42
|
|
58
|
+
_(obj.int).must_equal 42
|
|
59
|
+
_(col.default_function).must_be_nil
|
|
60
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
61
|
+
_(type).must_be_instance_of Type::Integer
|
|
62
|
+
_(type.limit).must_equal 4
|
|
63
|
+
assert_obj_set_and_save :int, -2_147_483_648
|
|
64
|
+
assert_obj_set_and_save :int, 2_147_483_647
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "smallint(2)" do
|
|
68
|
+
col = column("smallint")
|
|
69
|
+
_(col.sql_type).must_equal "smallint(2)"
|
|
70
|
+
_(col.type).must_equal :integer
|
|
71
|
+
_(col.null).must_equal true
|
|
72
|
+
_(col.default).must_equal 42
|
|
73
|
+
_(obj.smallint).must_equal 42
|
|
74
|
+
_(col.default_function).must_be_nil
|
|
75
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
76
|
+
_(type).must_be_instance_of Type::SmallInteger
|
|
77
|
+
_(type.limit).must_equal 2
|
|
78
|
+
assert_obj_set_and_save :smallint, -32_768
|
|
79
|
+
assert_obj_set_and_save :smallint, 32_767
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "tinyint(1)" do
|
|
83
|
+
col = column("tinyint")
|
|
84
|
+
_(col.sql_type).must_equal "tinyint(1)"
|
|
85
|
+
_(col.type).must_equal :integer
|
|
86
|
+
_(col.null).must_equal true
|
|
87
|
+
_(col.default).must_equal 42
|
|
88
|
+
_(obj.tinyint).must_equal 42
|
|
89
|
+
_(col.default_function).must_be_nil
|
|
90
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
91
|
+
_(type).must_be_instance_of Type::TinyInteger
|
|
92
|
+
_(type.limit).must_equal 1
|
|
93
|
+
assert_obj_set_and_save :tinyint, 0
|
|
94
|
+
assert_obj_set_and_save :tinyint, 255
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "bit" do
|
|
98
|
+
col = column("bit")
|
|
99
|
+
_(col.sql_type).must_equal "bit"
|
|
100
|
+
_(col.type).must_equal :boolean
|
|
101
|
+
_(col.null).must_equal true
|
|
102
|
+
_(col.default).must_equal true
|
|
103
|
+
_(obj.bit).must_equal true
|
|
104
|
+
_(col.default_function).must_be_nil
|
|
105
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
106
|
+
_(type).must_be_instance_of Type::Boolean
|
|
107
|
+
_(type.limit).must_be_nil
|
|
108
|
+
obj.bit = 0
|
|
109
|
+
_(obj.bit).must_equal false
|
|
110
|
+
obj.save!
|
|
111
|
+
_(obj.reload.bit).must_equal false
|
|
112
|
+
obj.bit = "1"
|
|
113
|
+
_(obj.bit).must_equal true
|
|
114
|
+
obj.save!
|
|
115
|
+
_(obj.reload.bit).must_equal true
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "decimal(9,2)" do
|
|
119
|
+
col = column("decimal_9_2")
|
|
120
|
+
_(col.sql_type).must_equal "decimal(9,2)"
|
|
121
|
+
_(col.type).must_equal :decimal
|
|
122
|
+
_(col.null).must_equal true
|
|
123
|
+
_(col.default).must_equal BigDecimal("12345.01")
|
|
124
|
+
_(obj.decimal_9_2).must_equal BigDecimal("12345.01")
|
|
125
|
+
_(col.default_function).must_be_nil
|
|
126
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
127
|
+
_(type).must_be_instance_of Type::Decimal
|
|
128
|
+
_(type.limit).must_be_nil
|
|
129
|
+
_(type.precision).must_equal 9
|
|
130
|
+
_(type.scale).must_equal 2
|
|
131
|
+
obj.decimal_9_2 = "1234567.8901"
|
|
132
|
+
_(obj.decimal_9_2).must_equal BigDecimal("1234567.89")
|
|
133
|
+
obj.save!
|
|
134
|
+
_(obj.reload.decimal_9_2).must_equal BigDecimal("1234567.89")
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "decimal(16,4)" do
|
|
138
|
+
col = column("decimal_16_4")
|
|
139
|
+
_(col.sql_type).must_equal "decimal(16,4)"
|
|
140
|
+
_(col.default).must_equal BigDecimal("1234567.89")
|
|
141
|
+
_(obj.decimal_16_4).must_equal BigDecimal("1234567.89")
|
|
142
|
+
_(col.default_function).must_be_nil
|
|
143
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
144
|
+
_(type.precision).must_equal 16
|
|
145
|
+
_(type.scale).must_equal 4
|
|
146
|
+
obj.decimal_16_4 = "1234567.8901001"
|
|
147
|
+
_(obj.decimal_16_4).must_equal BigDecimal("1234567.8901")
|
|
148
|
+
obj.save!
|
|
149
|
+
_(obj.reload.decimal_16_4).must_equal BigDecimal("1234567.8901")
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "numeric(18,0)" do
|
|
153
|
+
col = column("numeric_18_0")
|
|
154
|
+
_(col.sql_type).must_equal "numeric(18,0)"
|
|
155
|
+
_(col.type).must_equal :decimal
|
|
156
|
+
_(col.null).must_equal true
|
|
157
|
+
_(col.default).must_equal BigDecimal("191")
|
|
158
|
+
_(obj.numeric_18_0).must_equal BigDecimal("191")
|
|
159
|
+
_(col.default_function).must_be_nil
|
|
160
|
+
|
|
161
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
162
|
+
_(type).must_be_instance_of Type::DecimalWithoutScale
|
|
163
|
+
_(type.limit).must_be_nil
|
|
164
|
+
_(type.precision).must_equal 18
|
|
165
|
+
_(type.scale).must_be_nil
|
|
166
|
+
|
|
167
|
+
obj.numeric_18_0 = "192.1"
|
|
168
|
+
_(obj.numeric_18_0).must_equal BigDecimal("192")
|
|
169
|
+
|
|
170
|
+
obj.save!
|
|
171
|
+
_(obj.reload.numeric_18_0).must_equal BigDecimal("192")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "numeric(36,2)" do
|
|
175
|
+
col = column("numeric_36_2")
|
|
176
|
+
_(col.sql_type).must_equal "numeric(36,2)"
|
|
177
|
+
_(col.type).must_equal :decimal
|
|
178
|
+
_(col.null).must_equal true
|
|
179
|
+
_(col.default).must_equal BigDecimal("12345678901234567890.01")
|
|
180
|
+
_(obj.numeric_36_2).must_equal BigDecimal("12345678901234567890.01")
|
|
181
|
+
_(col.default_function).must_be_nil
|
|
182
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
183
|
+
_(type).must_be_instance_of Type::Decimal
|
|
184
|
+
_(type.limit).must_be_nil
|
|
185
|
+
_(type.precision).must_equal 36
|
|
186
|
+
_(type.scale).must_equal 2
|
|
187
|
+
obj.numeric_36_2 = "192.123"
|
|
188
|
+
_(obj.numeric_36_2).must_equal BigDecimal("192.12")
|
|
189
|
+
obj.save!
|
|
190
|
+
_(obj.reload.numeric_36_2).must_equal BigDecimal("192.12")
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "money" do
|
|
194
|
+
col = column("money")
|
|
195
|
+
_(col.sql_type).must_equal "money"
|
|
196
|
+
_(col.type).must_equal :money
|
|
197
|
+
_(col.null).must_equal true
|
|
198
|
+
_(col.default).must_equal BigDecimal("4.20")
|
|
199
|
+
_(obj.money).must_equal BigDecimal("4.20")
|
|
200
|
+
_(col.default_function).must_be_nil
|
|
201
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
202
|
+
_(type).must_be_instance_of Type::Money
|
|
203
|
+
_(type.limit).must_be_nil
|
|
204
|
+
_(type.precision).must_equal 19
|
|
205
|
+
_(type.scale).must_equal 4
|
|
206
|
+
obj.money = "922337203685477.58061"
|
|
207
|
+
_(obj.money).must_equal BigDecimal("922337203685477.5806")
|
|
208
|
+
obj.save!
|
|
209
|
+
_(obj.reload.money).must_equal BigDecimal("922337203685477.5806")
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "smallmoney" do
|
|
213
|
+
col = column("smallmoney")
|
|
214
|
+
_(col.sql_type).must_equal "smallmoney"
|
|
215
|
+
_(col.type).must_equal :smallmoney
|
|
216
|
+
_(col.null).must_equal true
|
|
217
|
+
_(col.default).must_equal BigDecimal("4.20")
|
|
218
|
+
_(obj.smallmoney).must_equal BigDecimal("4.20")
|
|
219
|
+
_(col.default_function).must_be_nil
|
|
220
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
221
|
+
_(type).must_be_instance_of Type::SmallMoney
|
|
222
|
+
_(type.limit).must_be_nil
|
|
223
|
+
_(type.precision).must_equal 10
|
|
224
|
+
_(type.scale).must_equal 4
|
|
225
|
+
obj.smallmoney = "214748.36461"
|
|
226
|
+
_(obj.smallmoney).must_equal BigDecimal("214748.3646")
|
|
227
|
+
obj.save!
|
|
228
|
+
_(obj.reload.smallmoney).must_equal BigDecimal("214748.3646")
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Approximate Numerics
|
|
232
|
+
# Float limits are adjusted to 24 or 53 by the database as per http://msdn.microsoft.com/en-us/library/ms173773.aspx
|
|
233
|
+
# Floats with a limit of <= 24 are reduced to reals by sqlserver on creation.
|
|
234
|
+
|
|
235
|
+
it "float" do
|
|
236
|
+
col = column("float")
|
|
237
|
+
_(col.sql_type).must_equal "float"
|
|
238
|
+
_(col.type).must_equal :float
|
|
239
|
+
_(col.null).must_equal true
|
|
240
|
+
_(col.default).must_equal 123.00000001
|
|
241
|
+
_(obj.float).must_equal 123.00000001
|
|
242
|
+
_(col.default_function).must_be_nil
|
|
243
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
244
|
+
_(type).must_be_instance_of Type::Float
|
|
245
|
+
_(type.limit).must_be_nil
|
|
246
|
+
_(type.precision).must_be_nil
|
|
247
|
+
_(type.scale).must_be_nil
|
|
248
|
+
obj.float = "214748.36461"
|
|
249
|
+
_(obj.float).must_equal 214748.36461
|
|
250
|
+
obj.save!
|
|
251
|
+
_(obj.reload.float).must_equal 214748.36461
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it "real" do
|
|
255
|
+
col = column("real")
|
|
256
|
+
_(col.sql_type).must_equal "real"
|
|
257
|
+
_(col.type).must_equal :real
|
|
258
|
+
_(col.null).must_equal true
|
|
259
|
+
_(col.default).must_be_close_to 123.45, 0.01
|
|
260
|
+
_(obj.real).must_be_close_to 123.45, 0.01
|
|
261
|
+
_(col.default_function).must_be_nil
|
|
262
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
263
|
+
_(type).must_be_instance_of Type::Real
|
|
264
|
+
_(type.limit).must_be_nil
|
|
265
|
+
_(type.precision).must_be_nil
|
|
266
|
+
_(type.scale).must_be_nil
|
|
267
|
+
obj.real = "214748.36461"
|
|
268
|
+
_(obj.real).must_be_close_to 214748.36461, 0.01
|
|
269
|
+
obj.save!
|
|
270
|
+
_(obj.reload.real).must_be_close_to 214748.36461, 0.01
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Date and Time
|
|
274
|
+
|
|
275
|
+
it "date" do
|
|
276
|
+
col = column("date")
|
|
277
|
+
_(col.sql_type).must_equal "date"
|
|
278
|
+
_(col.type).must_equal :date
|
|
279
|
+
_(col.null).must_equal true
|
|
280
|
+
_(col.default).must_equal Date.civil(1900, 1, 1)
|
|
281
|
+
_(obj.date).must_equal Date.civil(1900, 1, 1)
|
|
282
|
+
_(col.default_function).must_be_nil
|
|
283
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
284
|
+
_(type).must_be_instance_of Type::Date
|
|
285
|
+
_(type.limit).must_be_nil
|
|
286
|
+
_(type.precision).must_be_nil
|
|
287
|
+
_(type.scale).must_be_nil
|
|
288
|
+
# Can cast strings. SQL Server format.
|
|
289
|
+
obj.date = "04-01-1900"
|
|
290
|
+
obj.date.must_equal Date.civil(1900, 4, 1)
|
|
291
|
+
obj.save!
|
|
292
|
+
obj.date.must_equal Date.civil(1900, 4, 1)
|
|
293
|
+
obj.reload
|
|
294
|
+
obj.date.must_equal Date.civil(1900, 4, 1)
|
|
295
|
+
# Can cast strings. ISO format.
|
|
296
|
+
obj.date = "1900-04-01"
|
|
297
|
+
obj.date.must_equal Date.civil(1900, 4, 1)
|
|
298
|
+
obj.save!
|
|
299
|
+
obj.date.must_equal Date.civil(1900, 4, 1)
|
|
300
|
+
obj.reload
|
|
301
|
+
obj.date.must_equal Date.civil(1900, 4, 1)
|
|
302
|
+
# Can keep and return assigned date.
|
|
303
|
+
assert_obj_set_and_save :date, Date.civil(1972, 4, 14)
|
|
304
|
+
# Can accept and cast time objects.
|
|
305
|
+
obj.date = Time.utc(2010, 4, 14, 12, 34, 56, 3000)
|
|
306
|
+
_(obj.date).must_equal Date.civil(2010, 4, 14)
|
|
307
|
+
obj.save!
|
|
308
|
+
_(obj.reload.date).must_equal Date.civil(2010, 4, 14)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
it "datetime" do
|
|
312
|
+
col = column("datetime")
|
|
313
|
+
_(col.sql_type).must_equal "datetime"
|
|
314
|
+
_(col.type).must_equal :datetime
|
|
315
|
+
_(col.null).must_equal true
|
|
316
|
+
time = Time.utc 1753, 1, 1, 0, 0, 0, 123000
|
|
317
|
+
_(col.default).must_equal time, "Microseconds were <#{col.default.usec}> vs <123000>"
|
|
318
|
+
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <123000>"
|
|
319
|
+
_(col.default_function).must_be_nil
|
|
320
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
321
|
+
_(type).must_be_instance_of Type::DateTime
|
|
322
|
+
_(type.limit).must_be_nil
|
|
323
|
+
_(type.precision).must_be_nil
|
|
324
|
+
_(type.scale).must_be_nil
|
|
325
|
+
obj.save!
|
|
326
|
+
_(obj).must_equal obj.class.where(datetime: time).first
|
|
327
|
+
# Can save to proper accuracy and return again.
|
|
328
|
+
time = Time.utc 2010, 4, 1, 12, 34, 56, 3000
|
|
329
|
+
obj.datetime = time
|
|
330
|
+
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>"
|
|
331
|
+
obj.save!
|
|
332
|
+
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>"
|
|
333
|
+
obj.reload
|
|
334
|
+
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>"
|
|
335
|
+
_(obj).must_equal obj.class.where(datetime: time).first
|
|
336
|
+
# Can filter by datetime range
|
|
337
|
+
_(obj).must_equal obj.class.where(datetime: time..DateTime::Infinity.new).first
|
|
338
|
+
# Will cast to true DB value on attribute write, save and return again.
|
|
339
|
+
time = Time.utc 2010, 4, 1, 12, 34, 56, 234567
|
|
340
|
+
time2 = Time.utc 2010, 4, 1, 12, 34, 56, 233000
|
|
341
|
+
obj.datetime = time
|
|
342
|
+
_(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>"
|
|
343
|
+
obj.save!
|
|
344
|
+
_(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>"
|
|
345
|
+
obj.reload
|
|
346
|
+
_(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>"
|
|
347
|
+
_(obj).must_equal obj.class.where(datetime: time).first
|
|
348
|
+
_(obj).must_equal obj.class.where(datetime: time2).first
|
|
349
|
+
# Set and find nil.
|
|
350
|
+
obj.datetime = nil
|
|
351
|
+
_(obj.datetime).must_be_nil
|
|
352
|
+
obj.save!
|
|
353
|
+
_(obj.datetime).must_be_nil
|
|
354
|
+
_(obj).must_equal obj.class.where(datetime: nil).first
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it "datetime2" do
|
|
358
|
+
skip "datetime2 not supported in this protocol version" unless connection_tds_73
|
|
359
|
+
col = column("datetime2_7")
|
|
360
|
+
_(col.sql_type).must_equal "datetime2(7)"
|
|
361
|
+
_(col.type).must_equal :datetime
|
|
362
|
+
_(col.null).must_equal true
|
|
363
|
+
time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(999999900, 1000)
|
|
364
|
+
_(col.default).must_equal time, "Nanoseconds were <#{col.default.nsec}> vs <999999900>"
|
|
365
|
+
_(obj.datetime2_7).must_equal time, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <999999900>"
|
|
366
|
+
_(col.default_function).must_be_nil
|
|
367
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
368
|
+
_(type).must_be_instance_of Type::DateTime2
|
|
369
|
+
_(type.limit).must_be_nil
|
|
370
|
+
_(type.precision).must_equal 7
|
|
371
|
+
_(type.scale).must_be_nil
|
|
372
|
+
obj.save!
|
|
373
|
+
_(obj).must_equal obj.class.where(datetime2_7: time).first
|
|
374
|
+
# Can save 100 nanosecond precisoins and return again.
|
|
375
|
+
time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(123456755, 1000)
|
|
376
|
+
time2 = Time.utc 9999, 12, 31, 23, 59, 59, Rational(123456800, 1000)
|
|
377
|
+
obj.datetime2_7 = time
|
|
378
|
+
_(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>"
|
|
379
|
+
obj.save!
|
|
380
|
+
_(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>"
|
|
381
|
+
obj.reload
|
|
382
|
+
_(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>"
|
|
383
|
+
_(obj).must_equal obj.class.where(datetime2_7: time).first
|
|
384
|
+
_(obj).must_equal obj.class.where(datetime2_7: time2).first
|
|
385
|
+
# Can save small fraction nanosecond precisoins and return again.
|
|
386
|
+
time = Time.utc 2008, 6, 21, 13, 30, 0, Rational(15020, 1000)
|
|
387
|
+
time2 = Time.utc 2008, 6, 21, 13, 30, 0, Rational(15000, 1000)
|
|
388
|
+
obj.datetime2_7 = time
|
|
389
|
+
_(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <15000>"
|
|
390
|
+
obj.save!
|
|
391
|
+
_(obj.reload.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <15000>"
|
|
392
|
+
_(obj).must_equal obj.class.where(datetime2_7: time).first
|
|
393
|
+
_(obj).must_equal obj.class.where(datetime2_7: time2).first
|
|
394
|
+
# datetime2_3
|
|
395
|
+
time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(123456789, 1000)
|
|
396
|
+
col = column("datetime2_3")
|
|
397
|
+
_(connection.lookup_cast_type_from_column(col).precision).must_equal 3
|
|
398
|
+
obj.datetime2_3 = time
|
|
399
|
+
_(obj.datetime2_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetime2_3.nsec}> vs <123000000>"
|
|
400
|
+
obj.save!; obj.reload
|
|
401
|
+
_(obj.datetime2_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetime2_3.nsec}> vs <123000000>"
|
|
402
|
+
_(obj).must_equal obj.class.where(datetime2_3: time).first
|
|
403
|
+
# datetime2_1
|
|
404
|
+
col = column("datetime2_1")
|
|
405
|
+
_(connection.lookup_cast_type_from_column(col).precision).must_equal 1
|
|
406
|
+
obj.datetime2_1 = time
|
|
407
|
+
_(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>"
|
|
408
|
+
obj.save!; obj.reload
|
|
409
|
+
_(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>"
|
|
410
|
+
_(obj).must_equal obj.class.where(datetime2_1: time).first
|
|
411
|
+
# datetime2_0
|
|
412
|
+
col = column("datetime2_0")
|
|
413
|
+
_(connection.lookup_cast_type_from_column(col).precision).must_equal 0
|
|
414
|
+
time = Time.utc 2016, 4, 19, 16, 45, 40, 771036
|
|
415
|
+
obj.datetime2_0 = time
|
|
416
|
+
_(obj.datetime2_0).must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>"
|
|
417
|
+
obj.save!; obj.reload
|
|
418
|
+
_(obj.datetime2_0).must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>"
|
|
419
|
+
_(obj).must_equal obj.class.where(datetime2_0: time).first
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
it "datetimeoffset" do
|
|
423
|
+
skip "datetimeoffset not supported in this protocol version" unless connection_tds_73
|
|
424
|
+
col = column("datetimeoffset_7")
|
|
425
|
+
_(col.sql_type).must_equal "datetimeoffset(7)"
|
|
426
|
+
_(col.type).must_equal :datetimeoffset
|
|
427
|
+
_(col.null).must_equal true
|
|
428
|
+
_(col.default).must_equal Time.new(1984, 1, 24, 4, 20, 0, -28800).change(nsec: 123456700), "Nanoseconds <#{col.default.nsec}> vs <123456700>"
|
|
429
|
+
_(obj.datetimeoffset_7).must_equal Time.new(1984, 1, 24, 4, 20, 0, -28800).change(nsec: 123456700), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <999999900>"
|
|
430
|
+
_(col.default_function).must_be_nil
|
|
431
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
432
|
+
_(type).must_be_instance_of Type::DateTimeOffset
|
|
433
|
+
_(type.limit).must_be_nil
|
|
434
|
+
_(type.precision).must_equal 7
|
|
435
|
+
_(type.scale).must_be_nil
|
|
436
|
+
|
|
437
|
+
# Can save 100 nanosecond precisions and return again.
|
|
438
|
+
obj.datetimeoffset_7 = Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456755)
|
|
439
|
+
_(obj.datetimeoffset_7).must_equal Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>"
|
|
440
|
+
obj.save!
|
|
441
|
+
_(obj.datetimeoffset_7).must_equal Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>"
|
|
442
|
+
obj.reload
|
|
443
|
+
_(obj.datetimeoffset_7).must_equal Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>"
|
|
444
|
+
|
|
445
|
+
# Maintains the timezone
|
|
446
|
+
time = ActiveSupport::TimeZone["America/Los_Angeles"].local 2010, 12, 31, 23, 59, 59, Rational(123456800, 1000)
|
|
447
|
+
obj.datetimeoffset_7 = time
|
|
448
|
+
_(obj.datetimeoffset_7).must_equal time
|
|
449
|
+
obj.save!
|
|
450
|
+
_(obj.datetimeoffset_7).must_equal time
|
|
451
|
+
_(obj.reload.datetimeoffset_7).must_equal time
|
|
452
|
+
|
|
453
|
+
# With other precisions.
|
|
454
|
+
time = ActiveSupport::TimeZone["America/Los_Angeles"].local 2010, 12, 31, 23, 59, 59, Rational(123456755, 1000)
|
|
455
|
+
col = column("datetimeoffset_3")
|
|
456
|
+
_(connection.lookup_cast_type_from_column(col).precision).must_equal 3
|
|
457
|
+
obj.datetimeoffset_3 = time
|
|
458
|
+
_(obj.datetimeoffset_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetimeoffset_3.nsec}> vs <123000000>"
|
|
459
|
+
obj.save!
|
|
460
|
+
_(obj.datetimeoffset_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetimeoffset_3.nsec}> vs <123000000>"
|
|
461
|
+
col = column("datetime2_1")
|
|
462
|
+
_(connection.lookup_cast_type_from_column(col).precision).must_equal 1
|
|
463
|
+
obj.datetime2_1 = time
|
|
464
|
+
_(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>"
|
|
465
|
+
obj.save!
|
|
466
|
+
_(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>"
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it "smalldatetime" do
|
|
470
|
+
col = column("smalldatetime")
|
|
471
|
+
_(col.sql_type).must_equal "smalldatetime"
|
|
472
|
+
_(col.type).must_equal :smalldatetime
|
|
473
|
+
_(col.null).must_equal true
|
|
474
|
+
_(col.default).must_equal Time.utc(1901, 1, 1, 15, 45, 0, 0)
|
|
475
|
+
_(obj.smalldatetime).must_equal Time.utc(1901, 1, 1, 15, 45, 0, 0)
|
|
476
|
+
_(col.default_function).must_be_nil
|
|
477
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
478
|
+
_(type).must_be_instance_of Type::SmallDateTime
|
|
479
|
+
_(type.limit).must_be_nil
|
|
480
|
+
_(type.precision).must_be_nil
|
|
481
|
+
_(type.scale).must_be_nil
|
|
482
|
+
# Will remove fractional seconds and return again.
|
|
483
|
+
obj.smalldatetime = Time.utc(2078, 6, 5, 4, 20, 0, 3000)
|
|
484
|
+
_(obj.smalldatetime).must_equal Time.utc(2078, 6, 5, 4, 20, 0, 0), "Microseconds were <#{obj.smalldatetime.usec}> vs <0>"
|
|
485
|
+
obj.save!
|
|
486
|
+
_(obj.smalldatetime).must_equal Time.utc(2078, 6, 5, 4, 20, 0, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>"
|
|
487
|
+
obj.reload
|
|
488
|
+
_(obj.smalldatetime).must_equal Time.utc(2078, 6, 5, 4, 20, 0, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>"
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
it "time(7)" do
|
|
492
|
+
skip "time() not supported in this protocol version" unless connection_tds_73
|
|
493
|
+
col = column("time_7")
|
|
494
|
+
_(col.sql_type).must_equal "time(7)"
|
|
495
|
+
_(col.type).must_equal :time
|
|
496
|
+
_(col.null).must_equal true
|
|
497
|
+
_(col.default).must_equal Time.utc(1900, 1, 1, 4, 20, 0, Rational(288321500, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <288321500>"
|
|
498
|
+
_(col.default_function).must_be_nil
|
|
499
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
500
|
+
_(type).must_be_instance_of Type::Time
|
|
501
|
+
_(type.limit).must_be_nil
|
|
502
|
+
_(type.precision).must_equal 7
|
|
503
|
+
_(type.scale).must_be_nil
|
|
504
|
+
# Time's #usec precision (low micro)
|
|
505
|
+
obj.time_7 = Time.utc(2000, 1, 1, 15, 45, 0, 300)
|
|
506
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>"
|
|
507
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>"
|
|
508
|
+
obj.save!; obj.reload
|
|
509
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>"
|
|
510
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>"
|
|
511
|
+
# Time's #usec precision (high micro)
|
|
512
|
+
obj.time_7 = Time.utc(2000, 1, 1, 15, 45, 0, 234567)
|
|
513
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>"
|
|
514
|
+
obj.save!; obj.reload
|
|
515
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>"
|
|
516
|
+
# Time's #usec precision (high nano rounded)
|
|
517
|
+
obj.time_7 = Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321545, 1000))
|
|
518
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>"
|
|
519
|
+
obj.save!; obj.reload
|
|
520
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>"
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it "time(2)" do
|
|
524
|
+
skip "time() not supported in this protocol version" unless connection_tds_73
|
|
525
|
+
col = column("time_2")
|
|
526
|
+
_(col.sql_type).must_equal "time(2)"
|
|
527
|
+
_(col.type).must_equal :time
|
|
528
|
+
_(col.null).must_equal true
|
|
529
|
+
_(col.default).must_be_nil
|
|
530
|
+
_(col.default_function).must_be_nil
|
|
531
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
532
|
+
_(type).must_be_instance_of Type::Time
|
|
533
|
+
_(type.limit).must_be_nil
|
|
534
|
+
_(type.precision).must_equal 2
|
|
535
|
+
_(type.scale).must_be_nil
|
|
536
|
+
# Always uses TinyTDS/Windows 2000-01-01 convention too.
|
|
537
|
+
obj.time_2 = Time.utc(2015, 1, 10, 15, 45, 0, 0)
|
|
538
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0)
|
|
539
|
+
obj.save!; obj.reload
|
|
540
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0)
|
|
541
|
+
# Time's #usec precision (barely in 2 precision equal to 0.03 seconds)
|
|
542
|
+
obj.time_2 = Time.utc(2000, 1, 1, 15, 45, 0, 30000)
|
|
543
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>"
|
|
544
|
+
obj.save!; obj.reload
|
|
545
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>"
|
|
546
|
+
# Time's #usec precision (below 2 precision)
|
|
547
|
+
obj.time_2 = Time.utc(2000, 1, 1, 15, 45, 0, 4000)
|
|
548
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>"
|
|
549
|
+
obj.save!; obj.reload
|
|
550
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>"
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
it "time using default precision" do
|
|
554
|
+
skip "time() not supported in this protocol version" unless connection_tds_73
|
|
555
|
+
col = column("time_default")
|
|
556
|
+
_(col.sql_type).must_equal "time(7)"
|
|
557
|
+
_(col.type).must_equal :time
|
|
558
|
+
_(col.null).must_equal true
|
|
559
|
+
_(col.default).must_equal Time.utc(1900, 1, 1, 15, 3, 42, Rational(62197800, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <62197800>"
|
|
560
|
+
_(col.default_function).must_be_nil
|
|
561
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
562
|
+
_(type).must_be_instance_of Type::Time
|
|
563
|
+
_(type.limit).must_be_nil
|
|
564
|
+
_(type.precision).must_equal 7
|
|
565
|
+
_(type.scale).must_be_nil
|
|
566
|
+
# Time's #usec precision (low micro)
|
|
567
|
+
obj.time_default = Time.utc(2000, 1, 1, 15, 45, 0, 300)
|
|
568
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_default.usec}> vs <0>"
|
|
569
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_default.nsec}> vs <300>"
|
|
570
|
+
obj.save!; obj.reload
|
|
571
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_default.usec}> vs <0>"
|
|
572
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_default.nsec}> vs <300>"
|
|
573
|
+
# Time's #usec precision (high micro)
|
|
574
|
+
obj.time_default = Time.utc(2000, 1, 1, 15, 45, 0, 234567)
|
|
575
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_default.usec}> vs <234567>"
|
|
576
|
+
obj.save!; obj.reload
|
|
577
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_default.usec}> vs <234567>"
|
|
578
|
+
# Time's #usec precision (high nano rounded)
|
|
579
|
+
obj.time_default = Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321545, 1000))
|
|
580
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_default.nsec}> vs <288321500>"
|
|
581
|
+
obj.save!; obj.reload
|
|
582
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_default.nsec}> vs <288321500>"
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
# Character Strings
|
|
586
|
+
|
|
587
|
+
it "char(10)" do
|
|
588
|
+
col = column("char_10")
|
|
589
|
+
_(col.sql_type).must_equal "char(10)"
|
|
590
|
+
_(col.type).must_equal :char
|
|
591
|
+
_(col.null).must_equal true
|
|
592
|
+
_(col.default).must_equal "1234567890"
|
|
593
|
+
_(obj.char_10).must_equal "1234567890"
|
|
594
|
+
_(col.default_function).must_be_nil
|
|
595
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
596
|
+
_(type).must_be_instance_of Type::Char
|
|
597
|
+
_(type.limit).must_equal 10
|
|
598
|
+
_(type.precision).must_be_nil
|
|
599
|
+
_(type.scale).must_be_nil
|
|
600
|
+
# Basic set and save.
|
|
601
|
+
obj.char_10 = "012345"
|
|
602
|
+
_(obj.char_10.strip).must_equal "012345"
|
|
603
|
+
obj.save!
|
|
604
|
+
_(obj.reload.char_10.strip).must_equal "012345"
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
it "varchar(50)" do
|
|
608
|
+
col = column("varchar_50")
|
|
609
|
+
_(col.sql_type).must_equal "varchar(50)"
|
|
610
|
+
_(col.type).must_equal :varchar
|
|
611
|
+
_(col.null).must_equal true
|
|
612
|
+
_(col.default).must_equal "test varchar_50"
|
|
613
|
+
_(obj.varchar_50).must_equal "test varchar_50"
|
|
614
|
+
_(col.default_function).must_be_nil
|
|
615
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
616
|
+
_(type).must_be_instance_of Type::Varchar
|
|
617
|
+
_(type.limit).must_equal 50
|
|
618
|
+
_(type.precision).must_be_nil
|
|
619
|
+
_(type.scale).must_be_nil
|
|
620
|
+
# Basic set and save.
|
|
621
|
+
assert_obj_set_and_save :varchar_50, "Hello World"
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
it "varchar(max)" do
|
|
625
|
+
col = column("varchar_max")
|
|
626
|
+
_(col.sql_type).must_equal "varchar(max)"
|
|
627
|
+
_(col.type).must_equal :varchar_max
|
|
628
|
+
_(col.null).must_equal true
|
|
629
|
+
_(col.default).must_equal "test varchar_max"
|
|
630
|
+
_(obj.varchar_max).must_equal "test varchar_max"
|
|
631
|
+
_(col.default_function).must_be_nil
|
|
632
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
633
|
+
_(type).must_be_instance_of Type::VarcharMax
|
|
634
|
+
_(type.limit).must_equal 2_147_483_647
|
|
635
|
+
_(type.precision).must_be_nil
|
|
636
|
+
_(type.scale).must_be_nil
|
|
637
|
+
# Basic set and save.
|
|
638
|
+
assert_obj_set_and_save :varchar_max, "Hello World"
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
it "text" do
|
|
642
|
+
col = column("text")
|
|
643
|
+
_(col.sql_type).must_equal "text"
|
|
644
|
+
_(col.type).must_equal :text_basic
|
|
645
|
+
_(col.null).must_equal true
|
|
646
|
+
_(col.default).must_equal "test text"
|
|
647
|
+
_(obj.text).must_equal "test text"
|
|
648
|
+
_(col.default_function).must_be_nil
|
|
649
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
650
|
+
_(type).must_be_instance_of Type::Text
|
|
651
|
+
_(type.limit).must_equal 2_147_483_647
|
|
652
|
+
_(type.precision).must_be_nil
|
|
653
|
+
_(type.scale).must_be_nil
|
|
654
|
+
# Basic set and save.
|
|
655
|
+
assert_obj_set_and_save :text, "Hello World"
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
# Unicode Character Strings
|
|
659
|
+
|
|
660
|
+
it "nchar(10)" do
|
|
661
|
+
col = column("nchar_10")
|
|
662
|
+
_(col.sql_type).must_equal "nchar(10)"
|
|
663
|
+
_(col.type).must_equal :nchar
|
|
664
|
+
_(col.null).must_equal true
|
|
665
|
+
_(col.default).must_equal "12345678åå"
|
|
666
|
+
_(obj.nchar_10).must_equal "12345678åå"
|
|
667
|
+
_(col.default_function).must_be_nil
|
|
668
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
669
|
+
_(type).must_be_instance_of Type::UnicodeChar
|
|
670
|
+
_(type.limit).must_equal 10
|
|
671
|
+
_(type.precision).must_be_nil
|
|
672
|
+
_(type.scale).must_be_nil
|
|
673
|
+
# Basic set and save.
|
|
674
|
+
obj.nchar_10 = "五六"
|
|
675
|
+
_(obj.nchar_10.strip).must_equal "五六"
|
|
676
|
+
obj.save!
|
|
677
|
+
_(obj.reload.nchar_10.strip).must_equal "五六"
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
it "nvarchar(50)" do
|
|
681
|
+
col = column("nvarchar_50")
|
|
682
|
+
_(col.sql_type).must_equal "nvarchar(50)"
|
|
683
|
+
_(col.type).must_equal :string
|
|
684
|
+
_(col.null).must_equal true
|
|
685
|
+
_(col.default).must_equal "test nvarchar_50 åå"
|
|
686
|
+
_(obj.nvarchar_50).must_equal "test nvarchar_50 åå"
|
|
687
|
+
_(col.default_function).must_be_nil
|
|
688
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
689
|
+
_(type).must_be_instance_of Type::UnicodeVarchar
|
|
690
|
+
_(type.limit).must_equal 50
|
|
691
|
+
_(type.precision).must_be_nil
|
|
692
|
+
_(type.scale).must_be_nil
|
|
693
|
+
# Basic set and save.
|
|
694
|
+
assert_obj_set_and_save :nvarchar_50, "一二34五六"
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
it "nvarchar(max)" do
|
|
698
|
+
col = column("nvarchar_max")
|
|
699
|
+
_(col.sql_type).must_equal "nvarchar(max)"
|
|
700
|
+
_(col.type).must_equal :text
|
|
701
|
+
_(col.null).must_equal true
|
|
702
|
+
_(col.default).must_equal "test nvarchar_max åå"
|
|
703
|
+
_(obj.nvarchar_max).must_equal "test nvarchar_max åå"
|
|
704
|
+
_(col.default_function).must_be_nil
|
|
705
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
706
|
+
_(type).must_be_instance_of Type::UnicodeVarcharMax
|
|
707
|
+
_(type.limit).must_equal 2_147_483_647
|
|
708
|
+
_(type.precision).must_be_nil
|
|
709
|
+
_(type.scale).must_be_nil
|
|
710
|
+
# Basic set and save.
|
|
711
|
+
assert_obj_set_and_save :nvarchar_max, "一二34五六"
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
it "ntext" do
|
|
715
|
+
col = column("ntext")
|
|
716
|
+
_(col.sql_type).must_equal "ntext"
|
|
717
|
+
_(col.type).must_equal :ntext
|
|
718
|
+
_(col.null).must_equal true
|
|
719
|
+
_(col.default).must_equal "test ntext åå"
|
|
720
|
+
_(obj.ntext).must_equal "test ntext åå"
|
|
721
|
+
_(col.default_function).must_be_nil
|
|
722
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
723
|
+
_(type).must_be_instance_of Type::UnicodeText
|
|
724
|
+
_(type.limit).must_equal 2_147_483_647
|
|
725
|
+
_(type.precision).must_be_nil
|
|
726
|
+
_(type.scale).must_be_nil
|
|
727
|
+
# Basic set and save.
|
|
728
|
+
assert_obj_set_and_save :ntext, "一二34五六"
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
# Binary Strings
|
|
732
|
+
|
|
733
|
+
let(:binary_file) { File.join ARTest::SQLServer.test_root_sqlserver, "fixtures", "1px.gif" }
|
|
734
|
+
let(:binary_data) { File.open(binary_file, "rb") { |f| f.read } }
|
|
735
|
+
|
|
736
|
+
it "binary(49)" do
|
|
737
|
+
col = column("binary_49")
|
|
738
|
+
_(col.sql_type).must_equal "binary(49)"
|
|
739
|
+
_(col.type).must_equal :binary_basic
|
|
740
|
+
_(col.null).must_equal true
|
|
741
|
+
_(col.default).must_be_nil
|
|
742
|
+
_(col.default_function).must_be_nil
|
|
743
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
744
|
+
_(type).must_be_instance_of Type::Binary
|
|
745
|
+
_(type.limit).must_equal 49
|
|
746
|
+
_(type.precision).must_be_nil
|
|
747
|
+
_(type.scale).must_be_nil
|
|
748
|
+
# Basic set and save.
|
|
749
|
+
_(binary_data.encoding).must_equal Encoding::BINARY
|
|
750
|
+
_(binary_data.length).must_equal 49
|
|
751
|
+
obj.binary_49 = binary_data
|
|
752
|
+
_(obj.binary_49).must_equal binary_data
|
|
753
|
+
obj.save!
|
|
754
|
+
_(obj.reload.binary_49).must_equal binary_data
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
it "varbinary(49)" do
|
|
758
|
+
col = column("varbinary_49")
|
|
759
|
+
_(col.sql_type).must_equal "varbinary(49)"
|
|
760
|
+
_(col.type).must_equal :varbinary
|
|
761
|
+
_(col.null).must_equal true
|
|
762
|
+
_(col.default).must_be_nil
|
|
763
|
+
_(col.default_function).must_be_nil
|
|
764
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
765
|
+
_(type).must_be_instance_of Type::Varbinary
|
|
766
|
+
_(type.limit).must_equal 49
|
|
767
|
+
_(type.precision).must_be_nil
|
|
768
|
+
_(type.scale).must_be_nil
|
|
769
|
+
# Basic set and save.
|
|
770
|
+
binary_data20 = binary_data.to(20)
|
|
771
|
+
_(binary_data20.encoding).must_equal Encoding::BINARY
|
|
772
|
+
obj.varbinary_49 = binary_data20
|
|
773
|
+
_(obj.varbinary_49).must_equal binary_data20
|
|
774
|
+
obj.save!
|
|
775
|
+
_(obj.reload.varbinary_49).must_equal binary_data20
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
it "varbinary(max)" do
|
|
779
|
+
col = column("varbinary_max")
|
|
780
|
+
_(col.sql_type).must_equal "varbinary(max)"
|
|
781
|
+
_(col.type).must_equal :binary
|
|
782
|
+
_(col.null).must_equal true
|
|
783
|
+
_(col.default).must_be_nil
|
|
784
|
+
_(col.default_function).must_be_nil
|
|
785
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
786
|
+
_(type).must_be_instance_of Type::VarbinaryMax
|
|
787
|
+
_(type.limit).must_equal 2_147_483_647
|
|
788
|
+
_(type.precision).must_be_nil
|
|
789
|
+
_(type.scale).must_be_nil
|
|
790
|
+
# Basic set and save.
|
|
791
|
+
_(binary_data.encoding).must_equal Encoding::BINARY
|
|
792
|
+
assert_obj_set_and_save :varbinary_max, binary_data
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
# Other Data Types
|
|
796
|
+
|
|
797
|
+
it "uniqueidentifier" do
|
|
798
|
+
col = column("uniqueidentifier")
|
|
799
|
+
_(col.sql_type).must_equal "uniqueidentifier"
|
|
800
|
+
_(col.type).must_equal :uuid
|
|
801
|
+
_(col.null).must_equal true
|
|
802
|
+
_(col.default).must_be_nil
|
|
803
|
+
_(col.default_function).must_equal "newid()"
|
|
804
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
805
|
+
_(type).must_be_instance_of Type::Uuid
|
|
806
|
+
_(type.limit).must_be_nil
|
|
807
|
+
_(type.precision).must_be_nil
|
|
808
|
+
_(type.scale).must_be_nil
|
|
809
|
+
# Basic set and save.
|
|
810
|
+
obj.uniqueidentifier = "this will not qualify as valid"
|
|
811
|
+
_(obj.uniqueidentifier).must_be_nil
|
|
812
|
+
obj.save!; obj.reload
|
|
813
|
+
_(obj.uniqueidentifier).must_match Type::Uuid::ACCEPTABLE_UUID
|
|
814
|
+
obj.uniqueidentifier = "6F9619FF-8B86-D011-B42D-00C04FC964FF"
|
|
815
|
+
_(obj.uniqueidentifier).must_equal "6F9619FF-8B86-D011-B42D-00C04FC964FF"
|
|
816
|
+
obj.save!; obj.reload
|
|
817
|
+
_(obj.uniqueidentifier).must_equal "6F9619FF-8B86-D011-B42D-00C04FC964FF"
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
it "timestamp" do
|
|
821
|
+
col = column("timestamp")
|
|
822
|
+
_(col.sql_type).must_equal "timestamp"
|
|
823
|
+
_(col.type).must_equal :ss_timestamp
|
|
824
|
+
_(col.null).must_equal true
|
|
825
|
+
_(col.default).must_be_nil
|
|
826
|
+
_(col.default_function).must_be_nil
|
|
827
|
+
type = connection.lookup_cast_type_from_column(col)
|
|
828
|
+
_(type).must_be_instance_of Type::Timestamp
|
|
829
|
+
_(type.limit).must_be_nil
|
|
830
|
+
_(type.precision).must_be_nil
|
|
831
|
+
_(type.scale).must_be_nil
|
|
832
|
+
# Basic read.
|
|
833
|
+
_(obj.timestamp).must_be_nil
|
|
834
|
+
obj.save!; obj.reload
|
|
835
|
+
_(obj.timestamp).must_match %r|\000|
|
|
836
|
+
obj.timestamp
|
|
837
|
+
# Can set another attribute
|
|
838
|
+
obj.uniqueidentifier = "6F9619FF-8B86-D011-B42D-00C04FC964FF"
|
|
839
|
+
obj.save!
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
it "does not mark object as changed after save" do
|
|
843
|
+
obj.save!
|
|
844
|
+
obj.attributes
|
|
845
|
+
_(obj.changed?).must_equal false
|
|
846
|
+
end
|
|
847
|
+
end
|
|
848
|
+
end
|