Skip to content

Instantly share code, notes, and snippets.

@danielwertheim
Created October 28, 2011 11:51
Show Gist options
  • Save danielwertheim/1322116 to your computer and use it in GitHub Desktop.
Save danielwertheim/1322116 to your computer and use it in GitHub Desktop.
DbDataTypeTransaltor
public interface IDbDataTypeTranslator
{
string ToDbType(IIndexAccessor indexAccessor);
string ToDbType(Type dataType);
}
public class Sql2008DataTypeTranslator : IDbDataTypeTranslator
{
public string ToDbType(IIndexAccessor indexAccessor)
{
if(indexAccessor.IsEnumerable && indexAccessor.DataType.IsEnumerableBytesType())
throw new SisoDbException(
Sql2008Exceptions.SqlDbDataTypeTranslator_ByteArraysAreNotSupported.Inject(indexAccessor.Path));
if(indexAccessor.IsElement)
return ("[nvarchar](max)");
return ToDbType(indexAccessor.DataType);
}
public string ToDbType(Type dataType)
{
if (dataType.IsEnumerableType())
return ("[nvarchar](max)");
if (dataType.IsStringType())
return ("[nvarchar](max)");
if (dataType.IsIntType() || dataType.IsNullableIntType())
return ("[int]");
if (dataType.IsByteType() || dataType.IsNullableByteType())
return ("[tinyint]");
if (dataType.IsDateTimeType() || dataType.IsNullableDateTimeType())
return ("[datetime]");
if (dataType.IsLongType() || dataType.IsNullableLongType())
return ("[bigint]");
if (dataType.IsShortType() || dataType.IsNullableShortType())
return ("[smallint]");
if (dataType.IsBoolType() || dataType.IsNullableBoolType())
return ("[bit]");
if (dataType.IsGuidType() || dataType.IsNullableGuidType())
return ("[uniqueidentifier]");
if (dataType.IsDecimalType() || dataType.IsNullableDecimalType())
return ("[decimal](18,5)");
if (dataType.IsDoubleType() || dataType.IsNullableDoubleType())
return ("[float]");
if (dataType.IsSingleType() || dataType.IsNullableSingleType())
return ("[float]");
if (dataType.IsFloatType() || dataType.IsNullableFloatType())
return ("[float]");
if (dataType.IsCharType() || dataType.IsNullableCharType())
return ("[nchar](1)");
if (dataType.IsEnumType() || dataType.IsNullableEnumType())
return ("[int]");
throw new SisoDbException(
Sql2008Exceptions.SqlDbDataTypeTranslator_UnsupportedDataType.Inject(dataType.Name));
}
}
[TestFixture]
public class Sql2008DataTypeTranslatorTests : UnitTestBase
{
private Sql2008DataTypeTranslator _translator;
protected override void OnFixtureInitialize()
{
_translator = new Sql2008DataTypeTranslator();
}
[Test]
public void ToSql_ForUnsupportedTypeOnIndexAccessor_ThrowsSisoDbException()
{
var iac = GetFakeIndexAccessorForType<TimeSpan>(isUnique: false);
var ex = Assert.Throws<SisoDbException>(() => _translator.ToDbType(iac));
Assert.AreEqual("The datatype 'TimeSpan' is not supported!", ex.Message);
}
[Test]
public void ToSql_ForByteArray_ThrowsException()
{
var propertyFake = new Mock<IStructureProperty>();
propertyFake.Setup(x => x.Path).Returns("Bytes");
propertyFake.Setup(x => x.IsEnumerable).Returns(true);
propertyFake.Setup(x => x.ElementType).Returns(typeof (byte));
propertyFake.Setup(x => x.PropertyType).Returns(typeof (byte[]));
propertyFake.Setup(x => x.IsRootMember).Returns(true);
var iac = new IndexAccessor(propertyFake.Object);
var ex = Assert.Throws<SisoDbException>(() => _translator.ToDbType(iac));
Assert.AreEqual(
Sql2008Exceptions.SqlDbDataTypeTranslator_ByteArraysAreNotSupported.Inject("Bytes"),
ex.Message);
}
[Test]
public void ToSql_ForNonUniqueStringIndexAccessor_ReturnsSqlColumnStringWithNVarChar_Max()
{
var iac = GetFakeIndexAccessorForType<string>(isUnique: false);
AssertSqlTranslation(iac, "[nvarchar](max)");
}
[Test]
public void ToSql_ForUniqueStringIndexAccessor_ReturnsSqlColumnStringWithNVarChar_Max()
{
var iac = GetFakeIndexAccessorForType<string>(isUnique: true);
AssertSqlTranslation(iac, "[nvarchar](max)");
}
[Test]
public void ToSql_ForArrayOfInt_ReturnsSqlColumnStringWithNVarcar_Max()
{
AssertSqlTranslationForType<int[]>("[nvarchar](max)");
}
[Test]
public void ToSql_ForArrayOfString_ReturnsSqlColumnStringWithNVarcar_Max()
{
AssertSqlTranslationForType<string[]>("[nvarchar](max)");
}
[Test]
public void ToSql_ForInt_ReturnsSqlColumnStringWithInt()
{
AssertSqlTranslationForType<int>("[int]");
}
[Test]
public void ToSql_ForByte_ReturnsSqlColumnStringWithInt()
{
AssertSqlTranslationForType<byte>("[tinyint]");
}
[Test]
public void ToSql_ForDateTime_ReturnsSqlColumnStringWithDateTime()
{
AssertSqlTranslationForType<DateTime>("[datetime]");
}
[Test]
public void ToSql_ForLong_ReturnsSqlColumnStringWithBigInt()
{
AssertSqlTranslationForType<long>("[bigint]");
}
[Test]
public void ToSql_ForShort_ReturnsSqlColumnStringWithSmallInt()
{
AssertSqlTranslationForType<short>("[smallint]");
}
[Test]
public void ToSql_ForBool_ReturnsSqlColumnStringWithBit()
{
AssertSqlTranslationForType<bool>("[bit]");
}
[Test]
public void ToSql_ForGuid_ReturnsSqlColumnStringWithUniqueIdentifier()
{
AssertSqlTranslationForType<Guid>("[uniqueidentifier]");
}
[Test]
public void ToSql_ForDecimal_ReturnsSqlColumnStringWithDecimal_18_5()
{
AssertSqlTranslationForType<decimal>("[decimal](18,5)");
}
[Test]
public void ToSql_ForDouble_ReturnsSqlColumnStringWithFloat()
{
AssertSqlTranslationForType<double>("[float]");
}
[Test]
public void ToSql_ForSingle_ReturnsSqlColumnStringWithFloat()
{
AssertSqlTranslationForType<Single>("[float]");
}
[Test]
public void ToSql_ForFloat_ReturnsSqlColumnStringWithFloat()
{
AssertSqlTranslationForType<float>("[float]");
}
[Test]
public void ToSql_ForChar_ReturnsSqlColumnStringWithNChar_1()
{
AssertSqlTranslationForType<char>("[nchar](1)");
}
[Test]
public void ToSql_ForMyEnumDummy_ReturnsSqlColumnStringWithInt()
{
AssertSqlTranslationForType<MyEnumDummy>("[int]");
}
private void AssertSqlTranslationForType<T>(string expectedDbType)
{
var indexAccessor = GetFakeIndexAccessorForType<T>(isUnique: false);
var dbType = _translator.ToDbType(indexAccessor);
Assert.AreEqual(expectedDbType, dbType, indexAccessor.DataType.Name);
}
private void AssertSqlTranslation(IIndexAccessor indexAccessor, string expectedDbType)
{
var dbType = _translator.ToDbType(indexAccessor);
Assert.AreEqual(expectedDbType, dbType, indexAccessor.DataType.Name);
}
private static IIndexAccessor GetFakeIndexAccessorForType<T>(bool isUnique)
{
var iacFake = new Mock<IIndexAccessor>();
iacFake.Setup(x => x.DataType).Returns(typeof (T));
iacFake.Setup(x => x.IsUnique).Returns(isUnique);
return iacFake.Object;
}
private enum MyEnumDummy
{
A
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment