Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSureshkumar T <suresh@mono-cvs.ximian.com>2005-08-05 18:59:55 +0400
committerSureshkumar T <suresh@mono-cvs.ximian.com>2005-08-05 18:59:55 +0400
commit43bef71bf30bbe14a1b0095e4b0eef6a3b925018 (patch)
tree6598ae96d469f3df96f447585f222dc94b9a7b6d /mcs/class/System.Data/System.Data.Odbc
parent794851fe6a163c407f10b4888ab6b8db1a900a3e (diff)
In System.Data.Common:
2005-08-05 Sureshkumar T <tsureshkumar@novell.com> * DbDataAdapter.cs: - Update (): set parameter values only after getting the appropriate command from command builder. Close reader only if it is not closed before. Use parameter's SourceVersion. Whitespace corrections to comply with standard. In System.Data.SqlClient: 2005-08-05 Sureshkumar T <tsureshkumar@novell.com> * SqlCommandBuilder.cs: Set SourceVersion property to the created parameters as it is used by the Adapter's Update method. In System.Data.Odbc: 2005-08-05 Sureshkumar T <tsureshkumar@novell.com> * OdbcDataReader.cs: RecordsAffected: get value from command. GetSchemaTable (): set IsExpression based on BaseTableName. set AllowDBNull to false if the column is PK. * OdbcCommand.cs: correct UpdatedRowSource is returned. whitespace changes to conform to standard. * OdbcCommandBuilder.cs: Implemented. * OdbcParameter.cs: Direction is set to Input by default. svn path=/trunk/mcs/; revision=48043
Diffstat (limited to 'mcs/class/System.Data/System.Data.Odbc')
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/ChangeLog13
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs698
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/OdbcCommandBuilder.cs394
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs37
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs1
5 files changed, 750 insertions, 393 deletions
diff --git a/mcs/class/System.Data/System.Data.Odbc/ChangeLog b/mcs/class/System.Data/System.Data.Odbc/ChangeLog
index fa145da6536..92253492964 100644
--- a/mcs/class/System.Data/System.Data.Odbc/ChangeLog
+++ b/mcs/class/System.Data/System.Data.Odbc/ChangeLog
@@ -1,3 +1,16 @@
+2005-08-05 Sureshkumar T <tsureshkumar@novell.com>
+
+ * OdbcDataReader.cs: RecordsAffected: get value from command.
+ GetSchemaTable (): set IsExpression based on BaseTableName. set
+ AllowDBNull to false if the column is PK.
+
+ * OdbcCommand.cs: correct UpdatedRowSource is returned. whitespace
+ changes to conform to standard.
+
+ * OdbcCommandBuilder.cs: Implemented.
+
+ * OdbcParameter.cs: Direction is set to Input by default.
+
2005-07-22 Sureshkumar T <tsureshkumar@novell.com>
* OdbcParameter.cs: updated attributes & attribute descriptions to
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
index c98b6272dbc..97caae575aa 100644
--- a/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
+++ b/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
@@ -1,11 +1,11 @@
-//
-// System.Data.Odbc.OdbcCommand
-//
-// Authors:
-// Brian Ritchie (brianlritchie@hotmail.com)
-//
-// Copyright (C) Brian Ritchie, 2002
-//
+//
+// System.Data.Odbc.OdbcCommand
+//
+// Authors:
+// Brian Ritchie (brianlritchie@hotmail.com)
+//
+// Copyright (C) Brian Ritchie, 2002
+//
//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
@@ -29,109 +29,113 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-
+
using System;
-using System.ComponentModel;
-using System.Data;
-using System.Data.Common;
+using System.ComponentModel;
+using System.Data;
+using System.Data.Common;
#if NET_2_0
using System.Data.ProviderBase;
#endif // NET_2_0
-using System.Collections;
-using System.Runtime.InteropServices;
-
-namespace System.Data.Odbc
+using System.Collections;
+using System.Runtime.InteropServices;
+
+namespace System.Data.Odbc
{
- /// <summary>
- /// Represents an SQL statement or stored procedure to execute against a data source.
- /// </summary>
- [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.OdbcCommandDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]
- [ToolboxItemAttribute ("System.Drawing.Design.ToolboxItem, "+ Consts.AssemblySystem_Drawing)]
+ /// <summary>
+ /// Represents an SQL statement or stored procedure to execute against a data source.
+ /// </summary>
+ [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.OdbcCommandDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]
+ [ToolboxItemAttribute ("System.Drawing.Design.ToolboxItem, "+ Consts.AssemblySystem_Drawing)]
#if NET_2_0
- public sealed class OdbcCommand : DbCommandBase, ICloneable
+ public sealed class OdbcCommand : DbCommandBase, ICloneable
#else
- public sealed class OdbcCommand : Component, ICloneable, IDbCommand
+ public sealed class OdbcCommand : Component, ICloneable, IDbCommand
#endif //NET_2_0
- {
- #region Fields
-
+ {
+ #region Fields
+
#if ONLY_1_1
- string commandText;
- int timeout;
- CommandType commandType;
+ string commandText;
+ int timeout;
+ CommandType commandType;
+ UpdateRowSource updateRowSource = UpdateRowSource.Both;
#endif // ONLY_1_1
- OdbcConnection connection;
- OdbcTransaction transaction;
- OdbcParameterCollection _parameters;
-
- bool designTimeVisible;
- bool prepared=false;
- OdbcDataReader dataReader;
- IntPtr hstmt;
-
- #endregion // Fields
-
- #region Constructors
-
- public OdbcCommand ()
- {
- this.CommandText = String.Empty;
- this.CommandTimeout = 30; // default timeout
- this.CommandType = CommandType.Text;
- Connection = null;
- _parameters = new OdbcParameterCollection ();
- Transaction = null;
- designTimeVisible = false;
- dataReader = null;
- }
-
- public OdbcCommand (string cmdText) : this ()
- {
- CommandText = cmdText;
- }
-
- public OdbcCommand (string cmdText, OdbcConnection connection)
- : this (cmdText)
- {
- Connection = connection;
- }
-
- public OdbcCommand (string cmdText,
- OdbcConnection connection,
- OdbcTransaction transaction) : this (cmdText, connection)
- {
- this.Transaction = transaction;
- }
-
- #endregion // Constructors
-
- #region Properties
-
- internal IntPtr hStmt
- {
- get { return hstmt; }
- }
-
-
+ OdbcConnection connection;
+ OdbcTransaction transaction;
+ OdbcParameterCollection _parameters;
+
+ bool designTimeVisible;
+ bool prepared=false;
+ OdbcDataReader dataReader;
+ IntPtr hstmt;
+
+ #endregion // Fields
+
+ #region Constructors
+
+ public OdbcCommand ()
+ {
+ this.CommandText = String.Empty;
+ this.CommandTimeout = 30; // default timeout
+ this.CommandType = CommandType.Text;
+ Connection = null;
+ _parameters = new OdbcParameterCollection ();
+ Transaction = null;
+ designTimeVisible = false;
+ dataReader = null;
+#if ONLY_1_1
+ updateRowSource = UpdateRowSource.Both;
+#endif // ONLY_1_1
+ }
+
+ public OdbcCommand (string cmdText) : this ()
+ {
+ CommandText = cmdText;
+ }
+
+ public OdbcCommand (string cmdText, OdbcConnection connection)
+ : this (cmdText)
+ {
+ Connection = connection;
+ }
+
+ public OdbcCommand (string cmdText,
+ OdbcConnection connection,
+ OdbcTransaction transaction) : this (cmdText, connection)
+ {
+ this.Transaction = transaction;
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ internal IntPtr hStmt
+ {
+ get { return hstmt; }
+ }
+
+
#if ONLY_1_1
- [OdbcCategory ("Data")]
- [DefaultValue ("")]
- [OdbcDescriptionAttribute ("Command text to execute")]
- [EditorAttribute ("Microsoft.VSDesigner.Data.Odbc.Design.OdbcCommandTextEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
- [RefreshPropertiesAttribute (RefreshProperties.All)]
- public string CommandText
- {
- get {
- return commandText;
- }
- set {
- prepared=false;
- commandText = value;
- }
- }
-
-#else
+ [OdbcCategory ("Data")]
+ [DefaultValue ("")]
+ [OdbcDescriptionAttribute ("Command text to execute")]
+ [EditorAttribute ("Microsoft.VSDesigner.Data.Odbc.Design.OdbcCommandTextEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
+ [RefreshPropertiesAttribute (RefreshProperties.All)]
+ public string CommandText
+ {
+ get {
+ return commandText;
+ }
+ set {
+ prepared=false;
+ commandText = value;
+ }
+ }
+
+ #else
[OdbcCategory ("Data")]
[DefaultValue ("")]
[OdbcDescriptionAttribute ("Command text to execute")]
@@ -150,42 +154,42 @@ namespace System.Data.Odbc
#endif // ONLY_1_1
#if ONLY_1_1
- [OdbcDescriptionAttribute ("Time to wait for command to execute")]
- [DefaultValue (30)]
- public int CommandTimeout {
- get {
- return timeout;
- }
- set {
- timeout = value;
- }
- }
-
- [OdbcCategory ("Data")]
- [DefaultValue ("Text")]
- [OdbcDescriptionAttribute ("How to interpret the CommandText")]
- [RefreshPropertiesAttribute (RefreshProperties.All)]
- public CommandType CommandType {
- get {
- return commandType;
- }
- set {
- commandType = value;
- }
- }
-
- [OdbcCategory ("Behavior")]
- [OdbcDescriptionAttribute ("Connection used by the command")]
- [DefaultValue (null)]
- [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
- public OdbcConnection Connection {
- get {
- return connection;
- }
- set {
- connection = value;
- }
- }
+ [OdbcDescriptionAttribute ("Time to wait for command to execute")]
+ [DefaultValue (30)]
+ public int CommandTimeout {
+ get {
+ return timeout;
+ }
+ set {
+ timeout = value;
+ }
+ }
+
+ [OdbcCategory ("Data")]
+ [DefaultValue ("Text")]
+ [OdbcDescriptionAttribute ("How to interpret the CommandText")]
+ [RefreshPropertiesAttribute (RefreshProperties.All)]
+ public CommandType CommandType {
+ get {
+ return commandType;
+ }
+ set {
+ commandType = value;
+ }
+ }
+
+ [OdbcCategory ("Behavior")]
+ [OdbcDescriptionAttribute ("Connection used by the command")]
+ [DefaultValue (null)]
+ [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
+ public OdbcConnection Connection {
+ get {
+ return connection;
+ }
+ set {
+ connection = value;
+ }
+ }
#endif // ONLY_1_1
#if NET_2_0
@@ -198,77 +202,77 @@ namespace System.Data.Odbc
#endif // NET_2_0
#if ONLY_1_1
- [BrowsableAttribute (false)]
- [DesignOnlyAttribute (true)]
- [DefaultValue (true)]
- public bool DesignTimeVisible {
- get {
- return designTimeVisible;
- }
- set {
- designTimeVisible = value;
- }
- }
-
+ [BrowsableAttribute (false)]
+ [DesignOnlyAttribute (true)]
+ [DefaultValue (true)]
+ public bool DesignTimeVisible {
+ get {
+ return designTimeVisible;
+ }
+ set {
+ designTimeVisible = value;
+ }
+ }
+
#endif // ONLY_1_1
- [OdbcCategory ("Data")]
- [OdbcDescriptionAttribute ("The parameters collection")]
- [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
+ [OdbcCategory ("Data")]
+ [OdbcDescriptionAttribute ("The parameters collection")]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
public
#if NET_2_0
new
#endif // NET_2_0
- OdbcParameterCollection Parameters {
- get {
+ OdbcParameterCollection Parameters {
+ get {
#if ONLY_1_1
return _parameters;
-#else
+ #else
return base.Parameters as OdbcParameterCollection;
#endif // ONLY_1_1
- }
- }
-
- [BrowsableAttribute (false)]
- [OdbcDescriptionAttribute ("The transaction used by the command")]
- [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
+ }
+ }
+
+ [BrowsableAttribute (false)]
+ [OdbcDescriptionAttribute ("The transaction used by the command")]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public
#if NET_2_0
new
#endif // NET_2_0
- OdbcTransaction Transaction {
- get {
- return transaction;
- }
- set {
- transaction = value;
- }
- }
+ OdbcTransaction Transaction {
+ get {
+ return transaction;
+ }
+ set {
+ transaction = value;
+ }
+ }
#if ONLY_1_1
-
- [OdbcCategory ("Behavior")]
- [DefaultValue (UpdateRowSource.Both)]
- [OdbcDescriptionAttribute ("When used by a DataAdapter.Update, how command results are applied to the current DataRow")]
- public UpdateRowSource UpdatedRowSource {
- [MonoTODO]
- get {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- set {
- throw new NotImplementedException ();
- }
- }
-
- IDbConnection IDbCommand.Connection {
- get {
- return Connection;
- }
- set {
- Connection = (OdbcConnection) value;
- }
+
+ [OdbcCategory ("Behavior")]
+ [DefaultValue (UpdateRowSource.Both)]
+ [OdbcDescriptionAttribute ("When used by a DataAdapter.Update, how command results are applied to the current DataRow")]
+ public UpdateRowSource UpdatedRowSource {
+ [MonoTODO]
+ get {
+ return updateRowSource;
+ }
+ [MonoTODO]
+ set {
+ updateRowSource = value;
+ }
+ }
+
+ IDbConnection IDbCommand.Connection {
+ get {
+ return Connection;
+ }
+ set {
+ Connection = (OdbcConnection) value;
+ }
}
#endif // ONLY_1_1
#if NET_2_0
@@ -283,12 +287,12 @@ namespace System.Data.Odbc
#endif // NET_2_0
#if ONLY_1_1
- IDataParameterCollection IDbCommand.Parameters {
- get {
- return Parameters;
- }
+ IDataParameterCollection IDbCommand.Parameters {
+ get {
+ return Parameters;
+ }
}
-#else
+ #else
protected override DbParameterCollection DbParameterCollection
{
get { return _parameters as DbParameterCollection;}
@@ -297,12 +301,12 @@ namespace System.Data.Odbc
#endif // NET_2_0
#if ONLY_1_1
- IDbTransaction IDbCommand.Transaction {
- get {
- return (IDbTransaction) Transaction;
- }
- set {
- if (value is OdbcTransaction)
+ IDbTransaction IDbCommand.Transaction {
+ get {
+ return (IDbTransaction) Transaction;
+ }
+ set {
+ if (value is OdbcTransaction)
{
Transaction = (OdbcTransaction)value;
}
@@ -310,9 +314,9 @@ namespace System.Data.Odbc
{
throw new ArgumentException ();
}
- }
+ }
}
-#else
+ #else
protected override DbTransaction DbTransaction
{
get { return transaction; }
@@ -323,38 +327,38 @@ namespace System.Data.Odbc
#endif // ONLY_1_1
-
- #endregion // Properties
-
- #region Methods
-
+
+ #endregion // Properties
+
+ #region Methods
+
public
#if NET_2_0
override
#endif // NET_2_0
- void Cancel ()
- {
- if (hstmt!=IntPtr.Zero)
- {
- OdbcReturn Ret=libodbc.SQLCancel(hstmt);
- if ((Ret!=OdbcReturn.Success) && (Ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLCancel",OdbcHandleType.Stmt,hstmt));
- }
- else
- throw new InvalidOperationException();
- }
-
+ void Cancel ()
+ {
+ if (hstmt!=IntPtr.Zero)
+ {
+ OdbcReturn Ret=libodbc.SQLCancel(hstmt);
+ if ((Ret!=OdbcReturn.Success) && (Ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLCancel",OdbcHandleType.Stmt,hstmt));
+ }
+ else
+ throw new InvalidOperationException();
+ }
+
#if ONLY_1_1
- IDbDataParameter IDbCommand.CreateParameter ()
- {
- return CreateParameter ();
- }
-
- public OdbcParameter CreateParameter ()
- {
- return new OdbcParameter ();
- }
-#else
+ IDbDataParameter IDbCommand.CreateParameter ()
+ {
+ return CreateParameter ();
+ }
+
+ public OdbcParameter CreateParameter ()
+ {
+ return new OdbcParameter ();
+ }
+ #else
protected override DbParameter CreateDbParameter ()
{
return CreateParameter ();
@@ -362,119 +366,119 @@ namespace System.Data.Odbc
#endif // ONLY_1_1
-
- [MonoTODO]
- protected override void Dispose (bool disposing)
- {
- }
-
- private void ExecSQL(string sql)
- {
- OdbcReturn ret;
-
- if ((Parameters.Count>0) && !prepared)
- Prepare();
-
- if (prepared)
- {
- ret=libodbc.SQLExecute(hstmt);
- if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLExecute",OdbcHandleType.Stmt,hstmt));
- }
- else
- {
- ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, Connection.hDbc, ref hstmt);
- if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Dbc,Connection.hDbc));
-
- ret=libodbc.SQLExecDirect(hstmt, sql, sql.Length);
- if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLExecDirect",OdbcHandleType.Stmt,hstmt));
- }
- }
-
+
+ [MonoTODO]
+ protected override void Dispose (bool disposing)
+ {
+ }
+
+ private void ExecSQL(string sql)
+ {
+ OdbcReturn ret;
+
+ if ((Parameters.Count>0) && !prepared)
+ Prepare();
+
+ if (prepared)
+ {
+ ret=libodbc.SQLExecute(hstmt);
+ if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLExecute",OdbcHandleType.Stmt,hstmt));
+ }
+ else
+ {
+ ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, Connection.hDbc, ref hstmt);
+ if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Dbc,Connection.hDbc));
+
+ ret=libodbc.SQLExecDirect(hstmt, sql, sql.Length);
+ if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLExecDirect",OdbcHandleType.Stmt,hstmt));
+ }
+ }
+
public
#if NET_2_0
override
#endif // NET_2_0
- int ExecuteNonQuery ()
- {
+ int ExecuteNonQuery ()
+ {
return ExecuteNonQuery (true);
- }
-
+ }
+
private int ExecuteNonQuery (bool freeHandle)
{
int records = 0;
- if (Connection == null)
- throw new InvalidOperationException ();
- if (Connection.State == ConnectionState.Closed)
- throw new InvalidOperationException ();
- // FIXME: a third check is mentioned in .NET docs
-
- ExecSQL(CommandText);
+ if (Connection == null)
+ throw new InvalidOperationException ();
+ if (Connection.State == ConnectionState.Closed)
+ throw new InvalidOperationException ();
+ // FIXME: a third check is mentioned in .NET docs
+
+ ExecSQL(CommandText);
// .NET documentation says that except for INSERT, UPDATE and
// DELETE where the return value is the number of rows affected
// for the rest of the commands the return value is -1.
if ((CommandText.ToUpper().IndexOf("UPDATE")!=-1) ||
- (CommandText.ToUpper().IndexOf("INSERT")!=-1) ||
- (CommandText.ToUpper().IndexOf("DELETE")!=-1)) {
+ (CommandText.ToUpper().IndexOf("INSERT")!=-1) ||
+ (CommandText.ToUpper().IndexOf("DELETE")!=-1)) {
- int numrows = 0;
- OdbcReturn ret = libodbc.SQLRowCount(hstmt,ref numrows);
- records = numrows;
+ int numrows = 0;
+ OdbcReturn ret = libodbc.SQLRowCount(hstmt,ref numrows);
+ records = numrows;
}
else
- records = -1;
-
- if (freeHandle && !prepared) {
- OdbcReturn ret = libodbc.SQLFreeHandle( (ushort) OdbcHandleType.Stmt, hstmt);
- if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLFreeHandle",OdbcHandleType.Stmt,hstmt));
+ records = -1;
+
+ if (freeHandle && !prepared) {
+ OdbcReturn ret = libodbc.SQLFreeHandle( (ushort) OdbcHandleType.Stmt, hstmt);
+ if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLFreeHandle",OdbcHandleType.Stmt,hstmt));
}
- return records;
+ return records;
}
public
#if NET_2_0
override
#endif // NET_2_0
- void Prepare()
- {
- OdbcReturn ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, Connection.hDbc, ref hstmt);
- if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Dbc,Connection.hDbc));
-
- ret=libodbc.SQLPrepare(hstmt, CommandText, CommandText.Length);
- if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
- throw new OdbcException(new OdbcError("SQLPrepare",OdbcHandleType.Stmt,hstmt));
-
- int i=1;
- foreach (OdbcParameter p in Parameters)
- {
- p.Bind(hstmt, i);
- i++;
- }
-
- prepared=true;
- }
-
+ void Prepare()
+ {
+ OdbcReturn ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, Connection.hDbc, ref hstmt);
+ if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Dbc,Connection.hDbc));
+
+ ret=libodbc.SQLPrepare(hstmt, CommandText, CommandText.Length);
+ if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
+ throw new OdbcException(new OdbcError("SQLPrepare",OdbcHandleType.Stmt,hstmt));
+
+ int i=1;
+ foreach (OdbcParameter p in Parameters)
+ {
+ p.Bind(hstmt, i);
+ i++;
+ }
+
+ prepared=true;
+ }
+
public
#if NET_2_0
new
#endif // NET_2_0
- OdbcDataReader ExecuteReader ()
- {
- return ExecuteReader (CommandBehavior.Default);
- }
+ OdbcDataReader ExecuteReader ()
+ {
+ return ExecuteReader (CommandBehavior.Default);
+ }
#if ONLY_1_1
- IDataReader IDbCommand.ExecuteReader ()
+ IDataReader IDbCommand.ExecuteReader ()
{
- return ExecuteReader ();
+ return ExecuteReader ();
}
-#else
+ #else
protected override DbDataReader ExecuteDbDataReader (CommandBehavior behavior)
{
return ExecuteReader (behavior);
@@ -486,53 +490,53 @@ namespace System.Data.Odbc
#if NET_2_0
new
#endif // NET_2_0
- OdbcDataReader ExecuteReader (CommandBehavior behavior)
+ OdbcDataReader ExecuteReader (CommandBehavior behavior)
{
- ExecuteNonQuery(false);
- dataReader=new OdbcDataReader(this,behavior);
- return dataReader;
- }
+ int recordsAffected = ExecuteNonQuery(false);
+ dataReader=new OdbcDataReader(this, behavior, recordsAffected);
+ return dataReader;
+ }
#if ONLY_1_1
- IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)
- {
- return ExecuteReader (behavior);
- }
+ IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)
+ {
+ return ExecuteReader (behavior);
+ }
#endif // ONLY_1_1
#if ONLY_1_1
- public object ExecuteScalar ()
- {
- object val = null;
- OdbcDataReader reader=ExecuteReader();
- try
- {
- if (reader.Read ())
- val=reader[0];
- }
- finally
- {
- reader.Close();
- }
- return val;
+ public object ExecuteScalar ()
+ {
+ object val = null;
+ OdbcDataReader reader=ExecuteReader();
+ try
+ {
+ if (reader.Read ())
+ val=reader[0];
+ }
+ finally
+ {
+ reader.Close();
+ }
+ return val;
}
#endif // ONLY_1_1
- [MonoTODO]
- object ICloneable.Clone ()
- {
- throw new NotImplementedException ();
- }
-
+ [MonoTODO]
+ object ICloneable.Clone ()
+ {
+ throw new NotImplementedException ();
+ }
+
public
#if NET_2_0
override
#endif // NET_2_0
- void ResetCommandTimeout ()
- {
- CommandTimeout = 30;
- }
-
- #endregion
- }
-}
+ void ResetCommandTimeout ()
+ {
+ CommandTimeout = 30;
+ }
+
+ #endregion
+ }
+}
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcCommandBuilder.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcCommandBuilder.cs
index 8945f943097..74e8a2a3c48 100644
--- a/mcs/class/System.Data/System.Data.Odbc/OdbcCommandBuilder.cs
+++ b/mcs/class/System.Data/System.Data.Odbc/OdbcCommandBuilder.cs
@@ -3,6 +3,7 @@
//
// Author:
// Umadevi S (sumadevi@novell.com)
+// Sureshkumar T (tsureshkumar@novell.com)
//
// Copyright (C) Novell Inc, 2004
//
@@ -30,9 +31,10 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System.ComponentModel;
+using System.Text;
using System.Data;
using System.Data.Common;
+using System.ComponentModel;
namespace System.Data.Odbc
{
@@ -40,17 +42,25 @@ namespace System.Data.Odbc
/// Provides a means of automatically generating single-table commands used to reconcile changes made to a DataSet with the associated database. This class cannot be inherited.
/// </summary>
-#if ONLY_1_1
- public sealed class OdbcCommandBuilder : Component
-#else // NET_2_0 and higher
+#if NET_2_0
public sealed class OdbcCommandBuilder : DbCommandBuilder
-#endif // ONLY_1_1
+#else // 1_1
+ public sealed class OdbcCommandBuilder : Component
+#endif // NET_2_0
{
#region Fields
- OdbcDataAdapter adapter;
- string quotePrefix;
- string quoteSuffix;
+ private OdbcDataAdapter _adapter;
+ private string _quotePrefix;
+ private string _quoteSuffix;
+
+ private DataTable _schema;
+ private string _tableName;
+ private OdbcCommand _insertCommand;
+ private OdbcCommand _updateCommand;
+ private OdbcCommand _deleteCommand;
+
+ bool _disposed;
#endregion // Fields
@@ -58,15 +68,15 @@ namespace System.Data.Odbc
public OdbcCommandBuilder ()
{
- adapter = null;
- quotePrefix = String.Empty;
- quoteSuffix = String.Empty;
+ _adapter = null;
+ _quotePrefix = String.Empty;
+ _quoteSuffix = String.Empty;
}
public OdbcCommandBuilder (OdbcDataAdapter adapter)
: this ()
{
- this.adapter = adapter;
+ DataAdapter = adapter;
}
#endregion // Constructors
@@ -81,10 +91,57 @@ namespace System.Data.Odbc
#endif // NET_2_0
OdbcDataAdapter DataAdapter {
get {
- return adapter;
+ return _adapter;
}
set {
- adapter = value;
+ if (_adapter == value)
+ return;
+
+ if (_adapter != null)
+ _adapter.RowUpdating -= new OdbcRowUpdatingEventHandler (OnRowUpdating);
+ _adapter = value;
+ if (_adapter != null)
+ _adapter.RowUpdating += new OdbcRowUpdatingEventHandler (OnRowUpdating);
+
+ }
+ }
+
+ private OdbcCommand SelectCommand
+ {
+ get {
+ if (DataAdapter == null)
+ return null;
+ return DataAdapter.SelectCommand;
+ }
+ }
+
+ private DataTable Schema
+ {
+ get {
+ if (_schema == null)
+ RefreshSchema ();
+ return _schema;
+ }
+ }
+
+ private string TableName
+ {
+ get {
+ if (_tableName != String.Empty)
+ return _tableName;
+
+ DataRow [] schemaRows = Schema.Select ("BaseTableName is not null and BaseTableName <> ''");
+ if (schemaRows.Length > 1) {
+ string tableName = (string) schemaRows [0] ["BaseTableName"];
+ foreach (DataRow schemaRow in schemaRows) {
+ if ( (string) schemaRow ["BaseTableName"] != tableName)
+ throw new InvalidOperationException ("Dynamic SQL generation is not supported against multiple base tables.");
+ }
+ }
+ if (schemaRows.Length == 0)
+ throw new InvalidOperationException ("Cannot determine the base table name. Cannot proceed");
+ _tableName = schemaRows [0] ["BaseTableName"].ToString ();
+ return _tableName;
}
}
@@ -97,10 +154,10 @@ namespace System.Data.Odbc
#endif // NET_2_0
string QuotePrefix {
get {
- return quotePrefix;
+ return _quotePrefix;
}
set {
- quotePrefix = value;
+ _quotePrefix = value;
}
}
@@ -113,10 +170,10 @@ namespace System.Data.Odbc
#endif // NET_2_0
string QuoteSuffix {
get {
- return quoteSuffix;
+ return _quoteSuffix;
}
set {
- quoteSuffix = value;
+ _quoteSuffix = value;
}
}
@@ -124,55 +181,266 @@ namespace System.Data.Odbc
#region Methods
+ [MonoTODO]
public static void DeriveParameters (OdbcCommand command)
{
throw new NotImplementedException ();
}
- [MonoTODO]
protected override void Dispose (bool disposing)
{
- throw new NotImplementedException ();
+ if (_disposed)
+ return;
+
+ if (disposing) {
+ // dispose managed resource
+ if (_insertCommand != null) _insertCommand.Dispose ();
+ if (_updateCommand != null) _updateCommand.Dispose ();
+ if (_deleteCommand != null) _deleteCommand.Dispose ();
+ if (_schema != null) _insertCommand.Dispose ();
+
+ _insertCommand = null;
+ _updateCommand = null;
+ _deleteCommand = null;
+ _schema = null;
+ }
+ _disposed = true;
+ }
+
+ private bool IsUpdatable (DataRow schemaRow)
+ {
+ if ( (! schemaRow.IsNull ("IsAutoIncrement") && (bool) schemaRow ["IsAutoIncrement"])
+ || (! schemaRow.IsNull ("IsHidden") && (bool) schemaRow ["IsHidden"])
+ || (! schemaRow.IsNull ("IsExpression") && (bool) schemaRow ["IsExpression"])
+ || (! schemaRow.IsNull ("IsRowVersion") && (bool) schemaRow ["IsRowVersion"])
+ || (! schemaRow.IsNull ("IsReadOnly") && (bool) schemaRow ["IsReadOnly"])
+ )
+ return false;
+ return true;
+ }
+
+ private string GetColumnName (DataRow schemaRow)
+ {
+ string columnName = schemaRow.IsNull ("BaseColumnName") ? String.Empty : (string) schemaRow ["BaseColumnName"];
+ if (columnName == String.Empty)
+ columnName = schemaRow.IsNull ("ColumnName") ? String.Empty : (string) schemaRow ["ColumnName"];
+ return columnName;
+ }
+
+ private OdbcParameter AddParameter (OdbcCommand cmd, string paramName, OdbcType odbcType,
+ int length, string sourceColumnName, DataRowVersion rowVersion)
+ {
+ OdbcParameter param;
+ if (length >= 0 && sourceColumnName != String.Empty)
+ param = cmd.Parameters.Add (paramName, odbcType, length, sourceColumnName);
+ else
+ param = cmd.Parameters.Add (paramName, odbcType);
+ param.SourceVersion = rowVersion;
+ return param;
+ }
+
+ /*
+ * creates where clause for optimistic concurrency
+ */
+ private string CreateOptWhereClause (OdbcCommand command)
+ {
+ string [] whereClause = new string [Schema.Rows.Count];
+
+ int count = 0;
+
+ foreach (DataRow schemaRow in Schema.Rows) {
+
+ // exclude non updatable columns
+ if (! IsUpdatable (schemaRow))
+ continue;
+
+ string columnName = GetColumnName (schemaRow);
+ if (columnName == String.Empty)
+ throw new InvalidOperationException ("Cannot form delete command. Column name is missing!");
+
+ bool allowNull = schemaRow.IsNull ("AllowDBNull") || (bool) schemaRow ["AllowDBNull"];
+ OdbcType sqlDbType = schemaRow.IsNull ("ProviderType") ? OdbcType.VarChar : (OdbcType) schemaRow ["ProviderType"];
+ int length = schemaRow.IsNull ("ColumnSize") ? -1 : (int) schemaRow ["ColumnSize"];
+
+ if (allowNull) {
+ whereClause [count] = String.Format ("((? = 1 AND {0} IS NULL) OR ({0} = ?))",
+ columnName);
+ AddParameter (command, columnName, sqlDbType, length, columnName, DataRowVersion.Original);
+ AddParameter (command, columnName, sqlDbType, length, columnName, DataRowVersion.Original);
+ } else {
+ whereClause [count] = String.Format ( "({0} = ?)", columnName);
+ AddParameter (command, columnName, sqlDbType, length, columnName, DataRowVersion.Original);
+ }
+
+ count++;
+ }
+
+ return String.Join (" AND ", whereClause, 0, count);
}
- [MonoTODO]
public
#if NET_2_0
new
#endif // NET_2_0
- OdbcCommand GetDeleteCommand ()
+ OdbcCommand GetInsertCommand ()
{
- throw new NotImplementedException ();
+ // FIXME: check validity of adapter
+ if (_insertCommand != null)
+ return _insertCommand;
+
+ if (_schema == null)
+ RefreshSchema ();
+
+ _insertCommand = new OdbcCommand ();
+ _insertCommand.Connection = DataAdapter.SelectCommand.Connection;
+ _insertCommand.Transaction = DataAdapter.SelectCommand.Transaction;
+ _insertCommand.CommandType = CommandType.Text;
+ _insertCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ string query = String.Format ("INSERT INTO {0}", QuoteIdentifier (TableName));
+ string [] columns = new string [Schema.Rows.Count];
+ string [] values = new string [Schema.Rows.Count];
+
+ int count = 0;
+
+ foreach (DataRow schemaRow in Schema.Rows) {
+
+ // exclude non updatable columns
+ if (! IsUpdatable (schemaRow))
+ continue;
+
+ string columnName = GetColumnName (schemaRow);
+ if (columnName == String.Empty)
+ throw new InvalidOperationException ("Cannot form insert command. Column name is missing!");
+
+ // create column string & value string
+ columns [count] = QuoteIdentifier(columnName);
+ values [count++] = "?";
+
+ // create parameter and add
+ OdbcType sqlDbType = schemaRow.IsNull ("ProviderType") ? OdbcType.VarChar : (OdbcType) schemaRow ["ProviderType"];
+ int length = schemaRow.IsNull ("ColumnSize") ? -1 : (int) schemaRow ["ColumnSize"];
+
+ AddParameter (_insertCommand, columnName, sqlDbType, length, columnName, DataRowVersion.Current);
+ }
+
+ query = String.Format ("{0} ({1}) VALUES ({2})",
+ query,
+ String.Join (", ", columns, 0, count),
+ String.Join (", ", values, 0, count) );
+ _insertCommand.CommandText = query;
+ return _insertCommand;
}
- [MonoTODO]
public
#if NET_2_0
new
#endif // NET_2_0
- OdbcCommand GetInsertCommand ()
+ OdbcCommand GetUpdateCommand ()
{
- throw new NotImplementedException ();
+ // FIXME: check validity of adapter
+ if (_updateCommand != null)
+ return _updateCommand;
+
+ if (_schema == null)
+ RefreshSchema ();
+
+ _updateCommand = new OdbcCommand ();
+ _updateCommand.Connection = DataAdapter.SelectCommand.Connection;
+ _updateCommand.Transaction = DataAdapter.SelectCommand.Transaction;
+ _updateCommand.CommandType = CommandType.Text;
+ _updateCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ string query = String.Format ("UPDATE {0} SET", QuoteIdentifier (TableName));
+ string [] setClause = new string [Schema.Rows.Count];
+
+ int count = 0;
+
+ foreach (DataRow schemaRow in Schema.Rows) {
+
+ // exclude non updatable columns
+ if (! IsUpdatable (schemaRow))
+ continue;
+
+ string columnName = GetColumnName (schemaRow);
+ if (columnName == String.Empty)
+ throw new InvalidOperationException ("Cannot form update command. Column name is missing!");
+
+ OdbcType sqlDbType = schemaRow.IsNull ("ProviderType") ? OdbcType.VarChar : (OdbcType) schemaRow ["ProviderType"];
+ int length = schemaRow.IsNull ("ColumnSize") ? -1 : (int) schemaRow ["ColumnSize"];
+
+ // create column = value string
+ setClause [count] = String.Format ("{0} = ?", QuoteIdentifier(columnName));
+ AddParameter (_updateCommand, columnName, sqlDbType, length, columnName, DataRowVersion.Current);
+ count++;
+ }
+
+ // create where clause. odbc uses positional parameters. so where class
+ // is created seperate from the above loop.
+ string whereClause = CreateOptWhereClause (_updateCommand);
+
+ query = String.Format ("{0} {1} WHERE ({2})",
+ query,
+ String.Join (", ", setClause, 0, count),
+ whereClause);
+ _updateCommand.CommandText = query;
+ return _updateCommand;
}
- [MonoTODO]
public
#if NET_2_0
new
#endif // NET_2_0
- OdbcCommand GetUpdateCommand ()
+ OdbcCommand GetDeleteCommand ()
{
- throw new NotImplementedException ();
+ // FIXME: check validity of adapter
+ if (_deleteCommand != null)
+ return _deleteCommand;
+
+ if (_schema == null)
+ RefreshSchema ();
+
+ _deleteCommand = new OdbcCommand ();
+ _deleteCommand.Connection = DataAdapter.SelectCommand.Connection;
+ _deleteCommand.Transaction = DataAdapter.SelectCommand.Transaction;
+ _deleteCommand.CommandType = CommandType.Text;
+ _deleteCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ string query = String.Format ("DELETE FROM {0}", QuoteIdentifier (TableName));
+ string whereClause = CreateOptWhereClause (_deleteCommand);
+
+ query = String.Format ("{0} WHERE ({1})", query, whereClause);
+ _deleteCommand.CommandText = query;
+ return _deleteCommand;
}
- [MonoTODO]
public
#if NET_2_0
override
#endif // NET_2_0
void RefreshSchema ()
{
- throw new NotImplementedException ();
+ // creates metadata
+ if (SelectCommand == null)
+ throw new InvalidOperationException ("SelectCommand should be valid");
+ if (SelectCommand.Connection == null)
+ throw new InvalidOperationException ("SelectCommand's Connection should be valid");
+
+ CommandBehavior behavior = CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
+ if (SelectCommand.Connection.State != ConnectionState.Open) {
+ SelectCommand.Connection.Open ();
+ behavior |= CommandBehavior.CloseConnection;
+ }
+
+ OdbcDataReader reader = SelectCommand.ExecuteReader (behavior);
+ _schema = reader.GetSchemaTable ();
+ reader.Close ();
+
+ // force creation of commands
+ _insertCommand = null;
+ _updateCommand = null;
+ _deleteCommand = null;
+ _tableName = String.Empty;
}
#if NET_2_0
@@ -208,7 +476,71 @@ namespace System.Data.Odbc
}
#endif // NET_2_0
+
+#if NET_2_0
+ [MonoTODO]
+ public override
+#else
+ private
+#endif
+ string QuoteIdentifier (string unquotedIdentifier)
+ {
+#if NET_2_0
+ throw new NotImplementedException ();
+#else
+ if (unquotedIdentifier == null || unquotedIdentifier == String.Empty)
+ return unquotedIdentifier;
+ return String.Format ("{0}{1}{2}", QuotePrefix,
+ unquotedIdentifier, QuoteSuffix);
+#endif
+ }
+
+#if NET_2_0
+ [MonoTODO]
+ public override
+#else
+ private
+#endif
+ string UnquoteIdentifier (string quotedIdentifier)
+ {
+#if NET_2_0
+ throw new NotImplementedException ();
+#else
+ if (quotedIdentifier == null || quotedIdentifier == String.Empty)
+ return quotedIdentifier;
+
+ StringBuilder sb = new StringBuilder (quotedIdentifier.Length);
+ sb.Append (quotedIdentifier);
+ if (quotedIdentifier.StartsWith (QuotePrefix))
+ sb.Remove (0,QuotePrefix.Length);
+ if (quotedIdentifier.EndsWith (QuoteSuffix))
+ sb.Remove (sb.Length - QuoteSuffix.Length, QuoteSuffix.Length );
+ return sb.ToString ();
+#endif
+ }
+ private void OnRowUpdating (object sender, OdbcRowUpdatingEventArgs args)
+ {
+ if (args.Command != null)
+ return;
+ try {
+ switch (args.StatementType) {
+ case StatementType.Insert:
+ args.Command = GetInsertCommand ();
+ break;
+ case StatementType.Update:
+ args.Command = GetUpdateCommand ();
+ break;
+ case StatementType.Delete:
+ args.Command = GetDeleteCommand ();
+ break;
+ }
+ } catch (Exception e) {
+ args.Errors = e;
+ args.Status = UpdateStatus.ErrorsOccurred;
+ }
+ }
+
#endregion // Methods
}
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs
index 23ed1042391..421e71959b5 100644
--- a/mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs
+++ b/mcs/class/System.Data/System.Data.Odbc/OdbcDataReader.cs
@@ -57,6 +57,7 @@ namespace System.Data.Odbc
private int currentRow;
private OdbcColumn[] cols;
private IntPtr hstmt;
+ private int _recordsAffected = -1;
#if ONLY_1_1
private CommandBehavior behavior;
#endif // ONLY_1_1
@@ -84,6 +85,13 @@ namespace System.Data.Odbc
GetSchemaTable ();
}
+ internal OdbcDataReader (OdbcCommand command, CommandBehavior behavior,
+ int recordAffected) : this (command, behavior)
+ {
+ _recordsAffected = recordAffected;
+ }
+
+
#endregion
#region Properties
@@ -177,7 +185,7 @@ namespace System.Data.Odbc
#endif // NET_2_0
int RecordsAffected {
get {
- return -1;
+ return _recordsAffected;
}
}
@@ -542,9 +550,11 @@ namespace System.Data.Odbc
dataTableSchema.Columns.Add ("IsReadOnly", typeof (bool));
DataRow schemaRow;
-
+
for (int i = 0; i < cols.Length; i += 1 )
{
+ string baseTableName = String.Empty;
+ bool isKey = false;
OdbcColumn col=GetColumn(i);
schemaRow = dataTableSchema.NewRow ();
@@ -563,32 +573,29 @@ namespace System.Data.Odbc
for (int j=0; j < keys.Length; j++) {
if (keys [j] == col.ColumnName) {
schemaRow ["IsUnique"] = true;
- schemaRow ["IsKey"] = true;
+ schemaRow ["IsKey"] = (isKey = true);
+ col.AllowDBNull = false;
}
}
schemaRow["BaseCatalogName"] = "";
schemaRow["BaseColumnName"] = "";
schemaRow["BaseSchemaName"] = "";
- schemaRow["BaseTableName"] = "";
-
- try {
- schemaRow["BaseColumnName"] = GetColumnAttributeStr (i+1, FieldIdentifier.BaseColumnName);
- schemaRow["BaseTableName"] = GetColumnAttributeStr (i+1, FieldIdentifier.BaseTableName);
- } catch (Exception e) {
- // ignore these properties as they are optional.
- }
-
-
+
+ try {
+ baseTableName = GetColumnAttributeStr (i+1, FieldIdentifier.BaseTableName);
+ schemaRow["BaseColumnName"] = GetColumnAttributeStr (i+1, FieldIdentifier.BaseColumnName);
+ } catch (Exception) {}
+ schemaRow["BaseTableName"] = baseTableName;
schemaRow["DataType"] = col.DataType;
- schemaRow["AllowDBNull"] = col.AllowDBNull;
+ schemaRow["AllowDBNull"] = isKey ? false : true ;
schemaRow["ProviderType"] = (int) col.OdbcType;
// TODO: all of these
schemaRow["IsAliased"] = false;
- schemaRow["IsExpression"] = false;
+ schemaRow["IsExpression"] = baseTableName == String.Empty;
schemaRow["IsIdentity"] = false;
schemaRow["IsAutoIncrement"] = GetColumnAttribute (i+1, FieldIdentifier.AutoUniqueValue) == 1;
schemaRow["IsRowVersion"] = false;
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs
index e5266e520b5..92e08a406e3 100644
--- a/mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs
+++ b/mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs
@@ -85,6 +85,7 @@ namespace System.Data.Odbc
Precision = 0;
Scale = 0;
SourceColumn = String.Empty;
+ Direction = ParameterDirection.Input;
}
public OdbcParameter (string name, object value)