1+ using System . Data ;
2+ using System . Data . Common ;
3+ using Google . Cloud . Spanner . V1 ;
4+ using Google . Cloud . SpannerLib . MockServer ;
5+ using TypeCode = Google . Cloud . Spanner . V1 . TypeCode ;
6+
7+ namespace Google . Cloud . Spanner . DataProvider . Tests ;
8+
9+ public class SpannerParameterTests : AbstractMockServerTests
10+ {
11+ [ Test ]
12+ public void SettingValueDoesNotChangeDbType ( )
13+ {
14+ // ReSharper disable once UseObjectOrCollectionInitializer
15+ var p = new SpannerParameter { DbType = DbType . String } ;
16+ p . Value = 8 ;
17+ Assert . That ( p . DbType , Is . EqualTo ( DbType . String ) ) ;
18+ }
19+
20+ [ Test ]
21+ public void DefaultConstructor ( )
22+ {
23+ var p = new SpannerParameter ( ) ;
24+ Assert . That ( p . DbType , Is . EqualTo ( DbType . String ) , "DbType" ) ;
25+ Assert . That ( p . Direction , Is . EqualTo ( ParameterDirection . Input ) , "Direction" ) ;
26+ Assert . That ( p . IsNullable , Is . False , "IsNullable" ) ;
27+ Assert . That ( p . ParameterName , Is . Empty , "ParameterName" ) ;
28+ Assert . That ( p . Precision , Is . EqualTo ( 0 ) , "Precision" ) ;
29+ Assert . That ( p . Scale , Is . EqualTo ( 0 ) , "Scale" ) ;
30+ Assert . That ( p . Size , Is . EqualTo ( 0 ) , "Size" ) ;
31+ Assert . That ( p . SourceColumn , Is . Empty , "SourceColumn" ) ;
32+ Assert . That ( p . SourceVersion , Is . EqualTo ( DataRowVersion . Current ) , "SourceVersion" ) ;
33+ Assert . That ( p . Value , Is . Null , "Value" ) ;
34+ }
35+
36+ [ Test ]
37+ public void ConstructorValueDateTime ( )
38+ {
39+ var value = new DateTime ( 2004 , 8 , 24 ) ;
40+
41+ var p = new SpannerParameter ( "address" , value ) ;
42+ // Setting a parameter value does not change the type.
43+ Assert . That ( p . DbType , Is . EqualTo ( DbType . String ) , "B:DbType" ) ;
44+ Assert . That ( p . Direction , Is . EqualTo ( ParameterDirection . Input ) , "B:Direction" ) ;
45+ Assert . That ( p . IsNullable , Is . False , "B:IsNullable" ) ;
46+ Assert . That ( p . ParameterName , Is . EqualTo ( "address" ) , "B:ParameterName" ) ;
47+ Assert . That ( p . Precision , Is . EqualTo ( 0 ) , "B:Precision" ) ;
48+ Assert . That ( p . Scale , Is . EqualTo ( 0 ) , "B:Scale" ) ;
49+ Assert . That ( p . Size , Is . EqualTo ( 0 ) , "B:Size" ) ;
50+ Assert . That ( p . SourceColumn , Is . Empty , "B:SourceColumn" ) ;
51+ Assert . That ( p . SourceVersion , Is . EqualTo ( DataRowVersion . Current ) , "B:SourceVersion" ) ;
52+ Assert . That ( p . Value , Is . EqualTo ( value ) , "B:Value" ) ;
53+ }
54+
55+ [ Test ]
56+ public void ConstructorValueDbNull ( )
57+ {
58+ var p = new SpannerParameter ( "address" , DBNull . Value ) ;
59+ Assert . That ( p . DbType , Is . EqualTo ( DbType . String ) , "B:DbType" ) ;
60+ Assert . That ( p . Direction , Is . EqualTo ( ParameterDirection . Input ) , "B:Direction" ) ;
61+ Assert . That ( p . IsNullable , Is . False , "B:IsNullable" ) ;
62+ Assert . That ( p . ParameterName , Is . EqualTo ( "address" ) , "B:ParameterName" ) ;
63+ Assert . That ( p . Precision , Is . EqualTo ( 0 ) , "B:Precision" ) ;
64+ Assert . That ( p . Scale , Is . EqualTo ( 0 ) , "B:Scale" ) ;
65+ Assert . That ( p . Size , Is . EqualTo ( 0 ) , "B:Size" ) ;
66+ Assert . That ( p . SourceColumn , Is . Empty , "B:SourceColumn" ) ;
67+ Assert . That ( p . SourceVersion , Is . EqualTo ( DataRowVersion . Current ) , "B:SourceVersion" ) ;
68+ Assert . That ( p . Value , Is . EqualTo ( DBNull . Value ) , "B:Value" ) ;
69+ }
70+
71+ [ Test ]
72+ public void ConstructorValueNull ( )
73+ {
74+ var p = new SpannerParameter ( "address" , null ) ;
75+ Assert . That ( p . DbType , Is . EqualTo ( DbType . String ) , "A:DbType" ) ;
76+ Assert . That ( p . Direction , Is . EqualTo ( ParameterDirection . Input ) , "A:Direction" ) ;
77+ Assert . That ( p . IsNullable , Is . False , "A:IsNullable" ) ;
78+ Assert . That ( p . ParameterName , Is . EqualTo ( "address" ) , "A:ParameterName" ) ;
79+ Assert . That ( p . Precision , Is . EqualTo ( 0 ) , "A:Precision" ) ;
80+ Assert . That ( p . Scale , Is . EqualTo ( 0 ) , "A:Scale" ) ;
81+ Assert . That ( p . Size , Is . EqualTo ( 0 ) , "A:Size" ) ;
82+ Assert . That ( p . SourceColumn , Is . Empty , "A:SourceColumn" ) ;
83+ Assert . That ( p . SourceVersion , Is . EqualTo ( DataRowVersion . Current ) , "A:SourceVersion" ) ;
84+ Assert . That ( p . Value , Is . Null , "A:Value" ) ;
85+ }
86+
87+ [ Test ]
88+ public void Clone ( )
89+ {
90+ var expected = new SpannerParameter
91+ {
92+ Value = 42 ,
93+ ParameterName = "TheAnswer" ,
94+
95+ DbType = DbType . Int32 ,
96+
97+ Direction = ParameterDirection . InputOutput ,
98+ IsNullable = true ,
99+ Precision = 1 ,
100+ Scale = 2 ,
101+ Size = 4 ,
102+
103+ SourceVersion = DataRowVersion . Proposed ,
104+ SourceColumn = "source" ,
105+ SourceColumnNullMapping = true ,
106+ } ;
107+ var actual = expected . Clone ( ) ;
108+
109+ Assert . That ( actual . Value , Is . EqualTo ( expected . Value ) ) ;
110+ Assert . That ( actual . ParameterName , Is . EqualTo ( expected . ParameterName ) ) ;
111+
112+ Assert . That ( actual . DbType , Is . EqualTo ( expected . DbType ) ) ;
113+
114+ Assert . That ( actual . Direction , Is . EqualTo ( expected . Direction ) ) ;
115+ Assert . That ( actual . IsNullable , Is . EqualTo ( expected . IsNullable ) ) ;
116+ Assert . That ( actual . Precision , Is . EqualTo ( expected . Precision ) ) ;
117+ Assert . That ( actual . Scale , Is . EqualTo ( expected . Scale ) ) ;
118+ Assert . That ( actual . Size , Is . EqualTo ( expected . Size ) ) ;
119+
120+ Assert . That ( actual . SourceVersion , Is . EqualTo ( expected . SourceVersion ) ) ;
121+ Assert . That ( actual . SourceColumn , Is . EqualTo ( expected . SourceColumn ) ) ;
122+ Assert . That ( actual . SourceColumnNullMapping , Is . EqualTo ( expected . SourceColumnNullMapping ) ) ;
123+ }
124+
125+ [ Test ]
126+ public void ParameterNull ( )
127+ {
128+ var param = new SpannerParameter { ParameterName = "param" , DbType = DbType . Decimal } ;
129+ Assert . That ( param . Scale , Is . EqualTo ( 0 ) , "#A1" ) ;
130+ param . Value = DBNull . Value ;
131+ Assert . That ( param . Scale , Is . EqualTo ( 0 ) , "#A2" ) ;
132+
133+ param = new SpannerParameter { ParameterName = "param" , DbType = DbType . Int32 } ;
134+ Assert . That ( param . Scale , Is . EqualTo ( 0 ) , "#B1" ) ;
135+ param . Value = DBNull . Value ;
136+ Assert . That ( param . Scale , Is . EqualTo ( 0 ) , "#B2" ) ;
137+ }
138+
139+ [ Test ]
140+ public async Task MatchParamIndexCaseInsensitively ( )
141+ {
142+ const string sql = "SELECT @p,@P" ;
143+ Fixture . SpannerMock . AddOrUpdateStatementResult ( sql , StatementResult . CreateResultSet (
144+ new List < Tuple < TypeCode , string > > ( [ Tuple . Create ( TypeCode . String , "p" ) , Tuple . Create ( TypeCode . String , "p" ) ] ) ,
145+ new List < object [ ] > ( [ [ "Hello World" , "Hello World" ] ] ) ) ) ;
146+
147+ await using var conn = await OpenConnectionAsync ( ) ;
148+ await using var cmd = new SpannerCommand ( sql , conn ) ;
149+ cmd . AddParameter ( "p" , "Hello World" ) ;
150+ await cmd . ExecuteNonQueryAsync ( ) ;
151+
152+ var request = Fixture . SpannerMock . Requests . OfType < ExecuteSqlRequest > ( ) . Single ( r => r . Sql == sql ) ;
153+ Assert . That ( request , Is . Not . Null ) ;
154+ // TODO: Revisit once https://github.com/googleapis/go-sql-spanner/issues/594 has been decided.
155+ Assert . That ( request . Params . Fields . Count , Is . EqualTo ( 2 ) ) ;
156+ Assert . That ( request . Params . Fields [ "p" ] . StringValue , Is . EqualTo ( "Hello World" ) ) ;
157+ Assert . That ( request . Params . Fields [ "P" ] . HasNullValue ) ;
158+ }
159+
160+ [ Test ]
161+ public void PrecisionViaInterface ( )
162+ {
163+ var parameter = new SpannerParameter ( ) ;
164+ var paramIface = ( IDbDataParameter ) parameter ;
165+
166+ paramIface . Precision = 42 ;
167+
168+ Assert . That ( paramIface . Precision , Is . EqualTo ( ( byte ) 42 ) ) ;
169+ }
170+
171+ [ Test ]
172+ public void PrecisionViaBaseClass ( )
173+ {
174+ var parameter = new SpannerParameter ( ) ;
175+ var paramBase = ( DbParameter ) parameter ;
176+
177+ paramBase . Precision = 42 ;
178+
179+ Assert . That ( paramBase . Precision , Is . EqualTo ( ( byte ) 42 ) ) ;
180+ }
181+
182+ [ Test ]
183+ public void ScaleViaInterface ( )
184+ {
185+ var parameter = new SpannerParameter ( ) ;
186+ var paramIface = ( IDbDataParameter ) parameter ;
187+
188+ paramIface . Scale = 42 ;
189+
190+ Assert . That ( paramIface . Scale , Is . EqualTo ( ( byte ) 42 ) ) ;
191+ }
192+
193+ [ Test ]
194+ public void ScaleViaBaseClass ( )
195+ {
196+ var parameter = new SpannerParameter ( ) ;
197+ var paramBase = ( DbParameter ) parameter ;
198+
199+ paramBase . Scale = 42 ;
200+
201+ Assert . That ( paramBase . Scale , Is . EqualTo ( ( byte ) 42 ) ) ;
202+ }
203+
204+ [ Test ]
205+ public void NullValueThrows ( )
206+ {
207+ using var connection = OpenConnection ( ) ;
208+ using var command = new SpannerCommand ( "SELECT @p" , connection ) ;
209+ command . Parameters . Add ( new SpannerParameter ( "p" , null ) ) ;
210+
211+ Assert . That ( ( ) => command . ExecuteReader ( ) , Throws . InvalidOperationException ) ;
212+ }
213+
214+ }
0 commit comments