Skip to content

Commit 3be6a6d

Browse files
authored
Merge pull request #261 from smoothdeveloper/sqlprogrammability-resulttype
Add handling of ResultType static parameter for SqlProgrammabilityProvider
2 parents 6dcfaa3 + 886c910 commit 3be6a6d

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

src/SqlClient.Tests/ProgrammabilityTests.fs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ open FSharp.Data.SqlClient
77

88
type AdventureWorks = SqlProgrammabilityProvider<ConnectionStrings.AdventureWorksNamed>
99

10+
type AdventureWorksDataTables = SqlProgrammabilityProvider<ConnectionStrings.AdventureWorksLiteral, ResultType = ResultType.DataTable>
1011
type GetContactInformation = AdventureWorks.dbo.ufnGetContactInformation
1112

1213
[<Fact>]
@@ -259,5 +260,9 @@ let PassingImageAsParamDoesntGetCut() =
259260
Assert.Equal(existing.LargePhoto.Value.Length, inserted.LargePhoto.Value.Length)
260261
Assert.Equal(existing.LargePhoto, inserted.LargePhoto)
261262

262-
263-
263+
[<Fact>]
264+
let ``honors result type parameter: datatable`` () =
265+
let command = new AdventureWorksDataTables.Sales.GetUKSalesOrders(ConnectionStrings.AdventureWorksLiteral)
266+
let gbp = 1.0M<AdventureWorksDataTables.Sales.``Units of Measure``.GBP>
267+
let table : AdventureWorksDataTables.Sales.GetUKSalesOrders.Table = command.Execute(gbp)
268+
Assert.Equal<string>("Year", table.Columns.Year.ColumnName)

src/SqlClient/DesignTime.fs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ type internal ReturnType = {
3030
| Some x -> Expr.Value( x.ErasedTo.AssemblyQualifiedName)
3131
| None -> <@@ null: string @@>
3232

33+
module internal SharedLogic =
34+
/// Adds .Record or .Table inner type depending on resultType
35+
let alterReturnTypeAccordingToResultType (returnType: ReturnType) (cmdProvidedType: ProvidedTypeDefinition) resultType =
36+
if resultType = ResultType.Records then
37+
// Add .Record
38+
returnType.PerRow |> Option.iter (fun x -> cmdProvidedType.AddMember x.Provided)
39+
elif resultType = ResultType.DataTable then
40+
// add .Table
41+
returnType.Single |> cmdProvidedType.AddMember
42+
3343
type DesignTime private() =
3444
static member internal AddGeneratedMethod
3545
(sqlParameters: Parameter list, hasOutputParameters, executeArgs: ProvidedParameter list, erasedType, providedOutputType, name) =

src/SqlClient/SqlClientProvider.fs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,21 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
4444
ProvidedStaticParameter("ConfigFile", typeof<string>, "")
4545
ProvidedStaticParameter("DataDirectory", typeof<string>, "")
4646
ProvidedStaticParameter("UseReturnValue", typeof<bool>, false)
47-
],
47+
ProvidedStaticParameter("ResultType", typeof<ResultType>, ResultType.Records)
48+
],
4849
instantiationFunction = (fun typeName args ->
49-
let root = lazy this.CreateRootType(typeName, unbox args.[0], unbox args.[1], unbox args.[2], unbox args.[3])
50+
let root = lazy this.CreateRootType(typeName, unbox args.[0], unbox args.[1], unbox args.[2], unbox args.[3], unbox args.[4])
5051
cache.GetOrAdd(typeName, root)
5152
)
5253
)
5354

5455
providerType.AddXmlDoc """
5556
<summary>Typed access to SQL Server programmable objects: stored procedures, functions and user defined table types.</summary>
5657
<param name='ConnectionStringOrName'>String used to open a SQL Server database or the name of the connection string in the configuration file in the form of “name=&lt;connection string name&gt;”.</param>
57-
<param name='ResultType'>A value that defines structure of result: Records, Tuples, DataTable, or SqlDataReader.</param>
5858
<param name='ConfigFile'>The name of the configuration file that’s used for connection strings at DESIGN-TIME. The default value is app.config or web.config.</param>
5959
<param name='DataDirectory'>The name of the data directory that replaces |DataDirectory| in connection strings. The default value is the project or script directory.</param>
60+
<param name='UseReturnValue'>To be documented.</param>
61+
<param name='ResultType'>A value that defines structure of result: Records, Tuples, DataTable, or SqlDataReader, this affects only Stored Procedures.</param>
6062
"""
6163

6264
this.AddNamespace(nameSpace, [ providerType ])
@@ -68,7 +70,7 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
6870
|> defaultArg
6971
<| base.ResolveAssembly args
7072

71-
member internal this.CreateRootType( typeName, connectionStringOrName, configFile, dataDirectory, useReturnValue) =
73+
member internal this.CreateRootType( typeName, connectionStringOrName, configFile, dataDirectory, useReturnValue, resultType) =
7274
if String.IsNullOrWhiteSpace connectionStringOrName then invalidArg "ConnectionStringOrName" "Value is empty!"
7375

7476
let designTimeConnectionString = DesignTimeConnectionString.Parse(connectionStringOrName, config.ResolutionFolder, configFile)
@@ -122,7 +124,7 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
122124

123125
schemaType.AddMembersDelayed <| fun() ->
124126
[
125-
let routines = this.Routines(conn, schemaType.Name, udttsPerSchema, ResultType.Records, designTimeConnectionString, useReturnValue, uomPerSchema)
127+
let routines = this.Routines(conn, schemaType.Name, udttsPerSchema, resultType, designTimeConnectionString, useReturnValue, uomPerSchema)
126128
routines |> List.iter tagProvidedType
127129
yield! routines
128130

@@ -182,8 +184,8 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
182184

183185
let returnType = DesignTime.GetOutputTypes(outputColumns, resultType, rank, hasOutputParameters, unitsOfMeasurePerSchema)
184186

185-
do //Record
186-
returnType.PerRow |> Option.iter (fun x -> cmdProvidedType.AddMember x.Provided)
187+
do
188+
SharedLogic.alterReturnTypeAccordingToResultType returnType cmdProvidedType resultType
187189

188190
//ctors
189191
let sqlParameters = Expr.NewArray( typeof<SqlParameter>, parameters |> List.map QuotationsFactory.ToSqlParam)
@@ -218,17 +220,17 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
218220
yield upcast DesignTime.AddGeneratedMethod(parameters, hasOutputParameters, executeArgs, cmdProvidedType.BaseType, returnType.Single, "Execute")
219221

220222
if not hasOutputParameters
221-
then
223+
then
222224
let asyncReturnType = ProvidedTypeBuilder.MakeGenericType(typedefof<_ Async>, [ returnType.Single ])
223225
yield upcast DesignTime.AddGeneratedMethod(parameters, hasOutputParameters, executeArgs, cmdProvidedType.BaseType, asyncReturnType, "AsyncExecute")
224226

225227
if returnType.PerRow.IsSome
226-
then
228+
then
227229
let providedReturnType = ProvidedTypeBuilder.MakeGenericType(typedefof<_ option>, [ returnType.PerRow.Value.Provided ])
228230
let providedAsyncReturnType = ProvidedTypeBuilder.MakeGenericType(typedefof<_ Async>, [ providedReturnType ])
229231

230232
if not hasOutputParameters
231-
then
233+
then
232234
yield upcast DesignTime.AddGeneratedMethod(parameters, hasOutputParameters, executeArgs, cmdProvidedType.BaseType, providedReturnType, "ExecuteSingle")
233235
yield upcast DesignTime.AddGeneratedMethod(parameters, hasOutputParameters, executeArgs, cmdProvidedType.BaseType, providedAsyncReturnType, "AsyncExecuteSingle")
234236
]

src/SqlClient/SqlCommandProvider.fs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,7 @@ type SqlCommandProvider(config : TypeProviderConfig) as this =
120120
cmdProvidedType.AddMember(ProvidedProperty("ConnectionStringOrName", typeof<string>, [], IsStatic = true, GetterCode = fun _ -> <@@ connectionStringOrName @@>))
121121

122122
do
123-
if resultType = ResultType.Records then
124-
// Add .Record
125-
returnType.PerRow |> Option.iter (fun x -> cmdProvidedType.AddMember x.Provided)
126-
elif resultType = ResultType.DataTable then
127-
// add .Table
128-
returnType.Single |> cmdProvidedType.AddMember
123+
SharedLogic.alterReturnTypeAccordingToResultType returnType cmdProvidedType resultType
129124

130125
do //ctors
131126
let designTimeConfig =

0 commit comments

Comments
 (0)