2002-05-18 Daniel Morgan <danmorg@sc.rr.com>
authorDaniel Morgan <monodanmorg@yahoo.com>
Sat, 18 May 2002 15:17:15 +0000 (15:17 -0000)
committerDaniel Morgan <monodanmorg@yahoo.com>
Sat, 18 May 2002 15:17:15 +0000 (15:17 -0000)
* 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

mcs/class/Mono.Data.PostgreSqlClient/Mono.Data.PostgreSqlClient/PgSqlCommand.cs
mcs/class/Mono.Data.PostgreSqlClient/PgSqlCommand.cs
mcs/class/System.Data/ChangeLog
mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
mcs/class/System.Data/Test/PostgresTest.cs
mcs/class/System.Data/Test/TestSqlDataReader.cs

index 726b5655f46c696daa3d5ad4c23d6c7207812d18..84ae6eeb53972baab0111548ac36c63c2ba69364 100644 (file)
 // #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>\r
+               /// ExecuteScalar is used to retrieve one object
+               /// from one result set \r
+               /// that has one row and one column.\r
+               /// It is lightweight compared to ExecuteReader.\r
+               /// </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);
index 726b5655f46c696daa3d5ad4c23d6c7207812d18..84ae6eeb53972baab0111548ac36c63c2ba69364 100644 (file)
 // #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>\r
+               /// ExecuteScalar is used to retrieve one object
+               /// from one result set \r
+               /// that has one row and one column.\r
+               /// It is lightweight compared to ExecuteReader.\r
+               /// </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);
index ee941be8bf351e6a4ac67ba036467cce7262b690..ae0c75c07c1a56188d306a167d757bc7865308f2 100644 (file)
@@ -1,3 +1,13 @@
+2002-05-18  Daniel Morgan <danmorg@sc.rr.com>
+
+       * 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 <danmorg@sc.rr.com>
 
        * System.Data.build: took out all excluded
index 726b5655f46c696daa3d5ad4c23d6c7207812d18..84ae6eeb53972baab0111548ac36c63c2ba69364 100644 (file)
 // #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>\r
+               /// ExecuteScalar is used to retrieve one object
+               /// from one result set \r
+               /// that has one row and one column.\r
+               /// It is lightweight compared to ExecuteReader.\r
+               /// </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);
index d83de93e0917570d1c7db6b53bef8dce7169119d..35832aad1eb96b1d41e453fef29f3bac8e590093 100644 (file)
@@ -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";
index 927243a832669acb100cda0d7cef828d2914c467..c47c7a91e3552ccff1c2b8203813e49599af3315 100644 (file)
@@ -19,34 +19,26 @@ using System.Data.SqlClient;
 namespace TestSystemDataSqlClient {\r
        class TestSqlDataReader {\r
 \r
-               static void Test() { \r
-                       SqlConnection con = null;\r
+               static void Test(SqlConnection con, string sql, \r
+                               CommandType cmdType, CommandBehavior behavior,\r
+                               string testDesc) \r
+               { \r
                        SqlCommand cmd = null;\r
                        SqlDataReader rdr = null;\r
                        \r
-                       String connectionString = null;\r
-                       String sql = null;\r
                        int c;\r
                        int results = 0;\r
 \r
-                       connectionString = 
-                               "host=localhost;" +
-                               "dbname=test;" +
-                               "user=postgres";
-                               \r
-                       sql =   "select * from pg_user;" + \r
-                               "select * from pg_tables;" + \r
-                               "select * from pg_database;";\r
-                                                       \r
-                       con = new SqlConnection(connectionString);\r
-                       con.Open();\r
-\r
-                       Console.WriteLine("sql: " +\r
-                               sql);\r
+                       Console.WriteLine("Test: " + testDesc);\r
+                       Console.WriteLine("[BEGIN SQL]");\r
+                       Console.WriteLine(sql);\r
+                       Console.WriteLine("[END SQL]");\r
 \r
                        cmd = new SqlCommand(sql, con);\r
+                       cmd.CommandType = cmdType;\r
+                                               \r
                        Console.WriteLine("ExecuteReader...");\r
-                       rdr = cmd.ExecuteReader();\r
+                       rdr = cmd.ExecuteReader(behavior);\r
 \r
                        do {\r
                                results++;\r
@@ -72,32 +64,71 @@ namespace TestSystemDataSqlClient {
                                int nRows = 0;\r
 \r
                                // Read and display the rows\r
-                               while(rdr.Read()) {\r
-                                       Console.WriteLine("   Row " + nRows + ": ");\r
+                       while(rdr.Read()) {\r
+                               Console.WriteLine("   Row " + nRows + ": ");\r
 \r
-                                       for(c = 0; c < rdr.FieldCount; c++) {\r
-                                               if(rdr.IsDBNull(c) == true)\r
-                                                       Console.WriteLine("      " + \r
-                                                               rdr.GetName(c) + " is DBNull");\r
-                                               else\r
-                                                       Console.WriteLine("      " + \r
-                                                               rdr.GetName(c) + ": " +\r
-                                                               rdr[c].ToString());\r
-                                       }\r
-                                       nRows++;\r
+                               for(c = 0; c < rdr.FieldCount; c++) {\r
+                                       if(rdr.IsDBNull(c) == true)\r
+                                               Console.WriteLine("      " + \r
+                                                       rdr.GetName(c) + " is DBNull");\r
+                                       else\r
+                                               Console.WriteLine("      " + \r
+                                                       rdr.GetName(c) + ": " +\r
+                                                       rdr[c].ToString());\r
                                }\r
+                               nRows++;\r
+                       }\r
                                Console.WriteLine("   Total Rows: " + \r
                                        nRows);\r
                        } while(rdr.NextResult());\r
                        Console.WriteLine("Total Result sets: " + results);\r
                        \r
                        rdr.Close();\r
-                       con.Close();\r
                }\r
 \r
                [STAThread]\r
                static void Main(string[] args) {\r
-                       Test();\r
+                       String connectionString = null;\r
+                       connectionString = 
+                               "host=localhost;" +
+                               "dbname=test;" +
+                               "user=postgres";
+                                               \r
+                       SqlConnection con;\r
+                       con = new SqlConnection(connectionString);\r
+                       con.Open();\r
+\r
+                       string sql;\r
+\r
+                       // Text - only has one query (single query behavior)\r
+                       sql = "select * from pg_tables";\r
+                       Test(con, sql, CommandType.Text, \r
+                               CommandBehavior.SingleResult, "Text1");\r
+\r
+                       // Text - only has one query (default behavior)\r
+                       sql = "select * from pg_tables";\r
+                       Test(con, sql, CommandType.Text, \r
+                               CommandBehavior.Default, "Text2");\r
+                       \r
+                       // Text - has three queries\r
+                       sql =\r
+                               "select * from pg_user;" + \r
+                               "select * from pg_tables;" + \r
+                               "select * from pg_database";\r
+                       Test(con, sql, CommandType.Text, \r
+                               CommandBehavior.Default, "Text3Queries");\r
+                       \r
+                       // Table Direct\r
+                       sql = "pg_tables";\r
+                       Test(con, sql, CommandType.TableDirect, \r
+                               CommandBehavior.Default, "TableDirect1");\r
+\r
+                       // Stored Procedure\r
+                       sql = "version";\r
+                       Test(con, sql, CommandType.StoredProcedure, \r
+                               CommandBehavior.Default, "SP1");\r
+                       \r
+                       con.Close();\r
                }\r
        }\r
 }\r