Skip to content

Commit 7877cb0

Browse files
committed
Merge branch '7-0-stable' of https://github.com/rails-sqlserver/activerecord-sqlserver-adapter into 7-0-stable
2 parents faa34a7 + 34fe26a commit 7877cb0

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## Unreleased
2+
3+
#### Added
4+
5+
- [#1141](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1141) Added support for check constraints.
6+
17
## v7.0.5.1
28

39
#### Fixed

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,29 @@ def extract_foreign_key_action(action, fk_name)
240240
end
241241
end
242242

243+
def check_constraints(table_name)
244+
sql = <<~SQL
245+
select chk.name AS 'name',
246+
chk.definition AS 'expression'
247+
from sys.check_constraints chk
248+
inner join sys.tables st on chk.parent_object_id = st.object_id
249+
where
250+
st.name = '#{table_name}'
251+
SQL
252+
253+
chk_info = exec_query(sql, "SCHEMA")
254+
255+
chk_info.map do |row|
256+
options = {
257+
name: row["name"]
258+
}
259+
expression = row["expression"]
260+
expression = expression[1..-2] if expression.start_with?("(") && expression.end_with?(")")
261+
262+
CheckConstraintDefinition.new(table_name, expression, options)
263+
end
264+
end
265+
243266
def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
244267
type_limitable = %w(string integer float char nchar varchar nvarchar).include?(type.to_s)
245268
limit = nil unless type_limitable

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ def supports_datetime_with_precision?
228228
true
229229
end
230230

231+
def supports_check_constraints?
232+
true
233+
end
234+
231235
def supports_json?
232236
@version_year >= 2016
233237
end

test/cases/coerced_tests.rb

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,13 @@ def test_schema_dump_includes_decimal_options_coerced
14491449
output = dump_all_table_schema([/^[^n]/])
14501450
assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: 2\.78}, output
14511451
end
1452+
1453+
# SQL Server formats the check constraint expression differently.
1454+
coerce_tests! :test_schema_dumps_check_constraints
1455+
def test_schema_dumps_check_constraints_coerced
1456+
constraint_definition = dump_table_schema("products").split(/\n/).grep(/t.check_constraint.*products_price_check/).first.strip
1457+
assert_equal 't.check_constraint "[price]>[discounted_price]", name: "products_price_check"', constraint_definition
1458+
end
14521459
end
14531460

14541461
class SchemaDumperDefaultsTest < ActiveRecord::TestCase
@@ -2150,7 +2157,7 @@ def test_in_order_of_with_enums_keys_coerced
21502157
coerce_tests! :test_in_order_of_with_nil
21512158
def test_in_order_of_with_nil_coerced
21522159
Book.connection.remove_index(:books, column: [:author_id, :name])
2153-
2160+
21542161
original_test_in_order_of_with_nil
21552162
ensure
21562163
Book.where(author_id: nil, name: nil).delete_all
@@ -2294,3 +2301,51 @@ class ActiveRecord::Encryption::EncryptableRecordTest < ActiveRecord::Encryption
22942301
assert_not author.valid?
22952302
end
22962303
end
2304+
2305+
module ActiveRecord
2306+
class Migration
2307+
class CheckConstraintTest < ActiveRecord::TestCase
2308+
# SQL Server formats the check constraint expression differently.
2309+
coerce_tests! :test_check_constraints
2310+
def test_check_constraints_coerced
2311+
check_constraints = @connection.check_constraints("products")
2312+
assert_equal 1, check_constraints.size
2313+
2314+
constraint = check_constraints.first
2315+
assert_equal "products", constraint.table_name
2316+
assert_equal "products_price_check", constraint.name
2317+
assert_equal "[price]>[discounted_price]", constraint.expression
2318+
end
2319+
2320+
# SQL Server formats the check constraint expression differently.
2321+
coerce_tests! :test_add_check_constraint
2322+
def test_add_check_constraint_coerced
2323+
@connection.add_check_constraint :trades, "quantity > 0"
2324+
2325+
check_constraints = @connection.check_constraints("trades")
2326+
assert_equal 1, check_constraints.size
2327+
2328+
constraint = check_constraints.first
2329+
assert_equal "trades", constraint.table_name
2330+
assert_equal "chk_rails_2189e9f96c", constraint.name
2331+
assert_equal "[quantity]>(0)", constraint.expression
2332+
end
2333+
2334+
# SQL Server formats the check constraint expression differently.
2335+
coerce_tests! :test_remove_check_constraint
2336+
def test_remove_check_constraint_coerced
2337+
@connection.add_check_constraint :trades, "price > 0", name: "price_check"
2338+
@connection.add_check_constraint :trades, "quantity > 0", name: "quantity_check"
2339+
2340+
assert_equal 2, @connection.check_constraints("trades").size
2341+
@connection.remove_check_constraint :trades, name: "quantity_check"
2342+
assert_equal 1, @connection.check_constraints("trades").size
2343+
2344+
constraint = @connection.check_constraints("trades").first
2345+
assert_equal "trades", constraint.table_name
2346+
assert_equal "price_check", constraint.name
2347+
assert_equal "[price]>(0)", constraint.expression
2348+
end
2349+
end
2350+
end
2351+
end

0 commit comments

Comments
 (0)