Allow nilable types in DB.mapping

Previously, using a Nilable type in DB.mapping instead of nilable: true would
fail with a nil assertion error.
This commit is contained in:
RX14 2017-02-14 21:51:45 +00:00
parent 3fa1eac6c5
commit 0797ce72a3
2 changed files with 22 additions and 3 deletions

View file

@ -29,6 +29,13 @@ class MappingWithNilables
}) })
end end
class MappingWithNilTypes
DB.mapping({
c0: {type: Int32?, default: 10},
c1: String?,
})
end
class MappingWithKeys class MappingWithKeys
DB.mapping({ DB.mapping({
foo: {type: Int32, key: "c0"}, foo: {type: Int32, key: "c0"},
@ -100,14 +107,22 @@ describe "DB.mapping" do
expect_mapping("1,NULL", MappingWithDefaults, {c0: 1, c1: "c"}) expect_mapping("1,NULL", MappingWithDefaults, {c0: 1, c1: "c"})
end end
it "should initialize a mapping with nils if columns are missing" do it "should initialize a mapping with nilable set if columns are missing" do
expect_mapping("1", MappingWithNilables, {c0: 1, c1: nil}) expect_mapping("1", MappingWithNilables, {c0: 1, c1: nil})
end end
it "should initialize a mapping with nils ignoring default value is type is nilable" do it "should initialize a mapping with nilable set ignoring default value if NULL" do
expect_mapping("NULL,a", MappingWithNilables, {c0: nil, c1: "a"}) expect_mapping("NULL,a", MappingWithNilables, {c0: nil, c1: "a"})
end end
it "should initialize a mapping with nilable types if columns are missing" do
expect_mapping("1", MappingWithNilTypes, {c0: 1, c1: nil})
end
it "should initialize a mapping with nilable types ignoring default value if NULL" do
expect_mapping("NULL,a", MappingWithNilTypes, {c0: nil, c1: "a"})
end
it "should initialize a mapping with different keys" do it "should initialize a mapping with different keys" do
expect_mapping("1,a", MappingWithKeys, {foo: 1, bar: "a"}) expect_mapping("1,a", MappingWithKeys, {foo: 1, bar: "a"})
end end

View file

@ -64,6 +64,10 @@ module DB
{% properties[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %} {% properties[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %}
{% end %} {% end %}
{% for key, value in properties %}
{% value[:nilable] = true if value[:type].is_a?(Generic) && value[:type].type_vars.map(&.resolve).includes?(Nil) %}
{% end %}
{% for key, value in properties %} {% for key, value in properties %}
@{{key.id}} : {{value[:type]}} {{ (value[:nilable] ? "?" : "").id }} @{{key.id}} : {{value[:type]}} {{ (value[:nilable] ? "?" : "").id }}
@ -131,7 +135,7 @@ module DB
{% elsif value[:default] != nil %} {% elsif value[:default] != nil %}
@{{key.id}} = %var{key.id}.is_a?(Nil) ? {{value[:default]}} : %var{key.id} @{{key.id}} = %var{key.id}.is_a?(Nil) ? {{value[:default]}} : %var{key.id}
{% else %} {% else %}
@{{key.id}} = %var{key.id}.not_nil! @{{key.id}} = %var{key.id}.as({{value[:type]}})
{% end %} {% end %}
{% end %} {% end %}
end end