@@ -12,6 +12,28 @@ open ProviderImplementation.ProvidedTypes
1212open FSharp.Data
1313open System.Text .RegularExpressions
1414
15+ module RuntimeInternals =
16+ let setupTableFromSerializedColumns ( serializedSchema : string ) ( table : System.Data.DataTable ) =
17+ let primaryKey = ResizeArray()
18+ for line in serializedSchema.Split( '\n' ) do
19+ let xs = line.Split( '\t' )
20+ let col = new DataColumn()
21+ col.ColumnName <- xs.[ 0 ]
22+ col.DataType <- Type.GetType( xs.[ 1 ], throwOnError = true )
23+ col.AllowDBNull <- Boolean.Parse xs.[ 2 ]
24+ if col.DataType = typeof< string>
25+ then
26+ col.MaxLength <- int xs.[ 3 ]
27+ col.ReadOnly <- Boolean.Parse xs.[ 4 ]
28+ col.AutoIncrement <- Boolean.Parse xs.[ 5 ]
29+ if Boolean.Parse xs.[ 6 ]
30+ then
31+ primaryKey.Add col
32+ table.Columns.Add col
33+
34+ table.PrimaryKey <- Array.ofSeq primaryKey
35+
36+
1537type internal RowType = {
1638 Provided: Type
1739 ErasedTo: Type
@@ -31,6 +53,10 @@ type internal ReturnType = {
3153 | Some x -> Expr.Value( x.ErasedTo.AssemblyQualifiedName)
3254 | None -> <@@ null : string @@>
3355
56+ type internal DataTableType =
57+ | SqlProgrammabilityTable of isHostedExecution : bool * connectionString : DesignTimeConnectionString * schemaName : string * tableName : string * columns : Column list
58+ | CommandResultTable
59+
3460module internal SharedLogic =
3561 /// Adds .Record or .Table inner type depending on resultType
3662 let alterReturnTypeAccordingToResultType ( returnType : ReturnType ) ( cmdProvidedType : ProvidedTypeDefinition ) resultType =
@@ -246,7 +272,7 @@ type DesignTime private() =
246272
247273 rowType
248274
249- static member internal GetDataTableType ( typeName , dataRowType : ProvidedTypeDefinition , outputColumns : Column list ) =
275+ static member internal GetDataTableType ( typeName , dataRowType : ProvidedTypeDefinition , outputColumns : Column list , dataTableType : DataTableType ) =
250276 let tableType = ProvidedTypeBuilder.MakeGenericType( typedefof<_ DataTable>, [ dataRowType ])
251277 let tableProvidedType = ProvidedTypeDefinition( typeName, Some tableType)
252278
@@ -325,6 +351,41 @@ type DesignTime private() =
325351 )
326352 dataRowType.AddMember tableProperty
327353
354+ let getColumnsSerializedSchema columns =
355+ columns
356+ |> List.map ( fun x ->
357+ let nullable = x.Nullable || x.HasDefaultConstraint
358+ sprintf " %s \t %s \t %b \t %i \t %b \t %b \t %b "
359+ x.Name x.TypeInfo.ClrTypeFullName nullable x.MaxLength x.ReadOnly x.Identity x.PartOfUniqueKey
360+ )
361+ |> String.concat " \n "
362+
363+ let ctorCode =
364+ fun _ ->
365+ let serializedSchema = getColumnsSerializedSchema outputColumns
366+ match dataTableType with
367+ | SqlProgrammabilityTable ( isHostedExecution, connectionString, schemaName, tableName, _) ->
368+
369+ let twoPartTableName = sprintf " [%s ].[%s ]" schemaName tableName
370+
371+ <@@
372+ let connectionString = lazy %% connectionString.RunTimeValueExpr( isHostedExecution)
373+ let selectCommand = new SqlCommand( " SELECT * FROM " + twoPartTableName)
374+ let table = new DataTable< DataRow>( selectCommand, connectionString)
375+ table.TableName <- twoPartTableName
376+ RuntimeInternals.setupTableFromSerializedColumns serializedSchema table
377+ table
378+ @@>
379+ | CommandResultTable ->
380+ <@@
381+ let table = new DataTable< DataRow>( null , null )
382+ RuntimeInternals.setupTableFromSerializedColumns serializedSchema table
383+ table
384+ @@>
385+
386+
387+ ProvidedConstructor([], InvokeCode = ctorCode) |> tableProvidedType.AddMember
388+
328389 tableProvidedType
329390
330391 static member internal GetOutputTypes ( outputColumns : Column list , resultType , rank : ResultRank , hasOutputParameters , ? unitsOfMeasurePerSchema ) =
@@ -337,7 +398,7 @@ type DesignTime private() =
337398 elif resultType = ResultType.DataTable
338399 then
339400 let dataRowType = DesignTime.GetDataRowType( outputColumns, ?unitsOfMeasurePerSchema = unitsOfMeasurePerSchema)
340- let dataTableType = DesignTime.GetDataTableType( " Table" , dataRowType, outputColumns)
401+ let dataTableType = DesignTime.GetDataTableType( " Table" , dataRowType, outputColumns, CommandResultTable )
341402 dataTableType.AddMember dataRowType
342403
343404 { Single = dataTableType; PerRow = None }
@@ -807,4 +868,3 @@ type DesignTime private() =
807868 | None -> m.Groups.[ 0 ]. Value))
808869
809870 ( vars |> Array.map( fun ( name , typ ) -> sprintf " DECLARE %s%s %s = @%s " Prefixes.tableVar name typ name) |> String.concat " ; " ) + " ; " + commandText
810-
0 commit comments