Skip to content

Commit

Permalink
Split TP into separate design time and runtime assemblies
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Hanes committed Oct 25, 2018
1 parent 5036dcc commit 7e8c1bf
Show file tree
Hide file tree
Showing 46 changed files with 642 additions and 499 deletions.
15 changes: 12 additions & 3 deletions SqlClient.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2041
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{FD7933BD-2A90-49EB-A4B2-95F9D3076BBD}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -51,7 +51,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{
docs\tools\templates\template.cshtml = docs\tools\templates\template.cshtml
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SqlClient", "src\SqlClient\SqlClient.fsproj", "{8974CE2E-79B4-4887-859A-B853C2624138}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "SqlClient.DesignTime", "src\SqlClient.DesignTime\SqlClient.DesignTime.fsproj", "{8974CE2E-79B4-4887-859A-B853C2624138}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SqlClient", "src\SqlClient\SqlClient.fsproj", "{30BA2514-534A-42EA-A0E7-46DF9FDCA954}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -63,6 +65,10 @@ Global
{8974CE2E-79B4-4887-859A-B853C2624138}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8974CE2E-79B4-4887-859A-B853C2624138}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8974CE2E-79B4-4887-859A-B853C2624138}.Release|Any CPU.Build.0 = Release|Any CPU
{30BA2514-534A-42EA-A0E7-46DF9FDCA954}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30BA2514-534A-42EA-A0E7-46DF9FDCA954}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30BA2514-534A-42EA-A0E7-46DF9FDCA954}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30BA2514-534A-42EA-A0E7-46DF9FDCA954}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -72,4 +78,7 @@ Global
{573DBBFB-0F97-4327-8614-6A4151CD70BF} = {61AC061E-5824-41B7-8E09-8D3A73D564E5}
{CB79269B-025B-4D6A-AF84-0AD821F6A602} = {573DBBFB-0F97-4327-8614-6A4151CD70BF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {82096CC6-31F2-47A5-8D46-E41C63B4DB58}
EndGlobalSection
EndGlobal
19 changes: 14 additions & 5 deletions Tests.sln
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2041
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{E35ED000-5A6C-49E1-82CF-55CB8C16C2AB}"
ProjectSection(SolutionItems) = preProject
paket.dependencies = paket.dependencies
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SqlClient.Tests", "src\SqlClient.Tests\SqlClient.Tests.fsproj", "{624C31FF-2003-4334-B02E-AD5A79FE9ED8}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "SqlClient.Tests", "src\SqlClient.Tests\SqlClient.Tests.fsproj", "{624C31FF-2003-4334-B02E-AD5A79FE9ED8}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SqlClient.Tests.NET40", "src\SqlClient.Tests\SqlClient.Tests.NET40\SqlClient.Tests.NET40.fsproj", "{DE2EC181-0452-415D-82C3-1D43168D4FF1}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "SqlClient.Tests.NET40", "src\SqlClient.Tests\SqlClient.Tests.NET40\SqlClient.Tests.NET40.fsproj", "{DE2EC181-0452-415D-82C3-1D43168D4FF1}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Lib", "src\SqlClient.Tests\Lib\Lib.fsproj", "{17EE08F0-CE4C-4C17-A376-157249C9ABC2}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Lib", "src\SqlClient.Tests\Lib\Lib.fsproj", "{17EE08F0-CE4C-4C17-A376-157249C9ABC2}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SqlClient.DesignTime.Tests", "src\SqlClient.Tests\SqlClient.DesignTime.Tests\SqlClient.DesignTime.Tests.fsproj", "{7B283341-7AE6-4D02-8BFE-F94C80617F90}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -32,8 +34,15 @@ Global
{17EE08F0-CE4C-4C17-A376-157249C9ABC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17EE08F0-CE4C-4C17-A376-157249C9ABC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17EE08F0-CE4C-4C17-A376-157249C9ABC2}.Release|Any CPU.Build.0 = Release|Any CPU
{7B283341-7AE6-4D02-8BFE-F94C80617F90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B283341-7AE6-4D02-8BFE-F94C80617F90}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B283341-7AE6-4D02-8BFE-F94C80617F90}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B283341-7AE6-4D02-8BFE-F94C80617F90}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB177D8C-41D5-430D-94E8-485567A72F92}
EndGlobalSection
EndGlobal
4 changes: 2 additions & 2 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ Target.create "All" Target.DoNothing

open Fake.Core.TargetOperators // for ==>

"Clean"
==> "AssemblyInfo"
//"Clean"
"AssemblyInfo"
==> "Build"
==> "DeployTestDB"
==> "BuildTests"
Expand Down
5 changes: 5 additions & 0 deletions nuget/SqlClient.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@
<files>
<file src="..\bin\net40\FSharp.Data.SqlClient.dll" target="lib\net40" />
<file src="..\bin\net40\FSharp.Data.SqlClient.pdb" target="lib\net40" />
<file src="..\bin\net40\FSharp.Data.SqlClient.DesignTime.dll" target="lib\net40" />
<file src="..\bin\net40\FSharp.Data.SqlClient.DesignTime.pdb" target="lib\net40" />
<file src="..\bin\net40\FSharp.Data.SqlClient.xml" target="lib\net40" />
<file src="..\bin\net40\Microsoft.SqlServer.TransactSql.ScriptDom.dll" target="lib\net40" />
<file src="..\bin\net40\Microsoft.SqlServer.Types.dll" target="lib\net40" />
<file src="..\bin\net40\FSharp.Data.SqlClient.DesignTime.dll" target="lib\typeproviders\fsharp41\net40" />
<file src="..\bin\net40\Microsoft.SqlServer.TransactSql.ScriptDom.dll" target="lib\typeproviders\fsharp41\net40" />
<file src="..\bin\net40\Microsoft.SqlServer.Types.dll" target="lib\typeproviders\fsharp41\net40" />
</files>
</package>
2 changes: 1 addition & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ group Test
redirects: force

nuget FSharp.Core = 4.1.2
nuget FSharp.Configuration
nuget FSharp.Configuration = 1.4.0
nuget Newtonsoft.Json
nuget xunit = 1.9.2
nuget xunit.runner.visualstudio = 2.1.0
Expand Down
20 changes: 20 additions & 0 deletions src/SqlClient.DesignTime/AssemblyInfo.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Auto-Generated by FAKE; do not edit
namespace System
open System.Reflection
open System.Runtime.CompilerServices

[<assembly: AssemblyTitleAttribute("SqlClient")>]
[<assembly: AssemblyProductAttribute("FSharp.Data.SqlClient")>]
[<assembly: AssemblyDescriptionAttribute("SqlClient F# type providers")>]
[<assembly: AssemblyVersionAttribute("1.8.6")>]
[<assembly: AssemblyFileVersionAttribute("1.8.6")>]
[<assembly: InternalsVisibleToAttribute("SqlClient.Tests")>]
do ()

module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "SqlClient"
let [<Literal>] AssemblyProduct = "FSharp.Data.SqlClient"
let [<Literal>] AssemblyDescription = "SqlClient F# type providers"
let [<Literal>] AssemblyVersion = "1.8.6"
let [<Literal>] AssemblyFileVersion = "1.8.6"
let [<Literal>] InternalsVisibleTo = "SqlClient.Tests"
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,6 @@ open ProviderImplementation.ProvidedTypes
open FSharp.Data
open System.Text.RegularExpressions

module RuntimeInternals =
let setupTableFromSerializedColumns (serializedSchema: string) (table: System.Data.DataTable) =
let primaryKey = ResizeArray()
for line in serializedSchema.Split('\n') do
let xs = line.Split('\t')
let col = new DataColumn()
col.ColumnName <- xs.[0]
col.DataType <- Type.GetType( xs.[1], throwOnError = true)
col.AllowDBNull <- Boolean.Parse xs.[2]
if col.DataType = typeof<string>
then
col.MaxLength <- int xs.[3]
col.ReadOnly <- Boolean.Parse xs.[4]
col.AutoIncrement <- Boolean.Parse xs.[5]
if Boolean.Parse xs.[6]
then
primaryKey.Add col
table.Columns.Add col

table.PrimaryKey <- Array.ofSeq primaryKey


type internal RowType = {
Provided: Type
ErasedTo: Type
Expand Down Expand Up @@ -76,47 +54,6 @@ module Prefixes =
let tempTable = "##SQLCOMMANDPROVIDER_"
let tableVar = "@SQLCOMMANDPROVIDER_"

type TempTableLoader(fieldCount, items: obj seq) =
let enumerator = items.GetEnumerator()

interface IDataReader with
member this.FieldCount: int = fieldCount
member this.Read(): bool = enumerator.MoveNext()
member this.GetValue(i: int): obj =
let row : obj[] = unbox enumerator.Current
row.[i]
member this.Dispose(): unit = ()

member __.Close(): unit = invalidOp "NotImplementedException"
member __.Depth: int = invalidOp "NotImplementedException"
member __.GetBoolean(_: int): bool = invalidOp "NotImplementedException"
member __.GetByte(_ : int): byte = invalidOp "NotImplementedException"
member __.GetBytes(_ : int, _ : int64, _ : byte [], _ : int, _ : int): int64 = invalidOp "NotImplementedException"
member __.GetChar(_ : int): char = invalidOp "NotImplementedException"
member __.GetChars(_ : int, _ : int64, _ : char [], _ : int, _ : int): int64 = invalidOp "NotImplementedException"
member __.GetData(_ : int): IDataReader = invalidOp "NotImplementedException"
member __.GetDataTypeName(_ : int): string = invalidOp "NotImplementedException"
member __.GetDateTime(_ : int): System.DateTime = invalidOp "NotImplementedException"
member __.GetDecimal(_ : int): decimal = invalidOp "NotImplementedException"
member __.GetDouble(_ : int): float = invalidOp "NotImplementedException"
member __.GetFieldType(_ : int): System.Type = invalidOp "NotImplementedException"
member __.GetFloat(_ : int): float32 = invalidOp "NotImplementedException"
member __.GetGuid(_ : int): System.Guid = invalidOp "NotImplementedException"
member __.GetInt16(_ : int): int16 = invalidOp "NotImplementedException"
member __.GetInt32(_ : int): int = invalidOp "NotImplementedException"
member __.GetInt64(_ : int): int64 = invalidOp "NotImplementedException"
member __.GetName(_ : int): string = invalidOp "NotImplementedException"
member __.GetOrdinal(_ : string): int = invalidOp "NotImplementedException"
member __.GetSchemaTable(): DataTable = invalidOp "NotImplementedException"
member __.GetString(_ : int): string = invalidOp "NotImplementedException"
member __.GetValues(_ : obj []): int = invalidOp "NotImplementedException"
member __.IsClosed: bool = invalidOp "NotImplementedException"
member __.IsDBNull(_ : int): bool = invalidOp "NotImplementedException"
member __.Item with get (_ : int): obj = invalidOp "NotImplementedException"
member __.Item with get (_ : string): obj = invalidOp "NotImplementedException"
member __.NextResult(): bool = invalidOp "NotImplementedException"
member __.RecordsAffected: int = invalidOp "NotImplementedException"

type DesignTime private() =
static member internal AddGeneratedMethod
(sqlParameters: Parameter list, hasOutputParameters, executeArgs: ProvidedParameter list, erasedType, providedOutputType, name) =
Expand Down Expand Up @@ -163,7 +100,7 @@ type DesignTime private() =
if sqlParam.Direction.HasFlag( ParameterDirection.Output)
then
let mi =
typeof<DesignTime>
typeof<Mapper>
.GetMethod("SetRef")
.MakeGenericMethod( sqlParam.TypeInfo.ClrType)
Expr.Call(mi, [ argExpr; Expr.Var arr; Expr.Value index ]) |> Some
Expand Down Expand Up @@ -199,9 +136,6 @@ type DesignTime private() =

m

static member SetRef<'t>(r : byref<'t>, arr: (string * obj)[], i) =
r <- arr.[i] |> snd |> unbox

static member internal GetRecordType(columns: Column list, ?unitsOfMeasurePerSchema) =

columns
Expand Down Expand Up @@ -432,7 +366,7 @@ type DesignTime private() =
providedType, erasedToTupleType, mapping

let nullsToOptions = QuotationsFactory.MapArrayNullableItems(outputColumns, "MapArrayObjItemToOption")
let combineWithNullsToOptions = typeof<QuotationsFactory>.GetMethod("GetMapperWithNullsToOptions")
let combineWithNullsToOptions = typeof<Mapper>.GetMethod("GetMapperWithNullsToOptions")

{
Single =
Expand Down
72 changes: 72 additions & 0 deletions src/SqlClient.DesignTime/DesignTimeConnectionString.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
namespace FSharp.Data.SqlClient

open System.Configuration
open System.IO
open System
open System.Collections.Generic
open System.Diagnostics

[<CompilerMessageAttribute("This API supports the FSharp.Data.SqlClient infrastructure and is not intended to be used directly from your code.", 101, IsHidden = true)>]
type internal DesignTimeConnectionString =
| Literal of string
| NameInConfig of name: string * value: string * provider: string

static member Parse(s: string, resolutionFolder, fileName) =
match s.Trim().Split([|'='|], 2, StringSplitOptions.RemoveEmptyEntries) with
| [| "" |] -> invalidArg "ConnectionStringOrName" "Value is empty!"
| [| prefix; tail |] when prefix.Trim().ToLower() = "name" ->
let name = tail.Trim()
let value, provider = DesignTimeConnectionString.ReadFromConfig( name, resolutionFolder, fileName)
NameInConfig( name, value, provider)
| _ ->
Literal s

static member ReadFromConfig(name, resolutionFolder, fileName) =
let configFilename =
if fileName <> ""
then
let path = Path.Combine(resolutionFolder, fileName)
if not <| File.Exists path
then raise <| FileNotFoundException( sprintf "Could not find config file '%s'." path)
else path
else
let appConfig = Path.Combine(resolutionFolder, "app.config")
let webConfig = Path.Combine(resolutionFolder, "web.config")

if File.Exists appConfig then appConfig
elif File.Exists webConfig then webConfig
else failwithf "Cannot find either app.config or web.config."

let map = ExeConfigurationFileMap()
map.ExeConfigFilename <- configFilename
let configSection = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None).ConnectionStrings.ConnectionStrings
match configSection, lazy configSection.[name] with
| null, _ | _, Lazy null -> raise <| KeyNotFoundException(message = sprintf "Cannot find name %s in <connectionStrings> section of %s file." name configFilename)
| _, Lazy x ->
let providerName = if String.IsNullOrEmpty x.ProviderName then "System.Data.SqlClient" else x.ProviderName
x.ConnectionString, providerName

member this.Value =
match this with
| Literal value -> value
| NameInConfig(_, value, _) -> value

member this.RunTimeValueExpr isHostedExecution =
match this with
| Literal value -> <@@ value @@>
| NameInConfig(name, value, _) ->
<@@
let hostProcess = Process.GetCurrentProcess().ProcessName.ToUpper()
if isHostedExecution
|| (Environment.Is64BitProcess && hostProcess = "FSIANYCPU")
|| (not Environment.Is64BitProcess && hostProcess = "FSI")
then
value
else
let section = ConfigurationManager.ConnectionStrings.[name]
if section = null
then raise <| KeyNotFoundException(message = sprintf "Cannot find name %s in <connectionStrings> section of config file." name)
else section.ConnectionString
@@>

member this.IsDefinedByLiteral = match this with | Literal _ -> true | _ -> false
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type QuotationsFactory private() =
x
@@>

static member internal OptionToObj<'T> value = <@@ match %%value with Some (x : 'T) -> box x | None -> Extensions.DbNull @@>
static member internal OptionToObj<'T> value = <@@ match %%value with Some (x : 'T) -> box x | None -> DbNull @@>

static member internal MapArrayOptionItemToObj<'T>(arr, index) =
<@
Expand Down Expand Up @@ -103,11 +103,6 @@ type QuotationsFactory private() =
(%%exprArgs.[0] : DataRow).[name] <- match (%%exprArgs.[1] : option<'T>) with None -> DbNull | Some value -> box value
@>

static member GetMapperWithNullsToOptions(nullsToOptions, mapper: obj[] -> obj) =
fun values ->
nullsToOptions values
mapper values

static member private GetNonNullableValueFromDataRow<'T>(exprArgs : Expr list, name: string) =
<@ (%%exprArgs.[0] : DataRow).[name] @>

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ open System
[<AbstractClass>]
[<CompilerMessageAttribute("This API supports the FSharp.Data.SqlClient infrastructure and is not intended to be used directly from your code.", 101, IsHidden = true)>]
type SingleRootTypeProvider(config: TypeProviderConfig, providerName, parameters, ?isErased) as this =
inherit TypeProviderForNamespaces(config, addDefaultProbingLocation = true)
inherit TypeProviderForNamespaces (config, assemblyReplacementMap=[("FSharp.Data.SqlClient.DesignTime", "FSharp.Data.SqlClient")], addDefaultProbingLocation=true)

let cache = new Cache<ProvidedTypeDefinition>()
do
let isErased = defaultArg isErased true
let nameSpace = this.GetType().Namespace
let assembly = Assembly.LoadFrom( config.RuntimeAssembly)
let assembly = Assembly.GetExecutingAssembly()

let providerType = ProvidedTypeDefinition(assembly, nameSpace, providerName, Some typeof<obj>, hideObjectMethods = true, isErased = isErased)

Expand Down
Loading

0 comments on commit 7e8c1bf

Please sign in to comment.