#region Fields
- string sql = "";
- int timeout = 30;
+ private string sql = "";
+ private int timeout = 30;
// default is 30 seconds
// for command execution
- SqlConnection conn = null;
- SqlTransaction trans = null;
- CommandType cmdType = CommandType.Text;
- bool designTime = false;
- SqlParameterCollection parmCollection = new
+ private SqlConnection conn = null;
+ private SqlTransaction trans = null;
+ private CommandType cmdType = CommandType.Text;
+ private bool designTime = false;
+ private SqlParameterCollection parmCollection = new
SqlParameterCollection();
+ // SqlDataReader state data for ExecuteReader()
+ private SqlDataReader dataReader = null;
+ private string[] queries;
+ private int currentQuery;
+ CommandBehavior cmdBehavior = CommandBehavior.Default;
+
#endregion // Fields
#region Constructors
}
[MonoTODO]
- public SqlDataReader ExecuteReader (CommandBehavior behavior) {
- // FIXME: currently only works for a
- // single result set
- // ExecuteReader can be used
- // for multiple result sets
- SqlDataReader dataReader = null;
-
- IntPtr pgResult; // PGresult
+ public SqlDataReader ExecuteReader (CommandBehavior behavior)
+ {
+ if(conn.State != ConnectionState.Open)
+ throw new InvalidOperationException(
+ "ConnectionState is not Open");
+
+ cmdBehavior = behavior;
+
+ queries = null;
+ currentQuery = -1;
+ dataReader = new SqlDataReader(this);
+
+ if((behavior & CommandBehavior.SingleResult) == CommandBehavior.SingleResult) {
+ queries = new String[1];
+ queries[0] = sql;
+ }
+ else {
+ queries = sql.Split(new Char[] {';'});
+ }
+
+ dataReader.NextResult();
+
+ return dataReader;
+ }
+
+ internal SqlResult NextResult()
+ {
+ SqlResult res = new SqlResult();
+ res.Connection = this.Connection;
+
+ currentQuery++;
+
+ if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
+ ExecuteQuery(queries[currentQuery], res);
+ res.ResultReturned = true;
+ }
+ else {
+ res.ResultReturned = false;
+ }
+
+ return res;
+ }
+
+ private void ExecuteQuery (string query, SqlResult res)
+ {
+ IntPtr pgResult;
+
ExecStatusType execStatus;
if(conn.State != ConnectionState.Open)
throw new InvalidOperationException(
- "ConnnectionState is not Open");
+ "ConnectionState is not Open");
// FIXME: PQexec blocks
// while PQsendQuery is non-blocking
// 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);
if(execStatus == ExecStatusType.PGRES_TUPLES_OK) {
- DataTable dt = null;
- int rows, cols;
- string[] types;
-
- // FIXME: maybe i should move the
- // BuildTableSchema code
- // to the SqlDataReader?
- dt = BuildTableSchema(pgResult,
- out rows, out cols, out types);
- dataReader = new SqlDataReader(this, dt, pgResult,
- rows, cols, types);
+ res.BuildTableSchema(pgResult);
}
else {
String errorMessage;
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
}
-
- return dataReader;
- }
-
- internal DataTable BuildTableSchema (IntPtr pgResult,
- out int nRows,
- out int nFields,
- out string[] types) {
-
- int nCol;
-
- DataTable dt = new DataTable();
-
- nRows = PostgresLibrary.
- PQntuples(pgResult);
-
- nFields = PostgresLibrary.
- PQnfields(pgResult);
-
- int oid;
- types = new string[nFields];
-
- for(nCol = 0; nCol < nFields; nCol++) {
-
- DbType dbType;
-
- // get column name
- String fieldName;
- fieldName = PostgresLibrary.
- PQfname(pgResult, nCol);
-
- // get PostgreSQL data type (OID)
- oid = PostgresLibrary.
- PQftype(pgResult, nCol);
- types[nCol] = PostgresHelper.
- OidToTypname (oid, conn.Types);
-
- int definedSize;
- // get defined size of column
- definedSize = PostgresLibrary.
- PQfsize(pgResult, nCol);
-
- // build the data column and add it the table
- DataColumn dc = new DataColumn(fieldName);
-
- dbType = PostgresHelper.
- TypnameToSqlDbType(types[nCol]);
- dc.DataType = PostgresHelper.
- DbTypeToSystemType(dbType);
- dc.MaxLength = definedSize;
- dc.SetTable(dt);
-
- dt.Columns.Add(dc);
- }
- return dt;
}
[MonoTODO]
#endregion // Properties
+ #region Inner Classes
+
+ #endregion // Inner Classes
+
#region Destructors
[MonoTODO]
#endregion //Destructors
}
+
+ // SqlResult is used for passing Result Set data
+ // from SqlCommand to SqlDataReader
+ internal class SqlResult {
+
+ private DataTable dataTableSchema; // only will contain the schema
+ private IntPtr pg_result; // native PostgreSQL PGresult
+ private int rowCount;
+ private int fieldCount;
+ private string[] pgtypes; // PostgreSQL types (typname)
+ private bool resultReturned = false;
+ private SqlConnection con;
+
+ internal SqlConnection Connection {
+ set {
+ con = value;
+ }
+ }
+
+ internal bool ResultReturned {
+ get {
+ return resultReturned;
+ }
+ set {
+ resultReturned = value;
+ }
+ }
+
+ internal DataTable Table {
+ get {
+ return dataTableSchema;
+ }
+ }
+
+ internal IntPtr PgResult {
+ get {
+ return pg_result;
+ }
+ }
+
+ internal int RowCount {
+ get {
+ return rowCount;
+ }
+ }
+
+ internal int FieldCount {
+ get {
+ return fieldCount;
+ }
+ }
+
+ internal string[] PgTypes {
+ get {
+ return pgtypes;
+ }
+ }
+
+ internal void BuildTableSchema (IntPtr pgResult) {
+ pg_result = pgResult;
+
+ int nCol;
+
+ dataTableSchema = new DataTable();
+
+ rowCount = PostgresLibrary.
+ PQntuples(pgResult);
+
+ fieldCount = PostgresLibrary.
+ PQnfields(pgResult);
+
+ int oid;
+ pgtypes = new string[fieldCount];
+
+ for(nCol = 0; nCol < fieldCount; nCol++) {
+
+ DbType dbType;
+
+ // get column name
+ String fieldName;
+ fieldName = PostgresLibrary.
+ PQfname(pgResult, nCol);
+
+ // get PostgreSQL data type (OID)
+ oid = PostgresLibrary.
+ PQftype(pgResult, nCol);
+ pgtypes[nCol] = PostgresHelper.
+ OidToTypname (oid, con.Types);
+
+ int definedSize;
+ // get defined size of column
+ definedSize = PostgresLibrary.
+ PQfsize(pgResult, nCol);
+
+ // build the data column and add it the table
+ DataColumn dc = new DataColumn(fieldName);
+
+ dbType = PostgresHelper.
+ TypnameToSqlDbType(pgtypes[nCol]);
+ dc.DataType = PostgresHelper.
+ DbTypeToSystemType(dbType);
+ dc.MaxLength = definedSize;
+ dc.SetTable(dataTableSchema);
+
+ dataTableSchema.Columns.Add(dc);
+ }
+ }
+ }
}
//public sealed class SqlConnection : Component, IDbConnection,
// ICloneable
- public sealed class SqlConnection : IDbConnection {
+ public sealed class SqlConnection : IDbConnection, IDisposable
+ {
// FIXME: Need to implement class Component, \r
// and interfaces: ICloneable and IDisposable
[MonoTODO]
public void Open () {
- OpenDataSource ();
- }
-
- #endregion // Public Methods
-
- #region Protected Methods
-
- // FIXME: protected override void Dispose overrides Component
- // however, including Component causes other problems
- /*
- [MonoTODO]
- protected override void Dispose (bool disposing)
- {
- throw new NotImplementedException ();
- }
- */
-
- #endregion
-
- #region Private Methods
-
- private void OpenDataSource () {
if(dbname.Equals(""))
throw new InvalidOperationException(
"dbname missing");
}
}
+ #endregion // Public Methods
+
+ #region Protected Methods
+
+ // FIXME: protected override void Dispose overrides Component
+ // however, including Component causes other problems
+ /*
+ [MonoTODO]
+ protected override void Dispose (bool disposing)
+ {
+ throw new NotImplementedException ();
+ }
+ */
+
+ #endregion
+
+ #region Private Methods
+
private void SetupConnection() {
conState = ConnectionState.Open;
// FIXME: just a quick hack
conState = ConnectionState.Closed;
PostgresLibrary.PQfinish (pgConn);
+ pgConn = IntPtr.Zero;
}
private void SetConnectionString (string connectionString) {
#region Fields
private SqlCommand cmd;
- private DataTable table;
+ private DataTable table = null;
// columns in a row
private object[] fields; // data value in a .NET type
#region Constructors
- internal SqlDataReader (SqlCommand sqlCmd,
- DataTable dataTableSchema, IntPtr pg_result,
- int rowCount, int fieldCount, string[] pgtypes) {
+ internal SqlDataReader (SqlCommand sqlCmd) {
cmd = sqlCmd;
- table = dataTableSchema;
- pgResult = pg_result;
- rows = rowCount;
- cols = fieldCount;
- types = pgtypes;
open = true;
}
[MonoTODO]
public bool NextResult() {
- throw new NotImplementedException ();
+ SqlResult res;
+ currentRow = -1;
+
+ res = cmd.NextResult();
+
+ if(res.ResultReturned == true) {
+ table = res.Table;
+ pgResult = res.PgResult;
+ rows = res.RowCount;
+ cols = res.FieldCount;
+ types = res.PgTypes;
+ }
+
+ return res.ResultReturned;
}
[MonoTODO]
public bool Read() {
+
string dataValue;
int c = 0;
- //Console.WriteLine("if current row: " + currentRow + " rows: " + rows);
if(currentRow < rows - 1) {
- //Console.WriteLine("currentRow++: ");
currentRow++;
-
- //Console.WriteLine("re-init row --- cols: " + cols);
-
+
// re-init row
fields = new object[cols];
//dbTypes = new DbType[cols];
// FIXME: need to handle a NULL for each type
// maybe setting obj to System.DBNull.Value ?
-//
-// if(value == null) {
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("column is NULL");
-//#endif // DEBUG_PostgresLibrary
-// return null;
-// }
-// else if(value.Equals("")) {
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("column has a NULL");
-//#endif // DEBUG_PostgresLibrary
-//
-// return null;
-// }
-//
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("ConvertDbTypeToSystem typ: " +
-// typ + " value: " + value);
-//#endif // DEBUG_PostgresLibrary
-//
+
+ if(value == null) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is null");
+ return null;
+ }
+ else if(value.Equals("")) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is string empty");
+ return null;
+ }
+
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value: " + value);
// Date, Time, and DateTime
// are parsed based on ISO format
#region Fields
- string sql = "";
- int timeout = 30;
+ private string sql = "";
+ private int timeout = 30;
// default is 30 seconds
// for command execution
- SqlConnection conn = null;
- SqlTransaction trans = null;
- CommandType cmdType = CommandType.Text;
- bool designTime = false;
- SqlParameterCollection parmCollection = new
+ private SqlConnection conn = null;
+ private SqlTransaction trans = null;
+ private CommandType cmdType = CommandType.Text;
+ private bool designTime = false;
+ private SqlParameterCollection parmCollection = new
SqlParameterCollection();
+ // SqlDataReader state data for ExecuteReader()
+ private SqlDataReader dataReader = null;
+ private string[] queries;
+ private int currentQuery;
+ CommandBehavior cmdBehavior = CommandBehavior.Default;
+
#endregion // Fields
#region Constructors
}
[MonoTODO]
- public SqlDataReader ExecuteReader (CommandBehavior behavior) {
- // FIXME: currently only works for a
- // single result set
- // ExecuteReader can be used
- // for multiple result sets
- SqlDataReader dataReader = null;
-
- IntPtr pgResult; // PGresult
+ public SqlDataReader ExecuteReader (CommandBehavior behavior)
+ {
+ if(conn.State != ConnectionState.Open)
+ throw new InvalidOperationException(
+ "ConnectionState is not Open");
+
+ cmdBehavior = behavior;
+
+ queries = null;
+ currentQuery = -1;
+ dataReader = new SqlDataReader(this);
+
+ if((behavior & CommandBehavior.SingleResult) == CommandBehavior.SingleResult) {
+ queries = new String[1];
+ queries[0] = sql;
+ }
+ else {
+ queries = sql.Split(new Char[] {';'});
+ }
+
+ dataReader.NextResult();
+
+ return dataReader;
+ }
+
+ internal SqlResult NextResult()
+ {
+ SqlResult res = new SqlResult();
+ res.Connection = this.Connection;
+
+ currentQuery++;
+
+ if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
+ ExecuteQuery(queries[currentQuery], res);
+ res.ResultReturned = true;
+ }
+ else {
+ res.ResultReturned = false;
+ }
+
+ return res;
+ }
+
+ private void ExecuteQuery (string query, SqlResult res)
+ {
+ IntPtr pgResult;
+
ExecStatusType execStatus;
if(conn.State != ConnectionState.Open)
throw new InvalidOperationException(
- "ConnnectionState is not Open");
+ "ConnectionState is not Open");
// FIXME: PQexec blocks
// while PQsendQuery is non-blocking
// 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);
if(execStatus == ExecStatusType.PGRES_TUPLES_OK) {
- DataTable dt = null;
- int rows, cols;
- string[] types;
-
- // FIXME: maybe i should move the
- // BuildTableSchema code
- // to the SqlDataReader?
- dt = BuildTableSchema(pgResult,
- out rows, out cols, out types);
- dataReader = new SqlDataReader(this, dt, pgResult,
- rows, cols, types);
+ res.BuildTableSchema(pgResult);
}
else {
String errorMessage;
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
}
-
- return dataReader;
- }
-
- internal DataTable BuildTableSchema (IntPtr pgResult,
- out int nRows,
- out int nFields,
- out string[] types) {
-
- int nCol;
-
- DataTable dt = new DataTable();
-
- nRows = PostgresLibrary.
- PQntuples(pgResult);
-
- nFields = PostgresLibrary.
- PQnfields(pgResult);
-
- int oid;
- types = new string[nFields];
-
- for(nCol = 0; nCol < nFields; nCol++) {
-
- DbType dbType;
-
- // get column name
- String fieldName;
- fieldName = PostgresLibrary.
- PQfname(pgResult, nCol);
-
- // get PostgreSQL data type (OID)
- oid = PostgresLibrary.
- PQftype(pgResult, nCol);
- types[nCol] = PostgresHelper.
- OidToTypname (oid, conn.Types);
-
- int definedSize;
- // get defined size of column
- definedSize = PostgresLibrary.
- PQfsize(pgResult, nCol);
-
- // build the data column and add it the table
- DataColumn dc = new DataColumn(fieldName);
-
- dbType = PostgresHelper.
- TypnameToSqlDbType(types[nCol]);
- dc.DataType = PostgresHelper.
- DbTypeToSystemType(dbType);
- dc.MaxLength = definedSize;
- dc.SetTable(dt);
-
- dt.Columns.Add(dc);
- }
- return dt;
}
[MonoTODO]
#endregion // Properties
+ #region Inner Classes
+
+ #endregion // Inner Classes
+
#region Destructors
[MonoTODO]
#endregion //Destructors
}
+
+ // SqlResult is used for passing Result Set data
+ // from SqlCommand to SqlDataReader
+ internal class SqlResult {
+
+ private DataTable dataTableSchema; // only will contain the schema
+ private IntPtr pg_result; // native PostgreSQL PGresult
+ private int rowCount;
+ private int fieldCount;
+ private string[] pgtypes; // PostgreSQL types (typname)
+ private bool resultReturned = false;
+ private SqlConnection con;
+
+ internal SqlConnection Connection {
+ set {
+ con = value;
+ }
+ }
+
+ internal bool ResultReturned {
+ get {
+ return resultReturned;
+ }
+ set {
+ resultReturned = value;
+ }
+ }
+
+ internal DataTable Table {
+ get {
+ return dataTableSchema;
+ }
+ }
+
+ internal IntPtr PgResult {
+ get {
+ return pg_result;
+ }
+ }
+
+ internal int RowCount {
+ get {
+ return rowCount;
+ }
+ }
+
+ internal int FieldCount {
+ get {
+ return fieldCount;
+ }
+ }
+
+ internal string[] PgTypes {
+ get {
+ return pgtypes;
+ }
+ }
+
+ internal void BuildTableSchema (IntPtr pgResult) {
+ pg_result = pgResult;
+
+ int nCol;
+
+ dataTableSchema = new DataTable();
+
+ rowCount = PostgresLibrary.
+ PQntuples(pgResult);
+
+ fieldCount = PostgresLibrary.
+ PQnfields(pgResult);
+
+ int oid;
+ pgtypes = new string[fieldCount];
+
+ for(nCol = 0; nCol < fieldCount; nCol++) {
+
+ DbType dbType;
+
+ // get column name
+ String fieldName;
+ fieldName = PostgresLibrary.
+ PQfname(pgResult, nCol);
+
+ // get PostgreSQL data type (OID)
+ oid = PostgresLibrary.
+ PQftype(pgResult, nCol);
+ pgtypes[nCol] = PostgresHelper.
+ OidToTypname (oid, con.Types);
+
+ int definedSize;
+ // get defined size of column
+ definedSize = PostgresLibrary.
+ PQfsize(pgResult, nCol);
+
+ // build the data column and add it the table
+ DataColumn dc = new DataColumn(fieldName);
+
+ dbType = PostgresHelper.
+ TypnameToSqlDbType(pgtypes[nCol]);
+ dc.DataType = PostgresHelper.
+ DbTypeToSystemType(dbType);
+ dc.MaxLength = definedSize;
+ dc.SetTable(dataTableSchema);
+
+ dataTableSchema.Columns.Add(dc);
+ }
+ }
+ }
}
//public sealed class SqlConnection : Component, IDbConnection,
// ICloneable
- public sealed class SqlConnection : IDbConnection {
+ public sealed class SqlConnection : IDbConnection, IDisposable
+ {
// FIXME: Need to implement class Component, \r
// and interfaces: ICloneable and IDisposable
[MonoTODO]
public void Open () {
- OpenDataSource ();
- }
-
- #endregion // Public Methods
-
- #region Protected Methods
-
- // FIXME: protected override void Dispose overrides Component
- // however, including Component causes other problems
- /*
- [MonoTODO]
- protected override void Dispose (bool disposing)
- {
- throw new NotImplementedException ();
- }
- */
-
- #endregion
-
- #region Private Methods
-
- private void OpenDataSource () {
if(dbname.Equals(""))
throw new InvalidOperationException(
"dbname missing");
}
}
+ #endregion // Public Methods
+
+ #region Protected Methods
+
+ // FIXME: protected override void Dispose overrides Component
+ // however, including Component causes other problems
+ /*
+ [MonoTODO]
+ protected override void Dispose (bool disposing)
+ {
+ throw new NotImplementedException ();
+ }
+ */
+
+ #endregion
+
+ #region Private Methods
+
private void SetupConnection() {
conState = ConnectionState.Open;
// FIXME: just a quick hack
conState = ConnectionState.Closed;
PostgresLibrary.PQfinish (pgConn);
+ pgConn = IntPtr.Zero;
}
private void SetConnectionString (string connectionString) {
#region Fields
private SqlCommand cmd;
- private DataTable table;
+ private DataTable table = null;
// columns in a row
private object[] fields; // data value in a .NET type
#region Constructors
- internal SqlDataReader (SqlCommand sqlCmd,
- DataTable dataTableSchema, IntPtr pg_result,
- int rowCount, int fieldCount, string[] pgtypes) {
+ internal SqlDataReader (SqlCommand sqlCmd) {
cmd = sqlCmd;
- table = dataTableSchema;
- pgResult = pg_result;
- rows = rowCount;
- cols = fieldCount;
- types = pgtypes;
open = true;
}
[MonoTODO]
public bool NextResult() {
- throw new NotImplementedException ();
+ SqlResult res;
+ currentRow = -1;
+
+ res = cmd.NextResult();
+
+ if(res.ResultReturned == true) {
+ table = res.Table;
+ pgResult = res.PgResult;
+ rows = res.RowCount;
+ cols = res.FieldCount;
+ types = res.PgTypes;
+ }
+
+ return res.ResultReturned;
}
[MonoTODO]
public bool Read() {
+
string dataValue;
int c = 0;
- //Console.WriteLine("if current row: " + currentRow + " rows: " + rows);
if(currentRow < rows - 1) {
- //Console.WriteLine("currentRow++: ");
currentRow++;
-
- //Console.WriteLine("re-init row --- cols: " + cols);
-
+
// re-init row
fields = new object[cols];
//dbTypes = new DbType[cols];
// FIXME: need to handle a NULL for each type
// maybe setting obj to System.DBNull.Value ?
-//
-// if(value == null) {
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("column is NULL");
-//#endif // DEBUG_PostgresLibrary
-// return null;
-// }
-// else if(value.Equals("")) {
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("column has a NULL");
-//#endif // DEBUG_PostgresLibrary
-//
-// return null;
-// }
-//
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("ConvertDbTypeToSystem typ: " +
-// typ + " value: " + value);
-//#endif // DEBUG_PostgresLibrary
-//
+
+ if(value == null) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is null");
+ return null;
+ }
+ else if(value.Equals("")) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is string empty");
+ return null;
+ }
+
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value: " + value);
// Date, Time, and DateTime
// are parsed based on ISO format
+2002-05-17 Daniel Morgan <danmorg@sc.rr.com>
+
+ * System.Data.SqlClient/PostgresLibrary.cs: handle
+ data value from database being NULL
+
+ * System.Data.SqlClient/SqlCommand.cs: for ExecuteReader,
+ allow multiple result sets. Added new internal class
+ SqlResult to pass result set data from SqlCommand
+ to SqlDataReader.
+
+ * System.Data.SqlClient/SqlDataReader.cs: allow
+ multiple result sets.
+
+ * System.Data.SqlClient/SqlConnection.cs: moved
+ things around. Implement IDisposable.
+
+ * Test/TestSqlDataReader.cs: test for execution
+ of multiple result sets and display the results
+ of these multiple results sets
+
+ * Test/TestSqlDataAdapter.cs: tweaks
+
2002-05-17 Tim Coleman <tim@timcoleman.com>
* System.Data.Common/DbDataAdapter.cs:
- More implementation of Fill methods
// FIXME: need to handle a NULL for each type
// maybe setting obj to System.DBNull.Value ?
-//
-// if(value == null) {
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("column is NULL");
-//#endif // DEBUG_PostgresLibrary
-// return null;
-// }
-// else if(value.Equals("")) {
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("column has a NULL");
-//#endif // DEBUG_PostgresLibrary
-//
-// return null;
-// }
-//
-//#if DEBUG_PostgresLibrary
-// Console.WriteLine("ConvertDbTypeToSystem typ: " +
-// typ + " value: " + value);
-//#endif // DEBUG_PostgresLibrary
-//
+
+ if(value == null) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is null");
+ return null;
+ }
+ else if(value.Equals("")) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is string empty");
+ return null;
+ }
+
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value: " + value);
// Date, Time, and DateTime
// are parsed based on ISO format
#region Fields
- string sql = "";
- int timeout = 30;
+ private string sql = "";
+ private int timeout = 30;
// default is 30 seconds
// for command execution
- SqlConnection conn = null;
- SqlTransaction trans = null;
- CommandType cmdType = CommandType.Text;
- bool designTime = false;
- SqlParameterCollection parmCollection = new
+ private SqlConnection conn = null;
+ private SqlTransaction trans = null;
+ private CommandType cmdType = CommandType.Text;
+ private bool designTime = false;
+ private SqlParameterCollection parmCollection = new
SqlParameterCollection();
+ // SqlDataReader state data for ExecuteReader()
+ private SqlDataReader dataReader = null;
+ private string[] queries;
+ private int currentQuery;
+ CommandBehavior cmdBehavior = CommandBehavior.Default;
+
#endregion // Fields
#region Constructors
}
[MonoTODO]
- public SqlDataReader ExecuteReader (CommandBehavior behavior) {
- // FIXME: currently only works for a
- // single result set
- // ExecuteReader can be used
- // for multiple result sets
- SqlDataReader dataReader = null;
-
- IntPtr pgResult; // PGresult
+ public SqlDataReader ExecuteReader (CommandBehavior behavior)
+ {
+ if(conn.State != ConnectionState.Open)
+ throw new InvalidOperationException(
+ "ConnectionState is not Open");
+
+ cmdBehavior = behavior;
+
+ queries = null;
+ currentQuery = -1;
+ dataReader = new SqlDataReader(this);
+
+ if((behavior & CommandBehavior.SingleResult) == CommandBehavior.SingleResult) {
+ queries = new String[1];
+ queries[0] = sql;
+ }
+ else {
+ queries = sql.Split(new Char[] {';'});
+ }
+
+ dataReader.NextResult();
+
+ return dataReader;
+ }
+
+ internal SqlResult NextResult()
+ {
+ SqlResult res = new SqlResult();
+ res.Connection = this.Connection;
+
+ currentQuery++;
+
+ if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
+ ExecuteQuery(queries[currentQuery], res);
+ res.ResultReturned = true;
+ }
+ else {
+ res.ResultReturned = false;
+ }
+
+ return res;
+ }
+
+ private void ExecuteQuery (string query, SqlResult res)
+ {
+ IntPtr pgResult;
+
ExecStatusType execStatus;
if(conn.State != ConnectionState.Open)
throw new InvalidOperationException(
- "ConnnectionState is not Open");
+ "ConnectionState is not Open");
// FIXME: PQexec blocks
// while PQsendQuery is non-blocking
// 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);
if(execStatus == ExecStatusType.PGRES_TUPLES_OK) {
- DataTable dt = null;
- int rows, cols;
- string[] types;
-
- // FIXME: maybe i should move the
- // BuildTableSchema code
- // to the SqlDataReader?
- dt = BuildTableSchema(pgResult,
- out rows, out cols, out types);
- dataReader = new SqlDataReader(this, dt, pgResult,
- rows, cols, types);
+ res.BuildTableSchema(pgResult);
}
else {
String errorMessage;
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
}
-
- return dataReader;
- }
-
- internal DataTable BuildTableSchema (IntPtr pgResult,
- out int nRows,
- out int nFields,
- out string[] types) {
-
- int nCol;
-
- DataTable dt = new DataTable();
-
- nRows = PostgresLibrary.
- PQntuples(pgResult);
-
- nFields = PostgresLibrary.
- PQnfields(pgResult);
-
- int oid;
- types = new string[nFields];
-
- for(nCol = 0; nCol < nFields; nCol++) {
-
- DbType dbType;
-
- // get column name
- String fieldName;
- fieldName = PostgresLibrary.
- PQfname(pgResult, nCol);
-
- // get PostgreSQL data type (OID)
- oid = PostgresLibrary.
- PQftype(pgResult, nCol);
- types[nCol] = PostgresHelper.
- OidToTypname (oid, conn.Types);
-
- int definedSize;
- // get defined size of column
- definedSize = PostgresLibrary.
- PQfsize(pgResult, nCol);
-
- // build the data column and add it the table
- DataColumn dc = new DataColumn(fieldName);
-
- dbType = PostgresHelper.
- TypnameToSqlDbType(types[nCol]);
- dc.DataType = PostgresHelper.
- DbTypeToSystemType(dbType);
- dc.MaxLength = definedSize;
- dc.SetTable(dt);
-
- dt.Columns.Add(dc);
- }
- return dt;
}
[MonoTODO]
#endregion // Properties
+ #region Inner Classes
+
+ #endregion // Inner Classes
+
#region Destructors
[MonoTODO]
#endregion //Destructors
}
+
+ // SqlResult is used for passing Result Set data
+ // from SqlCommand to SqlDataReader
+ internal class SqlResult {
+
+ private DataTable dataTableSchema; // only will contain the schema
+ private IntPtr pg_result; // native PostgreSQL PGresult
+ private int rowCount;
+ private int fieldCount;
+ private string[] pgtypes; // PostgreSQL types (typname)
+ private bool resultReturned = false;
+ private SqlConnection con;
+
+ internal SqlConnection Connection {
+ set {
+ con = value;
+ }
+ }
+
+ internal bool ResultReturned {
+ get {
+ return resultReturned;
+ }
+ set {
+ resultReturned = value;
+ }
+ }
+
+ internal DataTable Table {
+ get {
+ return dataTableSchema;
+ }
+ }
+
+ internal IntPtr PgResult {
+ get {
+ return pg_result;
+ }
+ }
+
+ internal int RowCount {
+ get {
+ return rowCount;
+ }
+ }
+
+ internal int FieldCount {
+ get {
+ return fieldCount;
+ }
+ }
+
+ internal string[] PgTypes {
+ get {
+ return pgtypes;
+ }
+ }
+
+ internal void BuildTableSchema (IntPtr pgResult) {
+ pg_result = pgResult;
+
+ int nCol;
+
+ dataTableSchema = new DataTable();
+
+ rowCount = PostgresLibrary.
+ PQntuples(pgResult);
+
+ fieldCount = PostgresLibrary.
+ PQnfields(pgResult);
+
+ int oid;
+ pgtypes = new string[fieldCount];
+
+ for(nCol = 0; nCol < fieldCount; nCol++) {
+
+ DbType dbType;
+
+ // get column name
+ String fieldName;
+ fieldName = PostgresLibrary.
+ PQfname(pgResult, nCol);
+
+ // get PostgreSQL data type (OID)
+ oid = PostgresLibrary.
+ PQftype(pgResult, nCol);
+ pgtypes[nCol] = PostgresHelper.
+ OidToTypname (oid, con.Types);
+
+ int definedSize;
+ // get defined size of column
+ definedSize = PostgresLibrary.
+ PQfsize(pgResult, nCol);
+
+ // build the data column and add it the table
+ DataColumn dc = new DataColumn(fieldName);
+
+ dbType = PostgresHelper.
+ TypnameToSqlDbType(pgtypes[nCol]);
+ dc.DataType = PostgresHelper.
+ DbTypeToSystemType(dbType);
+ dc.MaxLength = definedSize;
+ dc.SetTable(dataTableSchema);
+
+ dataTableSchema.Columns.Add(dc);
+ }
+ }
+ }
}
//public sealed class SqlConnection : Component, IDbConnection,
// ICloneable
- public sealed class SqlConnection : IDbConnection {
+ public sealed class SqlConnection : IDbConnection, IDisposable
+ {
// FIXME: Need to implement class Component, \r
// and interfaces: ICloneable and IDisposable
[MonoTODO]
public void Open () {
- OpenDataSource ();
- }
-
- #endregion // Public Methods
-
- #region Protected Methods
-
- // FIXME: protected override void Dispose overrides Component
- // however, including Component causes other problems
- /*
- [MonoTODO]
- protected override void Dispose (bool disposing)
- {
- throw new NotImplementedException ();
- }
- */
-
- #endregion
-
- #region Private Methods
-
- private void OpenDataSource () {
if(dbname.Equals(""))
throw new InvalidOperationException(
"dbname missing");
}
}
+ #endregion // Public Methods
+
+ #region Protected Methods
+
+ // FIXME: protected override void Dispose overrides Component
+ // however, including Component causes other problems
+ /*
+ [MonoTODO]
+ protected override void Dispose (bool disposing)
+ {
+ throw new NotImplementedException ();
+ }
+ */
+
+ #endregion
+
+ #region Private Methods
+
private void SetupConnection() {
conState = ConnectionState.Open;
// FIXME: just a quick hack
conState = ConnectionState.Closed;
PostgresLibrary.PQfinish (pgConn);
+ pgConn = IntPtr.Zero;
}
private void SetConnectionString (string connectionString) {
#region Fields
private SqlCommand cmd;
- private DataTable table;
+ private DataTable table = null;
// columns in a row
private object[] fields; // data value in a .NET type
#region Constructors
- internal SqlDataReader (SqlCommand sqlCmd,
- DataTable dataTableSchema, IntPtr pg_result,
- int rowCount, int fieldCount, string[] pgtypes) {
+ internal SqlDataReader (SqlCommand sqlCmd) {
cmd = sqlCmd;
- table = dataTableSchema;
- pgResult = pg_result;
- rows = rowCount;
- cols = fieldCount;
- types = pgtypes;
open = true;
}
[MonoTODO]
public bool NextResult() {
- throw new NotImplementedException ();
+ SqlResult res;
+ currentRow = -1;
+
+ res = cmd.NextResult();
+
+ if(res.ResultReturned == true) {
+ table = res.Table;
+ pgResult = res.PgResult;
+ rows = res.RowCount;
+ cols = res.FieldCount;
+ types = res.PgTypes;
+ }
+
+ return res.ResultReturned;
}
[MonoTODO]
public bool Read() {
+
string dataValue;
int c = 0;
- //Console.WriteLine("if current row: " + currentRow + " rows: " + rows);
if(currentRow < rows - 1) {
- //Console.WriteLine("currentRow++: ");
currentRow++;
-
- //Console.WriteLine("re-init row --- cols: " + cols);
-
+
// re-init row
fields = new object[cols];
//dbTypes = new DbType[cols];
private bool caseSensitive;
private bool enforceConstraints;
private DataTableCollection tableCollection;
+ // private DataTableRelationCollection relationCollection;
+ private PropertyCollection properties;
#region Constructors
public PropertyCollection ExtendedProperties {
[MonoTODO]
get {
- throw new NotImplementedException ();
+ return properties;
}
}
public DataRelationCollection Relations {
[MonoTODO]
get{
- throw new NotImplementedException ();
+ //return relationCollection;
+ throw new NotImplementedException();
}
}
sqlQuery = "select * from pg_tables";
- try {
- System.Console.WriteLine ("new SqlDataAdapter...");
- adapter = new SqlDataAdapter (sqlQuery,
- connectionString);
+ System.Console.WriteLine ("new SqlDataAdapter...");
+ adapter = new SqlDataAdapter (sqlQuery,
+ connectionString);
- System.Console.WriteLine ("open connection...");
- adapter.SelectCommand.Connection.Open ();
+ System.Console.WriteLine ("open connection...");
+ adapter.SelectCommand.Connection.Open ();
- System.Console.WriteLine ("new DataSet...");
- dataSet = new DataSet ();
+ System.Console.WriteLine ("new DataSet...");
+ dataSet = new DataSet ();
+ try {
System.Console.WriteLine("Fill...");
adapter.Fill (dataSet);
}
System.Console.WriteLine ("get row...");
- if (null != dataSet) {
+ if (dataSet != null) {
foreach (DataRow row in dataSet.Tables["Table"].Rows)
Console.WriteLine("tablename: " + row["tablename"]);
System.Console.WriteLine("Done.");
using System.Data;\r
using System.Data.SqlClient;\r
\r
-namespace TestSystemDataSqlClient\r
-{\r
- class TestSqlDataReader\r
- {\r
+namespace TestSystemDataSqlClient {\r
+ class TestSqlDataReader {\r
\r
static void Test() { \r
SqlConnection con = 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 tid, tdesc, aint4, abpchar " + \r
- "from sometable";\r
- \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
+ sql);\r
\r
cmd = new SqlCommand(sql, con);\r
+ Console.WriteLine("ExecuteReader...");\r
rdr = cmd.ExecuteReader();\r
\r
- // get the DataTable that holds\r
- // the schema\r
- DataTable dt = rdr.GetSchemaTable();\r
- \r
- // number of columns in the table\r
- Console.WriteLine("dt.Columns.Count: " +\r
- dt.Columns.Count);\r
+ do {\r
+ results++;\r
+ Console.WriteLine("Result Set " + results + "...");\r
+\r
+ // get the DataTable that holds\r
+ // the schema\r
+ DataTable dt = rdr.GetSchemaTable();\r
+ \r
+ // number of columns in the table\r
+ Console.WriteLine(" Total Columns: " +\r
+ dt.Columns.Count);\r
\r
- // display the schema\r
- for(int c = 0; c < dt.Columns.Count; c++) {\r
- Console.WriteLine("* Column Name: " + \r
- dt.Columns[c].ColumnName);\r
- Console.WriteLine(" MaxLength: " +\r
- dt.Columns[c].MaxLength);\r
- Console.WriteLine(" Type: " +\r
- dt.Columns[c].DataType);\r
- }\r
- int nRows = 0;\r
- // Read and display the rows\r
- while(rdr.Read()) {\r
- Console.WriteLine("Row: " +\r
- rdr["tid"].ToString() + ", " + \r
- rdr["tdesc"].ToString() + ", " + \r
- rdr["aint4"].ToString() + ", " + \r
- rdr["abpchar"].ToString()\r
- );\r
+ // display the schema\r
+ for(c = 0; c < dt.Columns.Count; c++) {\r
+ Console.WriteLine(" Column Name: " + \r
+ dt.Columns[c].ColumnName);\r
+ Console.WriteLine(" MaxLength: " +\r
+ dt.Columns[c].MaxLength);\r
+ Console.WriteLine(" Type: " +\r
+ dt.Columns[c].DataType);\r
+ }\r
+ int nRows = 0;\r
\r
- Console.WriteLine("1: " + rdr.GetString(0));\r
- Console.WriteLine("2: " + rdr.GetString(1));\r
- Console.WriteLine("3: " + rdr.GetInt32(2));\r
- Console.WriteLine("4: " + rdr.GetString(3));\r
- nRows++;\r
- }\r
- Console.WriteLine("Rows: " + \r
- nRows);\r
+ // Read and display the rows\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
+ }\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
- {\r
+ static void Main(string[] args) {\r
Test();\r
}\r
-\r
}\r
}\r