Skip to content

Commit

Permalink
add function call support
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcos Magueta committed Jan 8, 2023
1 parent a92133b commit 8ae32a2
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 34 deletions.
71 changes: 38 additions & 33 deletions src/SQLProvider.Runtime/Providers.MsSqlServer.Ssdt.fs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ module MSSqlServerSsdt =
sb.AppendLine(s.FullName) |> ignore
failwith (sb.ToString())


/// Tries to parse a schema model from the given .dacpac file path.
let parseDacpac = findDacPacFile >> extractModelXml >> parseXml

Expand Down Expand Up @@ -369,38 +368,44 @@ type internal MSSqlServerProviderSsdt(tableNames: string, ssdtPath: string) =
)

member __.GetSprocs(con) =
ssdtSchema.Value.StoredProcs
|> List.map (fun sp ->
let inParams =
sp.Parameters
|> List.mapi (fun idx p ->
{ Name = p.Name
TypeMapping = MSSqlServerSsdt.tryFindMappingOrVariant p.DataType
Direction = if p.IsOutput then ParameterDirection.InputOutput else ParameterDirection.Input
Length = p.Length
Ordinal = idx }
)
let outParams =
sp.Parameters
|> List.filter (fun p -> p.IsOutput)
|> List.mapi (fun idx p ->
{ Name = p.Name
TypeMapping = MSSqlServerSsdt.tryFindMappingOrVariant p.DataType
Direction = ParameterDirection.InputOutput
Length = p.Length
Ordinal = idx }
)

// If no outParams, add a "ResultSet" property (see issue #706)
let outParams =
match outParams with
| [] -> [ sprocReturnParam 0 ]
| _ -> outParams

let spName = { ProcName = sp.Name; Owner = sp.Schema; PackageName = sp.Schema; }

Root("Procedures", Sproc({ Name = spName; Params = (fun con -> inParams); ReturnColumns = (fun con sparams -> outParams) }))
)

let convertExecutable type' elems =
elems
|> List.map (fun sp ->
let inParams =
sp.Parameters
|> List.mapi (fun idx p ->
{ Name = p.Name
TypeMapping = MSSqlServerSsdt.tryFindMappingOrVariant p.DataType
Direction = if p.IsOutput then ParameterDirection.InputOutput else ParameterDirection.Input
Length = p.Length
Ordinal = idx }
)
let outParams =
sp.Parameters
|> List.filter (fun p -> p.IsOutput)
|> List.mapi (fun idx p ->
{ Name = p.Name
TypeMapping = MSSqlServerSsdt.tryFindMappingOrVariant p.DataType
Direction = ParameterDirection.InputOutput
Length = p.Length
Ordinal = idx }
)

// If no outParams, add a "ResultSet" property (see issue #706)
let outParams =
match outParams with
| [] -> [ sprocReturnParam 0 ]
| _ -> outParams

let spName = { ProcName = sp.Name; Owner = sp.Schema; PackageName = sp.Schema; }

Root(type', Sproc({ Name = spName; Params = (fun con -> inParams); ReturnColumns = (fun con sparams -> outParams) }))
)
let sprocs = convertExecutable "Procedures" ssdtSchema.Value.StoredProcs
let funcs = convertExecutable "Functions" ssdtSchema.Value.Functions
List.append sprocs funcs

member __.GetIndividualsQueryText(table,amount) = String.Empty // Not implemented for SSDT
member __.GetIndividualQueryText(table,column) = String.Empty // Not implemented for SSDT

Expand Down
46 changes: 45 additions & 1 deletion src/SQLProvider.Runtime/Ssdt.DacpacParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type SsdtSchema = {
StoredProcs: SsdtStoredProc list
Relationships: SsdtRelationship list
Descriptions: SsdtDescriptionItem list
Functions: SsdtStoredProc list
}
and SsdtTable = {
FullName: string
Expand Down Expand Up @@ -373,6 +374,38 @@ let parseXml(xml: string) =
Name = parts.[1]
Parameters = parameters |> Seq.toList }

let parseFunctions (funElement: XmlNode) =
let fullName = funElement |> att "Name" |> RegexParsers.splitFullName |> fun n -> String.Join(".", n) |> fun n -> n.ToUpper()
let parameters =
let paramsNode = funElement |> nodes "x:Relationship" |> Seq.tryFind (fun r -> r |> att "Name" = "Parameters")
match paramsNode with
| Some e ->
e
|> nodes "x:Entry"
|> Seq.map (fun entry ->
let el = entry |> node "x:Element"
let parameterName = el |> att "Name"
let isOutput =
match el |> nodes "x:Property" |> Seq.tryFind (fun p -> p |> att "Name" = "IsOutput") with
| Some p when p |> att "Value" = "True" -> true
| _ -> false
let dataType =
el
|> node "x:Relationship/x:Entry/x:Element/x:Relationship/x:Entry/x:References"
|> att "Name"
{ FullName = parameterName
Name = parameterName |> RegexParsers.splitFullName |> Array.last
DataType = dataType |> removeBrackets
Length = ValueNone
IsOutput = isOutput })
| None -> Seq.empty

let parts = fullName |> RegexParsers.splitFullName
{ FullName = fullName
Schema = parts.[0]
Name = parts.[1]
Parameters = parameters |> Seq.toList }

let parseDescription (extElement: XmlNode) =
let fullName = extElement |> att "Name"
let parts = fullName |> RegexParsers.splitFullName
Expand All @@ -386,6 +419,16 @@ let parseXml(xml: string) =
Description = description
}

let functions =
let filterPredicate elem =
(att "Type" elem) = "SqlScalarFunction"
|| (att "Type" elem) = "SqlInlineTableValuedFunction"
model
|> nodes "x:Element"
|> Seq.filter filterPredicate
|> Seq.map parseFunctions
|> Seq.toList

let storedProcs =
model
|> nodes "x:Element"
Expand Down Expand Up @@ -465,4 +508,5 @@ let parseXml(xml: string) =
StoredProcs = storedProcs
TryGetTableByName = fun nm -> tablesAndViews |> (List.tryFind (fun t -> t.Name = nm) >> function Some x -> ValueSome x | None -> ValueNone)
Relationships = relationships
Descriptions = descriptions } : SsdtSchema
Descriptions = descriptions
Functions = functions } : SsdtSchema

0 comments on commit 8ae32a2

Please sign in to comment.