This commit is contained in:
466
source/Data/Data/FireBird/FireBirdCommandWrapper.cs
Normal file
466
source/Data/Data/FireBird/FireBirdCommandWrapper.cs
Normal file
@@ -0,0 +1,466 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using FirebirdSql.Data.FirebirdClient;
|
||||
using System.Text;
|
||||
|
||||
namespace GZTW.Data.FireBird
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Represents a SQL statement or stored procedure to execute against a Sql Server database.</para>
|
||||
/// </summary>
|
||||
public class FireBirdCommandWrapper : DBCommandWrapper
|
||||
{
|
||||
private FbCommand command;
|
||||
private int rowsAffected;
|
||||
private object[] parameterValues;
|
||||
private bool needsParameters = false;
|
||||
private char parameterToken;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Initialize a new instance of the <see cref="SqlCommandWrapper"/> class with the text of a query and the command type.</para>
|
||||
/// </summary>
|
||||
/// <param name="commandText"><para>The stored procedure name or SQL sting the command represents.</para></param>
|
||||
/// <param name="commandType"><para>One of the <see crer="CommandType"/> values.</para></param>
|
||||
/// <param name="parameterToken"><para>The parameter delimeter for database commands.</para></param>
|
||||
internal FireBirdCommandWrapper(string commandText, CommandType commandType, char parameterToken)
|
||||
{
|
||||
this.parameterToken = parameterToken;
|
||||
this.command = CreateCommand(commandText, commandType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Initialize a new instance of the <see cref="SqlCommandWrapper"/> class with the text of a query the command type, and the parameter values.</para>
|
||||
/// </summary>
|
||||
/// <param name="commandText"><para>The stored procedure name or SQL sting the command represents.</para></param>
|
||||
/// <param name="commandType"><para>One of the <see crer="CommandType"/> values.</para></param>
|
||||
/// <param name="parameterToken"><para>The parameter delimeter for database commands.</para></param>
|
||||
/// <param name="parameterValues"><para>The parameter values to assign in positional order.</para></param>
|
||||
internal FireBirdCommandWrapper(string commandText, CommandType commandType, char parameterToken, object[] parameterValues) : this(commandText, commandType, parameterToken)
|
||||
{
|
||||
//this.command = CreateCommand(commandText, commandType);
|
||||
this.parameterValues = parameterValues;
|
||||
if (commandType == CommandType.StoredProcedure)
|
||||
{
|
||||
this.needsParameters = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets the underlying <see cref="IDbCommand"/>.</para>
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <para>The underlying <see cref="IDbCommand"/>. The default is <see langword="null"/>.</para>
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <para>This command is a <see cref="SqlCommand"/></para>
|
||||
/// </remarks>
|
||||
/// <seealso cref="SqlCommand"/>
|
||||
public override IDbCommand Command
|
||||
{
|
||||
get { return this.command; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets or sets the rows affected by this command.</para>
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <para>The rows affected by this command.</para>
|
||||
/// </value>
|
||||
public override int RowsAffected
|
||||
{
|
||||
get { return this.rowsAffected; }
|
||||
set { this.rowsAffected = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets or sets the wait time before terminating the attempt to execute a command and generating an error.</para>
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <para>The wait time before terminating the attempt to execute a command and generating an error.</para>
|
||||
/// </value>
|
||||
/// /// <remarks>
|
||||
/// <para>The inner <see cref="FbCommand"/> does not implement a command timeout.</para>
|
||||
/// </remarks>
|
||||
public override int CommandTimeout
|
||||
{
|
||||
get { return -1; }
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
|
||||
/// <param name="size"><para>The maximum size of the data within the column.</para></param>
|
||||
/// <param name="direction"><para>One of the <see cref="ParameterDirection"/> values.</para></param>
|
||||
/// <param name="nullable"><para>Avalue indicating whether the parameter accepts null values.</para></param>
|
||||
/// <param name="precision"><para>The maximum number of digits used to represent the <paramref name="value"/>.</para></param>
|
||||
/// <param name="scale"><para>The number of decimal places to which <paramref name="value"/> is resolved.</para></param>
|
||||
/// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the <paramref name="value"/>.</para></param>
|
||||
/// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>
|
||||
/// <param name="value"><para>The value of the parameter.</para></param>
|
||||
public override void AddParameter(string name, DbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
|
||||
{
|
||||
this.command.Parameters.Add(CreateParameter(name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value));
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command.</para>
|
||||
// /// </summary>
|
||||
// /// <param name="name"><para>The name of the parameter.</para></param>
|
||||
// /// <param name="sqlType"><para>One of the <see cref="SqlDbType"/> values.</para></param>
|
||||
// /// <param name="size"><para>The maximum size of the data within the column.</para></param>
|
||||
// /// <param name="direction"><para>One of the <see cref="ParameterDirection"/> values.</para></param>
|
||||
// /// <param name="nullable"><para>Avalue indicating whether the parameter accepts null values.</para></param>
|
||||
// /// <param name="precision"><para>The maximum number of digits used to represent the <paramref name="value"/>.</para></param>
|
||||
// /// <param name="scale"><para>The number of decimal places to which <paramref name="value"/> is resolved.</para></param>
|
||||
// /// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the <paramref name="value"/>.</para></param>
|
||||
// /// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>
|
||||
// /// <param name="value"><para>The value of the parameter.</para></param>
|
||||
// public void AddParameter(string name, DbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
|
||||
// {
|
||||
// FireBirdDBParameter param = CreateParameter(name, dbType.String, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value);
|
||||
// param.DbType = dbType;
|
||||
// this.command.Parameters.Add(param);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
|
||||
/// <param name="direction"><para>One of the <see cref="ParameterDirection"/> values.</para></param>
|
||||
/// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the <paramref name="value"/>.</para></param>
|
||||
/// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>
|
||||
/// <param name="value"><para>The value of the parameter.</para></param>
|
||||
public override void AddParameter(string name, DbType dbType, ParameterDirection direction, string sourceColumn, DataRowVersion sourceVersion, object value)
|
||||
{
|
||||
FbParameter param = CreateParameter(name, dbType, 0, direction, false, 0, 0, sourceColumn, sourceVersion, value);
|
||||
this.command.Parameters.Add(param);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command set as <see cref="ParameterDirection"/> value of Output.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
|
||||
/// <param name="size"><para>The maximum size of the data within the column.</para></param>
|
||||
public override void AddOutParameter(string name, DbType dbType, int size)
|
||||
{
|
||||
AddParameter(name, dbType, size, ParameterDirection.Output, true, 0, 0, String.Empty, DataRowVersion.Default, DBNull.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command set as <see cref="ParameterDirection"/> value of Input.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
|
||||
/// <remarks>
|
||||
/// <para>This version of the method is used when you can have the same parameter object multiple times with different values.</para>
|
||||
/// </remarks>
|
||||
public override void AddInParameter(string name, DbType dbType)
|
||||
{
|
||||
AddParameter(name, dbType, ParameterDirection.Input, String.Empty, DataRowVersion.Default, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command set as <see cref="ParameterDirection"/> value of Input.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
|
||||
/// <param name="value"><para>The value of the parameter.</para></param>
|
||||
public override void AddInParameter(string name, DbType dbType, object value)
|
||||
{
|
||||
AddParameter(name, dbType, ParameterDirection.Input, String.Empty, DataRowVersion.Default, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special version for handling large strings efficiently
|
||||
/// For now, does nothing special as it's mssql that this was targetted to originally
|
||||
/// <para>Adds a new instance of an <see cref="OracleParameter"/> object to the command set as <see cref="ParameterDirection"/> value of Input.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="value"><para>The value of the parameter.</para></param>
|
||||
public override void AddLargeStringInParameter(string name, object value)
|
||||
{
|
||||
AddParameter(name, DbType.String, ParameterDirection.Input, String.Empty, DataRowVersion.Default, value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Adds a new instance of an <see cref="SqlParameter"/> object to the command set as <see cref="ParameterDirection"/> value of Input.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter.</para></param>
|
||||
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
|
||||
/// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the value.</para></param>
|
||||
/// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>
|
||||
public override void AddInParameter(string name, DbType dbType, string sourceColumn, DataRowVersion sourceVersion)
|
||||
{
|
||||
AddParameter(name, dbType, 0, ParameterDirection.Input, true, 0, 0, sourceColumn, sourceVersion, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Returns the value of the parameter for the given <paramref name="name"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter to get the value.</para></param>
|
||||
/// <returns><para>The value of the parameter.</para></returns>
|
||||
public override object GetParameterValue(string name)
|
||||
{
|
||||
return this.command.Parameters[BuildParameterName(name)].Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Sets the value of a parameter for the given <paramref name="name"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="name"><para>The name of the parameter to set the value.</para></param>
|
||||
/// <param name="value"><para>The new value of the parameter.</para></param>
|
||||
public override void SetParameterValue(string name, object value)
|
||||
{
|
||||
//this.command.Parameters[BuildParameterName(name)].Value = (value == null) ? DBNull.Value : value;
|
||||
//throw new NotSupportedException("DAL:SetParameterValue: FireBirdDB not implemented, use AddInParameter instead");
|
||||
|
||||
this.command.Parameters[BuildParameterName(name)].Value = (value == null) ? DBNull.Value : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set parameter by index for faster performance
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="value"></param>
|
||||
public override void SetParameterValue(int index, object value)
|
||||
{
|
||||
//Handle nulls or Guid's specially for firebird
|
||||
//as they are actually char 38's
|
||||
if(value==null || (Guid)value==Guid.Empty)
|
||||
{
|
||||
this.command.Parameters[index].Value=DBNull.Value;
|
||||
return;
|
||||
}
|
||||
|
||||
if(value is Guid)
|
||||
{
|
||||
this.command.Parameters[index].Value="{"+((Guid)value).ToString().ToUpper()+"}";
|
||||
|
||||
}
|
||||
else
|
||||
this.command.Parameters[index].Value = (value == null) ? DBNull.Value : value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Clean up resources.</para>
|
||||
/// </summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
this.command.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Dicover the parameters for a stored procedure using a separate connection and command.</para>
|
||||
/// </summary>
|
||||
/// <param name="parameterToken"><para>The parameter delimeter for database commands.</para></param>
|
||||
protected override void DoDiscoverParameters(char parameterToken)
|
||||
{
|
||||
throw new NotSupportedException("DAL: DoDiscoverParamenters: FireBirdDB stored procedures not implemented");
|
||||
// this.parameterToken = parameterToken;
|
||||
// using (SqlCommand newCommand = CreateNewCommandAndConnectionForDiscovery())
|
||||
// {
|
||||
// SqlCommandBuilder.DeriveParameters(newCommand);
|
||||
//
|
||||
// foreach (IDataParameter parameter in newCommand.Parameters)
|
||||
// {
|
||||
// IDataParameter cloneParameter = (IDataParameter)((ICloneable)parameter).Clone();
|
||||
// cloneParameter.ParameterName = BuildParameterName(cloneParameter.ParameterName);
|
||||
// this.command.Parameters.Add(cloneParameter);
|
||||
// }
|
||||
// newCommand.Connection.Close();
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Assign the values provided by a user to the command parameters discovered in positional order.</para>
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// <para>The number of parameters does not match number of values for stored procedure.</para>
|
||||
/// </exception>
|
||||
protected override void DoAssignParameterValues()
|
||||
{
|
||||
throw new NotSupportedException("DAL:DoAssignParameterValues: FireBirdDB stored procedures not implemented");
|
||||
|
||||
// if (SameNumberOfParametersAndValues() == false)
|
||||
// {
|
||||
// throw new InvalidOperationException(SR.ExceptionMessageParameterMatchFailure);
|
||||
// }
|
||||
//
|
||||
// int returnParameter = 1;
|
||||
// for (int i = 0; i < this.parameterValues.Length; i++)
|
||||
// {
|
||||
// IDataParameter parameter = this.command.Parameters[i + returnParameter];
|
||||
//
|
||||
// // There used to be code here that checked to see if the parameter was input or input/output
|
||||
// // before assigning the value to it. We took it out because of an operational bug with
|
||||
// // deriving parameters for a stored procedure. It turns out that output parameters are set
|
||||
// // to input/output after discovery, so any direction checking was unneeded. Should it ever
|
||||
// // be needed, it should go here, and check that a parameter is input or input/output before
|
||||
// // assigning a value to it.
|
||||
// SetParameterValue(parameter.ParameterName, this.parameterValues[i]);
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Determine if a stored procedure is using parameter discovery.</para>
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <para><see langword="true"/> if further preparation is needed.</para>
|
||||
/// </returns>
|
||||
protected override bool DoIsFurtherPreparationNeeded()
|
||||
{
|
||||
//throw new NotSupportedException("DoIsFurtherPreparationNeeded: FireBirdDB does not support stored procedures");
|
||||
|
||||
return this.needsParameters;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Create a parameter converting it as necessary.
|
||||
/// </devdoc>
|
||||
private FbParameter CreateParameter(string name, DbType type, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
|
||||
{
|
||||
FbParameter param = this.command.CreateParameter();
|
||||
param.ParameterName = BuildParameterName(name);
|
||||
|
||||
param.IsNullable=true;
|
||||
switch(type)
|
||||
{
|
||||
case DbType.Guid://char38 in firebird (ensure emptys save as nulls)
|
||||
param.FbDbType=FbDbType.Char;
|
||||
if(value==null || (Guid)value==Guid.Empty)
|
||||
param.Value=DBNull.Value;//"{"+Guid.Empty.ToString()+"}";
|
||||
else
|
||||
{
|
||||
param.Value="{"+((Guid)value).ToString().ToUpper()+"}";
|
||||
}
|
||||
break;
|
||||
//any and all binary byte[] types
|
||||
case DbType.Object:
|
||||
param.FbDbType=FbDbType.Binary;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.Binary:
|
||||
param.FbDbType=FbDbType.Binary;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.String:
|
||||
param.FbDbType=FbDbType.VarChar;
|
||||
param.Value = (value == null ) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.DateTime:
|
||||
param.FbDbType=FbDbType.TimeStamp;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.Int16:
|
||||
param.FbDbType=FbDbType.SmallInt;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.Int32:
|
||||
param.FbDbType=FbDbType.Integer;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.Int64:
|
||||
param.FbDbType=FbDbType.BigInt;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.Decimal:
|
||||
param.FbDbType=FbDbType.Decimal;
|
||||
param.Value = (value == null) ? DBNull.Value : value;
|
||||
break;
|
||||
case DbType.Boolean://small int in firebird
|
||||
param.FbDbType=FbDbType.SmallInt;
|
||||
if(value==null)
|
||||
param.Value=DBNull.Value;
|
||||
else
|
||||
{
|
||||
if((bool)value==true)
|
||||
param.Value=1;
|
||||
else
|
||||
param.Value=0;
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
throw new NotSupportedException("FireBirdCommandWrapper:CreateParameter encountered unexpected type:" + type.ToString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
param.Size = size;
|
||||
param.Direction = direction;
|
||||
|
||||
//param.IsNullable = nullable;
|
||||
|
||||
param.Precision = precision;
|
||||
param.Scale = scale;
|
||||
param.SourceColumn = sourceColumn;
|
||||
param.SourceVersion = sourceVersion;
|
||||
|
||||
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
private bool SameNumberOfParametersAndValues()
|
||||
{
|
||||
int returnParameterCount = 1;
|
||||
int numberOfParametersToStoredProcedure = this.command.Parameters.Count - returnParameterCount;
|
||||
int numberOfValuesProvidedForStoredProcedure = this.parameterValues.Length;
|
||||
return numberOfParametersToStoredProcedure == numberOfValuesProvidedForStoredProcedure;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Discovery has to be done on its own connection to allow for the case of the
|
||||
/// connection being used being enrolled in a transaction. The SqlCommandBuilder.DeriveParameters
|
||||
/// method creates a new SqlCommand internally to communicate to the database, and it
|
||||
/// reuses the same connection that is passed in on the command object. If this command
|
||||
/// object has a connection that is enrolled in a transaction, the DeriveParameters method does not
|
||||
/// honor that transaction, and the call fails. To avoid this, create your own connection and
|
||||
/// command, and use them.
|
||||
///
|
||||
/// You then have to clone each of the IDataParameter objects before it can be transferred to
|
||||
/// the original command, or another exception is thrown.
|
||||
/// </devdoc>
|
||||
// private SqlCommand CreateNewCommandAndConnectionForDiscovery()
|
||||
// {
|
||||
// SqlConnection clonedConnection = (SqlConnection)((ICloneable)this.command.Connection).Clone();
|
||||
// clonedConnection.Open();
|
||||
// SqlCommand newCommand = CreateCommand(this.command.CommandText, this.command.CommandType);
|
||||
// newCommand.Connection = clonedConnection;
|
||||
//
|
||||
// return newCommand;
|
||||
// }
|
||||
|
||||
private static FbCommand CreateCommand(string commandText, CommandType commandType)
|
||||
{
|
||||
FbCommand newCommand = new FbCommand();
|
||||
newCommand.CommandText = commandText;
|
||||
newCommand.CommandType = commandType;
|
||||
|
||||
return newCommand;
|
||||
}
|
||||
|
||||
private string BuildParameterName(string name)
|
||||
{
|
||||
//since the token is *always* specified, no need for this at all
|
||||
return name;
|
||||
// //System.Diagnostics.Debug.Assert(parameterToken != 0x0000);
|
||||
// if (name[0] != this.parameterToken)
|
||||
// {
|
||||
// return name.Insert(0, new string(this.parameterToken, 1));
|
||||
// }
|
||||
// return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
224
source/Data/Data/FireBird/FireBirdDataReaderWrapper.cs
Normal file
224
source/Data/Data/FireBird/FireBirdDataReaderWrapper.cs
Normal file
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using FirebirdSql.Data.FirebirdClient;
|
||||
//using FirebirdSql.Data.Firebird;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace GZTW.Data.FireBird
|
||||
{
|
||||
/// <devdoc>
|
||||
/// A wrapper to convert data from FireBird for the reader.
|
||||
/// </devdoc>
|
||||
internal class FireBirdDataReaderWrapper : MarshalByRefObject, IDataReader, IEnumerable
|
||||
{
|
||||
private FbDataReader innerReader;
|
||||
|
||||
public static explicit operator FbDataReader(FireBirdDataReaderWrapper fireBirdDataReaderWrapper)
|
||||
{
|
||||
return fireBirdDataReaderWrapper.InnerReader;
|
||||
}
|
||||
|
||||
public FireBirdDataReaderWrapper(FbDataReader reader)
|
||||
{
|
||||
this.innerReader = reader;
|
||||
}
|
||||
|
||||
public object this[int index]
|
||||
{
|
||||
get { return InnerReader[index]; }
|
||||
}
|
||||
|
||||
public object this[string name]
|
||||
{
|
||||
get { return InnerReader[name]; }
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)InnerReader).GetEnumerator();
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
//InnerReader.Dispose();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
InnerReader.Close();
|
||||
}
|
||||
|
||||
public DataTable GetSchemaTable()
|
||||
{
|
||||
return InnerReader.GetSchemaTable();
|
||||
}
|
||||
|
||||
public bool NextResult()
|
||||
{
|
||||
return InnerReader.NextResult();
|
||||
}
|
||||
|
||||
public bool Read()
|
||||
{
|
||||
return InnerReader.Read();
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get { return InnerReader.Depth; }
|
||||
}
|
||||
|
||||
public bool IsClosed
|
||||
{
|
||||
get { return InnerReader.IsClosed; }
|
||||
}
|
||||
|
||||
public int RecordsAffected
|
||||
{
|
||||
get { return InnerReader.RecordsAffected; }
|
||||
}
|
||||
|
||||
public int FieldCount
|
||||
{
|
||||
get { return InnerReader.FieldCount; }
|
||||
}
|
||||
|
||||
|
||||
public bool GetBoolean(int index)
|
||||
{
|
||||
if(InnerReader.GetInt16(index)!=0)
|
||||
return true;
|
||||
return false;
|
||||
//not directly supported, using int16 instead
|
||||
//int nBool=InnerReader.get
|
||||
//return InnerReader.GetBoolean(index);
|
||||
}
|
||||
|
||||
public byte GetByte(int index)
|
||||
{
|
||||
return InnerReader.GetByte(index);
|
||||
|
||||
}
|
||||
|
||||
public long GetBytes(int ordinal, long dataIndex, byte[] buffer, int bufferIndex, int length)
|
||||
{
|
||||
return InnerReader.GetBytes(ordinal, dataIndex, buffer, bufferIndex, length);
|
||||
}
|
||||
|
||||
public Char GetChar(int index)
|
||||
{
|
||||
return InnerReader.GetChar(index);
|
||||
}
|
||||
|
||||
public long GetChars(int index, long dataIndex, char[] buffer, int bufferIndex, int length)
|
||||
{
|
||||
return InnerReader.GetChars(index, dataIndex, buffer, bufferIndex, length);
|
||||
}
|
||||
|
||||
public IDataReader GetData(int index)
|
||||
{
|
||||
return InnerReader.GetData(index);
|
||||
}
|
||||
|
||||
public string GetDataTypeName(int index)
|
||||
{
|
||||
return InnerReader.GetDataTypeName(index);
|
||||
}
|
||||
|
||||
public DateTime GetDateTime(int ordinal_)
|
||||
{
|
||||
return InnerReader.GetDateTime(ordinal_);
|
||||
}
|
||||
|
||||
|
||||
public decimal GetDecimal(int index)
|
||||
{
|
||||
return InnerReader.GetDecimal(index);
|
||||
|
||||
}
|
||||
|
||||
public double GetDouble(int index)
|
||||
{
|
||||
return InnerReader.GetDouble(index);
|
||||
}
|
||||
|
||||
public Type GetFieldType(int index)
|
||||
{
|
||||
return InnerReader.GetFieldType(index);
|
||||
}
|
||||
|
||||
|
||||
public float GetFloat(int index)
|
||||
{
|
||||
return InnerReader.GetFloat(index);
|
||||
}
|
||||
|
||||
|
||||
//not directly supported using char38
|
||||
public Guid GetGuid(int index)
|
||||
{
|
||||
string sTemp=InnerReader.GetString(index);
|
||||
if(sTemp==null||sTemp=="")
|
||||
return Guid.Empty;
|
||||
else
|
||||
return new Guid(sTemp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public short GetInt16(int index)
|
||||
{
|
||||
return InnerReader.GetInt16(index);
|
||||
}
|
||||
|
||||
public int GetInt32(int index)
|
||||
{
|
||||
return InnerReader.GetInt32(index);
|
||||
}
|
||||
|
||||
public long GetInt64(int index)
|
||||
{
|
||||
return InnerReader.GetInt64(index);
|
||||
}
|
||||
|
||||
public string GetName(int index)
|
||||
{
|
||||
return InnerReader.GetName(index);
|
||||
}
|
||||
|
||||
public int GetOrdinal(string index)
|
||||
{
|
||||
|
||||
return InnerReader.GetOrdinal(index);
|
||||
}
|
||||
|
||||
|
||||
public string GetString(int index)
|
||||
{
|
||||
return InnerReader.GetString(index);
|
||||
|
||||
}
|
||||
|
||||
public object GetValue(int index)
|
||||
{
|
||||
return InnerReader.GetValue(index);
|
||||
}
|
||||
|
||||
public int GetValues(object[] values)
|
||||
{
|
||||
return InnerReader.GetValues(values);
|
||||
}
|
||||
|
||||
public bool IsDBNull(int index)
|
||||
{
|
||||
return InnerReader.IsDBNull(index);
|
||||
}
|
||||
|
||||
public FbDataReader InnerReader
|
||||
{
|
||||
get { return this.innerReader; }
|
||||
}
|
||||
}
|
||||
}
|
||||
251
source/Data/Data/FireBird/FireBirdDatabase.cs
Normal file
251
source/Data/Data/FireBird/FireBirdDatabase.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using FirebirdSql.Data.FirebirdClient;
|
||||
//using FirebirdSql.Data.Firebird;
|
||||
using System.Xml;
|
||||
//using GZTW.Common;
|
||||
|
||||
namespace GZTW.Data.FireBird
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Represents a FireBird Database.</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Firebird database
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class FireBirdDatabase : GZTWDatabase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="FireBirdDatabase"/> class.
|
||||
/// </summary>
|
||||
public FireBirdDatabase() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearPool()
|
||||
{
|
||||
FbConnection.ClearAllPools();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the DataBaseType enum for the active db type
|
||||
/// Used by higher layers when some DB specific code needs to be
|
||||
/// executed
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <para>DataBaseType enumeration value</para>
|
||||
/// </value>
|
||||
public override DataBaseType DBType
|
||||
{
|
||||
get
|
||||
{
|
||||
return DataBaseType.FireBird;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the schema fingerprint for database
|
||||
/// </summary>
|
||||
public override string SchemaFingerPrint//case 856
|
||||
{
|
||||
get
|
||||
{
|
||||
string _fingerprint = "";
|
||||
using (FbConnection cn = new FbConnection(ConnectionString))
|
||||
{
|
||||
try
|
||||
{
|
||||
cn.Open();
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
DataTable t=cn.GetSchema("Tables", new string[] { null, null,null, "TABLE" });
|
||||
//iterate all tables
|
||||
DataView dvTables = t.DefaultView;
|
||||
dvTables.Sort = "TABLE_NAME";
|
||||
|
||||
foreach (DataRowView dvTable in dvTables)
|
||||
{
|
||||
sb.Append(dvTable["TABLE_NAME"].ToString());
|
||||
sb.Append("\r\n");
|
||||
DataTable tColumns = cn.GetSchema("Columns", new string[] { null, null, dvTable["TABLE_NAME"].ToString() });
|
||||
DataView dvColumns = tColumns.DefaultView;
|
||||
dvColumns.Sort = "COLUMN_NAME";
|
||||
|
||||
foreach (DataRowView dvColumn in dvColumns)
|
||||
{
|
||||
|
||||
sb.Append("\t");
|
||||
sb.Append(dvColumn["COLUMN_NAME"].ToString());
|
||||
//sb.Append(" ");
|
||||
//string sType = "";
|
||||
//if (dvColumn["DOMAIN_NAME"] != System.DBNull.Value)
|
||||
//{
|
||||
// sType = dvColumn["DOMAIN_NAME"].ToString();
|
||||
|
||||
//}
|
||||
//else
|
||||
// sType = dvColumn["COLUMN_DATA_TYPE"].ToString();
|
||||
//sb.Append(sType);
|
||||
sb.Append("\r\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_fingerprint = sb.ToString().Trim();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (cn != null)
|
||||
cn.Close();
|
||||
}
|
||||
}
|
||||
|
||||
return _fingerprint;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets the parameter token used to delimit parameters for the Sql Database.</para>
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <para>The '?' symbol.</para>
|
||||
/// </value>
|
||||
protected override char ParameterToken
|
||||
{
|
||||
get { return '@'; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Get the connection for this database.</para>
|
||||
/// <seealso cref="IDbConnection"/>
|
||||
/// <seealso cref="FbConnection"/>
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <para>The <see cref="FbConnection"/> for this database.</para>
|
||||
/// </returns>
|
||||
public override IDbConnection GetConnection()
|
||||
{
|
||||
|
||||
//try
|
||||
//{
|
||||
return new FbConnection(ConnectionString);
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// System.Diagnostics.Debugger.Break();
|
||||
// ClearPool();
|
||||
// return new FbConnection(ConnectionString);
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We don't need stored procedures currently so throw and exception
|
||||
/// </summary>
|
||||
/// <param name="storedProcedureName"></param>
|
||||
/// <returns></returns>
|
||||
// public override DBCommandWrapper GetStoredProcCommandWrapper(string storedProcedureName)
|
||||
// {
|
||||
//// ArgumentValidation.CheckForNullReference(storedProcedureName, "storedProcedureName");
|
||||
//// ArgumentValidation.CheckForEmptyString(storedProcedureName, "storedProcedureName");
|
||||
////
|
||||
//// return new SqlCommandWrapper(storedProcedureName, CommandType.StoredProcedure, ParameterToken);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Not supported
|
||||
/// </summary>
|
||||
/// <param name="storedProcedureName"></param>
|
||||
/// <param name="parameterValues"></param>
|
||||
/// <returns></returns>
|
||||
// public override DBCommandWrapper GetStoredProcCommandWrapper(string storedProcedureName, params object[] parameterValues)
|
||||
// {
|
||||
//// ArgumentValidation.CheckForNullReference(storedProcedureName, "storedProcedureName");
|
||||
//// ArgumentValidation.CheckForEmptyString(storedProcedureName, "storedProcedureName");
|
||||
//// ArgumentValidation.CheckForNullReference(parameterValues, "parameterValues");
|
||||
////
|
||||
//// return new SqlCommandWrapper(storedProcedureName, CommandType.StoredProcedure, ParameterToken, parameterValues);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Create an <see cref="FbCommandWrapper"/> for a SQL query.</para>
|
||||
/// </summary>
|
||||
/// <param name="query"><para>The text of the query.</para></param>
|
||||
/// <returns><para>The <see cref="DBCommandWrapper"/> for the SQL query.</para></returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <para><paramref name="query"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para><paramref name="query"/> hast not been initialized.</para>
|
||||
/// </exception>
|
||||
public override DBCommandWrapper GetSqlStringCommandWrapper(string query)
|
||||
{
|
||||
ArgumentValidation.CheckForNullReference(query, "query");
|
||||
ArgumentValidation.CheckForEmptyString(query, "query");
|
||||
//Firebird uses the keyword FIRST exactly the same as ms sql TOP
|
||||
query=query.Replace(" TOP "," FIRST ");
|
||||
return new FireBirdCommandWrapper(query, CommandType.Text, ParameterToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Create a <see cref="FbDataAdapter"/> with the given update behavior and connection.</para>
|
||||
/// </summary>
|
||||
/// <param name="updateBehavior">
|
||||
/// <para>One of the <see cref="UpdateBehavior"/> values.</para>
|
||||
/// </param>
|
||||
/// <param name="connection">
|
||||
/// <para>The open connection to the database.</para>
|
||||
/// </param>
|
||||
/// <returns>An <see cref="DbDataAdapter"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <para><paramref name="connection"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
|
||||
/// </exception>
|
||||
protected override DbDataAdapter GetDataAdapter(UpdateBehavior updateBehavior, IDbConnection connection)
|
||||
{
|
||||
string queryStringToBeFilledInLater = String.Empty;
|
||||
FbDataAdapter adapter = new FbDataAdapter(queryStringToBeFilledInLater, (FbConnection)connection);
|
||||
|
||||
if (updateBehavior == UpdateBehavior.Continue)
|
||||
{
|
||||
adapter.RowUpdated += new FbRowUpdatedEventHandler(OnFireBirdRowUpdated);
|
||||
}
|
||||
return adapter;
|
||||
}
|
||||
|
||||
|
||||
public override IDataReader ExecuteReader(DBCommandWrapper commandWrapper)
|
||||
{
|
||||
return new FireBirdDataReaderWrapper((FbDataReader)base.ExecuteReader(commandWrapper));
|
||||
}
|
||||
|
||||
|
||||
public override IDataReader ExecuteReader(DBCommandWrapper commandWrapper, IDbTransaction transaction)
|
||||
{
|
||||
return new FireBirdDataReaderWrapper((FbDataReader)base.ExecuteReader(commandWrapper, transaction));
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Listens for the RowUpdate event on a dataadapter to support UpdateBehavior.Continue
|
||||
/// </devdoc>
|
||||
private void OnFireBirdRowUpdated(object sender, FbRowUpdatedEventArgs rowThatCouldNotBeWritten)
|
||||
{
|
||||
if (rowThatCouldNotBeWritten.RecordsAffected == 0)
|
||||
{
|
||||
if (rowThatCouldNotBeWritten.Errors != null)
|
||||
{
|
||||
rowThatCouldNotBeWritten.Row.RowError = SR.ExceptionMessageUpdateDataSetRowFailure;
|
||||
rowThatCouldNotBeWritten.Status = UpdateStatus.SkipCurrentRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user