-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathTVPTests.fs
210 lines (180 loc) · 7.53 KB
/
TVPTests.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#if WITH_LEGACY_NAMESPACE
module FSharp.Data.TVPTests
open FSharp.Data.SqlClient
#else
module FSharp.Data.SqlClient.TVPTests
#endif
open FSharp.Data
open Xunit
// If compile fails here, check prereqs.sql
type TableValuedTuple = SqlCommandProvider<"exec Person.myProc @x", ConnectionStrings.AdventureWorksNamed, SingleRow = true, ResultType = ResultType.Tuples>
type MyTableType = TableValuedTuple.MyTableType
[<Fact>]
let Basic() =
let cmd = new TableValuedTuple()
let p = [
MyTableType(myId = 1, myName = Some "monkey")
MyTableType(myId = 2, myName = Some "donkey")
]
Assert.Equal(Some(1, Some "monkey"), cmd.Execute(x = p))
[<Fact(Skip = "Flucky")>]
let InputIsEnumeratedExactlyOnce() =
let cmd = new TableValuedTuple()
let counter = ref 0
let x = seq {
counter := !counter + 1
yield MyTableType(myId = 1)
yield MyTableType(myId = 2, myName = Some "donkey")
}
cmd.Execute x |> ignore
Assert.Equal(1, !counter)
[<Fact>]
let NullableColumn() =
let cmd = new TableValuedTuple()
let p = [
MyTableType(myId = 1)
MyTableType(myId = 2, myName = Some "donkey")
]
Assert.Equal(Some(1, None), cmd.Execute p)
type TableValuedSingle = SqlCommandProvider<"exec SingleElementProc @x", ConnectionStringOrName = ConnectionStrings.AdventureWorksNamed>
[<Fact>]
let SingleColumn() =
let cmd = new TableValuedSingle()
let p = [
TableValuedSingle.SingleElementType(myId = 1)
TableValuedSingle.SingleElementType(myId = 2)
]
let result = cmd.Execute(x = p) |> List.ofSeq
Assert.Equal<int list>([1;2], result)
[<Fact>]
let tvpSqlParamCleanUp() =
let cmd = new TableValuedSingle()
let p = [
TableValuedSingle.SingleElementType(myId = 1)
TableValuedSingle.SingleElementType(myId = 2)
]
cmd.Execute(x = p) |> List.ofSeq |> ignore
let result = cmd.Execute(x = p) |> List.ofSeq
Assert.Equal<int list>([1;2], result)
type TableValuedSprocTuple = SqlCommandProvider<"exec Person.myProc @x", ConnectionStringOrName = ConnectionStrings.AdventureWorksNamed, SingleRow = true, ResultType = ResultType.Tuples>
[<Fact>]
let SprocTupleValue() =
let cmd = new TableValuedSprocTuple()
let p = [
TableValuedSprocTuple.MyTableType(myId = 1, myName = Some "monkey")
TableValuedSprocTuple.MyTableType(myId = 2, myName = Some "donkey")
]
let actual = cmd.Execute(p).Value
Assert.Equal((1, Some "monkey"), actual)
[<Fact>]
let ``SprocTupleValue works with empty table``() =
let cmd = new TableValuedSprocTuple()
let p = []
let actual = cmd.Execute(p)
Assert.Equal(None, actual)
type TableValuedTupleWithOptionalParams = SqlCommandProvider<"exec Person.myProc @x", ConnectionStrings.AdventureWorksNamed, AllParametersOptional = true>
[<Fact>]
let TableValuedTupleWithOptionalParams() =
let cmd = new TableValuedTupleWithOptionalParams()
cmd.Execute Array.empty |> ignore
(*
don't delete this test. The previous line fails with if combo of TVP and AllParametersOptional = true is not handled properly
Error 1 The type provider 'FSharp.Data.SqlCommandProvider' reported an error in the context of provided type 'FSharp.Data.SqlCommandProvider,CommandText="exec myProc @x",ConnectionStringOrName="name=AdventureWorks2012",AllParametersOptional="True"', member 'Execute'.
The error: Value cannot be null. C:\Users\mitekm\Documents\GitHub\FSharp.Data.SqlClient\src\SqlClient.Tests\TVPTests.fs 83 5 SqlClient.Tests
*)
type MyFunc = SqlCommandProvider<"select * from dbo.MyFunc(@x, @y)", ConnectionStrings.AdventureWorksNamed>
[<Fact>]
let TwoTVPParameterOfSameUDTT() =
let cmd = new MyFunc()
let xs = [ 1, Some "monkey" ]
let ys = [ 2, Some "donkey" ]
let xs' = [ for id, name in xs -> MyFunc.MyTableType(id, name) ]
let ys' = [ for id, name in ys -> MyFunc.MyTableType(id, name) ]
let expected = [ for id, name in xs @ ys -> MyFunc.Record(id, name) ]
Assert.Equal<_ list>(expected, cmd.Execute(xs', ys') |> Seq.toList)
open System.Data.SqlClient
[<Fact>]
let ReuseTVPTypeForDynamicADONET() =
use conn = new SqlConnection(ConnectionStrings.AdventureWorksLiteral)
use cmd = new SqlCommand("exec Person.myProc @x", conn)
let p = cmd.Parameters.Add( "@x", System.Data.SqlDbType.Structured)
p.TypeName <- "Person.MyTableType"
p.Value <- [
MyTableType(myId = 1, myName = Some "monkey")
MyTableType(myId = 2, myName = Some "donkey")
] |> Seq.cast<Microsoft.SqlServer.Server.SqlDataRecord>
conn.Open()
let expected = [ 1, "monkey"; 2, "donkey" ]
let actual = [
use cursor = cmd.ExecuteReader()
while cursor.Read() do
yield cursor.GetInt32(0), cursor.GetString(1)
]
Assert.Equal<_ list>( expected, actual)
type QueryTVO =
SqlCommandProvider<"
DECLARE @p1 AS dbo.MyTableType = @input
SELECT * from @p1
", ConnectionStrings.AdventureWorksNamed>
[<Fact(Skip ="Fails at runtime :(")>]
let UsingTVPInQuery() =
use cmd = new QueryTVO()
let expected = [
1, Some "monkey"
2, Some "donkey"
]
let actual =
cmd.Execute(input = [ for id, name in expected -> QueryTVO.MyTableType(id, name) ])
|> Seq.map(fun x -> x.myId, x.myName)
|> Seq.toList
Assert.Equal<_ list>(expected, actual)
type MappedTVP =
SqlCommandProvider<"
SELECT myId, myName from @input
", ConnectionStrings.AdventureWorksLiteral, TableVarMapping = "@input=dbo.MyTableType">
[<Fact>]
let UsingMappedTVPInQuery() =
printfn "%s" ConnectionStrings.AdventureWorksLiteral
use cmd = new MappedTVP(ConnectionStrings.AdventureWorksLiteral)
let expected = [
1, Some "monkey"
2, Some "donkey"
]
let actual =
cmd.Execute(input = [ for id, name in expected -> MappedTVP.MyTableType(id, name) ])
|> Seq.map(fun x -> x.myId, x.myName)
|> Seq.toList
Assert.Equal<_ list>(expected, actual)
type MappedTVPFixed =
SqlCommandProvider<"
SELECT myId, myName from @input
", ConnectionStrings.AdventureWorksLiteral, TableVarMapping = "@input=dbo.MyTableTypeFixed">
[<Fact>]
let UsingMappedTVPFixedInQuery() =
printfn "%s" ConnectionStrings.AdventureWorksLiteral
use cmd = new MappedTVPFixed(ConnectionStrings.AdventureWorksLiteral)
let expected = [
1, Some "monkey"
2, Some "donkey"
]
let actual =
cmd.Execute(input = [ for id, name in expected -> MappedTVPFixed.MyTableTypeFixed(id, name) ])
|> Seq.map(fun x -> x.myId, x.myName |> Option.map (fun s -> s.Trim()))
|> Seq.toList
Assert.Equal<_ list>(expected, actual)
type AdventureWorks = SqlProgrammabilityProvider<ConnectionStrings.AdventureWorksNamed>
[<Fact>]
let ``issue #345 decimal in TVP gets rounded`` () =
let value = Some 1.2345M
let tvp = [AdventureWorks.dbo.``User-Defined Table Types``.decimal_test_tvp(value)]
use cmd = new AdventureWorks.dbo.decimal_test(ConnectionStrings.AdventureWorksLiteral)
let resultvalue = cmd.Execute(tvp) |> Seq.head
Assert.Equal(value, resultvalue)
[<Fact>]
let ``issue #393 troubleshoot if datetimeoffset raises an exception`` () =
// N.B, this should be tested against SQL Azure
let value = System.DateTimeOffset.UtcNow
let tvp = [AdventureWorks.dbo.``User-Defined Table Types``.datetimeoffset_test_tvp(value)]
use cmd = new AdventureWorks.dbo.datetimeoffset_test(ConnectionStrings.AdventureWorksLiteral)
let resultvalue = cmd.Execute(tvp) |> Seq.head
Assert.Equal(value, resultvalue)