Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 58095e7

Browse files
committed
Refactor SQL Server Type Converters and tests to auto look for copies of SQL Server assemblies in local /bin
1 parent a487963 commit 58095e7

File tree

8 files changed

+95
-141
lines changed

8 files changed

+95
-141
lines changed

src/ServiceStack.OrmLite.SqlServer.Converters/ServiceStack.OrmLite.SqlServer.Converters.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
<HintPath>..\packages\Microsoft.SqlServer.Types.11.0.2\lib\net20\Microsoft.SqlServer.Types.dll</HintPath>
4747
<Private>True</Private>
4848
</Reference>
49+
<Reference Include="ServiceStack.Text, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
50+
<SpecificVersion>False</SpecificVersion>
51+
<HintPath>..\..\lib\ServiceStack.Text.dll</HintPath>
52+
</Reference>
4953
<Reference Include="System" />
5054
<Reference Include="System.Core" />
5155
<Reference Include="System.Xml.Linq" />
Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,91 @@
1-
using Microsoft.SqlServer.Types;
1+
using System;
2+
using System.IO;
3+
using System.Runtime.InteropServices;
4+
using Microsoft.SqlServer.Types;
25

36
namespace ServiceStack.OrmLite.SqlServer.Converters
47
{
58
public static class SqlServerConverters
69
{
7-
public static IOrmLiteDialectProvider Configure(IOrmLiteDialectProvider dialectProvider)
10+
public static string Msvcr100FileName = "msvcr100.dll";
11+
public static string SqlServerSpatial110FileName = "SqlServerSpatial110.dll";
12+
13+
public static IOrmLiteDialectProvider Configure(IOrmLiteDialectProvider dialectProvider, string libraryPath = null)
814
{
15+
LoadAssembly(Msvcr100FileName, libraryPath);
16+
LoadAssembly(SqlServerSpatial110FileName, libraryPath);
17+
918
dialectProvider.RegisterConverter<SqlGeography>(new SqlServerGeographyTypeConverter());
1019
dialectProvider.RegisterConverter<SqlGeometry>(new SqlServerGeometryTypeConverter());
1120
dialectProvider.RegisterConverter<SqlHierarchyId>(new SqlServerHierarchyIdTypeConverter());
1221
return dialectProvider;
1322
}
23+
24+
public static void LoadAssembly(string assemblyName, string libraryPath = null)
25+
{
26+
// default libraryPath to Windows System
27+
if (string.IsNullOrEmpty(libraryPath))
28+
{
29+
// Get the appropriate Windows System Path
30+
// 32-bit: C:\Windows\System32
31+
// 64-bit: C:\Windows\SysWOW64
32+
var systemPathEnum = (!Environment.Is64BitProcess)
33+
? Environment.SpecialFolder.SystemX86
34+
: Environment.SpecialFolder.System;
35+
36+
libraryPath = Environment.GetFolderPath(systemPathEnum);
37+
}
38+
39+
var arch = Environment.Is64BitProcess
40+
? "x64"
41+
: "x86";
42+
43+
var libraryPaths = new[]
44+
{
45+
libraryPath,
46+
"~/SqlServerTypes/{0}/".Fmt(arch).MapAbsolutePath(),
47+
"~/SqlServerTypes/{0}/".Fmt(arch).MapHostAbsolutePath(),
48+
};
49+
50+
foreach (var libraryDir in libraryPaths)
51+
{
52+
var assemblyPath = Path.Combine(libraryDir, assemblyName);
53+
if (!File.Exists(assemblyPath))
54+
continue;
55+
56+
// The versions of the files must match the version associated with Sql Server
57+
// These files can been installed from the Microsoft SQL Server Feature Pack
58+
//
59+
// SQL Server 2008: https://www.microsoft.com/en-us/download/details.aspx?id=44277
60+
// SQL Server 2008 R2: https://www.microsoft.com/en-us/download/details.aspx?id=44272
61+
// SQL Server 2012 SP2: http://www.microsoft.com/en-us/download/details.aspx?id=43339
62+
// SQL Server 2014 SP1: https://www.microsoft.com/en-us/download/details.aspx?id=46696
63+
64+
var ptr = LoadLibrary(assemblyPath);
65+
if (ptr == IntPtr.Zero)
66+
throw new Exception("Error loading {0} (ErrorCode: {1})".Fmt(
67+
assemblyPath, Marshal.GetLastWin32Error()));
68+
69+
return;
70+
}
71+
}
72+
73+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
74+
private static extern IntPtr LoadLibrary(string libname);
75+
76+
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
77+
private static extern bool FreeLibrary(IntPtr hModule);
78+
79+
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
80+
private static extern bool GetModuleHandleExA(int dwFlags, string moduleName, IntPtr phModule);
81+
82+
public static void UnloadUnmanagedAssembly(string assemblyName)
83+
{
84+
var hMod = IntPtr.Zero;
85+
if (GetModuleHandleExA(0, assemblyName, hMod))
86+
{
87+
while (FreeLibrary(hMod));
88+
}
89+
}
1490
}
1591
}

src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeographyTypeConverter.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ namespace ServiceStack.OrmLite.SqlServer.Converters
99
/// </summary>
1010
public class SqlServerGeographyTypeConverter : SqlServerSpatialTypeConverter
1111
{
12-
public SqlServerGeographyTypeConverter(string libraryPath = null, string msvcrFileName = "msvcr100.dll", string sqlSpatialFileName = "SqlServerSpatial110.dll")
13-
: base(libraryPath, msvcrFileName, sqlSpatialFileName)
14-
{ }
15-
1612
public override string ColumnDefinition
1713
{
1814
get { return "GEOGRAPHY"; }

src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeometryTypeConverter.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ namespace ServiceStack.OrmLite.SqlServer.Converters
99
/// </summary>
1010
public class SqlServerGeometryTypeConverter : SqlServerSpatialTypeConverter
1111
{
12-
public SqlServerGeometryTypeConverter(string libraryPath = null, string msvcrFileName = "msvcr100.dll", string sqlSpatialFileName = "SqlServerSpatial110.dll")
13-
: base(libraryPath, msvcrFileName, sqlSpatialFileName)
14-
{ }
15-
1612
public override string ColumnDefinition
1713
{
1814
get { return "GEOMETRY"; }
Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,11 @@
11
using System;
22
using System.Data;
33
using System.Data.SqlClient;
4-
using System.IO;
5-
using System.Runtime.InteropServices;
6-
using ServiceStack.OrmLite;
74

85
namespace ServiceStack.OrmLite.SqlServer.Converters
96
{
107
public abstract class SqlServerSpatialTypeConverter : OrmLiteConverter
118
{
12-
public SqlServerSpatialTypeConverter(string libraryPath = null, string msvcrFileName = "msvcr100.dll", string sqlSpatialFileName = "SqlServerSpatial110.dll")
13-
{
14-
// default libraryPath to Windows System
15-
if (String.IsNullOrEmpty(libraryPath))
16-
{
17-
// Get the appropriate Windows System Path
18-
// 32-bit: C:\Windows\System32
19-
// 64-bit: C:\Windows\SysWOW64
20-
var systemPathEnum = (!Environment.Is64BitProcess)
21-
? Environment.SpecialFolder.SystemX86
22-
: Environment.SpecialFolder.System;
23-
24-
libraryPath = Environment.GetFolderPath(systemPathEnum);
25-
}
26-
27-
// The versions of the files must match the version associated with Sql Server
28-
// These files can been installed from the Microsoft SQL Server Feature Pack
29-
//
30-
// SQL Server 2008: https://www.microsoft.com/en-us/download/details.aspx?id=44277
31-
// SQL Server 2008 R2: https://www.microsoft.com/en-us/download/details.aspx?id=44272
32-
// SQL Server 2012 SP2: http://www.microsoft.com/en-us/download/details.aspx?id=43339
33-
// SQL Server 2014 SP1: https://www.microsoft.com/en-us/download/details.aspx?id=46696
34-
LoadUnmanagedAssembly(libraryPath, msvcrFileName);
35-
LoadUnmanagedAssembly(libraryPath, sqlSpatialFileName);
36-
}
37-
389
public override DbType DbType
3910
{
4011
get { return DbType.Object; }
@@ -47,38 +18,5 @@ public override void InitDbParam(IDbDataParameter p, Type fieldType)
4718
sqlParam.IsNullable = (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable<>));
4819
sqlParam.UdtTypeName = ColumnDefinition;
4920
}
50-
51-
protected static void LoadUnmanagedAssembly(string libraryPath, string fileName)
52-
{
53-
var path = Path.Combine(libraryPath, fileName);
54-
var ptr = LoadLibrary(path);
55-
if (ptr == IntPtr.Zero)
56-
{
57-
throw new Exception(string.Format(
58-
"Error loading {0} (ErrorCode: {1})",
59-
fileName,
60-
Marshal.GetLastWin32Error()));
61-
}
62-
}
63-
64-
protected static void UnloadUnmanagedAssembly(string assemblyName)
65-
{
66-
var hMod = IntPtr.Zero;
67-
if (GetModuleHandleExA(0, assemblyName, hMod))
68-
{
69-
while (FreeLibrary(hMod))
70-
{
71-
}
72-
}
73-
}
74-
75-
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
76-
private static extern IntPtr LoadLibrary(string libname);
77-
78-
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
79-
private static extern bool FreeLibrary(IntPtr hModule);
80-
81-
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
82-
private static extern bool GetModuleHandleExA(int dwFlags, string moduleName, IntPtr phModule);
8321
}
8422
}

src/ServiceStack.OrmLite.SqlServerTests/Converters/ConvertersOrmLiteTestBase.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
using System;
22
using System.Configuration;
33
using System.Data;
4-
using System.Data.SqlClient;
5-
using System.Runtime.InteropServices;
64
using NUnit.Framework;
7-
using Microsoft.SqlServer.Types;
85
using ServiceStack.Logging;
9-
using ServiceStack.OrmLite.SqlServer;
106
using ServiceStack.OrmLite.SqlServer.Converters;
117

12-
namespace ServiceStack.OrmLite.SqlServerTests.Spatials
8+
namespace ServiceStack.OrmLite.SqlServerTests.Converters
139
{
1410
public class SqlServerConvertersOrmLiteTestBase
1511
{

src/ServiceStack.OrmLite.SqlServerTests/Converters/HierarchyIdTests.cs

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,21 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Data;
42
using System.Linq;
5-
using NUnit.Framework;
63
using Microsoft.SqlServer.Types;
4+
using NUnit.Framework;
75
using ServiceStack.DataAnnotations;
8-
using ServiceStack.OrmLite.SqlServer;
96

10-
namespace ServiceStack.OrmLite.SqlServerTests.Spatials
7+
namespace ServiceStack.OrmLite.SqlServerTests.Converters
118
{
129
[TestFixture]
1310
public class HierarchyIdTests : SqlServerConvertersOrmLiteTestBase
1411
{
15-
[SetUp]
16-
public void Setup()
17-
{
18-
OpenDbConnection().CreateTable<HierarchyTestTable>(true);
19-
}
20-
21-
// Avoid painful refactor to change all tests to use a using pattern
22-
private IDbConnection db;
23-
24-
public override IDbConnection OpenDbConnection(string connString = null)
25-
{
26-
if (db != null && db.State != ConnectionState.Open)
27-
db = null;
28-
29-
return db ?? (db = base.OpenDbConnection(connString));
30-
}
31-
32-
[TearDown]
33-
public void TearDown()
34-
{
35-
if (db == null)
36-
return;
37-
db.Dispose();
38-
db = null;
39-
}
4012
[Test]
4113
public void Can_insert_and_retrieve_HierarchyId()
4214
{
4315
using (var db = OpenDbConnection())
4416
{
17+
db.DropAndCreateTable<HierarchyTestTable>();
18+
4519
var stringValue = "/1/1/3/"; // 0x5ADE is hex
4620

4721
var treeId = SqlHierarchyId.Parse(stringValue);

src/ServiceStack.OrmLite.SqlServerTests/Converters/SpatialsTests.cs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,20 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Data;
4-
using System.Linq;
5-
using NUnit.Framework;
1+
using System.Linq;
62
using Microsoft.SqlServer.Types;
3+
using NUnit.Framework;
74
using ServiceStack.DataAnnotations;
8-
using ServiceStack.OrmLite.SqlServer;
95

10-
namespace ServiceStack.OrmLite.SqlServerTests.Spatials
6+
namespace ServiceStack.OrmLite.SqlServerTests.Converters
117
{
128
[TestFixture]
139
public class SpatialTests : SqlServerConvertersOrmLiteTestBase
1410
{
15-
[SetUp]
16-
public void Setup()
17-
{
18-
OpenDbConnection().CreateTable<GeoTestTable>(true);
19-
}
20-
21-
// Avoid painful refactor to change all tests to use a using pattern
22-
private IDbConnection db;
23-
24-
public override IDbConnection OpenDbConnection(string connString = null)
25-
{
26-
if (db != null && db.State != ConnectionState.Open)
27-
db = null;
28-
29-
return db ?? (db = base.OpenDbConnection(connString));
30-
}
31-
32-
[TearDown]
33-
public void TearDown()
34-
{
35-
if (db == null)
36-
return;
37-
db.Dispose();
38-
db = null;
39-
}
40-
4111
[Test]
4212
public void Can_insert_and_retrieve_SqlGeography()
4313
{
4414
using (var db = OpenDbConnection())
4515
{
16+
db.DropAndCreateTable<GeoTestTable>();
17+
4618
// Statue of Liberty
4719
var geo = SqlGeography.Point(40.6898329,-74.0452177, 4326);
4820

@@ -64,11 +36,13 @@ public void Can_insert_and_retrieve_SqlGeometry()
6436
{
6537
using (var db = OpenDbConnection())
6638
{
39+
db.DropAndCreateTable<GeoTestTable>();
40+
6741
// A simple line from (0,0) to (4,4) Length = SQRT(2 * 4^2)
6842
var wkt = new System.Data.SqlTypes.SqlChars("LINESTRING(0 0, 4 4)".ToCharArray());
6943
var shape = SqlGeometry.STLineFromText(wkt, 0);
7044

71-
db.Insert(new GeoTestTable() { Shape = shape });
45+
db.Insert(new GeoTestTable { Shape = shape });
7246

7347
var result = db.Select(db.From<GeoTestTable>()).First().Shape;
7448

0 commit comments

Comments
 (0)