+2002-11-26 Tim Coleman <tim@timcoleman.com>
+ * Mono.Data.TdsClient.build:
+ * makefile.gnu
+ Add System.EnterpriseServices to build.
+ * Mono.Data.TdsClient/TdsCommand.cs:
+ * Mono.Data.TdsClient/TdsConnection.cs:
+ * Mono.Data.TdsClient/TdsDataReader.cs:
+ * Mono.Data.TdsClient/TdsException.cs:
+ * Mono.Data.TdsClient/TdsParameter.cs:
+ * Mono.Data.TdsClient/TdsParameterCollection.cs:
+ * Mono.Data.TdsClient/TdsTransaction.cs:
+ * Mono.Data.TdsTypes/TdsDecimal.cs:
+ Copied over from the Sybase classes because the
+ whole world is changing and I want generic
+ TDS to keep up.
+
2002-11-21 Tim Coleman <tim@timcoleman.com>
* Mono.Data.TdsClient.build:
* Mono.Data.TdsClient/TdsCommand.cs:
<arg value="/unsafe"/>\r
<arg value="/noconfig"/>\r
<arg value="/r:System.dll"/>\r
+ <arg value="/r:System.EnterpriseServices.dll"/>\r
<arg value="/r:System.Xml.dll"/>\r
<arg value="/r:System.Data.dll"/>\r
<arg value="/r:../lib/Mono.Data.Tds.dll"/>\r
<references>\r
<includes name="../lib/corlib.dll"/>\r
<includes name="../lib/System.dll"/>\r
+ <includes name="../lib/System.EnterpriseServices.dll"/>\r
<includes name="../lib/System.Xml.dll"/>\r
<includes name="../lib/System.Data.dll"/>\r
<includes name="../lib/Mono.Data.Tds.dll"/>\r
// Mono.Data.TdsClient.TdsCommand.cs
//
// Author:
+// Rodrigo Moya (rodrigo@ximian.com)
+// Daniel Morgan (danmorg@sc.rr.com)
// Tim Coleman (tim@timcoleman.com)
//
-// Copyright (C) 2002 Tim Coleman
+// (C) Ximian, Inc 2002 http://www.ximian.com/
+// (C) Daniel Morgan, 2002
+// Copyright (C) Tim Coleman, 2002
//
+using Mono.Data.Tds;
using Mono.Data.Tds.Protocol;
using System;
+using System.Collections;
+using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
+using System.Data.Common;
+using System.Runtime.InteropServices;
+using System.Text;
namespace Mono.Data.TdsClient {
- public class TdsCommand : Component, ICloneable, IDbCommand
+ public sealed class TdsCommand : Component, IDbCommand, ICloneable
{
#region Fields
- string commandText;
+ bool disposed = false;
int commandTimeout;
+ bool designTimeVisible;
+ string commandText;
CommandType commandType;
TdsConnection connection;
- TdsParameterCollection parameters;
TdsTransaction transaction;
+ UpdateRowSource updatedRowSource;
+ CommandBehavior behavior = CommandBehavior.Default;
+ TdsParameterCollection parameters;
#endregion // Fields
#region Constructors
- public TdsCommand ()
+ public TdsCommand()
: this (String.Empty, null, null)
{
}
- public TdsCommand (string commandText)
+ public TdsCommand (string commandText)
: this (commandText, null, null)
{
+ commandText = commandText;
}
- public TdsCommand (string commandText, TdsConnection connection)
+ public TdsCommand (string commandText, TdsConnection connection)
: this (commandText, connection, null)
{
+ Connection = connection;
}
- public TdsCommand (string commandText, TdsConnection connection, TdsTransaction transaction)
+ public TdsCommand (string commandText, TdsConnection connection, TdsTransaction transaction)
{
this.commandText = commandText;
+ this.connection = connection;
this.transaction = transaction;
this.commandType = CommandType.Text;
- this.connection = connection;
+ this.updatedRowSource = UpdateRowSource.Both;
+
+ this.designTimeVisible = false;
+ this.commandTimeout = 30;
+ parameters = new TdsParameterCollection (this);
}
#endregion // Constructors
#region Properties
+ internal CommandBehavior CommandBehavior {
+ get { return behavior; }
+ }
+
public string CommandText {
get { return commandText; }
set { commandText = value; }
}
public int CommandTimeout {
- get { return commandTimeout; }
- set { commandTimeout = value; }
+ get { return commandTimeout; }
+ set {
+ if (commandTimeout < 0)
+ throw new ArgumentException ("The property value assigned is less than 0.");
+ commandTimeout = value;
+ }
}
- public CommandType CommandType {
+ public CommandType CommandType {
get { return commandType; }
- set { commandType = value; }
+ set {
+ if (value == CommandType.TableDirect)
+ throw new ArgumentException ("CommandType.TableDirect is not supported by the Mono TdsClient Data Provider.");
+ commandType = value;
+ }
}
- public TdsConnection Connection {
+ public TdsConnection Connection {
get { return connection; }
set {
if (transaction != null && connection.Transaction != null && connection.Transaction.IsOpen)
throw new InvalidOperationException ("The Connection property was changed while a transaction was in progress.");
transaction = null;
- connection = value;
+ connection = value;
}
}
+ public bool DesignTimeVisible {
+ get { return designTimeVisible; }
+ set { designTimeVisible = value; }
+ }
+
+ public TdsParameterCollection Parameters {
+ get { return parameters; }
+ }
+
+ internal ITds Tds {
+ get { return Connection.Tds; }
+ }
+
IDbConnection IDbCommand.Connection {
get { return Connection; }
set {
- if (!(value is TdsConnection))
- throw new ArgumentException ();
- Connection = (TdsConnection) value;
+ if (!(value is TdsConnection))
+ throw new InvalidCastException ("The value was not a valid TdsConnection.");
+ Connection = (TdsConnection) value;
}
}
- IDataParameterCollection IDbCommand.Parameters {
+ IDataParameterCollection IDbCommand.Parameters {
get { return Parameters; }
}
IDbTransaction IDbCommand.Transaction {
get { return Transaction; }
set {
- if (!(value is TdsTransaction))
+ if (!(value is TdsTransaction))
throw new ArgumentException ();
Transaction = (TdsTransaction) value;
}
}
- public TdsParameterCollection Parameters {
- get { return parameters; }
- }
-
- internal ITds Tds {
- get { return connection.Tds; }
- }
-
public TdsTransaction Transaction {
get { return transaction; }
set { transaction = value; }
+ }
+
+ public UpdateRowSource UpdatedRowSource {
+ get { return updatedRowSource; }
+ set { updatedRowSource = value; }
}
- [MonoTODO]
- public UpdateRowSource UpdatedRowSource {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ #endregion // Fields
+
+ #region Methods
+
+ public void Cancel ()
+ {
+ if (Connection == null || Connection.Tds == null)
+ return;
+ Connection.Tds.Cancel ();
}
- #endregion // Properties
+ internal void CloseDataReader (bool moreResults)
+ {
+ GetOutputParameters ();
+ Connection.DataReader = null;
+
+ if ((behavior & CommandBehavior.CloseConnection) != 0)
+ Connection.Close ();
+ }
- #region Methods
+ public TdsParameter CreateParameter ()
+ {
+ return new TdsParameter ();
+ }
- [MonoTODO]
- public void Cancel ()
+ internal void DeriveParameters ()
{
- throw new NotImplementedException ();
+ if (commandType != CommandType.StoredProcedure)
+ throw new InvalidOperationException (String.Format ("TdsCommand DeriveParameters only supports CommandType.StoredProcedure, not CommandType.{0}", commandType));
+ ValidateCommand ("DeriveParameters");
+
+ TdsParameterCollection localParameters = new TdsParameterCollection (this);
+ localParameters.Add ("@P1", TdsType.NVarChar, commandText.Length).Value = commandText;
+
+ string sql = "sp_procedure_params_rowset";
+
+ Connection.Tds.ExecProc (sql, localParameters.MetaParameters, 0, true);
+
+ TdsDataReader reader = new TdsDataReader (this);
+ parameters.Clear ();
+ object[] dbValues = new object[reader.FieldCount];
+
+ while (reader.Read ()) {
+ reader.GetValues (dbValues);
+ parameters.Add (new TdsParameter (dbValues));
+ }
+ reader.Close ();
}
- [MonoTODO]
- TdsParameter CreateParameter ()
+ private void Execute (CommandBehavior behavior, bool wantResults)
{
- throw new NotImplementedException ();
+ TdsMetaParameterCollection parms = Parameters.MetaParameters;
+ bool schemaOnly = ((CommandBehavior & CommandBehavior.SchemaOnly) > 0);
+ bool keyInfo = ((CommandBehavior & CommandBehavior.SchemaOnly) > 0);
+
+ StringBuilder sql1 = new StringBuilder ();
+ StringBuilder sql2 = new StringBuilder ();
+
+ if (schemaOnly || keyInfo)
+ sql1.Append ("SET FMTONLY OFF;");
+ if (keyInfo) {
+ sql1.Append ("SET NO_BROWSETABLE ON;");
+ sql2.Append ("SET NO_BROWSETABLE OFF;");
+ }
+ if (schemaOnly) {
+ sql1.Append ("SET FMTONLY ON;");
+ sql2.Append ("SET FMTONLY OFF;");
+ }
+
+ switch (CommandType) {
+ case CommandType.StoredProcedure:
+ if (keyInfo || schemaOnly)
+ Connection.Tds.Execute (sql1.ToString ());
+ Connection.Tds.ExecProc (CommandText, parms, CommandTimeout, wantResults);
+ if (keyInfo || schemaOnly)
+ Connection.Tds.Execute (sql2.ToString ());
+ break;
+ case CommandType.Text:
+ string sql = String.Format ("{0}{1}{2}", sql1.ToString (), CommandText, sql2.ToString ());
+ Connection.Tds.Execute (sql, parms, CommandTimeout, wantResults);
+ break;
+ }
}
public int ExecuteNonQuery ()
{
ValidateCommand ("ExecuteNonQuery");
- return connection.Tds.ExecuteNonQuery (FormatQuery (commandText, commandType));
+ int result = 0;
+
+ try {
+ Execute (CommandBehavior.Default, false);
+ }
+ catch (TdsTimeoutException e) {
+ throw TdsException.FromTdsInternalException ((TdsInternalException) e);
+ }
+
+ GetOutputParameters ();
+ return result;
}
public TdsDataReader ExecuteReader ()
public TdsDataReader ExecuteReader (CommandBehavior behavior)
{
ValidateCommand ("ExecuteReader");
- connection.DataReader = new TdsDataReader (this);
- return connection.DataReader;
+ try {
+ Execute (behavior, true);
+ }
+ catch (TdsTimeoutException e) {
+ throw TdsException.FromTdsInternalException ((TdsInternalException) e);
+ }
+ Connection.DataReader = new TdsDataReader (this);
+ return Connection.DataReader;
}
- [MonoTODO]
public object ExecuteScalar ()
{
- throw new NotImplementedException ();
+ ValidateCommand ("ExecuteScalar");
+ try {
+ Execute (CommandBehavior.Default, true);
+ }
+ catch (TdsTimeoutException e) {
+ throw TdsException.FromTdsInternalException ((TdsInternalException) e);
+ }
+
+ if (!Connection.Tds.NextResult () || !Connection.Tds.NextRow ())
+ return null;
+
+ object result = Connection.Tds.ColumnValues [0];
+ CloseDataReader (true);
+ return result;
}
- private static string FormatQuery (string commandText, CommandType commandType)
+ private void GetOutputParameters ()
{
- switch (commandType) {
- case CommandType.Text :
- return commandText;
- case CommandType.TableDirect :
- return String.Format ("select * from {0}", commandText);
- case CommandType.StoredProcedure :
- return String.Format ("exec {0}", commandText);
+ Connection.Tds.SkipToEnd ();
+
+ IList list = Connection.Tds.ColumnValues;
+
+ if (list != null && list.Count > 0) {
+ int index = 0;
+ foreach (TdsParameter parameter in parameters) {
+ if (parameter.Direction != ParameterDirection.Input) {
+ parameter.Value = list [index];
+ index += 1;
+ }
+ if (index >= list.Count)
+ break;
+ }
}
- throw new InvalidOperationException ("Invalid command type");
}
- [MonoTODO]
- object ICloneable.Clone()
- {
- throw new NotImplementedException ();
- }
+ object ICloneable.Clone ()
+ {
+ return new TdsCommand (commandText, Connection);
+ }
IDbDataParameter IDbCommand.CreateParameter ()
{
return ExecuteReader (behavior);
}
- [MonoTODO]
public void Prepare ()
{
- throw new NotImplementedException ();
+ throw new NotSupportedException ("TdsClient does not support PREPARE.");
+ }
+
+ public void ResetCommandTimeout ()
+ {
+ commandTimeout = 30;
}
private void ValidateCommand (string method)
{
- if (connection == null)
+ if (Connection == null)
throw new InvalidOperationException (String.Format ("{0} requires a Connection object to continue.", method));
- if (connection.Transaction != null && transaction != connection.Transaction)
+ if (Connection.Transaction != null && transaction != Connection.Transaction)
throw new InvalidOperationException ("The Connection object does not have the same transaction as the command object.");
- if (connection.State != ConnectionState.Open)
+ if (Connection.State != ConnectionState.Open)
throw new InvalidOperationException (String.Format ("ExecuteNonQuery requires an open Connection object to continue. This connection is closed.", method));
if (commandText == String.Empty || commandText == null)
throw new InvalidOperationException ("The command text for this Command has not been set.");
- if (connection.DataReader != null)
+ if (Connection.DataReader != null)
throw new InvalidOperationException ("There is already an open DataReader associated with this Connection which must be closed first.");
}
- #endregion // Methods
+ #endregion // Methods
}
}
// Author:
// Tim Coleman (tim@timcoleman.com)
//
-// Copyright (C) 2002 Tim Coleman
+// Copyright (C) Tim Coleman, 2002
//
using Mono.Data.Tds.Protocol;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
+using System.Data.Common;
+using System.EnterpriseServices;
using System.Net;
using System.Text;
namespace Mono.Data.TdsClient {
- public class TdsConnection : Component, ICloneable, IDbConnection
+ public sealed class TdsConnection : Component, IDbConnection, ICloneable
{
#region Fields
+ bool disposed = false;
- public static readonly string LibraryName = "Mono.Data.TdsClient";
+ // The set of SQL connection pools
+ static Hashtable TdsConnectionPools = new Hashtable ();
- string dataSource; // the database server name
- int port; // which port to use
- int packetSize = 512; // what size are the packets we send/receive?
- bool connectionReset;
- bool pooling;
- int minPoolSize;
- int maxPoolSize;
+ // The current connection pool
+ TdsConnectionPool pool;
+ // The connection string that identifies this connection
string connectionString = null;
- int connectionTimeout = 15;
- IsolationLevel isolationLevel = IsolationLevel.ReadCommitted;
-
- ConnectionState state = ConnectionState.Closed;
- TdsConnectionParameters parms = new TdsConnectionParameters ();
+ // The transaction object for the current transaction
TdsTransaction transaction = null;
- // This is the collection of connection pools available
- static Hashtable pools = new Hashtable ();
- TdsConnectionPool pool;
+ // Connection parameters
+ TdsConnectionParameters parms = new TdsConnectionParameters ();
+ bool connectionReset;
+ bool pooling;
+ string dataSource;
+ int connectionTimeout;
+ int minPoolSize;
+ int maxPoolSize;
+ int packetSize;
+ int port = 1533;
- // Our TDS object, the real workhorse
- ITds tds = null;
+ // The current state
+ ConnectionState state = ConnectionState.Closed;
TdsDataReader dataReader = null;
- static readonly object EventTdsInfoMessage = new object ();
- static readonly object EventStateChange = new object ();
+ // The TDS object
+ ITds tds;
#endregion // Fields
#region Constructors
- public TdsConnection ()
- : this (String.Empty, 1433)
+ public TdsConnection ()
+ : this (String.Empty)
{
}
-
- public TdsConnection (string connectionString)
- : this (connectionString, 1433)
+
+ public TdsConnection (string connectionString)
{
+ ConnectionString = connectionString;
}
- public TdsConnection (string connectionString, int port)
- {
- this.port = port;
- parms.User = null;
- parms.Password = null;
- parms.LibraryName = LibraryName;
- SetConnectionString (connectionString);
- }
-
#endregion // Constructors
#region Properties
-
- public string ConnectionString {
+
+ public string ConnectionString {
get { return connectionString; }
set { SetConnectionString (value); }
}
-
+
public int ConnectionTimeout {
get { return connectionTimeout; }
}
- public string Database {
+ public string Database {
get { return tds.Database; }
}
}
public string DataSource {
- get { return DataSource; }
+ get { return dataSource; }
}
public int PacketSize {
- get { return PacketSize; }
+ get { return packetSize; }
}
public string ServerVersion {
- get {
- if (state == ConnectionState.Closed)
- throw new InvalidOperationException ();
- return tds.ServerVersion;
- }
+ get { return tds.ServerVersion; }
}
public ConnectionState State {
get { return state; }
}
-
+
internal ITds Tds {
get { return tds; }
}
- internal TdsTransaction Transaction {
+ internal TdsTransaction Transaction {
get { return transaction; }
+ set { transaction = value; }
}
-
+
public string WorkstationId {
get { return parms.Hostname; }
}
#endregion // Properties
-
- #region Events
-
- public event TdsInfoMessageEventHandler InfoMessage {
- add { Events.AddHandler (EventTdsInfoMessage, value); }
- remove { Events.RemoveHandler (EventTdsInfoMessage, value); }
- }
-
- public event StateChangeEventHandler StateChange {
- add { Events.AddHandler (EventStateChange, value); }
- remove { Events.RemoveHandler (EventStateChange, value); }
- }
-
- #endregion // Events
-
- #region Delegates
+ #region Events and Delegates
+
+ public event TdsInfoMessageEventHandler InfoMessage;
+ public event StateChangeEventHandler StateChange;
+
private void ErrorHandler (object sender, TdsInternalErrorMessageEventArgs e)
{
throw new TdsException (e.Class, e.LineNumber, e.Message, e.Number, e.Procedure, e.Server, "Mono TdsClient Data Provider", e.State);
- }
+ }
private void MessageHandler (object sender, TdsInternalInfoMessageEventArgs e)
{
OnTdsInfoMessage (CreateTdsInfoMessageEvent (e.Errors));
}
- #endregion // Delegates
+ #endregion // Events and Delegates
#region Methods
public TdsTransaction BeginTransaction (IsolationLevel iso, string transactionName)
{
- if (state == ConnectionState.Closed)
- throw new InvalidOperationException ("Invalid operation. The connection is closed.");
- if (transaction != null && transaction.IsOpen)
+ if (State == ConnectionState.Closed)
+ throw new InvalidOperationException ("The connection is not open.");
+ if (Transaction != null)
throw new InvalidOperationException ("TdsConnection does not support parallel transactions.");
- tds.ExecuteNonQuery (String.Format ("BEGIN TRANSACTION {0}", transactionName));
+
+ string isolevel = String.Empty;
+ switch (iso) {
+ case IsolationLevel.Chaos:
+ isolevel = "CHAOS";
+ break;
+ case IsolationLevel.ReadCommitted:
+ isolevel = "READ COMMITTED";
+ break;
+ case IsolationLevel.ReadUncommitted:
+ isolevel = "READ UNCOMMITTED";
+ break;
+ case IsolationLevel.RepeatableRead:
+ isolevel = "REPEATABLE READ";
+ break;
+ case IsolationLevel.Serializable:
+ isolevel = "SERIALIZABLE";
+ break;
+ }
+
+ tds.Execute (String.Format ("SET TRANSACTION ISOLATION LEVEL {0}\nBEGIN TRANSACTION {1}", isolevel, transactionName));
transaction = new TdsTransaction (this, iso);
return transaction;
}
- public void ChangeDatabase (string database)
+ public void ChangeDatabase (string database)
{
if (!IsValidDatabaseName (database))
- throw new ArgumentException (String.Format ("The database name {0} is not valid.", database));
- if (Database == database)
- return;
- tds.ExecuteNonQuery (String.Format ("use {0}", database));
+ throw new ArgumentException (String.Format ("The database name {0} is not valid."));
+ if (State != ConnectionState.Open)
+ throw new InvalidOperationException ("The connection is not open");
+ tds.Execute (String.Format ("use {0}", database));
}
private void ChangeState (ConnectionState currentState)
OnStateChange (CreateStateChangeEvent (originalState, currentState));
}
- public void Close ()
+ public void Close ()
{
- // rollback any open transactions
- if (transaction != null && transaction.IsOpen)
- transaction.Rollback ();
-
- // if we aren't pooling, just close the connection
- // otherwise, relinquish the lock that we established in
- // the connection pool.
+ if (Transaction != null && Transaction.IsOpen)
+ Transaction.Rollback ();
if (pooling)
pool.ReleaseConnection (tds);
else
tds.Disconnect ();
-
tds.TdsErrorMessage -= new TdsInternalErrorMessageEventHandler (ErrorHandler);
tds.TdsInfoMessage -= new TdsInternalInfoMessageEventHandler (MessageHandler);
ChangeState (ConnectionState.Closed);
}
- [MonoTODO]
- protected override void Dispose (bool disposing)
- {
- Close ();
- }
-
- public TdsCommand CreateCommand ()
+ public TdsCommand CreateCommand ()
{
TdsCommand command = new TdsCommand ();
command.Connection = this;
return command;
}
+ private StateChangeEventArgs CreateStateChangeEvent (ConnectionState originalState, ConnectionState currentState)
+ {
+ return new StateChangeEventArgs (originalState, currentState);
+ }
+
private TdsInfoMessageEventArgs CreateTdsInfoMessageEvent (TdsInternalErrorCollection errors)
{
return new TdsInfoMessageEventArgs (errors);
}
- private StateChangeEventArgs CreateStateChangeEvent (ConnectionState originalState, ConnectionState currentState)
+ protected override void Dispose (bool disposing)
{
- return new StateChangeEventArgs (originalState, currentState);
+ if (!disposed) {
+ if (disposing) {
+ if (State == ConnectionState.Open)
+ Close ();
+ parms = null;
+ dataSource = null;
+ }
+ base.Dispose (disposing);
+ disposed = true;
+ }
}
- object ICloneable.Clone()
- {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ public void EnlistDistributedTransaction (ITransaction transaction)
+ {
+ throw new NotImplementedException ();
+ }
+
+ object ICloneable.Clone ()
+ {
+ return new TdsConnection (ConnectionString);
+ }
IDbTransaction IDbConnection.BeginTransaction ()
{
return BeginTransaction ();
}
- IDbTransaction IDbConnection.BeginTransaction (IsolationLevel il)
+ IDbTransaction IDbConnection.BeginTransaction (IsolationLevel iso)
{
- return BeginTransaction (il);
+ return BeginTransaction (iso);
}
IDbCommand IDbConnection.CreateCommand ()
return CreateCommand ();
}
- static bool IsValidDatabaseName (string database)
+ void IDisposable.Dispose ()
{
- if (database.Length > 32 || database.Length < 1)
- return false;
-
- if (database[0] == '"' && database[database.Length] == '"')
- database = database.Substring (1, database.Length - 2);
- else if (Char.IsDigit (database[0]))
- return false;
-
- if (database[0] == '_')
- return false;
-
- foreach (char c in database.Substring (1, database.Length - 1))
- if (!Char.IsLetterOrDigit (c) && c != '_')
- return false;
- return true;
+ Dispose (true);
+ GC.SuppressFinalize (this);
}
- public void Open ()
+ [MonoTODO ("Figure out the Tds way to reset the connection.")]
+ public void Open ()
{
if (connectionString == null)
- throw new InvalidOperationException ("The ConnectionString property has not been initialized.");
- if (parms.User == null)
- throw new ArgumentException ("User name is null.");
- if (parms.Password == null)
- throw new ArgumentException ("Password is null. This may be a bug with blank passwords.");
-
- if (!pooling)
- tds = new Tds42 (DataSource, port, PacketSize, ConnectionTimeout);
- else {
- pool = (TdsConnectionPool) pools[connectionString];
- if (pool == null) {
- lock (pools) {
+ throw new InvalidOperationException ("Connection string has not been initialized.");
+
+ try {
+ if (!pooling)
+ tds = new Tds42 (DataSource, port, PacketSize, ConnectionTimeout);
+ else {
+ pool = (TdsConnectionPool) TdsConnectionPools [connectionString];
+ if (pool == null) {
pool = new TdsConnectionPool (dataSource, port, packetSize, ConnectionTimeout, minPoolSize, maxPoolSize);
- pools[connectionString] = pool;
+ TdsConnectionPools [connectionString] = pool;
}
+ tds = pool.AllocateConnection ();
}
- tds = pool.AllocateConnection ();
+ }
+ catch (TdsTimeoutException e) {
+ throw TdsException.FromTdsInternalException ((TdsInternalException) e);
}
tds.TdsErrorMessage += new TdsInternalErrorMessageEventHandler (ErrorHandler);
if (!tds.IsConnected) {
tds.Connect (parms);
+ ChangeState (ConnectionState.Open);
ChangeDatabase (parms.Database);
}
-
- ChangeState (ConnectionState.Open);
- }
-
- [MonoTODO]
- private void SetConnectionString (string connectionString)
- {
- connectionString += ";";
- NameValueCollection parameters = new NameValueCollection ();
-
- if (connectionString == String.Empty)
- return;
-
- bool inQuote = false;
- bool inDQuote = false;
-
- string name = String.Empty;
- string value = String.Empty;
- StringBuilder sb = new StringBuilder ();
-
- foreach (char c in connectionString)
- {
- switch (c) {
- case '\'':
- inQuote = !inQuote;
- break;
- case '"' :
- inDQuote = !inDQuote;
- break;
- case ';' :
- if (!inDQuote && !inQuote) {
- value = sb.ToString ();
- parameters [name.ToUpper ().Trim ()] = value.Trim ();
- name = String.Empty;
- value = String.Empty;
- sb = new StringBuilder ();
- }
- else
- sb.Append (c);
- break;
- case '=' :
- if (!inDQuote && !inQuote) {
- name = sb.ToString ();
- sb = new StringBuilder ();
- }
- else
- sb.Append (c);
- break;
- default:
- sb.Append (c);
- break;
- }
+ else if (connectionReset) {
+ // tds.ExecuteNonQuery ("EXEC sp_reset_connection"); FIXME
+ ChangeState (ConnectionState.Open);
}
+ }
- if (this.ConnectionString == null)
- {
- SetDefaultConnectionParameters (parameters);
- }
+ void SetConnectionString (string connectionString)
+ {
+ connectionString += ";";
+ NameValueCollection parameters = new NameValueCollection ();
+
+ if (connectionString == String.Empty)
+ return;
+
+ bool inQuote = false;
+ bool inDQuote = false;
+
+ string name = String.Empty;
+ string value = String.Empty;
+ StringBuilder sb = new StringBuilder ();
+
+ foreach (char c in connectionString)
+ {
+ switch (c) {
+ case '\'':
+ inQuote = !inQuote;
+ break;
+ case '"' :
+ inDQuote = !inDQuote;
+ break;
+ case ';' :
+ if (!inDQuote && !inQuote) {
+ if (name != String.Empty && name != null) {
+ value = sb.ToString ();
+ parameters [name.ToUpper ().Trim ()] = value.Trim ();
+ }
+ name = String.Empty;
+ value = String.Empty;
+ sb = new StringBuilder ();
+ }
+ else
+ sb.Append (c);
+ break;
+ case '=' :
+ if (!inDQuote && !inQuote) {
+ name = sb.ToString ();
+ sb = new StringBuilder ();
+ }
+ else
+ sb.Append (c);
+ break;
+ default:
+ sb.Append (c);
+ break;
+ }
+ }
+
+ if (this.ConnectionString == null)
+ {
+ SetDefaultConnectionParameters (parameters);
+ }
+
+ SetProperties (parameters);
+
+ this.connectionString = connectionString;
+ }
- SetProperties (parameters);
+ void SetDefaultConnectionParameters (NameValueCollection parameters)
+ {
+ if (null == parameters.Get ("APPLICATION NAME"))
+ parameters["APPLICATION NAME"] = ".Net TdsClient Data Provider";
+ if (null == parameters.Get ("CONNECT TIMEOUT") && null == parameters.Get ("CONNECTION TIMEOUT"))
+ parameters["CONNECT TIMEOUT"] = "15";
+ if (null == parameters.Get ("CONNECTION LIFETIME"))
+ parameters["CONNECTION LIFETIME"] = "0";
+ if (null == parameters.Get ("CONNECTION RESET"))
+ parameters["CONNECTION RESET"] = "true";
+ if (null == parameters.Get ("ENLIST"))
+ parameters["ENLIST"] = "true";
+ if (null == parameters.Get ("INTEGRATED SECURITY") && null == parameters.Get ("TRUSTED_CONNECTION"))
+ parameters["INTEGRATED SECURITY"] = "false";
+ if (null == parameters.Get ("MAX POOL SIZE"))
+ parameters["MAX POOL SIZE"] = "100";
+ if (null == parameters.Get ("MIN POOL SIZE"))
+ parameters["MIN POOL SIZE"] = "0";
+ if (null == parameters.Get ("NETWORK LIBRARY") && null == parameters.Get ("NET"))
+ parameters["NETWORK LIBRARY"] = "dbmssocn";
+ if (null == parameters.Get ("PACKET SIZE"))
+ parameters["PACKET SIZE"] = "512";
+ if (null == parameters.Get ("PERSIST SECURITY INFO"))
+ parameters["PERSIST SECURITY INFO"] = "false";
+ if (null == parameters.Get ("POOLING"))
+ parameters["POOLING"] = "true";
+ if (null == parameters.Get ("WORKSTATION ID"))
+ parameters["WORKSTATION ID"] = Dns.GetHostByName ("localhost").HostName;
+ }
- this.connectionString = connectionString;
+ private void SetProperties (NameValueCollection parameters)
+ {
+ string value;
+ foreach (string name in parameters) {
+ value = parameters[name];
+
+ switch (name) {
+ case "APPLICATION NAME" :
+ parms.ApplicationName = value;
+ break;
+ case "ATTACHDBFILENAME" :
+ case "EXTENDED PROPERTIES" :
+ case "INITIAL FILE NAME" :
+ break;
+ case "CONNECT TIMEOUT" :
+ case "CONNECTION TIMEOUT" :
+ connectionTimeout = Int32.Parse (value);
+ break;
+ case "CONNECTION LIFETIME" :
+ break;
+ case "CONNECTION RESET" :
+ connectionReset = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
+ break;
+ case "CURRENT LANGUAGE" :
+ parms.Language = value;
+ break;
+ case "DATA SOURCE" :
+ case "SERVER" :
+ case "ADDRESS" :
+ case "ADDR" :
+ case "NETWORK ADDRESS" :
+ dataSource = value;
+ break;
+ case "ENLIST" :
+ break;
+ case "INITIAL CATALOG" :
+ case "DATABASE" :
+ parms.Database = value;
+ break;
+ case "INTEGRATED SECURITY" :
+ case "TRUSTED_CONNECTION" :
+ break;
+ case "MAX POOL SIZE" :
+ maxPoolSize = Int32.Parse (value);
+ break;
+ case "MIN POOL SIZE" :
+ minPoolSize = Int32.Parse (value);
+ break;
+ case "NET" :
+ case "NETWORK LIBRARY" :
+ if (!value.ToUpper ().Equals ("DBMSSOCN"))
+ throw new ArgumentException ("Unsupported network library.");
+ break;
+ case "PACKET SIZE" :
+ packetSize = Int32.Parse (value);
+ break;
+ case "PASSWORD" :
+ case "PWD" :
+ parms.Password = value;
+ break;
+ case "PERSIST SECURITY INFO" :
+ break;
+ case "POOLING" :
+ pooling = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
+ break;
+ case "USER ID" :
+ parms.User = value;
+ break;
+ case "WORKSTATION ID" :
+ parms.Hostname = value;
+ break;
+ }
+ }
}
- private void SetDefaultConnectionParameters (NameValueCollection parameters)
- {
- if (null == parameters.Get ("APPLICATION NAME"))
- parameters["APPLICATION NAME"] = ".Net SqlClient Data Provider";
- if (null == parameters.Get ("CONNECT TIMEOUT") && null == parameters.Get ("CONNECTION TIMEOUT"))
- parameters["CONNECT TIMEOUT"] = "15";
- if (null == parameters.Get ("CONNECTION LIFETIME"))
- parameters["CONNECTION LIFETIME"] = "0";
- if (null == parameters.Get ("CONNECTION RESET"))
- parameters["CONNECTION RESET"] = "true";
- if (null == parameters.Get ("ENLIST"))
- parameters["ENLIST"] = "true";
- if (null == parameters.Get ("INTEGRATED SECURITY") && null == parameters.Get ("TRUSTED_CONNECTION"))
- parameters["INTEGRATED SECURITY"] = "false";
- if (null == parameters.Get ("MAX POOL SIZE"))
- parameters["MAX POOL SIZE"] = "100";
- if (null == parameters.Get ("MIN POOL SIZE"))
- parameters["MIN POOL SIZE"] = "0";
- if (null == parameters.Get ("NETWORK LIBRARY") && null == parameters.Get ("NET"))
- parameters["NETWORK LIBRARY"] = "dbmssocn";
- if (null == parameters.Get ("PACKET SIZE"))
- parameters["PACKET SIZE"] = "512";
- if (null == parameters.Get ("PERSIST SECURITY INFO"))
- parameters["PERSIST SECURITY INFO"] = "false";
- if (null == parameters.Get ("POOLING"))
- parameters["POOLING"] = "true";
- if (null == parameters.Get ("WORKSTATION ID"))
- parameters["WORKSTATION ID"] = Dns.GetHostByName ("localhost").HostName;
- }
-
- private void SetProperties (NameValueCollection parameters)
+ static bool IsValidDatabaseName (string database)
{
- string value;
- foreach (string name in parameters) {
- value = parameters[name];
-
- switch (name) {
- case "APPLICATION NAME" :
- parms.ApplicationName = value;
- break;
- case "ATTACHDBFILENAME" :
- case "EXTENDED PROPERTIES" :
- case "INITIAL FILE NAME" :
- break;
- case "CONNECT TIMEOUT" :
- case "CONNECTION TIMEOUT" :
- connectionTimeout = Int32.Parse (value);
- break;
- case "CONNECTION LIFETIME" :
- break;
- case "CONNECTION RESET" :
- connectionReset = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
- break;
- case "CURRENT LANGUAGE" :
- parms.Language = value;
- break;
- case "DATA SOURCE" :
- case "SERVER" :
- case "ADDRESS" :
- case "ADDR" :
- case "NETWORK ADDRESS" :
- dataSource = value;
- break;
- case "ENLIST" :
- break;
- case "INITIAL CATALOG" :
- case "DATABASE" :
- parms.Database = value;
- break;
- case "INTEGRATED SECURITY" :
- case "TRUSTED_CONNECTION" :
- break;
- case "MAX POOL SIZE" :
- maxPoolSize = Int32.Parse (value);
- break;
- case "MIN POOL SIZE" :
- minPoolSize = Int32.Parse (value);
- break;
- case "NET" :
- case "NETWORK LIBRARY" :
- if (!value.ToUpper ().Equals ("DBMSSOCN"))
- throw new NotSupportedException ("Unsupported network library.");
- break;
- case "PACKET SIZE" :
- packetSize = Int32.Parse (value);
- break;
- case "PASSWORD" :
- case "PWD" :
- parms.Password = value;
- break;
- case "PERSIST SECURITY INFO" :
- break;
- case "POOLING" :
- pooling = !(value.ToUpper ().Equals ("FALSE") || value.ToUpper ().Equals ("NO"));
- break;
- case "USER ID" :
- parms.User = value;
- break;
- case "WORKSTATION ID" :
- parms.Hostname = value;
- break;
- }
- }
+ if (database.Length > 32 || database.Length < 1)
+ return false;
+
+ if (database[0] == '"' && database[database.Length] == '"')
+ database = database.Substring (1, database.Length - 2);
+ else if (Char.IsDigit (database[0]))
+ return false;
+
+ if (database[0] == '_')
+ return false;
+
+ foreach (char c in database.Substring (1, database.Length - 1))
+ if (!Char.IsLetterOrDigit (c) && c != '_')
+ return false;
+ return true;
}
private void OnTdsInfoMessage (TdsInfoMessageEventArgs value)
{
- TdsInfoMessageEventHandler handler = (TdsInfoMessageEventHandler) Events [EventTdsInfoMessage];
- if (handler != null)
- handler (this, value);
+ if (InfoMessage != null)
+ InfoMessage (this, value);
}
private void OnStateChange (StateChangeEventArgs value)
{
- StateChangeEventHandler handler = (StateChangeEventHandler) Events [EventStateChange];
- if (handler != null)
- handler (this, value);
+ if (StateChange != null)
+ StateChange (this, value);
}
#endregion // Methods
// Mono.Data.TdsClient.TdsDataReader.cs
//
// Author:
+// Rodrigo Moya (rodrigo@ximian.com)
+// Daniel Morgan (danmorg@sc.rr.com)
// Tim Coleman (tim@timcoleman.com)
//
-// Copyright (C) 2002 Tim Coleman
+// (C) Ximian, Inc 2002
+// (C) Daniel Morgan 2002
+// Copyright (C) Tim Coleman, 2002
//
+using Mono.Data.TdsTypes;
using Mono.Data.Tds.Protocol;
using System;
using System.Collections;
using System.Data.Common;
namespace Mono.Data.TdsClient {
- public class TdsDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
+ public sealed class TdsDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
{
#region Fields
+ TdsCommand command;
+ ArrayList dataTypeNames;
+ bool disposed = false;
int fieldCount;
- bool hasRows;
bool isClosed;
- int recordsAffected;
+ bool isSelect;
bool moreResults;
-
- ArrayList dataTypeNames;
- ArrayList dataTypes;
-
- TdsCommand command;
-
- DataTable schemaTable = ConstructSchemaTable ();
+ int resultsRead;
+ int rowsRead;
+ DataTable schemaTable;
#endregion // Fields
internal TdsDataReader (TdsCommand command)
{
this.command = command;
- this.fieldCount = 0;
- this.isClosed = false;
+ schemaTable = ConstructSchemaTable ();
+ resultsRead = 0;
+ fieldCount = 0;
+ isClosed = false;
+ isSelect = (command.CommandText.Trim ().ToUpper ().StartsWith ("SELECT"));
+ command.Tds.RecordsAffected = 0;
NextResult ();
}
get { return fieldCount; }
}
- public bool HasRows {
- get { return hasRows; }
- }
-
public bool IsClosed {
get { return isClosed; }
}
}
public int RecordsAffected {
- get { return recordsAffected; }
+ get {
+ if (isSelect)
+ return -1;
+ else
+ return command.Tds.RecordsAffected;
+ }
}
#endregion // Properties
- #region Methods
+ #region Methods
- [MonoTODO]
public void Close ()
{
isClosed = true;
-
- throw new NotImplementedException ();
+ command.CloseDataReader (moreResults);
}
private static DataTable ConstructSchemaTable ()
Type stringType = Type.GetType ("System.String");
Type intType = Type.GetType ("System.Int32");
Type typeType = Type.GetType ("System.Type");
+ Type shortType = Type.GetType ("System.Int16");
DataTable schemaTable = new DataTable ("SchemaTable");
schemaTable.Columns.Add ("ColumnName", stringType);
schemaTable.Columns.Add ("ColumnOrdinal", intType);
schemaTable.Columns.Add ("ColumnSize", intType);
- schemaTable.Columns.Add ("NumericPrecision", intType);
- schemaTable.Columns.Add ("NumericScale", intType);
+ schemaTable.Columns.Add ("NumericPrecision", shortType);
+ schemaTable.Columns.Add ("NumericScale", shortType);
schemaTable.Columns.Add ("IsUnique", booleanType);
schemaTable.Columns.Add ("IsKey", booleanType);
schemaTable.Columns.Add ("BaseServerName", stringType);
schemaTable.Columns.Add ("BaseTableName", stringType);
schemaTable.Columns.Add ("DataType", typeType);
schemaTable.Columns.Add ("AllowDBNull", booleanType);
- schemaTable.Columns.Add ("ProviderType", booleanType);
+ schemaTable.Columns.Add ("ProviderType", intType);
schemaTable.Columns.Add ("IsAliased", booleanType);
schemaTable.Columns.Add ("IsExpression", booleanType);
schemaTable.Columns.Add ("IsIdentity", booleanType);
return schemaTable;
}
- [MonoTODO]
+ private void Dispose (bool disposing)
+ {
+ if (!disposed) {
+ if (disposing) {
+ schemaTable.Dispose ();
+ Close ();
+ }
+ disposed = true;
+ }
+ }
+
public bool GetBoolean (int i)
{
- throw new NotImplementedException ();
+ object value = GetValue (i);
+ if (!(value is bool))
+ throw new InvalidCastException ();
+ return (bool) value;
}
- [MonoTODO]
public byte GetByte (int i)
{
- throw new NotImplementedException ();
+ object value = GetValue (i);
+ if (!(value is byte))
+ throw new InvalidCastException ();
+ return (byte) value;
}
- [MonoTODO]
public long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
{
- throw new NotImplementedException ();
+ object value = GetValue (i);
+ if (!(value is byte []))
+ throw new InvalidCastException ();
+ Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
+ return ((byte []) value).Length - dataIndex;
}
- [MonoTODO]
public char GetChar (int i)
{
- throw new NotImplementedException ();
+ object value = GetValue (i);
+ if (!(value is char))
+ throw new InvalidCastException ();
+ return (char) value;
}
- [MonoTODO]
public long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
{
- throw new NotImplementedException ();
+ object value = GetValue (i);
+ if (!(value is char[]))
+ throw new InvalidCastException ();
+ Array.Copy ((char []) value, (int) dataIndex, buffer, bufferIndex, length);
+ return ((char []) value).Length - dataIndex;
}
- [MonoTODO]
+ [MonoTODO ("Implement GetData")]
public IDataReader GetData (int i)
{
- throw new NotImplementedException ();
+ throw new NotImplementedException ();
}
- [MonoTODO]
public string GetDataTypeName (int i)
{
- throw new NotImplementedException ();
+ return (string) dataTypeNames [i];
}
public DateTime GetDateTime (int i)
public Type GetFieldType (int i)
{
- return GetValue (i).GetType ();
+ return (Type) schemaTable.Rows[i]["DataType"];
}
public float GetFloat (int i)
return (float) value;
}
- [MonoTODO]
public Guid GetGuid (int i)
{
- throw new NotImplementedException ();
+ object value = GetValue (i);
+ if (!(value is Guid))
+ throw new InvalidCastException ();
+ return (Guid) value;
}
public short GetInt16 (int i)
return (string) schemaTable.Rows[i]["ColumnName"];
}
- [MonoTODO]
public int GetOrdinal (string name)
{
- foreach (DataRow schemaRow in schemaTable.Rows)
+ foreach (DataRow schemaRow in schemaTable.Rows)
if (((string) schemaRow ["ColumnName"]).Equals (name))
return (int) schemaRow ["ColumnOrdinal"];
- foreach (DataRow schemaRow in schemaTable.Rows)
+ foreach (DataRow schemaRow in schemaTable.Rows)
if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
return (int) schemaRow ["ColumnOrdinal"];
throw new IndexOutOfRangeException ();
fieldCount = 0;
dataTypeNames = new ArrayList ();
- dataTypes = new ArrayList ();
foreach (TdsSchemaInfo schema in command.Tds.Schema) {
DataRow row = schemaTable.NewRow ();
row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
- row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
+ row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
+ // We don't always get the base column name.
+ if (row ["BaseColumnName"] == DBNull.Value)
+ row ["BaseColumnName"] = row ["ColumnName"];
+
switch ((TdsColumnType) schema ["ColumnType"]) {
- case TdsColumnType.Image :
- dataTypeNames.Add ("image");
- row ["ProviderType"] = (int) TdsType.Image;
- row ["DataType"] = typeof (byte[]);
- row ["IsLong"] = true;
- break;
- case TdsColumnType.Text :
- dataTypes.Add (typeof (string));
- dataTypeNames.Add ("text");
- row ["ProviderType"] = (int) TdsType.Text;
- row ["DataType"] = typeof (string);
- row ["IsLong"] = true;
- break;
- case TdsColumnType.UniqueIdentifier :
- dataTypeNames.Add ("uniqueidentifier");
- row ["ProviderType"] = (int) TdsType.UniqueIdentifier;
- row ["DataType"] = typeof (Guid);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.VarBinary :
- case TdsColumnType.BigVarBinary :
- dataTypeNames.Add ("varbinary");
- row ["ProviderType"] = (int) TdsType.VarBinary;
- row ["DataType"] = typeof (byte[]);
- row ["IsLong"] = true;
- break;
- case TdsColumnType.IntN :
- case TdsColumnType.Int4 :
- dataTypeNames.Add ("int");
- row ["ProviderType"] = (int) TdsType.Int;
- row ["DataType"] = typeof (int);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.VarChar :
- case TdsColumnType.BigVarChar :
- dataTypeNames.Add ("varchar");
- row ["ProviderType"] = (int) TdsType.VarChar;
- row ["DataType"] = typeof (string);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Binary :
- case TdsColumnType.BigBinary :
- dataTypeNames.Add ("binary");
- row ["ProviderType"] = (int) TdsType.Binary;
- row ["DataType"] = typeof (byte[]);
- row ["IsLong"] = true;
- break;
- case TdsColumnType.Char :
- case TdsColumnType.BigChar :
- dataTypeNames.Add ("char");
- row ["ProviderType"] = (int) TdsType.Char;
- row ["DataType"] = typeof (string);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Int1 :
- dataTypeNames.Add ("tinyint");
- row ["ProviderType"] = (int) TdsType.TinyInt;
- row ["DataType"] = typeof (byte);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Bit :
- case TdsColumnType.BitN :
- dataTypeNames.Add ("bit");
- row ["ProviderType"] = (int) TdsType.Bit;
- row ["DataType"] = typeof (bool);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Int2 :
- dataTypeNames.Add ("smallint");
- row ["ProviderType"] = (int) TdsType.SmallInt;
- row ["DataType"] = typeof (short);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.DateTime4 :
- case TdsColumnType.DateTime :
- case TdsColumnType.DateTimeN :
- dataTypeNames.Add ("datetime");
- row ["ProviderType"] = (int) TdsType.DateTime;
- row ["DataType"] = typeof (DateTime);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Real :
- dataTypeNames.Add ("real");
- row ["ProviderType"] = (int) TdsType.Real;
- row ["DataType"] = typeof (float);
- break;
- case TdsColumnType.Money :
- case TdsColumnType.MoneyN :
- case TdsColumnType.Money4 :
- dataTypeNames.Add ("money");
- row ["ProviderType"] = (int) TdsType.Money;
- row ["DataType"] = typeof (decimal);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Float8 :
- case TdsColumnType.FloatN :
- dataTypeNames.Add ("float");
- row ["ProviderType"] = (int) TdsType.Float;
- row ["DataType"] = typeof (double);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.NText :
- dataTypeNames.Add ("ntext");
- row ["ProviderType"] = (int) TdsType.NText;
- row ["DataType"] = typeof (string);
- row ["IsLong"] = true;
- break;
- case TdsColumnType.NVarChar :
- dataTypeNames.Add ("nvarchar");
- row ["ProviderType"] = (int) TdsType.NVarChar;
- row ["DataType"] = typeof (string);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.Decimal :
- case TdsColumnType.Numeric :
- dataTypeNames.Add ("decimal");
- row ["ProviderType"] = (int) TdsType.Decimal;
- row ["DataType"] = typeof (decimal);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.NChar :
- dataTypeNames.Add ("nchar");
- row ["ProviderType"] = (int) TdsType.Char;
- row ["DataType"] = typeof (string);
- row ["IsLong"] = false;
- break;
- case TdsColumnType.SmallMoney :
- dataTypeNames.Add ("smallmoney");
- row ["ProviderType"] = (int) TdsType.SmallMoney;
- row ["DataType"] = typeof (decimal);
- row ["IsLong"] = false;
- break;
- default :
- dataTypeNames.Add ("variant");
- row ["ProviderType"] = (int) TdsType.Variant;
- row ["DataType"] = typeof (object);
- row ["IsLong"] = false;
- break;
+ case TdsColumnType.Image :
+ dataTypeNames.Add ("image");
+ row ["ProviderType"] = (int) TdsType.Image;
+ row ["DataType"] = typeof (byte[]);
+ row ["IsLong"] = true;
+ break;
+ case TdsColumnType.Text :
+ dataTypeNames.Add ("text");
+ row ["ProviderType"] = (int) TdsType.Text;
+ row ["DataType"] = typeof (string);
+ row ["IsLong"] = true;
+ break;
+ case TdsColumnType.UniqueIdentifier :
+ dataTypeNames.Add ("uniqueidentifier");
+ row ["ProviderType"] = (int) TdsType.UniqueIdentifier;
+ row ["DataType"] = typeof (Guid);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.VarBinary :
+ case TdsColumnType.BigVarBinary :
+ dataTypeNames.Add ("varbinary");
+ row ["ProviderType"] = (int) TdsType.VarBinary;
+ row ["DataType"] = typeof (byte[]);
+ row ["IsLong"] = true;
+ break;
+ case TdsColumnType.IntN :
+ case TdsColumnType.Int4 :
+ dataTypeNames.Add ("int");
+ row ["ProviderType"] = (int) TdsType.Int;
+ row ["DataType"] = typeof (int);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.VarChar :
+ case TdsColumnType.BigVarChar :
+ dataTypeNames.Add ("varchar");
+ row ["ProviderType"] = (int) TdsType.VarChar;
+ row ["DataType"] = typeof (string);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Binary :
+ case TdsColumnType.BigBinary :
+ dataTypeNames.Add ("binary");
+ row ["ProviderType"] = (int) TdsType.Binary;
+ row ["DataType"] = typeof (byte[]);
+ row ["IsLong"] = true;
+ break;
+ case TdsColumnType.Char :
+ case TdsColumnType.BigChar :
+ dataTypeNames.Add ("char");
+ row ["ProviderType"] = (int) TdsType.Char;
+ row ["DataType"] = typeof (string);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Int1 :
+ dataTypeNames.Add ("tinyint");
+ row ["ProviderType"] = (int) TdsType.TinyInt;
+ row ["DataType"] = typeof (byte);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Bit :
+ case TdsColumnType.BitN :
+ dataTypeNames.Add ("bit");
+ row ["ProviderType"] = (int) TdsType.Bit;
+ row ["DataType"] = typeof (bool);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Int2 :
+ dataTypeNames.Add ("smallint");
+ row ["ProviderType"] = (int) TdsType.SmallInt;
+ row ["DataType"] = typeof (short);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.DateTime4 :
+ case TdsColumnType.DateTime :
+ case TdsColumnType.DateTimeN :
+ dataTypeNames.Add ("datetime");
+ row ["ProviderType"] = (int) TdsType.DateTime;
+ row ["DataType"] = typeof (DateTime);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Real :
+ dataTypeNames.Add ("real");
+ row ["ProviderType"] = (int) TdsType.Real;
+ row ["DataType"] = typeof (float);
+ break;
+ case TdsColumnType.Money :
+ case TdsColumnType.MoneyN :
+ case TdsColumnType.Money4 :
+ dataTypeNames.Add ("money");
+ row ["ProviderType"] = (int) TdsType.Money;
+ row ["DataType"] = typeof (decimal);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Float8 :
+ case TdsColumnType.FloatN :
+ dataTypeNames.Add ("float");
+ row ["ProviderType"] = (int) TdsType.Float;
+ row ["DataType"] = typeof (double);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.NText :
+ dataTypeNames.Add ("ntext");
+ row ["ProviderType"] = (int) TdsType.NText;
+ row ["DataType"] = typeof (string);
+ row ["IsLong"] = true;
+ break;
+ case TdsColumnType.NVarChar :
+ dataTypeNames.Add ("nvarchar");
+ row ["ProviderType"] = (int) TdsType.NVarChar;
+ row ["DataType"] = typeof (string);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.Decimal :
+ case TdsColumnType.Numeric :
+ dataTypeNames.Add ("decimal");
+ row ["ProviderType"] = (int) TdsType.Decimal;
+ row ["DataType"] = typeof (decimal);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.NChar :
+ dataTypeNames.Add ("nchar");
+ row ["ProviderType"] = (int) TdsType.NChar;
+ row ["DataType"] = typeof (string);
+ row ["IsLong"] = false;
+ break;
+ case TdsColumnType.SmallMoney :
+ dataTypeNames.Add ("smallmoney");
+ row ["ProviderType"] = (int) TdsType.SmallMoney;
+ row ["DataType"] = typeof (decimal);
+ row ["IsLong"] = false;
+ break;
+ default :
+ dataTypeNames.Add ("variant");
+ row ["ProviderType"] = (int) TdsType.Variant;
+ row ["DataType"] = typeof (object);
+ row ["IsLong"] = false;
+ break;
}
schemaTable.Rows.Add (row);
fieldCount += 1;
}
return schemaTable;
- }
+ }
private static object GetSchemaValue (TdsSchemaInfo schema, object key)
{
return DBNull.Value;
}
+ public TdsBinary GetTdsBinary (int i)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TdsBoolean GetTdsBoolean (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsBoolean))
+ throw new InvalidCastException ();
+ return (TdsBoolean) value;
+ }
+
+ public TdsByte GetTdsByte (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsByte))
+ throw new InvalidCastException ();
+ return (TdsByte) value;
+ }
+
+ public TdsDateTime GetTdsDateTime (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsDateTime))
+ throw new InvalidCastException ();
+ return (TdsDateTime) value;
+ }
+
+ public TdsDecimal GetTdsDecimal (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsDecimal))
+ throw new InvalidCastException ();
+ return (TdsDecimal) value;
+ }
+
+ public TdsDouble GetTdsDouble (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsDouble))
+ throw new InvalidCastException ();
+ return (TdsDouble) value;
+ }
+
+ public TdsGuid GetTdsGuid (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsGuid))
+ throw new InvalidCastException ();
+ return (TdsGuid) value;
+ }
+
+ public TdsInt16 GetTdsInt16 (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsInt16))
+ throw new InvalidCastException ();
+ return (TdsInt16) value;
+ }
+
+ public TdsInt32 GetTdsInt32 (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsInt32))
+ throw new InvalidCastException ();
+ return (TdsInt32) value;
+ }
+
+ public TdsInt64 GetTdsInt64 (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsInt64))
+ throw new InvalidCastException ();
+ return (TdsInt64) value;
+ }
+
+ public TdsMoney GetTdsMoney (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsMoney))
+ throw new InvalidCastException ();
+ return (TdsMoney) value;
+ }
+
+ public TdsSingle GetTdsSingle (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsSingle))
+ throw new InvalidCastException ();
+ return (TdsSingle) value;
+ }
+
+ public TdsString GetTdsString (int i)
+ {
+ object value = GetTdsValue (i);
+ if (!(value is TdsString))
+ throw new InvalidCastException ();
+ return (TdsString) value;
+ }
+
+ [MonoTODO ("Implement TdsBigDecimal conversion. TdsType.Real fails tests?")]
+ public object GetTdsValue (int i)
+ {
+ TdsType type = (TdsType) (schemaTable.Rows [i]["ProviderType"]);
+ object value = GetValue (i);
+
+ switch (type) {
+ case TdsType.BigInt:
+ if (value == null)
+ return TdsInt64.Null;
+ return (TdsInt64) ((long) value);
+ case TdsType.Binary:
+ case TdsType.Image:
+ case TdsType.VarBinary:
+ case TdsType.Timestamp:
+ if (value == null)
+ return TdsBinary.Null;
+ return (TdsBinary) ((byte[]) value);
+ case TdsType.Bit:
+ if (value == null)
+ return TdsBoolean.Null;
+ return (TdsBoolean) ((bool) value);
+ case TdsType.Char:
+ case TdsType.NChar:
+ case TdsType.NText:
+ case TdsType.NVarChar:
+ case TdsType.Text:
+ case TdsType.VarChar:
+ if (value == null)
+ return TdsString.Null;
+ return (TdsString) ((string) value);
+ case TdsType.DateTime:
+ case TdsType.SmallDateTime:
+ if (value == null)
+ return TdsDateTime.Null;
+ return (TdsDateTime) ((DateTime) value);
+ case TdsType.Decimal:
+ if (value == null)
+ return TdsDecimal.Null;
+ if (value is TdsBigDecimal)
+ return TdsDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
+ return (TdsDecimal) ((decimal) value);
+ case TdsType.Float:
+ if (value == null)
+ return TdsDouble.Null;
+ return (TdsDouble) ((double) value);
+ case TdsType.Int:
+ if (value == null)
+ return TdsInt32.Null;
+ return (TdsInt32) ((int) value);
+ case TdsType.Money:
+ case TdsType.SmallMoney:
+ if (value == null)
+ return TdsMoney.Null;
+ return (TdsMoney) ((decimal) value);
+ case TdsType.Real:
+ if (value == null)
+ return TdsSingle.Null;
+ return (TdsSingle) ((float) value);
+ case TdsType.UniqueIdentifier:
+ if (value == null)
+ return TdsGuid.Null;
+ return (TdsGuid) ((Guid) value);
+ case TdsType.SmallInt:
+ if (value == null)
+ return TdsInt16.Null;
+ return (TdsInt16) ((short) value);
+ case TdsType.TinyInt:
+ if (value == null)
+ return TdsByte.Null;
+ return (TdsByte) ((byte) value);
+ }
+
+ throw new InvalidOperationException ("The type of this column is unknown.");
+ }
+
+ public int GetTdsValues (object[] values)
+ {
+ int count = 0;
+ int columnCount = schemaTable.Rows.Count;
+ int arrayCount = values.Length;
+
+ if (arrayCount > columnCount)
+ count = columnCount;
+ else
+ count = arrayCount;
+
+ for (int i = 0; i < count; i += 1)
+ values [i] = GetTdsValue (i);
+
+ return count;
+ }
+
public string GetString (int i)
{
object value = GetValue (i);
public object GetValue (int i)
{
- return command.Tds.ColumnValues[i];
+ return command.Tds.ColumnValues [i];
}
public int GetValues (object[] values)
{
int len = values.Length;
+ int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
+
+ // If a four-byte decimal is stored, then we can't convert to
+ // a native type. Throw an OverflowException.
+ if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
+ throw new OverflowException ();
+
command.Tds.ColumnValues.CopyTo (0, values, 0, len);
return (len > FieldCount ? len : FieldCount);
}
- [MonoTODO]
void IDisposable.Dispose ()
{
- throw new NotImplementedException ();
+ Dispose (true);
+ GC.SuppressFinalize (this);
}
- [MonoTODO]
IEnumerator IEnumerable.GetEnumerator ()
{
- throw new NotImplementedException ();
+ return new DbEnumerator (this);
}
- [MonoTODO]
public bool IsDBNull (int i)
{
- throw new NotImplementedException ();
+ return GetValue (i) == null;
}
public bool NextResult ()
{
+ if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
+ return false;
+ if (command.Tds.DoneProc)
+ return false;
+
schemaTable.Rows.Clear ();
- return command.Tds.NextResult ();
+
+ moreResults = command.Tds.NextResult ();
+ GetSchemaTable ();
+
+ rowsRead = 0;
+ resultsRead += 1;
+ return moreResults;
}
public bool Read ()
{
- return command.Tds.NextRow ();
+ if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
+ return false;
+ if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
+ return false;
+ if (!moreResults)
+ return false;
+
+ bool result = command.Tds.NextRow ();
+
+ rowsRead += 1;
+
+ return result;
}
- #endregion // Methods
+ #endregion // Methods
}
}
// Author:
// Tim Coleman (tim@timcoleman.com)
//
-// Copyright (C) 2002 Tim Coleman
+// Copyright (C) Tim Coleman, 2002
//
using Mono.Data.Tds.Protocol;
using System;
+using System.Data;
using System.Runtime.Serialization;
+using System.Text;
namespace Mono.Data.TdsClient {
- public class TdsException : SystemException
+ [Serializable]
+ public sealed class TdsException : SystemException
{
#region Fields
- byte theClass;
- TdsErrorCollection errors;
- int lineNumber;
- string message;
- int number;
- string procedure;
- string server;
- string source;
- byte state;
+ TdsErrorCollection errors;
- #endregion // Fields
+ #endregion Fields
#region Constructors
- internal TdsException ()
- : base ("a TDS Exception has occurred.")
+ internal TdsException ()
+ : base ("a SQL Exception has occurred.")
{
errors = new TdsErrorCollection();
}
- internal TdsException (byte theClass, int lineNumber, string message, int number, string procedure, string server, string source, byte state)
- : base (message)
+ internal TdsException (byte theClass, int lineNumber, string message, int number, string procedure, string server, string source, byte state)
+ : base (message)
{
errors = new TdsErrorCollection (theClass, lineNumber, message, number, procedure, server, source, state);
}
#region Properties
public byte Class {
- get { return theClass; }
+ get { return errors [0].Class; }
}
public TdsErrorCollection Errors {
}
public int LineNumber {
- get { return lineNumber; }
+ get { return errors [0].LineNumber; }
}
-
- public override string Message {
- get { return message; }
+
+ public override string Message {
+ get {
+ StringBuilder result = new StringBuilder ();
+ foreach (TdsError error in Errors) {
+ if (result.Length > 0)
+ result.Append ('\n');
+ result.Append (error.Message);
+ }
+ return result.ToString ();
+ }
}
-
+
public int Number {
- get { return number; }
+ get { return errors [0].Number; }
}
-
+
public string Procedure {
- get { return procedure; }
+ get { return errors [0].Procedure; }
}
public string Server {
- get { return server; }
+ get { return errors [0].Server; }
}
-
+
public override string Source {
- get { return source; }
+ get { return errors [0].Source; }
}
public byte State {
- get { return state; }
+ get { return errors [0].State; }
}
#endregion // Properties
#region Methods
[MonoTODO]
- public override void GetObjectData (SerializationInfo si, StreamingContext context)
+ public override void GetObjectData (SerializationInfo si, StreamingContext context)
{
throw new NotImplementedException ();
}
+ internal static TdsException FromTdsInternalException (TdsInternalException e)
+ {
+ return new TdsException (e.Class, e.LineNumber, e.Message, e.Number, e.Procedure, e.Server, "Mono TdsClient Data Provider", e.State);
+ }
+
#endregion // Methods
}
}
// Mono.Data.TdsClient.TdsParameter.cs
//
// Author:
+// Rodrigo Moya (rodrigo@ximian.com)
+// Daniel Morgan (danmorg@sc.rr.com)
// Tim Coleman (tim@timcoleman.com)
//
+// (C) Ximian, Inc. 2002
// Copyright (C) Tim Coleman, 2002
//
+using Mono.Data.Tds;
+using Mono.Data.Tds.Protocol;
using System;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Runtime.InteropServices;
+using System.Text;
namespace Mono.Data.TdsClient {
- public sealed class TdsParameter : IDbDataParameter, IDataParameter
+ public sealed class TdsParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
{
#region Fields
+ TdsMetaParameter metaParameter;
+
+ TdsParameterCollection container = null;
DbType dbType;
- ParameterDirection direction;
+ ParameterDirection direction = ParameterDirection.Input;
bool isNullable;
+ bool isSizeSet = false;
+ bool isTypeSet = false;
int offset;
- string parameterName;
- object objectValue;
+ TdsType sybaseType;
string sourceColumn;
DataRowVersion sourceVersion;
- byte precision;
- byte scale;
- int size;
#endregion // Fields
#region Constructors
- public TdsParameter ()
+ public TdsParameter ()
+ : this (String.Empty, TdsType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
+ {
+ }
+
+ public TdsParameter (string parameterName, object value)
+ {
+ metaParameter = new TdsMetaParameter (parameterName, value);
+ this.sourceVersion = DataRowVersion.Current;
+ InferTdsType (value);
+ }
+
+ public TdsParameter (string parameterName, TdsType dbType)
+ : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
+ {
+ }
+
+ public TdsParameter (string parameterName, TdsType dbType, int size)
+ : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
+ {
+ }
+
+ public TdsParameter (string parameterName, TdsType dbType, int size, string sourceColumn)
+ : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
+ {
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ public TdsParameter (string parameterName, TdsType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
{
+ metaParameter = new TdsMetaParameter (parameterName, size, isNullable, precision, scale, value);
+
+ TdsType = dbType;
+ Direction = direction;
+ SourceColumn = sourceColumn;
+ SourceVersion = sourceVersion;
}
- public TdsParameter (string parameterName, object value)
+ // This constructor is used internally to construct a
+ // TdsParameter. The value array comes from sp_procedure_params_rowset.
+ // This is in TdsCommand.DeriveParameters.
+ internal TdsParameter (object[] dbValues)
{
- this.parameterName = parameterName;
- this.objectValue = value;
+ Precision = 0;
+ Scale = 0;
+ Direction = ParameterDirection.Input;
+
+ ParameterName = (string) dbValues[3];
+
+ switch ((short) dbValues[5]) {
+ case 1:
+ Direction = ParameterDirection.Input;
+ break;
+ case 2:
+ Direction = ParameterDirection.Output;
+ break;
+ case 3:
+ Direction = ParameterDirection.InputOutput;
+ break;
+ case 4:
+ Direction = ParameterDirection.ReturnValue;
+ break;
+ }
+
+ IsNullable = (bool) dbValues[8];
+
+ if (dbValues[12] != null)
+ Precision = (byte) ((short) dbValues[12]);
+ if (dbValues[13] != null)
+ Scale = (byte) ((short) dbValues[13]);
+
+ SetDbTypeName ((string) dbValues[16]);
}
#endregion // Constructors
#region Properties
+ // Used to ensure that only one collection can contain this
+ // parameter
+ internal TdsParameterCollection Container {
+ get { return container; }
+ set { container = value; }
+ }
+
public DbType DbType {
get { return dbType; }
- set { dbType = value; }
+ set {
+ SetDbType (value);
+ isTypeSet = true;
+ }
}
public ParameterDirection Direction {
get { return direction; }
- set { direction = value; }
+ set {
+ direction = value;
+ if (direction == ParameterDirection.Output)
+ MetaParameter.Direction = TdsParameterDirection.Output;
+ }
+ }
+
+ internal TdsMetaParameter MetaParameter {
+ get { return metaParameter; }
}
- public bool IsNullable {
- get { return isNullable; }
+ string IDataParameter.ParameterName {
+ get { return metaParameter.ParameterName; }
+ set { metaParameter.ParameterName = value; }
+ }
+
+ public bool IsNullable {
+ get { return metaParameter.IsNullable; }
+ set { metaParameter.IsNullable = value; }
}
public int Offset {
get { return offset; }
set { offset = value; }
}
-
+
public string ParameterName {
- get { return parameterName; }
- set { parameterName = value; }
+ get { return metaParameter.ParameterName; }
+ set { metaParameter.ParameterName = value; }
}
public byte Precision {
- get { return precision; }
- set { precision = value; }
+ get { return metaParameter.Precision; }
+ set { metaParameter.Precision = value; }
}
- public byte Scale {
- get { return scale; }
- set { scale = value; }
+ public byte Scale {
+ get { return metaParameter.Scale; }
+ set { metaParameter.Scale = value; }
}
- public int Size {
- get { return size; }
- set { size = value; }
+ public int Size {
+ get { return metaParameter.Size; }
+ set { metaParameter.Size = value; }
}
public string SourceColumn {
get { return sourceVersion; }
set { sourceVersion = value; }
}
+
+ public TdsType TdsType {
+ get { return sybaseType; }
+ set {
+ SetTdsType (value);
+ isTypeSet = true;
+ }
+ }
public object Value {
- get { return objectValue; }
- set { objectValue = value; }
+ get { return metaParameter.Value; }
+ set {
+ if (!isTypeSet)
+ InferTdsType (value);
+ metaParameter.Value = value;
+ }
}
#endregion // Properties
+
+ #region Methods
+
+ object ICloneable.Clone ()
+ {
+ return new TdsParameter (ParameterName, TdsType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
+ }
+
+ // If the value is set without the DbType/TdsType being set, then we
+ // infer type information.
+ private void InferTdsType (object value)
+ {
+ Type type = value.GetType ();
+
+ string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
+
+ switch (type.FullName) {
+ case "System.Int64":
+ SetTdsType (TdsType.BigInt);
+ break;
+ case "System.Boolean":
+ SetTdsType (TdsType.Bit);
+ break;
+ case "System.String":
+ SetTdsType (TdsType.NVarChar);
+ break;
+ case "System.DateTime":
+ SetTdsType (TdsType.DateTime);
+ break;
+ case "System.Decimal":
+ SetTdsType (TdsType.Decimal);
+ break;
+ case "System.Double":
+ SetTdsType (TdsType.Float);
+ break;
+ case "System.Byte[]":
+ SetTdsType (TdsType.VarBinary);
+ break;
+ case "System.Byte":
+ SetTdsType (TdsType.TinyInt);
+ break;
+ case "System.Int32":
+ SetTdsType (TdsType.Int);
+ break;
+ case "System.Single":
+ SetTdsType (TdsType.Real);
+ break;
+ case "System.Int16":
+ SetTdsType (TdsType.SmallInt);
+ break;
+ case "System.Guid":
+ SetTdsType (TdsType.UniqueIdentifier);
+ break;
+ case "System.Object":
+ SetTdsType (TdsType.Variant);
+ break;
+ default:
+ throw new ArgumentException (exception);
+ }
+ }
+
+ // When the DbType is set, we also set the TdsType, as well as the SQL Server
+ // string representation of the type name. If the DbType is not convertible
+ // to an TdsType, throw an exception.
+ private void SetDbType (DbType type)
+ {
+ string exception = String.Format ("No mapping exists from DbType {0} to a known TdsType.", type);
+
+ switch (type) {
+ case DbType.AnsiString:
+ MetaParameter.TypeName = "varchar";
+ sybaseType = TdsType.VarChar;
+ break;
+ case DbType.AnsiStringFixedLength:
+ MetaParameter.TypeName = "char";
+ sybaseType = TdsType.Char;
+ break;
+ case DbType.Binary:
+ MetaParameter.TypeName = "varbinary";
+ sybaseType = TdsType.VarBinary;
+ break;
+ case DbType.Boolean:
+ MetaParameter.TypeName = "bit";
+ sybaseType = TdsType.Bit;
+ break;
+ case DbType.Byte:
+ MetaParameter.TypeName = "tinyint";
+ sybaseType = TdsType.TinyInt;
+ break;
+ case DbType.Currency:
+ sybaseType = TdsType.Money;
+ MetaParameter.TypeName = "money";
+ break;
+ case DbType.Date:
+ case DbType.DateTime:
+ MetaParameter.TypeName = "datetime";
+ sybaseType = TdsType.DateTime;
+ break;
+ case DbType.Decimal:
+ MetaParameter.TypeName = "decimal";
+ sybaseType = TdsType.Decimal;
+ break;
+ case DbType.Double:
+ MetaParameter.TypeName = "float";
+ sybaseType = TdsType.Float;
+ break;
+ case DbType.Guid:
+ MetaParameter.TypeName = "uniqueidentifier";
+ sybaseType = TdsType.UniqueIdentifier;
+ break;
+ case DbType.Int16:
+ MetaParameter.TypeName = "smallint";
+ sybaseType = TdsType.SmallInt;
+ break;
+ case DbType.Int32:
+ MetaParameter.TypeName = "int";
+ sybaseType = TdsType.Int;
+ break;
+ case DbType.Int64:
+ MetaParameter.TypeName = "bigint";
+ sybaseType = TdsType.BigInt;
+ break;
+ case DbType.Object:
+ MetaParameter.TypeName = "sql_variant";
+ sybaseType = TdsType.Variant;
+ break;
+ case DbType.Single:
+ MetaParameter.TypeName = "real";
+ sybaseType = TdsType.Real;
+ break;
+ case DbType.String:
+ MetaParameter.TypeName = "nvarchar";
+ sybaseType = TdsType.NVarChar;
+ break;
+ case DbType.StringFixedLength:
+ MetaParameter.TypeName = "nchar";
+ sybaseType = TdsType.NChar;
+ break;
+ case DbType.Time:
+ MetaParameter.TypeName = "datetime";
+ sybaseType = TdsType.DateTime;
+ break;
+ default:
+ throw new ArgumentException (exception);
+ }
+ dbType = type;
+ }
+
+ // Used by internal constructor which has a SQL Server typename
+ private void SetDbTypeName (string dbTypeName)
+ {
+ switch (dbTypeName.ToLower ()) {
+ case "bigint":
+ TdsType = TdsType.BigInt;
+ break;
+ case "binary":
+ TdsType = TdsType.Binary;
+ break;
+ case "bit":
+ TdsType = TdsType.Bit;
+ break;
+ case "char":
+ TdsType = TdsType.Char;
+ break;
+ case "datetime":
+ TdsType = TdsType.DateTime;
+ break;
+ case "decimal":
+ TdsType = TdsType.Decimal;
+ break;
+ case "float":
+ TdsType = TdsType.Float;
+ break;
+ case "image":
+ TdsType = TdsType.Image;
+ break;
+ case "int":
+ TdsType = TdsType.Int;
+ break;
+ case "money":
+ TdsType = TdsType.Money;
+ break;
+ case "nchar":
+ TdsType = TdsType.NChar;
+ break;
+ case "ntext":
+ TdsType = TdsType.NText;
+ break;
+ case "nvarchar":
+ TdsType = TdsType.NVarChar;
+ break;
+ case "real":
+ TdsType = TdsType.Real;
+ break;
+ case "smalldatetime":
+ TdsType = TdsType.SmallDateTime;
+ break;
+ case "smallint":
+ TdsType = TdsType.SmallInt;
+ break;
+ case "smallmoney":
+ TdsType = TdsType.SmallMoney;
+ break;
+ case "text":
+ TdsType = TdsType.Text;
+ break;
+ case "timestamp":
+ TdsType = TdsType.Timestamp;
+ break;
+ case "tinyint":
+ TdsType = TdsType.TinyInt;
+ break;
+ case "uniqueidentifier":
+ TdsType = TdsType.UniqueIdentifier;
+ break;
+ case "varbinary":
+ TdsType = TdsType.VarBinary;
+ break;
+ case "varchar":
+ TdsType = TdsType.VarChar;
+ break;
+ default:
+ TdsType = TdsType.Variant;
+ break;
+ }
+ }
+
+ // When the TdsType is set, we also set the DbType, as well as the SQL Server
+ // string representation of the type name. If the TdsType is not convertible
+ // to a DbType, throw an exception.
+ private void SetTdsType (TdsType type)
+ {
+ string exception = String.Format ("No mapping exists from TdsType {0} to a known DbType.", type);
+
+ switch (type) {
+ case TdsType.BigInt:
+ MetaParameter.TypeName = "bigint";
+ dbType = DbType.Int64;
+ break;
+ case TdsType.Binary:
+ MetaParameter.TypeName = "binary";
+ dbType = DbType.Binary;
+ break;
+ case TdsType.Timestamp:
+ MetaParameter.TypeName = "timestamp";
+ dbType = DbType.Binary;
+ break;
+ case TdsType.VarBinary:
+ MetaParameter.TypeName = "varbinary";
+ dbType = DbType.Binary;
+ break;
+ case TdsType.Bit:
+ MetaParameter.TypeName = "bit";
+ dbType = DbType.Boolean;
+ break;
+ case TdsType.Char:
+ MetaParameter.TypeName = "char";
+ dbType = DbType.AnsiStringFixedLength;
+ break;
+ case TdsType.DateTime:
+ MetaParameter.TypeName = "datetime";
+ dbType = DbType.DateTime;
+ break;
+ case TdsType.SmallDateTime:
+ MetaParameter.TypeName = "smalldatetime";
+ dbType = DbType.DateTime;
+ break;
+ case TdsType.Decimal:
+ MetaParameter.TypeName = "decimal";
+ dbType = DbType.Decimal;
+ break;
+ case TdsType.Float:
+ MetaParameter.TypeName = "float";
+ dbType = DbType.Double;
+ break;
+ case TdsType.Image:
+ MetaParameter.TypeName = "image";
+ dbType = DbType.Binary;
+ break;
+ case TdsType.Int:
+ MetaParameter.TypeName = "int";
+ dbType = DbType.Int32;
+ break;
+ case TdsType.Money:
+ MetaParameter.TypeName = "money";
+ dbType = DbType.Currency;
+ break;
+ case TdsType.SmallMoney:
+ MetaParameter.TypeName = "smallmoney";
+ dbType = DbType.Currency;
+ break;
+ case TdsType.NChar:
+ MetaParameter.TypeName = "nchar";
+ dbType = DbType.StringFixedLength;
+ break;
+ case TdsType.NText:
+ MetaParameter.TypeName = "ntext";
+ dbType = DbType.String;
+ break;
+ case TdsType.NVarChar:
+ MetaParameter.TypeName = "nvarchar";
+ dbType = DbType.String;
+ break;
+ case TdsType.Real:
+ MetaParameter.TypeName = "real";
+ dbType = DbType.Single;
+ break;
+ case TdsType.SmallInt:
+ MetaParameter.TypeName = "smallint";
+ dbType = DbType.Int16;
+ break;
+ case TdsType.Text:
+ MetaParameter.TypeName = "text";
+ dbType = DbType.AnsiString;
+ break;
+ case TdsType.VarChar:
+ MetaParameter.TypeName = "varchar";
+ dbType = DbType.AnsiString;
+ break;
+ case TdsType.TinyInt:
+ MetaParameter.TypeName = "tinyint";
+ dbType = DbType.Byte;
+ break;
+ case TdsType.UniqueIdentifier:
+ MetaParameter.TypeName = "uniqueidentifier";
+ dbType = DbType.Guid;
+ break;
+ case TdsType.Variant:
+ MetaParameter.TypeName = "sql_variant";
+ dbType = DbType.Object;
+ break;
+ default:
+ throw new ArgumentException (exception);
+ }
+ sybaseType = type;
+ }
+
+ public override string ToString()
+ {
+ return ParameterName;
+ }
+
+ #endregion // Methods
}
}
-
// Mono.Data.TdsClient.TdsParameterCollection.cs
//
// Author:
+// Rodrigo Moya (rodrigo@ximian.com)
+// Daniel Morgan (danmorg@sc.rr.com)
// Tim Coleman (tim@timcoleman.com)
//
+// (C) Ximian, Inc 2002
// Copyright (C) Tim Coleman, 2002
//
-using Mono.Data.Tds.Protocol;
+using Mono.Data.Tds;
using System;
-using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
-using System.Runtime.InteropServices;
+using System.Collections;
namespace Mono.Data.TdsClient {
+ [ListBindable (false)]
public sealed class TdsParameterCollection : MarshalByRefObject, IDataParameterCollection, IList, ICollection, IEnumerable
{
#region Fields
- ArrayList list = new ArrayList ();
+ ArrayList list = new ArrayList();
+ TdsMetaParameterCollection metaParameters;
+ TdsCommand command;
#endregion // Fields
+ #region Constructors
+
+ internal TdsParameterCollection (TdsCommand command)
+ {
+ this.command = command;
+ metaParameters = new TdsMetaParameterCollection ();
+ }
+
+ #endregion // Constructors
+
#region Properties
public int Count {
- get { return list.Count; }
+ get { return list.Count; }
}
- object IList.this [int index] {
- get { return (TdsParameter) this[index]; }
- set { this[index] = (TdsParameter) value; }
+ public TdsParameter this [int index] {
+ get { return (TdsParameter) list [index]; }
+ set { list [index] = (TdsParameter) value; }
}
- public TdsParameter this [int index] {
- get {
- if (index >= Count)
- throw new IndexOutOfRangeException ();
- return (TdsParameter) list[index];
- }
+ object IDataParameterCollection.this [string parameterName] {
+ get { return this[parameterName]; }
set {
- if (index >= Count)
- throw new IndexOutOfRangeException ();
- list[index] = (TdsParameter) value;
+ if (!(value is TdsParameter))
+ throw new InvalidCastException ("Only SQLParameter objects can be used.");
+ this [parameterName] = (TdsParameter) value;
}
}
- object IDataParameterCollection.this [string parameterName] {
- get { return (TdsParameter) this[parameterName]; }
- set { this [parameterName] = (TdsParameter) value; }
+ public TdsParameter this [string parameterName] {
+ get {
+ foreach (TdsParameter p in list)
+ if (p.ParameterName.Equals (parameterName))
+ return p;
+ throw new IndexOutOfRangeException ("The specified name does not exist: " + parameterName);
+ }
+ set {
+ if (!Contains (parameterName))
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
+ this [IndexOf (parameterName)] = value;
+ }
}
- public TdsParameter this [string parameterName] {
- get { return this[IndexOf (parameterName)]; }
- set { this[IndexOf (parameterName)] = value; }
+ object IList.this [int index] {
+ get { return (TdsParameter) this [index]; }
+ set { this [index] = (TdsParameter) value; }
}
bool IList.IsFixedSize {
- get { return false; }
+ get { return list.IsFixedSize; }
}
bool IList.IsReadOnly {
- get { return false; }
+ get { return list.IsReadOnly; }
}
bool ICollection.IsSynchronized {
- [MonoTODO]
- get { throw new NotImplementedException (); }
+ get { return list.IsSynchronized; }
}
object ICollection.SyncRoot {
- [MonoTODO]
- get { throw new NotImplementedException (); }
+ get { return list.SyncRoot; }
}
+ internal TdsMetaParameterCollection MetaParameters {
+ get { return metaParameters; }
+ }
+
#endregion // Properties
- #region Methods
+ #region Methods
public int Add (object value)
{
if (!(value is TdsParameter))
- throw new InvalidCastException ();
+ throw new InvalidCastException ("The parameter was not an TdsParameter.");
Add ((TdsParameter) value);
return IndexOf (value);
}
-
+
public TdsParameter Add (TdsParameter value)
{
+ if (value.Container != null)
+ throw new ArgumentException ("The TdsParameter specified in the value parameter is already added to this or another TdsParameterCollection.");
+
+ value.Container = this;
list.Add (value);
- return value;
+ metaParameters.Add (value.MetaParameter);
+ return value;
}
-
+
public TdsParameter Add (string parameterName, object value)
{
return Add (new TdsParameter (parameterName, value));
}
+
+ public TdsParameter Add (string parameterName, TdsType sybaseType)
+ {
+ return Add (new TdsParameter (parameterName, sybaseType));
+ }
- public void Clear ()
+ public TdsParameter Add (string parameterName, TdsType sybaseType, int size)
{
- list.Clear ();
+ return Add (new TdsParameter (parameterName, sybaseType, size));
}
+ public TdsParameter Add (string parameterName, TdsType sybaseType, int size, string sourceColumn)
+ {
+ return Add (new TdsParameter (parameterName, sybaseType, size, sourceColumn));
+ }
+
+ public void Clear()
+ {
+ metaParameters.Clear ();
+ list.Clear ();
+ }
+
public bool Contains (object value)
{
- return list.Contains (value);
+ if (!(value is TdsParameter))
+ throw new InvalidCastException ("The parameter was not an TdsParameter.");
+ return Contains (((TdsParameter) value).ParameterName);
}
public bool Contains (string value)
{
- return (IndexOf (value) >= 0);
+ foreach (TdsParameter p in list)
+ if (p.ParameterName.Equals (value))
+ return true;
+ return false;
}
public void CopyTo (Array array, int index)
{
- throw new NotImplementedException ();
+ list.CopyTo (array, index);
}
- public IEnumerator GetEnumerator ()
+ public IEnumerator GetEnumerator()
{
return list.GetEnumerator ();
}
-
+
public int IndexOf (object value)
{
- return list.IndexOf (value);
+ if (!(value is TdsParameter))
+ throw new InvalidCastException ("The parameter was not an TdsParameter.");
+ return IndexOf (((TdsParameter) value).ParameterName);
}
-
+
public int IndexOf (string parameterName)
{
- for (int i = 0; i < list.Count; i += 1)
- if (((TdsParameter) list[i]).ParameterName == parameterName)
- return i;
- return -1;
+ return list.IndexOf (parameterName);
}
public void Insert (int index, object value)
public void Remove (object value)
{
+ metaParameters.Remove (((TdsParameter) value).MetaParameter);
list.Remove (value);
}
public void RemoveAt (int index)
{
+ metaParameters.RemoveAt (index);
list.RemoveAt (index);
}
RemoveAt (IndexOf (parameterName));
}
-
- #endregion // Methods
+ #endregion // Methods
}
}
-
// Author:
// Tim Coleman (tim@timcoleman.com)
//
-// Copyright (C) 2002 Tim Coleman
+// Copyright (C) Tim Coleman, 2002
//
-using Mono.Data.Tds.Protocol;
using System;
-using System.ComponentModel;
using System.Data;
+using System.Data.Common;
namespace Mono.Data.TdsClient {
- public class TdsTransaction : Component, ICloneable, IDbTransaction
+ public sealed class TdsTransaction : MarshalByRefObject, IDbTransaction, IDisposable
{
#region Fields
+ bool disposed = false;
+
TdsConnection connection;
IsolationLevel isolationLevel;
bool isOpen;
- #endregion // Fields
+ #endregion
#region Constructors
{
this.connection = connection;
this.isolationLevel = isolevel;
-
- connection.Tds.ExecuteNonQuery ("BEGIN TRAN");
isOpen = true;
}
#region Properties
- TdsConnection Connection {
+ public TdsConnection Connection {
get { return connection; }
}
- IDbConnection IDbTransaction.Connection {
- get { return Connection; }
+ internal bool IsOpen {
+ get { return isOpen; }
}
- IsolationLevel IDbTransaction.IsolationLevel {
+ public IsolationLevel IsolationLevel {
get { return isolationLevel; }
}
-
- public bool IsOpen {
- get { return isOpen; }
+
+ IDbConnection IDbTransaction.Connection {
+ get { return Connection; }
}
#endregion // Properties
-
- #region Methods
+
+ #region Methods
public void Commit ()
{
if (!isOpen)
- throw new InvalidOperationException ("This TdsTransaction has completed; it is no longer usable.");
- connection.Tds.ExecuteNonQuery ("IF @@TRANCOUNT>0 COMMIT TRAN");
+ throw new InvalidOperationException ("The Transaction was not open.");
+ connection.Tds.Execute ("COMMIT TRANSACTION");
+ connection.Transaction = null;
isOpen = false;
+ }
+
+ private void Dispose (bool disposing)
+ {
+ if (!disposed) {
+ if (disposing)
+ Rollback ();
+ disposed = true;
+ }
}
- object ICloneable.Clone()
- {
- throw new NotImplementedException ();
- }
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
public void Rollback ()
+ {
+ Rollback (String.Empty);
+ }
+
+ public void Rollback (string transactionName)
{
if (!isOpen)
- throw new InvalidOperationException ("This TdsTransaction has completed; it is no longer usable.");
- connection.Tds.ExecuteNonQuery ("IF @@TRANCOUNT>0 ROLLBACK TRAN");
+ throw new InvalidOperationException ("The Transaction was not open.");
+ connection.Tds.Execute (String.Format ("ROLLBACK TRANSACTION {0}", transactionName));
isOpen = false;
}
public void Save (string savePointName)
{
if (!isOpen)
- throw new InvalidOperationException ("This TdsTransaction has completed; it is no longer usable.");
- connection.Tds.ExecuteNonQuery (String.Format ("SAVE TRAN {0}", savePointName));
+ throw new InvalidOperationException ("The Transaction was not open.");
+ connection.Tds.Execute (String.Format ("SAVE TRANSACTION {0}", savePointName));
}
- #endregion // Methods
+ #endregion // Methods
}
}
namespace Mono.Data.TdsTypes {
public struct TdsDecimal : INullable, IComparable
{
+
#region Fields
int[] value;
byte scale;
bool positive;
- private bool notNull;
+ bool notNull;
// borrowed from System.Decimal
const int SCALE_SHIFT = 16;
const int SIGN_SHIFT = 31;
const int RESERVED_SS32_BITS = 0x7F00FFFF;
- public static readonly byte MaxPrecision = 38;
- public static readonly byte MaxScale = 28;
- public static readonly TdsDecimal MaxValue = new TdsDecimal (79228162514264337593543950335.0);
- public static readonly TdsDecimal MinValue = new TdsDecimal (-79228162514264337593543950335.0);
+ public static readonly byte MaxPrecision = 38;
+ public static readonly byte MaxScale = 38;
+
+ public static readonly TdsDecimal MaxValue = new TdsDecimal (MaxPrecision, (byte)0, true, (int)716002642, Int32.MaxValue, (int)1518778966, (int)1262177448);
+ public static readonly TdsDecimal MinValue = new TdsDecimal (MaxPrecision, (byte)0, false, (int)716002642, Int32.MaxValue, (int)1518778966, (int)1262177448);
public static readonly TdsDecimal Null;
#endregion
throw new NotImplementedException ();
}
+ internal static TdsDecimal FromTdsBigDecimal (TdsBigDecimal x)
+ {
+ if (x == null)
+ return Null;
+ else
+ return new TdsDecimal (x.Precision, x.Scale, !x.IsNegative, x.Data);
+ }
+
public override int GetHashCode ()
{
return (int)this.Value;
LIBRARY = $(topdir)/class/lib/Mono.Data.TdsClient.dll
LIB_LIST = list
-LIB_FLAGS = -r corlib -r System -r System.Xml -r System.Data.dll -r Mono.Data.Tds
+LIB_FLAGS = -r corlib -r System -r System.Xml -r System.Data -r Mono.Data.Tds -r System.EnterpriseServices
SOURCES_INCLUDE=*.cs
SOURCES_EXCLUDE=\