| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928 |
- //
- // System.Data.SqlClient.SqlCommand.cs
- //
- // Author:
- // Rodrigo Moya ([email protected])
- // Daniel Morgan ([email protected])
- // Tim Coleman ([email protected])
- //
- // (C) Ximian, Inc 2002 http://www.ximian.com/
- // (C) Daniel Morgan, 2002
- // (C) Copyright 2002 Tim Coleman
- //
- // Credits:
- // SQL and concepts were used from libgda 0.8.190 (GNOME Data Access)
- // http://www.gnome-db.org/
- // with permission from the authors of the
- // PostgreSQL provider in libgda:
- // Michael Lausch <[email protected]>
- // Rodrigo Moya <[email protected]>
- // Vivien Malerba <[email protected]>
- // Gonzalo Paniagua Javier <[email protected]>
- //
- // use #define DEBUG_SqlCommand if you want to spew debug messages
- // #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 {
- /// <summary>
- /// Represents a SQL statement that is executed
- /// while connected to a SQL database.
- /// </summary>
- // public sealed class SqlCommand : Component, IDbCommand, ICloneable
- public sealed class SqlCommand : IDbCommand {
- #region Fields
- private string sql = "";
- private int timeout = 30;
- // default is 30 seconds
- // for command execution
- 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 = null;
- private int currentQuery = -1;
- private CommandBehavior cmdBehavior = CommandBehavior.Default;
- private ParmUtil parmUtil = null;
-
- #endregion // Fields
- #region Constructors
- public SqlCommand() {
- sql = "";
- }
- public SqlCommand (string cmdText) {
- sql = cmdText;
- }
- public SqlCommand (string cmdText, SqlConnection connection) {
- sql = cmdText;
- conn = connection;
- }
- public SqlCommand (string cmdText, SqlConnection connection,
- SqlTransaction transaction) {
- sql = cmdText;
- conn = connection;
- trans = transaction;
- }
- #endregion // Constructors
- #region Methods
- [MonoTODO]
- public void Cancel () {
- // FIXME: use non-blocking Exec for this
- throw new NotImplementedException ();
- }
- // FIXME: is this the correct way to return a stronger type?
- [MonoTODO]
- IDbDataParameter IDbCommand.CreateParameter () {
- return CreateParameter ();
- }
- [MonoTODO]
- public SqlParameter CreateParameter () {
- return new SqlParameter ();
- }
- public int ExecuteNonQuery () {
- IntPtr pgResult; // PGresult
- 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?
- // int PQsendQuery(PGconn *conn,
- // const char *query);
- // execute SQL command
- // uses internal property to get the PGConn IntPtr
- pgResult = PostgresLibrary.
- PQexec (conn.PostgresConnection, query);
- execStatus = PostgresLibrary.
- PQresultStatus (pgResult);
-
- if(execStatus == ExecStatusType.PGRES_COMMAND_OK ||
- execStatus == ExecStatusType.PGRES_TUPLES_OK ) {
- rowsAffectedString = PostgresLibrary.
- PQcmdTuples (pgResult);
- if(rowsAffectedString != null)
- if(rowsAffectedString.Equals("") == false)
- rowsAffected = int.Parse(rowsAffectedString);
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
- }
- else {
- String errorMessage;
-
- errorMessage = PostgresLibrary.
- PQresStatus(execStatus);
- errorMessage += " " + PostgresLibrary.
- PQresultErrorMessage(pgResult);
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
- throw new SqlException(0, 0,
- errorMessage, 0, "",
- conn.DataSource, "SqlCommand", 0);
- }
-
- return rowsAffected;
- }
-
- [MonoTODO]
- IDataReader IDbCommand.ExecuteReader () {
- return ExecuteReader ();
- }
- [MonoTODO]
- public SqlDataReader ExecuteReader () {
- return ExecuteReader(CommandBehavior.Default);
- }
- [MonoTODO]
- IDataReader IDbCommand.ExecuteReader (
- CommandBehavior behavior) {
- return ExecuteReader (behavior);
- }
- [MonoTODO]
- 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);
- queries = sql.Split(new Char[] {';'});
- dataReader.NextResult();
-
- return dataReader;
- }
- internal SqlResult NextResult()
- {
- SqlResult res = new SqlResult();
- res.Connection = this.Connection;
- res.Behavior = cmdBehavior;
- string statement;
-
- currentQuery++;
- res.CurrentQuery = currentQuery;
- if(currentQuery < queries.Length && queries[currentQuery].Equals("") == false) {
- res.SQL = queries[currentQuery];
- statement = TweakQuery(queries[currentQuery], cmdType);
- ExecuteQuery(statement, res);
- res.ResultReturned = true;
- }
- else {
- res.ResultReturned = false;
- }
- return res;
- }
- private string TweakQuery(string query, CommandType commandType) {
- string statement = "";
- StringBuilder td;
- #if DEBUG_SqlCommand
- Console.WriteLine("---------[][] TweakQuery() [][]--------");
- Console.WriteLine("CommandType: " + commandType + " CommandBehavior: " + cmdBehavior);
- Console.WriteLine("SQL before command type: " + query);
- #endif
- // finish building SQL based on CommandType
- switch(commandType) {
- case CommandType.Text:
- statement = query;
- break;
- case CommandType.StoredProcedure:
- statement =
- "SELECT " + query + "()";
- break;
- case CommandType.TableDirect:
- // NOTE: this is for the PostgreSQL provider
- // and for OleDb, according to the docs,
- // an exception is thrown if you try to use
- // this with SqlCommand
- string[] directTables = query.Split(
- new Char[] {','});
-
- td = new StringBuilder("SELECT * FROM ");
-
- for(int tab = 0; tab < directTables.Length; tab++) {
- if(tab > 0)
- 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;
- }
- #if DEBUG_SqlCommand
- Console.WriteLine("SQL after command type: " + statement);
- #endif
- // TODO: this parameters utility
- // currently only support input variables
- // need todo output, input/output, and return.
- #if DEBUG_SqlCommand
- Console.WriteLine("using ParmUtil in TweakQuery()...");
- #endif
- parmUtil = new ParmUtil(statement, parmCollection);
- #if DEBUG_SqlCommand
- Console.WriteLine("ReplaceWithParms...");
- #endif
- statement = parmUtil.ReplaceWithParms();
- #if DEBUG_SqlCommand
- Console.WriteLine("SQL after ParmUtil: " + statement);
- #endif
- return statement;
- }
- private void ExecuteQuery (string query, SqlResult res)
- {
- IntPtr pgResult;
-
- ExecStatusType execStatus;
- if(conn.State != ConnectionState.Open)
- throw new InvalidOperationException(
- "ConnectionState is not Open");
- // FIXME: PQexec blocks
- // while PQsendQuery is non-blocking
- // which is better to use?
- // int PQsendQuery(PGconn *conn,
- // const char *query);
- // execute SQL command
- // uses internal property to get the PGConn IntPtr
- pgResult = PostgresLibrary.
- PQexec (conn.PostgresConnection, query);
- execStatus = PostgresLibrary.
- PQresultStatus (pgResult);
-
- res.ExecStatus = execStatus;
- if(execStatus == ExecStatusType.PGRES_TUPLES_OK ||
- execStatus == ExecStatusType.PGRES_COMMAND_OK) {
- res.BuildTableSchema(pgResult);
- }
- else {
- String errorMessage;
-
- errorMessage = PostgresLibrary.
- PQresStatus(execStatus);
- errorMessage += " " + PostgresLibrary.
- PQresultErrorMessage(pgResult);
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
- throw new SqlException(0, 0,
- errorMessage, 0, "",
- conn.DataSource, "SqlCommand", 0);
- }
- }
- // since SqlCommand has resources so SqlDataReader
- // can do Read() and NextResult(), need to free
- // those resources. Also, need to allow this SqlCommand
- // and this SqlConnection to do things again.
- internal void CloseReader() {
- dataReader = null;
- queries = null;
- if((cmdBehavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection) {
- conn.CloseReader(true);
- }
- else {
- conn.CloseReader(false);
- }
- }
- // only meant to be used between SqlConnectioin,
- // SqlCommand, and SqlDataReader
- internal void OpenReader(SqlDataReader reader) {
- conn.OpenReader(reader);
- }
- /// <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
- ExecStatusType execStatus;
- object obj = null; // return
- int nRow = 0; // first row
- int nCol = 0; // first column
- 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?
- // int PQsendQuery(PGconn *conn,
- // const char *query);
- // execute SQL command
- // uses internal property to get the PGConn IntPtr
- pgResult = PostgresLibrary.
- PQexec (conn.PostgresConnection, query);
- execStatus = PostgresLibrary.
- PQresultStatus (pgResult);
- if(execStatus == ExecStatusType.PGRES_COMMAND_OK) {
- // result was a SQL Command
- // close result set
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
- return null; // return null reference
- }
- else if(execStatus == ExecStatusType.PGRES_TUPLES_OK) {
- // result was a SQL Query
- nRows = PostgresLibrary.
- PQntuples(pgResult);
- nFields = PostgresLibrary.
- PQnfields(pgResult);
- if(nRows > 0 && nFields > 0) {
- // get column name
- //String fieldName;
- //fieldName = PostgresLibrary.
- // PQfname(pgResult, nCol);
- int oid;
- string sType;
- DbType dbType;
- // get PostgreSQL data type (OID)
- oid = PostgresLibrary.
- PQftype(pgResult, nCol);
- sType = PostgresHelper.
- OidToTypname (oid, conn.Types);
- dbType = PostgresHelper.
- TypnameToSqlDbType(sType);
- int definedSize;
- // get defined size of column
- definedSize = PostgresLibrary.
- PQfsize(pgResult, nCol);
- // get data value
- value = PostgresLibrary.
- PQgetvalue(
- pgResult,
- nRow, nCol);
- int columnIsNull;
- // is column NULL?
- columnIsNull = PostgresLibrary.
- PQgetisnull(pgResult,
- nRow, nCol);
- int actualLength;
- // get Actual Length
- actualLength = PostgresLibrary.
- PQgetlength(pgResult,
- nRow, nCol);
-
- obj = PostgresHelper.
- ConvertDbTypeToSystem (
- dbType,
- value);
- }
- // close result set
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
- }
- else {
- String errorMessage;
-
- errorMessage = PostgresLibrary.
- PQresStatus(execStatus);
- errorMessage += " " + PostgresLibrary.
- PQresultErrorMessage(pgResult);
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
- throw new SqlException(0, 0,
- errorMessage, 0, "",
- conn.DataSource, "SqlCommand", 0);
- }
-
- return obj;
- }
- [MonoTODO]
- public XmlReader ExecuteXmlReader () {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- public void Prepare () {
- // FIXME: parameters have to be implemented for this
- throw new NotImplementedException ();
- }
- [MonoTODO]
- public SqlCommand Clone () {
- throw new NotImplementedException ();
- }
- #endregion // Methods
- #region Properties
- public string CommandText {
- get {
- return sql;
- }
- set {
- sql = value;
- }
- }
- public int CommandTimeout {
- get {
- return timeout;
- }
-
- set {
- // FIXME: if value < 0, throw
- // ArgumentException
- // if (value < 0)
- // throw ArgumentException;
- timeout = value;
- }
- }
- public CommandType CommandType {
- get {
- return cmdType;
- }
- set {
- cmdType = value;
- }
- }
- // FIXME: for property Connection, is this the correct
- // way to handle a return of a stronger type?
- IDbConnection IDbCommand.Connection {
- get {
- return Connection;
- }
- set {
- // FIXME: throw an InvalidOperationException
- // if the change was during a
- // transaction in progress
- // csc
- Connection = (SqlConnection) value;
- // mcs
- // Connection = value;
-
- // FIXME: set Transaction property to null
- }
- }
-
- public SqlConnection Connection {
- get {
- // conn defaults to null
- return conn;
- }
- set {
- // FIXME: throw an InvalidOperationException
- // if the change was during
- // a transaction in progress
- conn = value;
- // FIXME: set Transaction property to null
- }
- }
- public bool DesignTimeVisible {
- get {
- return designTime;
- }
-
- set{
- designTime = value;
- }
- }
- // FIXME; for property Parameters, is this the correct
- // way to handle a stronger return type?
- IDataParameterCollection IDbCommand.Parameters {
- get {
- return Parameters;
- }
- }
- public SqlParameterCollection Parameters {
- get {
- return parmCollection;
- }
- }
- // FIXME: for property Transaction, is this the correct
- // way to handle a return of a stronger type?
- IDbTransaction IDbCommand.Transaction {
- get {
- return Transaction;
- }
- set {
- // FIXME: error handling - do not allow
- // setting of transaction if transaction
- // has already begun
- // csc
- Transaction = (SqlTransaction) value;
- // mcs
- // Transaction = value;
- }
- }
- public SqlTransaction Transaction {
- get {
- return trans;
- }
- set {
- // FIXME: error handling
- trans = value;
- }
- }
- [MonoTODO]
- public UpdateRowSource UpdatedRowSource {
- // FIXME: do this once DbDataAdaptor
- // and DataRow are done
- get {
- throw new NotImplementedException ();
- }
- set {
- throw new NotImplementedException ();
- }
- }
- #endregion // Properties
- #region Inner Classes
- #endregion // Inner Classes
- #region Destructors
- [MonoTODO]
- public void Dispose() {
- // FIXME: need proper way to release resources
- // Dispose(true);
- }
- [MonoTODO]
- ~SqlCommand() {
- // FIXME: need proper way to release resources
- // Dispose(false);
- }
- #endregion //Destructors
- }
- // SqlResult is used for passing Result Set data
- // from SqlCommand to SqlDataReader
- internal class SqlResult {
- private DataTable dataTableSchema = null; // only will contain the schema
- private IntPtr pg_result = IntPtr.Zero; // native PostgreSQL PGresult
- private int rowCount = 0;
- private int fieldCount = 0;
- private string[] pgtypes = null; // PostgreSQL types (typname)
- private bool resultReturned = false;
- private SqlConnection con = null;
- private int rowsAffected = -1;
- private ExecStatusType execStatus = ExecStatusType.PGRES_FATAL_ERROR;
- private int currentQuery = -1;
- private string sql = "";
- private CommandBehavior cmdBehavior = CommandBehavior.Default;
- internal CommandBehavior Behavior {
- get {
- return cmdBehavior;
- }
- set {
- cmdBehavior = value;
- }
- }
- internal string SQL {
- get {
- return sql;
- }
- set {
- sql = value;
- }
- }
- internal ExecStatusType ExecStatus {
- get {
- return execStatus;
- }
- set {
- execStatus = value;
- }
- }
- internal int CurrentQuery {
- get {
- return currentQuery;
- }
- set {
- currentQuery = value;
- }
- }
- internal SqlConnection Connection {
- get {
- return con;
- }
- set {
- con = value;
- }
- }
- internal int RecordsAffected {
- get {
- return rowsAffected;
- }
- }
- 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;
-
- // need to set IDataReader.RecordsAffected property
- string rowsAffectedString;
- rowsAffectedString = PostgresLibrary.
- PQcmdTuples (pgResult);
- if(rowsAffectedString != null)
- if(rowsAffectedString.Equals("") == false)
- rowsAffected = int.Parse(rowsAffectedString);
-
- // Only Results from SQL SELECT Queries
- // get a DataTable for schema of the result
- // otherwise, DataTable is null reference
- if(execStatus == ExecStatusType.PGRES_TUPLES_OK) {
- dataTableSchema = new DataTable ();
- dataTableSchema.Columns.Add ("ColumnName", typeof (string));
- dataTableSchema.Columns.Add ("ColumnOrdinal", typeof (int));
- dataTableSchema.Columns.Add ("ColumnSize", typeof (int));
- dataTableSchema.Columns.Add ("NumericPrecision", typeof (int));
- dataTableSchema.Columns.Add ("NumericScale", typeof (int));
- dataTableSchema.Columns.Add ("IsUnique", typeof (bool));
- dataTableSchema.Columns.Add ("IsKey", typeof (bool));
- DataColumn dc = dataTableSchema.Columns["IsKey"];
- dc.AllowDBNull = true; // IsKey can have a DBNull
- dataTableSchema.Columns.Add ("BaseCatalogName", typeof (string));
- dataTableSchema.Columns.Add ("BaseColumnName", typeof (string));
- dataTableSchema.Columns.Add ("BaseSchemaName", typeof (string));
- dataTableSchema.Columns.Add ("BaseTableName", typeof (string));
- dataTableSchema.Columns.Add ("DataType", typeof(string));
- dataTableSchema.Columns.Add ("AllowDBNull", typeof (bool));
- dataTableSchema.Columns.Add ("ProviderType", typeof (int));
- dataTableSchema.Columns.Add ("IsAliased", typeof (bool));
- dataTableSchema.Columns.Add ("IsExpression", typeof (bool));
- dataTableSchema.Columns.Add ("IsIdentity", typeof (bool));
- dataTableSchema.Columns.Add ("IsAutoIncrement", typeof (bool));
- dataTableSchema.Columns.Add ("IsRowVersion", typeof (bool));
- dataTableSchema.Columns.Add ("IsHidden", typeof (bool));
- dataTableSchema.Columns.Add ("IsLong", typeof (bool));
- dataTableSchema.Columns.Add ("IsReadOnly", typeof (bool));
- fieldCount = PostgresLibrary.PQnfields (pgResult);
- rowCount = PostgresLibrary.PQntuples(pgResult);
- pgtypes = new string[fieldCount];
- // TODO: for CommandBehavior.SingleRow
- // use IRow, otherwise, IRowset
- if(fieldCount > 0)
- if((cmdBehavior & CommandBehavior.SingleRow) == CommandBehavior.SingleRow)
- fieldCount = 1;
- // TODO: for CommandBehavior.SchemaInfo
- if((cmdBehavior & CommandBehavior.SchemaOnly) == CommandBehavior.SchemaOnly)
- fieldCount = 0;
- // TODO: for CommandBehavior.SingleResult
- if((cmdBehavior & CommandBehavior.SingleResult) == CommandBehavior.SingleResult)
- if(currentQuery > 0)
- fieldCount = 0;
- // TODO: for CommandBehavior.SequentialAccess - used for reading Large OBjects
- //if((cmdBehavior & CommandBehavior.SequentialAccess) == CommandBehavior.SequentialAccess) {
- //}
- DataRow schemaRow;
- int oid;
- DbType dbType;
- Type typ;
-
- for (int i = 0; i < fieldCount; i += 1 ) {
- schemaRow = dataTableSchema.NewRow ();
- string columnName = PostgresLibrary.PQfname (pgResult, i);
- schemaRow["ColumnName"] = columnName;
- schemaRow["ColumnOrdinal"] = i+1;
- schemaRow["ColumnSize"] = PostgresLibrary.PQfsize (pgResult, i);
- schemaRow["NumericPrecision"] = 0;
- schemaRow["NumericScale"] = 0;
- // TODO: need to get KeyInfo
- if((cmdBehavior & CommandBehavior.KeyInfo) == CommandBehavior.KeyInfo) {
- bool IsUnique, IsKey;
- GetKeyInfo(columnName, out IsUnique, out IsKey);
- }
- else {
- schemaRow["IsUnique"] = false;
- schemaRow["IsKey"] = DBNull.Value;
- }
- schemaRow["BaseCatalogName"] = "";
- schemaRow["BaseColumnName"] = columnName;
- schemaRow["BaseSchemaName"] = "";
- schemaRow["BaseTableName"] = "";
-
- // PostgreSQL type to .NET type stuff
- oid = PostgresLibrary.PQftype (pgResult, i);
- pgtypes[i] = PostgresHelper.OidToTypname (oid, con.Types);
- dbType = PostgresHelper.TypnameToSqlDbType (pgtypes[i]);
-
- typ = PostgresHelper.DbTypeToSystemType (dbType);
- string st = typ.ToString();
- schemaRow["DataType"] = st;
- schemaRow["AllowDBNull"] = false;
- schemaRow["ProviderType"] = oid;
- schemaRow["IsAliased"] = false;
- schemaRow["IsExpression"] = false;
- schemaRow["IsIdentity"] = false;
- schemaRow["IsAutoIncrement"] = false;
- schemaRow["IsRowVersion"] = false;
- schemaRow["IsHidden"] = false;
- schemaRow["IsLong"] = false;
- schemaRow["IsReadOnly"] = false;
- schemaRow.AcceptChanges();
- dataTableSchema.Rows.Add (schemaRow);
- }
-
- #if DEBUG_SqlCommand
- Console.WriteLine("********** DEBUG Table Schema BEGIN ************");
- foreach (DataRow myRow in dataTableSchema.Rows) {
- foreach (DataColumn myCol in dataTableSchema.Columns)
- Console.WriteLine(myCol.ColumnName + " = " + myRow[myCol]);
- Console.WriteLine();
- }
- Console.WriteLine("********** DEBUG Table Schema END ************");
- #endif // DEBUG_SqlCommand
- }
- }
- // TODO: how do we get the key info if
- // we don't have the tableName?
- private void GetKeyInfo(string columnName, out bool isUnique, out bool isKey) {
- isUnique = false;
- isKey = false;
- string sql;
- sql =
- "SELECT i.indkey, i.indisprimary, i.indisunique " +
- "FROM pg_class c, pg_class c2, pg_index i " +
- "WHERE c.relname = ':tableName' AND c.oid = i.indrelid " +
- "AND i.indexrelid = c2.oid ";
- }
- }
- }
|