2 // DataProviderBaseTest.cs : A base class that provides the common
4 // 1) Reading a config file containing the
5 // database connection parameters, different
6 // tables and their description, Values that
7 // the tables are populated with.
8 // 2) Retrieves data from these tables;
9 // 3) Compares the retrieved values against the ones
10 // contained in the config file.
12 // A class specific to each database (and ODBC) are derived from this class.
13 // These classes contain code specific to different databases (like establishing
14 // a connection, comparing date values, etc).
17 // Satya Sudha K (ksathyasudha@novell.com)
20 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
22 // Permission is hereby granted, free of charge, to any person obtaining
23 // a copy of this software and associated documentation files (the
24 // "Software"), to deal in the Software without restriction, including
25 // without limitation the rights to use, copy, modify, merge, publish,
26 // distribute, sublicense, and/or sell copies of the Software, and to
27 // permit persons to whom the Software is furnished to do so, subject to
28 // the following conditions:
30 // The above copyright notice and this permission notice shall be
31 // included in all copies or substantial portions of the Software.
33 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
35 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
37 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
38 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
39 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 using System.Collections;
46 using System.Xml.XPath;
48 using System.Configuration;
49 using System.Text.RegularExpressions;
51 namespace MonoTests.System.Data {
53 public class BaseRetrieve {
55 public IDbConnection con;
56 public IDbCommand cmd;
57 public IDataReader rdr;
58 protected XmlNode configDoc;
60 public BaseRetrieve (string database)
65 configDoc = (XmlNode) ConfigurationSettings.GetConfig (database);
72 cmd = con.CreateCommand ();
75 // Method that actually runs the entire test : Connects to a database,
76 // retrieves values from different tables, and compares them against
77 // the values that we had entered
78 public void RunTest ()
89 string noOfTables = null;
90 string tableName = null;
91 int [] columnNos = null;
94 noOfTables = ConfigClass.GetElement (configDoc, "tables", "numTables");
95 short numTables = Convert.ToInt16 (noOfTables);
96 string noOfQueries = ConfigClass.GetElement (configDoc, "queries", "numQueries");
97 Console.WriteLine ("**** Running Queries ****");
99 if (noOfQueries != null) {
101 int numQueries = Convert.ToInt32 (noOfQueries);
103 for (int index = 1; index <= numQueries; index++) {
104 string queryStr = ConfigClass.GetElement (configDoc, "queries", "query" + index);
106 rdr = RunQuery (queryStr, ref columnNos, ref tableNum);
110 CompareData (rdr, configDoc, columnNos, tableNum);
115 string storedProc = null;
117 storedProc = ConfigClass.GetElement (configDoc, "StoredProcExists");
118 } catch (Exception e) {
122 if (storedProc.Equals ("Y")) {
124 Console.WriteLine ("\n**** Running tests for stored procedures *****\n");
125 int numStoredProc = Convert.ToInt32 (ConfigClass.GetElement(configDoc,
126 "StoredProc", "NumStoredProc"));
127 for (int index = 1; index <= numStoredProc; index++) {
129 string storedProcTag = "StoredProc" + index;
130 string type = ConfigClass.GetElement (configDoc, "StoredProc",
131 storedProcTag, "type");
132 string nameTemplate = ConfigClass.GetElement (configDoc, "StoredProc",
133 storedProcTag, "name");
134 if (type.Equals("generic")) {
136 // There is stored proc correspoding to each table
137 // Run all such stored proc
138 for (short i = 1; i <= numTables; i++) {
141 tableName = ConfigClass.GetElement (configDoc, "tables",
143 } catch (XPathException e) {
144 Console.WriteLine (e.Message);
145 continue; // need not return here; try with the next one
148 string storedProcName = nameTemplate.Replace ("{{TABLE}}", tableName);
149 rdr = QueryUsingStoredProc (cmd, storedProcName, null);
153 CompareData (rdr, configDoc, null, i);
160 } catch (Exception e) {
161 Console.WriteLine ("ERROR : " + e.Message);
162 Console.WriteLine ("STACKTRACE : " + e.StackTrace);
170 public virtual IDataReader QueryUsingStoredProc (IDbCommand cmd,
171 string storedProcName,
174 cmd.CommandType = CommandType.StoredProcedure;
175 cmd.CommandText = storedProcName;
176 IDataReader rdr = null;
179 rdr = cmd.ExecuteReader ();
180 } catch (Exception e) {
181 Console.WriteLine ("Could not execute command : " + cmd.CommandText);
182 Console.WriteLine ("ERROR : " + e.Message);
183 Console.WriteLine ("STACKTRACE : " + e.StackTrace);
190 IDataReader RunQuery (string queryStr, ref int [] columnNos, ref int tableNum)
192 string regexp = "\\b(Select|select) (?<columnList>(COLUMNS|((COLUMN\\d+,)*(COLUMN\\d+)))) from (?<tableName>TABLE\\d+)( order by (?<OrderBy>COLUMN\\d+))*";
193 Match m = Regex.Match (queryStr, regexp, RegexOptions.ExplicitCapture);
195 Console.WriteLine ("Incorrect query format!!!");
203 string tableTag = m.Result ("${tableName}");
204 tableNum = Convert.ToInt32 (tableTag.Replace ("TABLE", ""));
205 string tableName = ConfigClass.GetElement (configDoc, "tables", tableTag.ToLower (), "name");
206 queryStr = queryStr.Replace (tableTag, tableName);
208 for (int i = 0; i<m.Groups.Count; i++) {
210 Group g = m.Groups [i];
211 CaptureCollection cc = g.Captures;
213 for (int j = 0; j < cc.Count; j++) {
215 string matchedVal = cc [j].Value;
217 if (matchedVal.Equals ("COLUMNS")) {
218 string [] columnNames = ConfigClass.GetColumnNames (configDoc, tableNum);
219 queryStr = queryStr.Replace ("COLUMNS", String.Join (",", columnNames));
220 columnNos = new int [columnNames.Length];
221 for (int index = 1; index <= columnNos.Length; index++)
222 columnNos [index - 1] = index;
224 } else if (matchedVal.StartsWith ("COLUMN")) {
225 // May be a column name or a comma
226 // separated list of columns
227 string [] listOfColumns = matchedVal.Split (',');
228 if (columnNos == null) {
230 columnNos = new int [listOfColumns.Length];
232 foreach (string str in listOfColumns) {
233 int columnNo = Convert.ToInt32 (str.Replace("COLUMN", ""));
234 columnNos [colIndex ++] = columnNo;
238 foreach (string str in listOfColumns) {
240 string columnName = ConfigClass.GetElement (configDoc, "tables",
241 tableTag.ToLower (), str.ToLower (), "name");
242 queryStr = queryStr.Replace (str, columnName);
251 IDataReader rdr = null;
252 cmd.CommandText = queryStr;
254 rdr = cmd.ExecuteReader ();
255 } catch (Exception e) {
256 Console.WriteLine ("ERROR : " + e.Message);
257 Console.WriteLine ("\nSTACKTRACE : " + e.StackTrace);
265 void CompareData (IDataReader rdr,
271 string errorMsg = "";
272 string tableName = null;
274 tableName = ConfigClass.GetElement (doc, "tables", "table"+numTable, "name");
275 } catch (Exception e) {
276 Console.WriteLine ("ERROR : " + e.Message );
277 Console.WriteLine ("STACKTRACE : " + e.StackTrace );
283 string columnValue = null;
284 for (int i = 0; i < rdr.FieldCount; i++) {
288 if (columnNos == null)
291 columnNum = columnNos [i];
293 columnValue = ConfigClass.GetElement (doc, "values", "table" + numTable,
294 "row" + rowNum, "column" + columnNum);
295 } catch (Exception e) {
296 Console.WriteLine ("ERROR : " + e.Message);
297 Console.WriteLine ("STACKTRACE : " + e.StackTrace);
301 Console.Write ("Table : {0} : ROW: {1} COL: {2}", tableName, rowNum, columnNum);
303 obj = GetValue (rdr, i);
304 } catch (Exception e) {
306 Console.WriteLine ("...FAIL");
307 errorMsg = "ERROR : " + e.Message;
308 errorMsg += "\nSTACKTRACE : " + e.StackTrace;
309 errorMsg += "\nProbably the 'GetFieldType()' method returned a wrong type!!";
310 Console.WriteLine (errorMsg);
315 if (AreEqual (obj, columnValue, ref errorMsg)) {
316 Console.WriteLine ("...OK");
318 Console.WriteLine ("...FAIL");
319 if (!errorMsg.Equals ("")) {
320 // There was some exception
321 Console.WriteLine (errorMsg);
324 Console.WriteLine ("Expected : "+columnValue+" Got : "+obj);
328 Console.WriteLine ("======================");
332 public virtual object GetValue (IDataReader rdr, int columnIndex)
337 if (rdr.IsDBNull (columnIndex)) {
341 Type type = rdr.GetFieldType (columnIndex);
343 switch (type.Name.ToLower ()) {
345 case "byte" : value = rdr.GetByte (columnIndex);
347 case "sbyte" : value = rdr.GetInt16 (columnIndex);
349 case "boolean" : value = rdr.GetBoolean (columnIndex);
351 case "int16" : value = rdr.GetInt16 (columnIndex);
354 case "int32" : value = rdr.GetInt32 (columnIndex);
357 case "int64" : value = rdr.GetInt64 (columnIndex);
359 case "single" : value = rdr.GetFloat (columnIndex);
361 case "double" : value = rdr.GetDouble (columnIndex);
364 case "decimal" : value = rdr.GetDecimal (columnIndex);
366 case "datetime": value = rdr.GetDateTime (columnIndex);
368 case "string": value = rdr.GetString (columnIndex);
370 default : value = rdr.GetValue (columnIndex);
378 public virtual Boolean AreEqual (object obj, string value, ref string errorMsg)
381 if ((obj == null) || (value.Equals("null"))) {
382 if (obj == null && value.Equals ("null"))
387 object valObj = ConvertToValueType (obj.GetType (), value, ref errorMsg);
388 if (valObj == null) {
389 errorMsg = "Could not convert values!!\n" + errorMsg;
392 return valObj.Equals (obj);
395 public virtual object ConvertToValueType (Type objType, string value, ref string errorMsg)
398 value = value.Trim ('\'');
399 value = value.Trim ('\"');
401 switch (Type.GetTypeCode (objType)) {
403 case TypeCode.Int16 :
404 return ConvertToInt16 (objType, value, ref errorMsg);
405 case TypeCode.Int32 :
406 return ConvertToInt32 (objType, value, ref errorMsg);
407 case TypeCode.Int64 :
408 return ConvertToInt64 (objType, value, ref errorMsg);
409 case TypeCode.Boolean :
410 return ConvertToBoolean (objType, value, ref errorMsg);
412 return ConvertToByte (objType, value, ref errorMsg);
413 case TypeCode.DateTime :
414 return ConvertToDateTime (objType, value, ref errorMsg);
415 case TypeCode.Decimal :
416 return ConvertToDecimal (objType, value, ref errorMsg);
417 case TypeCode.Double :
418 return ConvertToDouble (objType, value, ref errorMsg);
419 case TypeCode.Single :
420 return ConvertToSingle (objType, value, ref errorMsg);
424 if ( objType.ToString () == "System.TimeSpan")
425 return ConvertToTimespan (objType, value, ref errorMsg);
427 return ConvertValue (objType, value, ref errorMsg);
430 public virtual object ConvertValue (Type type, string value, ref string errorMsg)
432 object valObj = null;
435 valObj = Convert.ChangeType (value, type);
436 } catch (InvalidCastException e) {
437 errorMsg = "Cant compare values!! \n";
438 errorMsg += "ERROR : " + e.Message;
439 errorMsg += "\nSTACKTRACE : " + e.StackTrace;
441 } catch (Exception e) {
442 errorMsg = "ERROR : " + e.Message;
443 errorMsg += "\nSTACKTRACE : " + e.StackTrace;
451 public virtual object ConvertToInt16 (Type type, string value, ref string errorMsg)
453 return ConvertValue (type, value, ref errorMsg);
456 public virtual object ConvertToInt32 (Type type, string value, ref string errorMsg)
458 return ConvertValue (type, value, ref errorMsg);
461 public virtual object ConvertToInt64 (Type type, string value, ref string errorMsg)
463 return ConvertValue (type, value, ref errorMsg);
466 public virtual object ConvertToBoolean (Type type, string value, ref string errorMsg)
468 return ConvertValue (type, value, ref errorMsg);
471 public virtual object ConvertToByte (Type type, string value, ref string errorMsg)
473 return ConvertValue (type, value, ref errorMsg);
476 public virtual object ConvertToDateTime (Type type, string value, ref string errorMsg)
478 return ConvertValue (type, value, ref errorMsg);
481 public virtual object ConvertToDecimal (Type type, string value, ref string errorMsg)
483 return ConvertValue (type, value, ref errorMsg);
486 public virtual object ConvertToDouble (Type type, string value, ref string errorMsg)
488 return ConvertValue (type, value, ref errorMsg);
491 public virtual object ConvertToSingle (Type type, string value, ref string errorMsg)
493 return ConvertValue (type, value, ref errorMsg);
496 public virtual object ConvertToTimespan (Type type, string value, ref string errorMsg)
498 return ConvertValue (type, value, ref errorMsg);
501 public virtual void GetConnection()