Bläddra i källkod

2002-05-18 Daniel Morgan <[email protected]>

	* System.Data.SqlClient/SqlCommand.cs: handle CommandTypes
	Text, TableDirect, and StoredProcedure

	* Test/PostgresTest.cs: changed call to version()
	stored procedure to use the CommandType of StoredProcedure

	* Test/TestSqlDataReader.cs: test all the CommandTypes

svn path=/trunk/mcs/; revision=4743
Daniel Morgan 23 år sedan
förälder
incheckning
ec6e751eb5

+ 58 - 3
mcs/class/Mono.Data.PostgreSqlClient/Mono.Data.PostgreSqlClient/PgSqlCommand.cs

@@ -23,10 +23,12 @@
 // #define DEBUG_SqlCommand
 
 using System;
+using System.Collections;
 using System.ComponentModel;
 using System.Data;
 using System.Data.Common;
 using System.Runtime.InteropServices;
+using System.Text;
 using System.Xml;
 
 namespace System.Data.SqlClient {
@@ -108,11 +110,14 @@ namespace System.Data.SqlClient {
 			int rowsAffected = -1;
 			ExecStatusType execStatus;
 			String rowsAffectedString;
+			string query;
 
 			if(conn.State != ConnectionState.Open)
 				throw new InvalidOperationException(
 					"ConnnectionState is not Open");
 
+			query = TweakQuery(sql, cmdType);
+
 			// FIXME: PQexec blocks 
 			// while PQsendQuery is non-blocking
 			// which is better to use?
@@ -122,7 +127,7 @@ namespace System.Data.SqlClient {
 			// execute SQL command
 			// uses internal property to get the PGConn IntPtr
 			pgResult = PostgresLibrary.
-				PQexec (conn.PostgresConnection, sql);
+				PQexec (conn.PostgresConnection, query);
 
 			execStatus = PostgresLibrary.
 				PQresultStatus (pgResult);
@@ -200,11 +205,13 @@ namespace System.Data.SqlClient {
 		{
 			SqlResult res = new SqlResult();
 			res.Connection = this.Connection;
+			string statement;
 		
 			currentQuery++;
 
 			if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
-				ExecuteQuery(queries[currentQuery], res);
+				statement = TweakQuery(queries[currentQuery], cmdType);
+				ExecuteQuery(statement, res);
 				res.ResultReturned = true;
 			}
 			else {
@@ -214,6 +221,45 @@ namespace System.Data.SqlClient {
 			return res;
 		}
 
+		private string TweakQuery(string query, CommandType commandType) {
+			string statement = "";
+			StringBuilder td;
+
+			// TODO: need to handle parameters
+			
+			// finish building SQL based on CommandType
+			switch(commandType) {
+			case CommandType.Text:
+				statement = query;
+				break;
+			case CommandType.StoredProcedure:
+				statement = 
+					"SELECT " + query + "()";
+				break;
+			case CommandType.TableDirect:
+				string[] directTables = query.Split(
+					new Char[] {','});	
+										 
+				td = new StringBuilder("SELECT * FROM ");
+				
+				for(int tab = 0; tab < directTables.Length; tab++) {
+					if(tab > 0 && tab < directTables.Length - 1)
+						td.Append(',');
+					td.Append(directTables[tab]);
+					// FIXME: if multipe tables, how do we
+					//        join? based on Primary/Foreign Keys?
+					//        Otherwise, a Cartesian Product happens
+				}
+				statement = td.ToString();
+				break;
+			default:
+				// FIXME: throw an exception?
+				statement = query;
+				break;
+			}
+			return statement;
+		}
+
 		private void ExecuteQuery (string query, SqlResult res)
 		{			
 			IntPtr pgResult;
@@ -266,6 +312,12 @@ namespace System.Data.SqlClient {
 			queries = null;
 		}
 
+		/// <summary>
+		/// ExecuteScalar is used to retrieve one object
+		/// from one result set 
+		/// that has one row and one column.
+		/// It is lightweight compared to ExecuteReader.
+		/// </summary>
 		[MonoTODO]
 		public object ExecuteScalar () {
 			IntPtr pgResult; // PGresult
@@ -276,11 +328,14 @@ namespace System.Data.SqlClient {
 			String value;
 			int nRows;
 			int nFields;
+			string query;
 
 			if(conn.State != ConnectionState.Open)
 				throw new InvalidOperationException(
 					"ConnnectionState is not Open");
 
+			query = TweakQuery(sql, cmdType);
+
 			// FIXME: PQexec blocks 
 			// while PQsendQuery is non-blocking
 			// which is better to use?
@@ -290,7 +345,7 @@ namespace System.Data.SqlClient {
 			// execute SQL command
 			// uses internal property to get the PGConn IntPtr
 			pgResult = PostgresLibrary.
-				PQexec (conn.PostgresConnection, sql);
+				PQexec (conn.PostgresConnection, query);
 
 			execStatus = PostgresLibrary.
 				PQresultStatus (pgResult);

+ 58 - 3
mcs/class/Mono.Data.PostgreSqlClient/PgSqlCommand.cs

@@ -23,10 +23,12 @@
 // #define DEBUG_SqlCommand
 
 using System;
+using System.Collections;
 using System.ComponentModel;
 using System.Data;
 using System.Data.Common;
 using System.Runtime.InteropServices;
+using System.Text;
 using System.Xml;
 
 namespace System.Data.SqlClient {
@@ -108,11 +110,14 @@ namespace System.Data.SqlClient {
 			int rowsAffected = -1;
 			ExecStatusType execStatus;
 			String rowsAffectedString;
+			string query;
 
 			if(conn.State != ConnectionState.Open)
 				throw new InvalidOperationException(
 					"ConnnectionState is not Open");
 
+			query = TweakQuery(sql, cmdType);
+
 			// FIXME: PQexec blocks 
 			// while PQsendQuery is non-blocking
 			// which is better to use?
@@ -122,7 +127,7 @@ namespace System.Data.SqlClient {
 			// execute SQL command
 			// uses internal property to get the PGConn IntPtr
 			pgResult = PostgresLibrary.
-				PQexec (conn.PostgresConnection, sql);
+				PQexec (conn.PostgresConnection, query);
 
 			execStatus = PostgresLibrary.
 				PQresultStatus (pgResult);
@@ -200,11 +205,13 @@ namespace System.Data.SqlClient {
 		{
 			SqlResult res = new SqlResult();
 			res.Connection = this.Connection;
+			string statement;
 		
 			currentQuery++;
 
 			if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
-				ExecuteQuery(queries[currentQuery], res);
+				statement = TweakQuery(queries[currentQuery], cmdType);
+				ExecuteQuery(statement, res);
 				res.ResultReturned = true;
 			}
 			else {
@@ -214,6 +221,45 @@ namespace System.Data.SqlClient {
 			return res;
 		}
 
+		private string TweakQuery(string query, CommandType commandType) {
+			string statement = "";
+			StringBuilder td;
+
+			// TODO: need to handle parameters
+			
+			// finish building SQL based on CommandType
+			switch(commandType) {
+			case CommandType.Text:
+				statement = query;
+				break;
+			case CommandType.StoredProcedure:
+				statement = 
+					"SELECT " + query + "()";
+				break;
+			case CommandType.TableDirect:
+				string[] directTables = query.Split(
+					new Char[] {','});	
+										 
+				td = new StringBuilder("SELECT * FROM ");
+				
+				for(int tab = 0; tab < directTables.Length; tab++) {
+					if(tab > 0 && tab < directTables.Length - 1)
+						td.Append(',');
+					td.Append(directTables[tab]);
+					// FIXME: if multipe tables, how do we
+					//        join? based on Primary/Foreign Keys?
+					//        Otherwise, a Cartesian Product happens
+				}
+				statement = td.ToString();
+				break;
+			default:
+				// FIXME: throw an exception?
+				statement = query;
+				break;
+			}
+			return statement;
+		}
+
 		private void ExecuteQuery (string query, SqlResult res)
 		{			
 			IntPtr pgResult;
@@ -266,6 +312,12 @@ namespace System.Data.SqlClient {
 			queries = null;
 		}
 
+		/// <summary>
+		/// ExecuteScalar is used to retrieve one object
+		/// from one result set 
+		/// that has one row and one column.
+		/// It is lightweight compared to ExecuteReader.
+		/// </summary>
 		[MonoTODO]
 		public object ExecuteScalar () {
 			IntPtr pgResult; // PGresult
@@ -276,11 +328,14 @@ namespace System.Data.SqlClient {
 			String value;
 			int nRows;
 			int nFields;
+			string query;
 
 			if(conn.State != ConnectionState.Open)
 				throw new InvalidOperationException(
 					"ConnnectionState is not Open");
 
+			query = TweakQuery(sql, cmdType);
+
 			// FIXME: PQexec blocks 
 			// while PQsendQuery is non-blocking
 			// which is better to use?
@@ -290,7 +345,7 @@ namespace System.Data.SqlClient {
 			// execute SQL command
 			// uses internal property to get the PGConn IntPtr
 			pgResult = PostgresLibrary.
-				PQexec (conn.PostgresConnection, sql);
+				PQexec (conn.PostgresConnection, query);
 
 			execStatus = PostgresLibrary.
 				PQresultStatus (pgResult);

+ 10 - 0
mcs/class/System.Data/ChangeLog

@@ -1,3 +1,13 @@
+2002-05-18  Daniel Morgan <[email protected]>
+
+	* System.Data.SqlClient/SqlCommand.cs: handle CommandTypes
+	Text, TableDirect, and StoredProcedure
+	
+	* Test/PostgresTest.cs: changed call to version() 
+	stored procedure to use the CommandType of StoredProcedure
+	
+	* Test/TestSqlDataReader.cs: test all the CommandTypes
+
 2002-05-18  Daniel Morgan <[email protected]>
 
 	* System.Data.build: took out all excluded

+ 58 - 3
mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs

@@ -23,10 +23,12 @@
 // #define DEBUG_SqlCommand
 
 using System;
+using System.Collections;
 using System.ComponentModel;
 using System.Data;
 using System.Data.Common;
 using System.Runtime.InteropServices;
+using System.Text;
 using System.Xml;
 
 namespace System.Data.SqlClient {
@@ -108,11 +110,14 @@ namespace System.Data.SqlClient {
 			int rowsAffected = -1;
 			ExecStatusType execStatus;
 			String rowsAffectedString;
+			string query;
 
 			if(conn.State != ConnectionState.Open)
 				throw new InvalidOperationException(
 					"ConnnectionState is not Open");
 
+			query = TweakQuery(sql, cmdType);
+
 			// FIXME: PQexec blocks 
 			// while PQsendQuery is non-blocking
 			// which is better to use?
@@ -122,7 +127,7 @@ namespace System.Data.SqlClient {
 			// execute SQL command
 			// uses internal property to get the PGConn IntPtr
 			pgResult = PostgresLibrary.
-				PQexec (conn.PostgresConnection, sql);
+				PQexec (conn.PostgresConnection, query);
 
 			execStatus = PostgresLibrary.
 				PQresultStatus (pgResult);
@@ -200,11 +205,13 @@ namespace System.Data.SqlClient {
 		{
 			SqlResult res = new SqlResult();
 			res.Connection = this.Connection;
+			string statement;
 		
 			currentQuery++;
 
 			if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
-				ExecuteQuery(queries[currentQuery], res);
+				statement = TweakQuery(queries[currentQuery], cmdType);
+				ExecuteQuery(statement, res);
 				res.ResultReturned = true;
 			}
 			else {
@@ -214,6 +221,45 @@ namespace System.Data.SqlClient {
 			return res;
 		}
 
+		private string TweakQuery(string query, CommandType commandType) {
+			string statement = "";
+			StringBuilder td;
+
+			// TODO: need to handle parameters
+			
+			// finish building SQL based on CommandType
+			switch(commandType) {
+			case CommandType.Text:
+				statement = query;
+				break;
+			case CommandType.StoredProcedure:
+				statement = 
+					"SELECT " + query + "()";
+				break;
+			case CommandType.TableDirect:
+				string[] directTables = query.Split(
+					new Char[] {','});	
+										 
+				td = new StringBuilder("SELECT * FROM ");
+				
+				for(int tab = 0; tab < directTables.Length; tab++) {
+					if(tab > 0 && tab < directTables.Length - 1)
+						td.Append(',');
+					td.Append(directTables[tab]);
+					// FIXME: if multipe tables, how do we
+					//        join? based on Primary/Foreign Keys?
+					//        Otherwise, a Cartesian Product happens
+				}
+				statement = td.ToString();
+				break;
+			default:
+				// FIXME: throw an exception?
+				statement = query;
+				break;
+			}
+			return statement;
+		}
+
 		private void ExecuteQuery (string query, SqlResult res)
 		{			
 			IntPtr pgResult;
@@ -266,6 +312,12 @@ namespace System.Data.SqlClient {
 			queries = null;
 		}
 
+		/// <summary>
+		/// ExecuteScalar is used to retrieve one object
+		/// from one result set 
+		/// that has one row and one column.
+		/// It is lightweight compared to ExecuteReader.
+		/// </summary>
 		[MonoTODO]
 		public object ExecuteScalar () {
 			IntPtr pgResult; // PGresult
@@ -276,11 +328,14 @@ namespace System.Data.SqlClient {
 			String value;
 			int nRows;
 			int nFields;
+			string query;
 
 			if(conn.State != ConnectionState.Open)
 				throw new InvalidOperationException(
 					"ConnnectionState is not Open");
 
+			query = TweakQuery(sql, cmdType);
+
 			// FIXME: PQexec blocks 
 			// while PQsendQuery is non-blocking
 			// which is better to use?
@@ -290,7 +345,7 @@ namespace System.Data.SqlClient {
 			// execute SQL command
 			// uses internal property to get the PGConn IntPtr
 			pgResult = PostgresLibrary.
-				PQexec (conn.PostgresConnection, sql);
+				PQexec (conn.PostgresConnection, query);
 
 			execStatus = PostgresLibrary.
 				PQresultStatus (pgResult);

+ 4 - 1
mcs/class/System.Data/Test/PostgresTest.cs

@@ -92,8 +92,10 @@ namespace TestSystemDataSqlClient {
 			IDbCommand callStoredProcCommand = cnc.CreateCommand ();
 			object data;
 
+			callStoredProcCommand.CommandType = 
+				CommandType.StoredProcedure;
 			callStoredProcCommand.CommandText =
-				"select version()";
+				"version";
 							
 			data = callStoredProcCommand.ExecuteScalar ();
 
@@ -217,6 +219,7 @@ namespace TestSystemDataSqlClient {
 
 			Console.WriteLine("Aggregate: " + agg);
 
+			selectCommand.CommandType = CommandType.Text;
 			selectCommand.CommandText = 
 				"select " + agg +
 				"from mono_postgres_test";

+ 64 - 33
mcs/class/System.Data/Test/TestSqlDataReader.cs

@@ -19,34 +19,26 @@ using System.Data.SqlClient;
 namespace TestSystemDataSqlClient {
 	class TestSqlDataReader {
 
-		static void Test() { 
-			SqlConnection con = null;
+		static void Test(SqlConnection con, string sql, 
+				CommandType cmdType, CommandBehavior behavior,
+				string testDesc) 
+		{ 
 			SqlCommand cmd = null;
 			SqlDataReader rdr = null;
 			
-			String connectionString = null;
-			String sql = null;
 			int c;
 			int results = 0;
 
-			connectionString = 
-				"host=localhost;" +
-				"dbname=test;" +
-				"user=postgres";
-				
-			sql = 	"select * from pg_user;" + 
-				"select * from pg_tables;" + 
-				"select * from pg_database;";
-							
-			con = new SqlConnection(connectionString);
-			con.Open();
-
-			Console.WriteLine("sql: " +
-				sql);
+			Console.WriteLine("Test: " + testDesc);
+			Console.WriteLine("[BEGIN SQL]");
+			Console.WriteLine(sql);
+			Console.WriteLine("[END SQL]");
 
 			cmd = new SqlCommand(sql, con);
+			cmd.CommandType = cmdType;
+						
 			Console.WriteLine("ExecuteReader...");
-			rdr = cmd.ExecuteReader();
+			rdr = cmd.ExecuteReader(behavior);
 
 			do {
 				results++;
@@ -72,32 +64,71 @@ namespace TestSystemDataSqlClient {
 				int nRows = 0;
 
 				// Read and display the rows
-				while(rdr.Read()) {
-					Console.WriteLine("   Row " + nRows + ": ");
+			while(rdr.Read()) {
+				Console.WriteLine("   Row " + nRows + ": ");
 
-					for(c = 0; c < rdr.FieldCount; c++) {
-						if(rdr.IsDBNull(c) == true)
-							Console.WriteLine("      " + 
-								rdr.GetName(c) + " is DBNull");
-						else
-							Console.WriteLine("      " + 
-								rdr.GetName(c) + ": " +
-								rdr[c].ToString());
-					}
-					nRows++;
+				for(c = 0; c < rdr.FieldCount; c++) {
+					if(rdr.IsDBNull(c) == true)
+						Console.WriteLine("      " + 
+							rdr.GetName(c) + " is DBNull");
+					else
+						Console.WriteLine("      " + 
+							rdr.GetName(c) + ": " +
+							rdr[c].ToString());
 				}
+				nRows++;
+			}
 				Console.WriteLine("   Total Rows: " + 
 					nRows);
 			} while(rdr.NextResult());
 			Console.WriteLine("Total Result sets: " + results);
 			
 			rdr.Close();
-			con.Close();
 		}
 
 		[STAThread]
 		static void Main(string[] args) {
-			Test();
+			String connectionString = null;
+			connectionString = 
+				"host=localhost;" +
+				"dbname=test;" +
+				"user=postgres";
+						
+			SqlConnection con;
+			con = new SqlConnection(connectionString);
+			con.Open();
+
+			string sql;
+
+			// Text - only has one query (single query behavior)
+			sql = "select * from pg_tables";
+			Test(con, sql, CommandType.Text, 
+				CommandBehavior.SingleResult, "Text1");
+
+			// Text - only has one query (default behavior)
+			sql = "select * from pg_tables";
+			Test(con, sql, CommandType.Text, 
+				CommandBehavior.Default, "Text2");
+			
+			// Text - has three queries
+			sql =
+				"select * from pg_user;" + 
+				"select * from pg_tables;" + 
+				"select * from pg_database";
+			Test(con, sql, CommandType.Text, 
+				CommandBehavior.Default, "Text3Queries");
+			
+			// Table Direct
+			sql = "pg_tables";
+			Test(con, sql, CommandType.TableDirect, 
+				CommandBehavior.Default, "TableDirect1");
+
+			// Stored Procedure
+			sql = "version";
+			Test(con, sql, CommandType.StoredProcedure, 
+				CommandBehavior.Default, "SP1");
+			
+			con.Close();
 		}
 	}
 }