You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
168
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/DbDataRecord.cs
vendored
Normal file
168
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/DbDataRecord.cs
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel; //Component
|
||||
using System.Data;
|
||||
using System.Reflection; //Missing
|
||||
using System.Runtime.InteropServices; //Marshal
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class DbSchemaInfo
|
||||
{
|
||||
internal DbSchemaInfo()
|
||||
{
|
||||
}
|
||||
|
||||
internal string _name;
|
||||
internal string _typename;
|
||||
internal Type _type;
|
||||
internal ODBC32.SQL_TYPE? _dbtype;
|
||||
internal object _scale;
|
||||
internal object _precision;
|
||||
|
||||
// extension to allow BindCol
|
||||
//
|
||||
internal int _columnlength; //
|
||||
internal int _valueOffset; // offset to the data in the row buffer
|
||||
internal int _lengthOffset; // offset to the length in the row buffer
|
||||
internal ODBC32.SQL_C _sqlctype; // need this to bind the value
|
||||
internal ODBC32.SQL_TYPE _sql_type; // need that to properly marshal the value
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Cache
|
||||
//
|
||||
// This is a on-demand cache, only caching what the user requests.
|
||||
// The reational is that for ForwardOnly access (the default and LCD of drivers)
|
||||
// we cannot obtain the data more than once, and even GetData(0) (to determine is-null)
|
||||
// still obtains data for fixed lenght types.
|
||||
|
||||
// So simple code like:
|
||||
// if(!rReader.IsDBNull(i))
|
||||
// rReader.GetInt32(i)
|
||||
//
|
||||
// Would fail, unless we cache on the IsDBNull call, and return the cached
|
||||
// item for GetInt32. This actually improves perf anyway, (even if the driver could
|
||||
// support it), since we are not making a seperate interop call...
|
||||
|
||||
// We do not cache all columns, so reading out of order is still not
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
internal sealed class DbCache
|
||||
{
|
||||
//Data
|
||||
|
||||
private bool[] _isBadValue;
|
||||
private DbSchemaInfo[] _schema;
|
||||
private object[] _values;
|
||||
private OdbcDataReader _record;
|
||||
internal int _count;
|
||||
internal bool _randomaccess = true;
|
||||
|
||||
//Constructor
|
||||
internal DbCache(OdbcDataReader record, int count)
|
||||
{
|
||||
_count = count;
|
||||
_record = record;
|
||||
_randomaccess = (!record.IsBehavior(CommandBehavior.SequentialAccess));
|
||||
_values = new object[count];
|
||||
_isBadValue = new bool[count];
|
||||
}
|
||||
|
||||
//Accessor
|
||||
internal object this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isBadValue[i])
|
||||
{
|
||||
OverflowException innerException = (OverflowException)Values[i];
|
||||
throw new OverflowException(innerException.Message, innerException);
|
||||
}
|
||||
return Values[i];
|
||||
}
|
||||
set
|
||||
{
|
||||
Values[i] = value;
|
||||
_isBadValue[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
internal int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
}
|
||||
|
||||
internal void InvalidateValue(int i)
|
||||
{
|
||||
_isBadValue[i] = true;
|
||||
}
|
||||
|
||||
internal object[] Values
|
||||
{
|
||||
get
|
||||
{
|
||||
return _values;
|
||||
}
|
||||
}
|
||||
|
||||
internal object AccessIndex(int i)
|
||||
{
|
||||
//Note: We could put this directly in this[i], instead of having an explicit overload.
|
||||
//However that means that EVERY access into the cache takes the hit of checking, so
|
||||
//something as simple as the following code would take two hits. It's nice not to
|
||||
//have to take the hit when you know what your doing.
|
||||
//
|
||||
// if(cache[i] == null)
|
||||
// ....
|
||||
// return cache[i];
|
||||
|
||||
object[] values = this.Values;
|
||||
if (_randomaccess)
|
||||
{
|
||||
//Random
|
||||
//Means that the user can ask for the values int any order (ie: out of order).
|
||||
// In order to acheive this on a forward only stream, we need to actually
|
||||
// retreive all the value in between so they can go back to values they've skipped
|
||||
for (int c = 0; c < i; c++)
|
||||
{
|
||||
if (values[c] == null)
|
||||
{
|
||||
values[c] = _record.GetValue(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return values[i];
|
||||
}
|
||||
|
||||
internal DbSchemaInfo GetSchema(int i)
|
||||
{
|
||||
if (_schema == null)
|
||||
{
|
||||
_schema = new DbSchemaInfo[Count];
|
||||
}
|
||||
if (_schema[i] == null)
|
||||
{
|
||||
_schema[i] = new DbSchemaInfo();
|
||||
}
|
||||
return _schema[i];
|
||||
}
|
||||
|
||||
internal void FlushValues()
|
||||
{
|
||||
//Set all objects to null (to explcitly release them)
|
||||
//Note: SchemaInfo remains the same for all rows - no need to reget those...
|
||||
int count = _values.Length;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
_values[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1047
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/Odbc32.cs
vendored
Normal file
1047
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/Odbc32.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1242
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs
vendored
Normal file
1242
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
368
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcCommandBuilder.cs
vendored
Normal file
368
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcCommandBuilder.cs
vendored
Normal file
@@ -0,0 +1,368 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Data.ProviderBase;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
public sealed class OdbcCommandBuilder : DbCommandBuilder
|
||||
{
|
||||
public OdbcCommandBuilder() : base()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public OdbcCommandBuilder(OdbcDataAdapter adapter) : this()
|
||||
{
|
||||
DataAdapter = adapter;
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(null),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.OdbcCommandBuilder_DataAdapter), // MDAC 60524
|
||||
]
|
||||
new public OdbcDataAdapter DataAdapter
|
||||
{
|
||||
get
|
||||
{
|
||||
return (base.DataAdapter as OdbcDataAdapter);
|
||||
}
|
||||
set
|
||||
{
|
||||
base.DataAdapter = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void OdbcRowUpdatingHandler(object sender, OdbcRowUpdatingEventArgs ruevent)
|
||||
{
|
||||
RowUpdatingHandler(ruevent);
|
||||
}
|
||||
|
||||
new public OdbcCommand GetInsertCommand()
|
||||
{
|
||||
return (OdbcCommand)base.GetInsertCommand();
|
||||
}
|
||||
new public OdbcCommand GetInsertCommand(bool useColumnsForParameterNames)
|
||||
{
|
||||
return (OdbcCommand)base.GetInsertCommand(useColumnsForParameterNames);
|
||||
}
|
||||
|
||||
new public OdbcCommand GetUpdateCommand()
|
||||
{
|
||||
return (OdbcCommand)base.GetUpdateCommand();
|
||||
}
|
||||
new public OdbcCommand GetUpdateCommand(bool useColumnsForParameterNames)
|
||||
{
|
||||
return (OdbcCommand)base.GetUpdateCommand(useColumnsForParameterNames);
|
||||
}
|
||||
|
||||
new public OdbcCommand GetDeleteCommand()
|
||||
{
|
||||
return (OdbcCommand)base.GetDeleteCommand();
|
||||
}
|
||||
new public OdbcCommand GetDeleteCommand(bool useColumnsForParameterNames)
|
||||
{
|
||||
return (OdbcCommand)base.GetDeleteCommand(useColumnsForParameterNames);
|
||||
}
|
||||
|
||||
override protected string GetParameterName(int parameterOrdinal)
|
||||
{
|
||||
return "p" + parameterOrdinal.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
override protected string GetParameterName(string parameterName)
|
||||
{
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
override protected string GetParameterPlaceholder(int parameterOrdinal)
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
|
||||
override protected void ApplyParameterInfo(DbParameter parameter, DataRow datarow, StatementType statementType, bool whereClause)
|
||||
{
|
||||
OdbcParameter p = (OdbcParameter)parameter;
|
||||
object valueType = datarow[SchemaTableColumn.ProviderType];
|
||||
p.OdbcType = (OdbcType)valueType;
|
||||
|
||||
object bvalue = datarow[SchemaTableColumn.NumericPrecision];
|
||||
if (DBNull.Value != bvalue)
|
||||
{
|
||||
byte bval = (byte)(short)bvalue;
|
||||
p.PrecisionInternal = ((0xff != bval) ? bval : (byte)0);
|
||||
}
|
||||
|
||||
bvalue = datarow[SchemaTableColumn.NumericScale];
|
||||
if (DBNull.Value != bvalue)
|
||||
{
|
||||
byte bval = (byte)(short)bvalue;
|
||||
p.ScaleInternal = ((0xff != bval) ? bval : (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
static public void DeriveParameters(OdbcCommand command)
|
||||
{
|
||||
// MDAC 65927
|
||||
OdbcConnection.ExecutePermission.Demand();
|
||||
|
||||
if (null == command)
|
||||
{
|
||||
throw ADP.ArgumentNull("command");
|
||||
}
|
||||
switch (command.CommandType)
|
||||
{
|
||||
case System.Data.CommandType.Text:
|
||||
throw ADP.DeriveParametersNotSupported(command);
|
||||
case System.Data.CommandType.StoredProcedure:
|
||||
break;
|
||||
case System.Data.CommandType.TableDirect:
|
||||
// CommandType.TableDirect - do nothing, parameters are not supported
|
||||
throw ADP.DeriveParametersNotSupported(command);
|
||||
default:
|
||||
throw ADP.InvalidCommandType(command.CommandType);
|
||||
}
|
||||
if (ADP.IsEmpty(command.CommandText))
|
||||
{
|
||||
throw ADP.CommandTextRequired(ADP.DeriveParameters);
|
||||
}
|
||||
|
||||
OdbcConnection connection = command.Connection;
|
||||
|
||||
if (null == connection)
|
||||
{
|
||||
throw ADP.ConnectionRequired(ADP.DeriveParameters);
|
||||
}
|
||||
|
||||
ConnectionState state = connection.State;
|
||||
|
||||
if (ConnectionState.Open != state)
|
||||
{
|
||||
throw ADP.OpenConnectionRequired(ADP.DeriveParameters, state);
|
||||
}
|
||||
|
||||
OdbcParameter[] list = DeriveParametersFromStoredProcedure(connection, command);
|
||||
|
||||
OdbcParameterCollection parameters = command.Parameters;
|
||||
parameters.Clear();
|
||||
|
||||
int count = list.Length;
|
||||
if (0 < count)
|
||||
{
|
||||
for (int i = 0; i < list.Length; ++i)
|
||||
{
|
||||
parameters.Add(list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DeriveParametersFromStoredProcedure (
|
||||
// OdbcConnection connection,
|
||||
// OdbcCommand command);
|
||||
//
|
||||
// Uses SQLProcedureColumns to create an array of OdbcParameters
|
||||
//
|
||||
|
||||
static private OdbcParameter[] DeriveParametersFromStoredProcedure(OdbcConnection connection, OdbcCommand command)
|
||||
{
|
||||
List<OdbcParameter> rParams = new List<OdbcParameter>();
|
||||
|
||||
// following call ensures that the command has a statement handle allocated
|
||||
CMDWrapper cmdWrapper = command.GetStatementHandle();
|
||||
OdbcStatementHandle hstmt = cmdWrapper.StatementHandle;
|
||||
int cColsAffected;
|
||||
|
||||
// maps an enforced 4-part qualified string as follows
|
||||
// parts[0] = null - ignored but removal would be a run-time breaking change from V1.0
|
||||
// parts[1] = CatalogName (optional, may be null)
|
||||
// parts[2] = SchemaName (optional, may be null)
|
||||
// parts[3] = ProcedureName
|
||||
//
|
||||
string quote = connection.QuoteChar(ADP.DeriveParameters);
|
||||
string[] parts = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quote, quote, '.', 4, true, Res.ODBC_ODBCCommandText, false);
|
||||
if (null == parts[3])
|
||||
{ // match everett behavior, if the commandtext is nothing but whitespace set the command text to the whitespace
|
||||
parts[3] = command.CommandText;
|
||||
}
|
||||
// note: native odbc appears to ignore all but the procedure name
|
||||
ODBC32.RetCode retcode = hstmt.ProcedureColumns(parts[1], parts[2], parts[3], null);
|
||||
|
||||
// Note: the driver does not return an error if the given stored procedure does not exist
|
||||
// therefore we cannot handle that case and just return not parameters.
|
||||
|
||||
if (ODBC32.RetCode.SUCCESS != retcode)
|
||||
{
|
||||
connection.HandleError(hstmt, retcode);
|
||||
}
|
||||
|
||||
using (OdbcDataReader reader = new OdbcDataReader(command, cmdWrapper, CommandBehavior.Default))
|
||||
{
|
||||
reader.FirstResult();
|
||||
cColsAffected = reader.FieldCount;
|
||||
|
||||
// go through the returned rows and filter out relevant parameter data
|
||||
//
|
||||
while (reader.Read())
|
||||
{
|
||||
// devnote: column types are specified in the ODBC Programmer's Reference
|
||||
// COLUMN_TYPE Smallint 16bit
|
||||
// COLUMN_SIZE Integer 32bit
|
||||
// DECIMAL_DIGITS Smallint 16bit
|
||||
// NUM_PREC_RADIX Smallint 16bit
|
||||
|
||||
OdbcParameter parameter = new OdbcParameter();
|
||||
|
||||
parameter.ParameterName = reader.GetString(ODBC32.COLUMN_NAME - 1);
|
||||
switch ((ODBC32.SQL_PARAM)reader.GetInt16(ODBC32.COLUMN_TYPE - 1))
|
||||
{
|
||||
case ODBC32.SQL_PARAM.INPUT:
|
||||
parameter.Direction = ParameterDirection.Input;
|
||||
break;
|
||||
case ODBC32.SQL_PARAM.OUTPUT:
|
||||
parameter.Direction = ParameterDirection.Output;
|
||||
break;
|
||||
|
||||
case ODBC32.SQL_PARAM.INPUT_OUTPUT:
|
||||
parameter.Direction = ParameterDirection.InputOutput;
|
||||
break;
|
||||
case ODBC32.SQL_PARAM.RETURN_VALUE:
|
||||
parameter.Direction = ParameterDirection.ReturnValue;
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Unexpected Parametertype while DeriveParamters");
|
||||
break;
|
||||
}
|
||||
parameter.OdbcType = TypeMap.FromSqlType((ODBC32.SQL_TYPE)reader.GetInt16(ODBC32.DATA_TYPE - 1))._odbcType;
|
||||
parameter.Size = (int)reader.GetInt32(ODBC32.COLUMN_SIZE - 1);
|
||||
switch (parameter.OdbcType)
|
||||
{
|
||||
case OdbcType.Decimal:
|
||||
case OdbcType.Numeric:
|
||||
parameter.ScaleInternal = (Byte)reader.GetInt16(ODBC32.DECIMAL_DIGITS - 1);
|
||||
parameter.PrecisionInternal = (Byte)reader.GetInt16(ODBC32.NUM_PREC_RADIX - 1);
|
||||
break;
|
||||
}
|
||||
rParams.Add(parameter);
|
||||
}
|
||||
}
|
||||
retcode = hstmt.CloseCursor();
|
||||
return rParams.ToArray(); ;
|
||||
}
|
||||
|
||||
public override string QuoteIdentifier(string unquotedIdentifier)
|
||||
{
|
||||
return QuoteIdentifier(unquotedIdentifier, null /* use DataAdapter.SelectCommand.Connection if available */);
|
||||
}
|
||||
public string QuoteIdentifier(string unquotedIdentifier, OdbcConnection connection)
|
||||
{
|
||||
ADP.CheckArgumentNull(unquotedIdentifier, "unquotedIdentifier");
|
||||
|
||||
// if the user has specificed a prefix use the user specified prefix and suffix
|
||||
// otherwise get them from the provider
|
||||
string quotePrefix = QuotePrefix;
|
||||
string quoteSuffix = QuoteSuffix;
|
||||
if (ADP.IsEmpty(quotePrefix) == true)
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
// VSTFDEVDIV 479567: use the adapter's connection if QuoteIdentifier was called from
|
||||
// DbCommandBuilder instance (which does not have an overload that gets connection object)
|
||||
connection = base.GetConnection() as OdbcConnection;
|
||||
if (connection == null)
|
||||
{
|
||||
throw ADP.QuotePrefixNotSet(ADP.QuoteIdentifier);
|
||||
}
|
||||
}
|
||||
quotePrefix = connection.QuoteChar(ADP.QuoteIdentifier);
|
||||
quoteSuffix = quotePrefix;
|
||||
}
|
||||
|
||||
// by the ODBC spec "If the data source does not support quoted identifiers, a blank is returned."
|
||||
// So if a blank is returned the string is returned unchanged. Otherwise the returned string is used
|
||||
// to quote the string
|
||||
if ((ADP.IsEmpty(quotePrefix) == false) && (quotePrefix != " "))
|
||||
{
|
||||
return ADP.BuildQuotedString(quotePrefix, quoteSuffix, unquotedIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
return unquotedIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override protected void SetRowUpdatingHandler(DbDataAdapter adapter)
|
||||
{
|
||||
Debug.Assert(adapter is OdbcDataAdapter, "!OdbcDataAdapter");
|
||||
if (adapter == base.DataAdapter)
|
||||
{ // removal case
|
||||
((OdbcDataAdapter)adapter).RowUpdating -= OdbcRowUpdatingHandler;
|
||||
}
|
||||
else
|
||||
{ // adding case
|
||||
((OdbcDataAdapter)adapter).RowUpdating += OdbcRowUpdatingHandler;
|
||||
}
|
||||
}
|
||||
|
||||
public override string UnquoteIdentifier(string quotedIdentifier)
|
||||
{
|
||||
return UnquoteIdentifier(quotedIdentifier, null /* use DataAdapter.SelectCommand.Connection if available */);
|
||||
}
|
||||
|
||||
public string UnquoteIdentifier(string quotedIdentifier, OdbcConnection connection)
|
||||
{
|
||||
ADP.CheckArgumentNull(quotedIdentifier, "quotedIdentifier");
|
||||
|
||||
|
||||
// if the user has specificed a prefix use the user specified prefix and suffix
|
||||
// otherwise get them from the provider
|
||||
string quotePrefix = QuotePrefix;
|
||||
string quoteSuffix = QuoteSuffix;
|
||||
if (ADP.IsEmpty(quotePrefix) == true)
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
// VSTFDEVDIV 479567: use the adapter's connection if UnquoteIdentifier was called from
|
||||
// DbCommandBuilder instance (which does not have an overload that gets connection object)
|
||||
connection = base.GetConnection() as OdbcConnection;
|
||||
if (connection == null)
|
||||
{
|
||||
throw ADP.QuotePrefixNotSet(ADP.UnquoteIdentifier);
|
||||
}
|
||||
}
|
||||
quotePrefix = connection.QuoteChar(ADP.UnquoteIdentifier);
|
||||
quoteSuffix = quotePrefix;
|
||||
}
|
||||
|
||||
String unquotedIdentifier;
|
||||
// by the ODBC spec "If the data source does not support quoted identifiers, a blank is returned."
|
||||
// So if a blank is returned the string is returned unchanged. Otherwise the returned string is used
|
||||
// to unquote the string
|
||||
if ((ADP.IsEmpty(quotePrefix) == false) || (quotePrefix != " "))
|
||||
{
|
||||
// ignoring the return value because it is acceptable for the quotedString to not be quoted in this
|
||||
// context.
|
||||
ADP.RemoveStringQuotes(quotePrefix, quoteSuffix, quotedIdentifier, out unquotedIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
unquotedIdentifier = quotedIdentifier;
|
||||
}
|
||||
return unquotedIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
1046
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs
vendored
Normal file
1046
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
207
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionFactory.cs
vendored
Normal file
207
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionFactory.cs
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.Data.Common;
|
||||
using System.Data.ProviderBase;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcConnectionFactory : DbConnectionFactory
|
||||
{
|
||||
private OdbcConnectionFactory() : base() { }
|
||||
// At this time, the ODBC Provider doesn't have any connection pool counters
|
||||
// because we'd only confuse people with "non-pooled" connections that are
|
||||
// actually being pooled by the native pooler.
|
||||
|
||||
private const string _MetaData = ":MetaDataXml";
|
||||
private const string _defaultMetaDataXml = "defaultMetaDataXml";
|
||||
|
||||
public static readonly OdbcConnectionFactory SingletonInstance = new OdbcConnectionFactory();
|
||||
|
||||
override public DbProviderFactory ProviderFactory
|
||||
{
|
||||
get
|
||||
{
|
||||
return OdbcFactory.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
|
||||
{
|
||||
DbConnectionInternal result = new OdbcConnectionOpen(owningObject as OdbcConnection, options as OdbcConnectionString);
|
||||
return result;
|
||||
}
|
||||
|
||||
override protected DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous)
|
||||
{
|
||||
Debug.Assert(!ADP.IsEmpty(connectionString), "empty connectionString");
|
||||
OdbcConnectionString result = new OdbcConnectionString(connectionString, (null != previous));
|
||||
return result;
|
||||
}
|
||||
|
||||
override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions)
|
||||
{
|
||||
// At this time, the ODBC provider only supports native pooling so we
|
||||
// simply return NULL to indicate that.
|
||||
return null;
|
||||
}
|
||||
|
||||
override internal DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions)
|
||||
{
|
||||
return new OdbcConnectionPoolGroupProviderInfo();
|
||||
}
|
||||
|
||||
// SxS (VSDD 545786): metadata files are opened from <.NetRuntimeFolder>\CONFIG\<metadatafilename.xml>
|
||||
// this operation is safe in SxS because the file is opened in read-only mode and each NDP runtime accesses its own copy of the metadata
|
||||
// under the runtime folder.
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
override protected DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal internalConnection, out bool cacheMetaDataFactory)
|
||||
{
|
||||
Debug.Assert(internalConnection != null, "internalConnection may not be null.");
|
||||
cacheMetaDataFactory = false;
|
||||
|
||||
OdbcConnection odbcOuterConnection = ((OdbcConnectionOpen)internalConnection).OuterConnection;
|
||||
Debug.Assert(odbcOuterConnection != null, "outer connection may not be null.");
|
||||
|
||||
NameValueCollection settings = (NameValueCollection)PrivilegedConfigurationManager.GetSection("system.data.odbc");
|
||||
Stream XMLStream = null;
|
||||
|
||||
// get the DBMS Name
|
||||
object driverName = null;
|
||||
string stringValue = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DRIVER_NAME);
|
||||
if (stringValue != null)
|
||||
{
|
||||
driverName = stringValue;
|
||||
}
|
||||
|
||||
if (settings != null)
|
||||
{
|
||||
string[] values = null;
|
||||
string metaDataXML = null;
|
||||
// first try to get the provider specific xml
|
||||
|
||||
// if driver name is not supported we can't build the settings key needed to
|
||||
// get the provider specific XML path
|
||||
if (driverName != null)
|
||||
{
|
||||
metaDataXML = ((string)driverName) + _MetaData;
|
||||
values = settings.GetValues(metaDataXML);
|
||||
}
|
||||
|
||||
// if we did not find provider specific xml see if there is new default xml
|
||||
if (values == null)
|
||||
{
|
||||
metaDataXML = _defaultMetaDataXml;
|
||||
values = settings.GetValues(metaDataXML);
|
||||
}
|
||||
|
||||
// If there is an XML file get it
|
||||
if (values != null)
|
||||
{
|
||||
XMLStream = ADP.GetXmlStreamFromValues(values, metaDataXML);
|
||||
}
|
||||
}
|
||||
|
||||
// use the embedded xml if the user did not over ride it
|
||||
if (XMLStream == null)
|
||||
{
|
||||
XMLStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("System.Data.Odbc.OdbcMetaData.xml");
|
||||
cacheMetaDataFactory = true;
|
||||
}
|
||||
|
||||
Debug.Assert(XMLStream != null, "XMLstream may not be null.");
|
||||
|
||||
String versionString = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DBMS_VER);
|
||||
|
||||
return new OdbcMetaDataFactory(XMLStream,
|
||||
versionString,
|
||||
versionString,
|
||||
odbcOuterConnection);
|
||||
}
|
||||
|
||||
override internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection)
|
||||
{
|
||||
OdbcConnection c = (connection as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
return c.PoolGroup;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
override internal DbConnectionInternal GetInnerConnection(DbConnection connection)
|
||||
{
|
||||
OdbcConnection c = (connection as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
return c.InnerConnection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
override protected int GetObjectId(DbConnection connection)
|
||||
{
|
||||
OdbcConnection c = (connection as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
return c.ObjectID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
override internal void PermissionDemand(DbConnection outerConnection)
|
||||
{
|
||||
OdbcConnection c = (outerConnection as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
c.PermissionDemand();
|
||||
}
|
||||
}
|
||||
|
||||
override internal void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup)
|
||||
{
|
||||
OdbcConnection c = (outerConnection as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
c.PoolGroup = poolGroup;
|
||||
}
|
||||
}
|
||||
|
||||
override internal void SetInnerConnectionEvent(DbConnection owningObject, DbConnectionInternal to)
|
||||
{
|
||||
OdbcConnection c = (owningObject as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
c.SetInnerConnectionEvent(to);
|
||||
}
|
||||
}
|
||||
|
||||
override internal bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from)
|
||||
{
|
||||
OdbcConnection c = (owningObject as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
return c.SetInnerConnectionFrom(to, from);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override internal void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to)
|
||||
{
|
||||
OdbcConnection c = (owningObject as OdbcConnection);
|
||||
if (null != c)
|
||||
{
|
||||
c.SetInnerConnectionTo(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
297
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionHandle.cs
vendored
Normal file
297
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionHandle.cs
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcConnectionHandle : OdbcHandle
|
||||
{
|
||||
private HandleState _handleState;
|
||||
|
||||
private enum HandleState
|
||||
{
|
||||
Allocated = 0,
|
||||
Connected = 1,
|
||||
Transacted = 2,
|
||||
TransactionInProgress = 3,
|
||||
}
|
||||
|
||||
internal OdbcConnectionHandle(OdbcConnection connection, OdbcConnectionString constr, OdbcEnvironmentHandle environmentHandle) : base(ODBC32.SQL_HANDLE.DBC, environmentHandle)
|
||||
{
|
||||
if (null == connection)
|
||||
{
|
||||
throw ADP.ArgumentNull("connection");
|
||||
}
|
||||
if (null == constr)
|
||||
{
|
||||
throw ADP.ArgumentNull("constr");
|
||||
}
|
||||
|
||||
ODBC32.RetCode retcode;
|
||||
|
||||
//Set connection timeout (only before open).
|
||||
//Note: We use login timeout since its odbc 1.0 option, instead of using
|
||||
//connectiontimeout (which affects other things besides just login) and its
|
||||
//a odbc 3.0 feature. The ConnectionTimeout on the managed providers represents
|
||||
//the login timeout, nothing more.
|
||||
int connectionTimeout = connection.ConnectionTimeout;
|
||||
retcode = SetConnectionAttribute2(ODBC32.SQL_ATTR.LOGIN_TIMEOUT, (IntPtr)connectionTimeout, (Int32)ODBC32.SQL_IS.UINTEGER);
|
||||
|
||||
string connectionString = constr.UsersConnectionString(false);
|
||||
|
||||
// Connect to the driver. (Using the connection string supplied)
|
||||
//Note: The driver doesn't filter out the password in the returned connection string
|
||||
//so their is no need for us to obtain the returned connection string
|
||||
// Prepare to handle a ThreadAbort Exception between SQLDriverConnectW and update of the state variables
|
||||
retcode = Connect(connectionString);
|
||||
connection.HandleError(this, retcode);
|
||||
}
|
||||
|
||||
private ODBC32.RetCode AutoCommitOff()
|
||||
{
|
||||
ODBC32.RetCode retcode;
|
||||
|
||||
Debug.Assert(HandleState.Connected <= _handleState, "AutoCommitOff while in wrong state?");
|
||||
|
||||
// Avoid runtime injected errors in the following block.
|
||||
// must call SQLSetConnectAttrW and set _handleState
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
retcode = UnsafeNativeMethods.SQLSetConnectAttrW(this, ODBC32.SQL_ATTR.AUTOCOMMIT, ODBC32.SQL_AUTOCOMMIT_OFF, (Int32)ODBC32.SQL_IS.UINTEGER);
|
||||
switch (retcode)
|
||||
{
|
||||
case ODBC32.RetCode.SUCCESS:
|
||||
case ODBC32.RetCode.SUCCESS_WITH_INFO:
|
||||
_handleState = HandleState.Transacted;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ODBC.TraceODBC(3, "SQLSetConnectAttrW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode BeginTransaction(ref IsolationLevel isolevel)
|
||||
{
|
||||
ODBC32.RetCode retcode = ODBC32.RetCode.SUCCESS;
|
||||
ODBC32.SQL_ATTR isolationAttribute;
|
||||
if (IsolationLevel.Unspecified != isolevel)
|
||||
{
|
||||
ODBC32.SQL_TRANSACTION sql_iso;
|
||||
switch (isolevel)
|
||||
{
|
||||
case IsolationLevel.ReadUncommitted:
|
||||
sql_iso = ODBC32.SQL_TRANSACTION.READ_UNCOMMITTED;
|
||||
isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
|
||||
break;
|
||||
case IsolationLevel.ReadCommitted:
|
||||
sql_iso = ODBC32.SQL_TRANSACTION.READ_COMMITTED;
|
||||
isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
|
||||
break;
|
||||
case IsolationLevel.RepeatableRead:
|
||||
sql_iso = ODBC32.SQL_TRANSACTION.REPEATABLE_READ;
|
||||
isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
|
||||
break;
|
||||
case IsolationLevel.Serializable:
|
||||
sql_iso = ODBC32.SQL_TRANSACTION.SERIALIZABLE;
|
||||
isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
|
||||
break;
|
||||
case IsolationLevel.Snapshot:
|
||||
sql_iso = ODBC32.SQL_TRANSACTION.SNAPSHOT;
|
||||
// VSDD 414121: Snapshot isolation level must be set through SQL_COPT_SS_TXN_ISOLATION (http://msdn.microsoft.com/en-us/library/ms131709.aspx)
|
||||
isolationAttribute = ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION;
|
||||
break;
|
||||
case IsolationLevel.Chaos:
|
||||
throw ODBC.NotSupportedIsolationLevel(isolevel);
|
||||
default:
|
||||
throw ADP.InvalidIsolationLevel(isolevel);
|
||||
}
|
||||
|
||||
//Set the isolation level (unless its unspecified)
|
||||
retcode = SetConnectionAttribute2(isolationAttribute, (IntPtr)sql_iso, (Int32)ODBC32.SQL_IS.INTEGER);
|
||||
|
||||
//Note: The Driver can return success_with_info to indicate it "rolled" the
|
||||
//isolevel to the next higher value. If this is the case, we need to requery
|
||||
//the value if th euser asks for it...
|
||||
//We also still propagate the info, since it could be other info as well...
|
||||
|
||||
if (ODBC32.RetCode.SUCCESS_WITH_INFO == retcode)
|
||||
{
|
||||
isolevel = IsolationLevel.Unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
switch (retcode)
|
||||
{
|
||||
case ODBC32.RetCode.SUCCESS:
|
||||
case ODBC32.RetCode.SUCCESS_WITH_INFO:
|
||||
//Turn off auto-commit (which basically starts the transaction)
|
||||
retcode = AutoCommitOff();
|
||||
_handleState = HandleState.TransactionInProgress;
|
||||
break;
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode CompleteTransaction(short transactionOperation)
|
||||
{
|
||||
bool mustRelease = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
DangerousAddRef(ref mustRelease);
|
||||
ODBC32.RetCode retcode = CompleteTransaction(transactionOperation, base.handle);
|
||||
return retcode;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mustRelease)
|
||||
{
|
||||
DangerousRelease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
private ODBC32.RetCode CompleteTransaction(short transactionOperation, IntPtr handle)
|
||||
{
|
||||
// must only call this code from ReleaseHandle or DangerousAddRef region
|
||||
|
||||
ODBC32.RetCode retcode = ODBC32.RetCode.SUCCESS;
|
||||
|
||||
// using ConstrainedRegions to make the native ODBC call and change the _handleState
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
if (HandleState.TransactionInProgress == _handleState)
|
||||
{
|
||||
retcode = UnsafeNativeMethods.SQLEndTran(HandleType, handle, transactionOperation);
|
||||
if ((ODBC32.RetCode.SUCCESS == retcode) || (ODBC32.RetCode.SUCCESS_WITH_INFO == retcode))
|
||||
{
|
||||
_handleState = HandleState.Transacted;
|
||||
}
|
||||
Bid.TraceSqlReturn("<odbc.SQLEndTran|API|ODBC|RET> %08X{SQLRETURN}\n", retcode);
|
||||
}
|
||||
|
||||
if (HandleState.Transacted == _handleState)
|
||||
{ // AutoCommitOn
|
||||
retcode = UnsafeNativeMethods.SQLSetConnectAttrW(handle, ODBC32.SQL_ATTR.AUTOCOMMIT, ODBC32.SQL_AUTOCOMMIT_ON, (Int32)ODBC32.SQL_IS.UINTEGER);
|
||||
_handleState = HandleState.Connected;
|
||||
Bid.TraceSqlReturn("<odbc.SQLSetConnectAttr|API|ODBC|RET> %08X{SQLRETURN}\n", retcode);
|
||||
}
|
||||
}
|
||||
//Overactive assert which fires if handle was allocated - but failed to connect to the server
|
||||
//it can more legitmately fire if transaction failed to rollback - but there isn't much we can do in that situation
|
||||
//Debug.Assert((HandleState.Connected == _handleState) || (HandleState.TransactionInProgress == _handleState), "not expected HandleState.Connected");
|
||||
return retcode;
|
||||
}
|
||||
private ODBC32.RetCode Connect(string connectionString)
|
||||
{
|
||||
Debug.Assert(HandleState.Allocated == _handleState, "SQLDriverConnect while in wrong state?");
|
||||
|
||||
ODBC32.RetCode retcode;
|
||||
|
||||
// Avoid runtime injected errors in the following block.
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
short cbActualSize;
|
||||
retcode = UnsafeNativeMethods.SQLDriverConnectW(this, ADP.PtrZero, connectionString, ODBC32.SQL_NTS, ADP.PtrZero, 0, out cbActualSize, (short)ODBC32.SQL_DRIVER.NOPROMPT);
|
||||
switch (retcode)
|
||||
{
|
||||
case ODBC32.RetCode.SUCCESS:
|
||||
case ODBC32.RetCode.SUCCESS_WITH_INFO:
|
||||
_handleState = HandleState.Connected;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ODBC.TraceODBC(3, "SQLDriverConnectW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
override protected bool ReleaseHandle()
|
||||
{
|
||||
// NOTE: The SafeHandle class guarantees this will be called exactly once and is non-interrutible.
|
||||
ODBC32.RetCode retcode;
|
||||
|
||||
// must call complete the transaction rollback, change handle state, and disconnect the connection
|
||||
retcode = CompleteTransaction(ODBC32.SQL_ROLLBACK, handle);
|
||||
|
||||
if ((HandleState.Connected == _handleState) || (HandleState.TransactionInProgress == _handleState))
|
||||
{
|
||||
retcode = UnsafeNativeMethods.SQLDisconnect(handle);
|
||||
_handleState = HandleState.Allocated;
|
||||
Bid.TraceSqlReturn("<odbc.SQLDisconnect|API|ODBC|RET> %08X{SQLRETURN}\n", retcode);
|
||||
}
|
||||
Debug.Assert(HandleState.Allocated == _handleState, "not expected HandleState.Allocated");
|
||||
return base.ReleaseHandle();
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetConnectionAttribute(ODBC32.SQL_ATTR attribute, byte[] buffer, out int cbActual)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetConnectAttrW(this, attribute, buffer, buffer.Length, out cbActual);
|
||||
Bid.Trace("<odbc.SQLGetConnectAttr|ODBC> SQLRETURN=%d, Attribute=%d, BufferLength=%d, StringLength=%d\n", (int)retcode, (int)attribute, buffer.Length, (int)cbActual);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetFunctions(ODBC32.SQL_API fFunction, out Int16 fExists)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetFunctions(this, fFunction, out fExists);
|
||||
ODBC.TraceODBC(3, "SQLGetFunctions", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetInfo2(ODBC32.SQL_INFO info, byte[] buffer, out short cbActual)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetInfoW(this, info, buffer, checked((short)buffer.Length), out cbActual);
|
||||
Bid.Trace("<odbc.SQLGetInfo|ODBC> SQLRETURN=%d, InfoType=%d, BufferLength=%d, StringLength=%d\n", (int)retcode, (int)info, buffer.Length, (int)cbActual);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetInfo1(ODBC32.SQL_INFO info, byte[] buffer)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetInfoW(this, info, buffer, checked((short)buffer.Length), ADP.PtrZero);
|
||||
Bid.Trace("<odbc.SQLGetInfo|ODBC> SQLRETURN=%d, InfoType=%d, BufferLength=%d\n", (int)retcode, (int)info, buffer.Length);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode SetConnectionAttribute2(ODBC32.SQL_ATTR attribute, IntPtr value, Int32 length)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetConnectAttrW(this, attribute, value, length);
|
||||
ODBC.TraceODBC(3, "SQLSetConnectAttrW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode SetConnectionAttribute3(ODBC32.SQL_ATTR attribute, string buffer, Int32 length)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetConnectAttrW(this, attribute, buffer, length);
|
||||
Bid.Trace("<odbc.SQLSetConnectAttr|ODBC> SQLRETURN=%d, Attribute=%d, BufferLength=%d\n", (int)retcode, (int)attribute, buffer.Length);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode SetConnectionAttribute4(ODBC32.SQL_ATTR attribute, System.Transactions.IDtcTransaction transaction, Int32 length)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetConnectAttrW(this, attribute, transaction, length);
|
||||
ODBC.TraceODBC(3, "SQLSetConnectAttrW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
93
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionOpen.cs
vendored
Normal file
93
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionOpen.cs
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Data.ProviderBase;
|
||||
using System.Threading;
|
||||
using SysTx = System.Transactions;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcConnectionOpen : DbConnectionInternal
|
||||
{
|
||||
// Construct from a compiled connection string
|
||||
internal OdbcConnectionOpen(OdbcConnection outerConnection, OdbcConnectionString connectionOptions)
|
||||
{
|
||||
#if DEBUG
|
||||
try { // use this to help validate this object is only created after the following permission has been previously demanded in the current codepath
|
||||
if (null != outerConnection) {
|
||||
outerConnection.UserConnectionOptions.DemandPermission();
|
||||
}
|
||||
else {
|
||||
connectionOptions.DemandPermission();
|
||||
}
|
||||
}
|
||||
catch(System.Security.SecurityException) {
|
||||
System.Diagnostics.Debug.Assert(false, "unexpected SecurityException for current codepath");
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
OdbcEnvironmentHandle environmentHandle = OdbcEnvironment.GetGlobalEnvironmentHandle();
|
||||
outerConnection.ConnectionHandle = new OdbcConnectionHandle(outerConnection, connectionOptions, environmentHandle);
|
||||
}
|
||||
|
||||
internal OdbcConnection OuterConnection
|
||||
{
|
||||
get
|
||||
{
|
||||
OdbcConnection outerConnection = (OdbcConnection)Owner;
|
||||
|
||||
if (null == outerConnection)
|
||||
throw ODBC.OpenConnectionNoOwner();
|
||||
|
||||
return outerConnection;
|
||||
}
|
||||
}
|
||||
|
||||
override public string ServerVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return OuterConnection.Open_GetServerVersion();
|
||||
}
|
||||
}
|
||||
|
||||
override protected void Activate(SysTx.Transaction transaction)
|
||||
{
|
||||
OdbcConnection.ExecutePermission.Demand();
|
||||
}
|
||||
|
||||
override public DbTransaction BeginTransaction(IsolationLevel isolevel)
|
||||
{
|
||||
return BeginOdbcTransaction(isolevel);
|
||||
}
|
||||
|
||||
internal OdbcTransaction BeginOdbcTransaction(IsolationLevel isolevel)
|
||||
{
|
||||
return OuterConnection.Open_BeginTransaction(isolevel);
|
||||
}
|
||||
|
||||
override public void ChangeDatabase(string value)
|
||||
{
|
||||
OuterConnection.Open_ChangeDatabase(value);
|
||||
}
|
||||
|
||||
override protected DbReferenceCollection CreateReferenceCollection()
|
||||
{
|
||||
return new OdbcReferenceCollection();
|
||||
}
|
||||
|
||||
override protected void Deactivate()
|
||||
{
|
||||
NotifyWeakReference(OdbcReferenceCollection.Closing);
|
||||
}
|
||||
|
||||
override public void EnlistTransaction(SysTx.Transaction transaction)
|
||||
{
|
||||
OuterConnection.Open_EnlistTransaction(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
248
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs
vendored
Normal file
248
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.ProviderBase;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcConnectionPoolGroupProviderInfo : DbConnectionPoolGroupProviderInfo
|
||||
{
|
||||
private string _driverName;
|
||||
private string _driverVersion;
|
||||
private string _quoteChar;
|
||||
|
||||
private char _escapeChar;
|
||||
private bool _hasQuoteChar;
|
||||
private bool _hasEscapeChar;
|
||||
|
||||
private bool _isV3Driver;
|
||||
private int _supportedSQLTypes;
|
||||
private int _testedSQLTypes;
|
||||
private int _restrictedSQLBindTypes; // These, otherwise supported types, are not available for binding
|
||||
|
||||
// flags for unsupported Attributes
|
||||
private bool _noCurrentCatalog;
|
||||
private bool _noConnectionDead;
|
||||
|
||||
private bool _noQueryTimeout;
|
||||
private bool _noSqlSoptSSNoBrowseTable;
|
||||
private bool _noSqlSoptSSHiddenColumns;
|
||||
|
||||
// SSS_WARNINGS_OFF
|
||||
private bool _noSqlCASSColumnKey;
|
||||
// SSS_WARNINGS_ON
|
||||
|
||||
// flags for unsupported Functions
|
||||
private bool _noSqlPrimaryKeys;
|
||||
|
||||
internal string DriverName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _driverName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_driverName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string DriverVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return _driverVersion;
|
||||
}
|
||||
set
|
||||
{
|
||||
_driverVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasQuoteChar
|
||||
{
|
||||
// the value is set together with the QuoteChar (see set_QuoteChar);
|
||||
get
|
||||
{
|
||||
return _hasQuoteChar;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasEscapeChar
|
||||
{
|
||||
// the value is set together with the EscapeChar (see set_EscapeChar);
|
||||
get
|
||||
{
|
||||
return _hasEscapeChar;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal string QuoteChar
|
||||
{
|
||||
get
|
||||
{
|
||||
return _quoteChar;
|
||||
}
|
||||
set
|
||||
{
|
||||
_quoteChar = value;
|
||||
_hasQuoteChar = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal char EscapeChar
|
||||
{
|
||||
get
|
||||
{
|
||||
return _escapeChar;
|
||||
}
|
||||
set
|
||||
{
|
||||
_escapeChar = value;
|
||||
_hasEscapeChar = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsV3Driver
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isV3Driver;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isV3Driver = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal int SupportedSQLTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _supportedSQLTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
_supportedSQLTypes = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal int TestedSQLTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _testedSQLTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
_testedSQLTypes = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal int RestrictedSQLBindTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _restrictedSQLBindTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
_restrictedSQLBindTypes = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal bool NoCurrentCatalog
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noCurrentCatalog;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noCurrentCatalog = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool NoConnectionDead
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noConnectionDead;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noConnectionDead = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal bool NoQueryTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noQueryTimeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noQueryTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool NoSqlSoptSSNoBrowseTable
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noSqlSoptSSNoBrowseTable;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noSqlSoptSSNoBrowseTable = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool NoSqlSoptSSHiddenColumns
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noSqlSoptSSHiddenColumns;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noSqlSoptSSHiddenColumns = value;
|
||||
}
|
||||
}
|
||||
|
||||
// SSS_WARNINGS_OFF
|
||||
internal bool NoSqlCASSColumnKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noSqlCASSColumnKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noSqlCASSColumnKey = value;
|
||||
}
|
||||
}
|
||||
// SSS_WARNINGS_ON
|
||||
|
||||
internal bool NoSqlPrimaryKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
return _noSqlPrimaryKeys;
|
||||
}
|
||||
set
|
||||
{
|
||||
_noSqlPrimaryKeys = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
73
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionString.cs
vendored
Normal file
73
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionString.cs
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcConnectionString : DbConnectionOptions
|
||||
{
|
||||
// instances of this class are intended to be immutable, i.e readonly
|
||||
// used by pooling classes so it is much easier to verify correctness
|
||||
// when not worried about the class being modified during execution
|
||||
|
||||
private static class KEY
|
||||
{
|
||||
internal const string SaveFile = "savefile";
|
||||
}
|
||||
|
||||
private readonly string _expandedConnectionString;
|
||||
|
||||
internal OdbcConnectionString(string connectionString, bool validate) : base(connectionString, null, true)
|
||||
{
|
||||
if (!validate)
|
||||
{
|
||||
string filename = null;
|
||||
int position = 0;
|
||||
_expandedConnectionString = ExpandDataDirectories(ref filename, ref position);
|
||||
}
|
||||
if (validate || (null == _expandedConnectionString))
|
||||
{
|
||||
// do not check string length if it was expanded because the final result may be shorter than the original
|
||||
if ((null != connectionString) && (ODBC32.MAX_CONNECTION_STRING_LENGTH < connectionString.Length))
|
||||
{ // MDAC 83536
|
||||
throw ODBC.ConnectionStringTooLong();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override System.Security.PermissionSet CreatePermissionSet()
|
||||
{
|
||||
System.Security.PermissionSet permissionSet;
|
||||
if (ContainsKey(KEY.SaveFile))
|
||||
{
|
||||
permissionSet = new NamedPermissionSet("FullTrust");
|
||||
}
|
||||
else
|
||||
{
|
||||
permissionSet = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
|
||||
permissionSet.AddPermission(new OdbcPermission(this));
|
||||
}
|
||||
return permissionSet;
|
||||
}
|
||||
|
||||
protected internal override string Expand()
|
||||
{
|
||||
if (null != _expandedConnectionString)
|
||||
{
|
||||
return _expandedConnectionString;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.Expand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
384
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionStringbuilder.cs
vendored
Normal file
384
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcConnectionStringbuilder.cs
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
[DefaultProperty("Driver")]
|
||||
[System.ComponentModel.TypeConverterAttribute(typeof(OdbcConnectionStringBuilder.OdbcConnectionStringBuilderConverter))]
|
||||
public sealed class OdbcConnectionStringBuilder : DbConnectionStringBuilder
|
||||
{
|
||||
private enum Keywords
|
||||
{ // must maintain same ordering as _validKeywords array
|
||||
// NamedConnection,
|
||||
Dsn,
|
||||
|
||||
Driver,
|
||||
}
|
||||
|
||||
private static readonly string[] s_validKeywords;
|
||||
private static readonly Dictionary<string, Keywords> s_keywords;
|
||||
|
||||
private string[] _knownKeywords;
|
||||
|
||||
private string _dsn = DbConnectionStringDefaults.Dsn;
|
||||
// private string _namedConnection = DbConnectionStringDefaults.NamedConnection;
|
||||
|
||||
private string _driver = DbConnectionStringDefaults.Driver;
|
||||
|
||||
static OdbcConnectionStringBuilder()
|
||||
{
|
||||
string[] validKeywords = new string[2];
|
||||
validKeywords[(int)Keywords.Driver] = DbConnectionStringKeywords.Driver;
|
||||
validKeywords[(int)Keywords.Dsn] = DbConnectionStringKeywords.Dsn;
|
||||
// validKeywords[(int)Keywords.NamedConnection] = DbConnectionStringKeywords.NamedConnection;
|
||||
s_validKeywords = validKeywords;
|
||||
|
||||
Dictionary<string, Keywords> hash = new Dictionary<string, Keywords>(2, StringComparer.OrdinalIgnoreCase);
|
||||
hash.Add(DbConnectionStringKeywords.Driver, Keywords.Driver);
|
||||
hash.Add(DbConnectionStringKeywords.Dsn, Keywords.Dsn);
|
||||
// hash.Add(DbConnectionStringKeywords.NamedConnection, Keywords.NamedConnection);
|
||||
Debug.Assert(2 == hash.Count, "initial expected size is incorrect");
|
||||
s_keywords = hash;
|
||||
}
|
||||
|
||||
public OdbcConnectionStringBuilder() : this((string)null)
|
||||
{
|
||||
}
|
||||
|
||||
public OdbcConnectionStringBuilder(string connectionString) : base(true)
|
||||
{
|
||||
if (!ADP.IsEmpty(connectionString))
|
||||
{
|
||||
ConnectionString = connectionString;
|
||||
}
|
||||
}
|
||||
|
||||
public override object this[string keyword]
|
||||
{
|
||||
get
|
||||
{
|
||||
ADP.CheckArgumentNull(keyword, "keyword");
|
||||
Keywords index;
|
||||
if (s_keywords.TryGetValue(keyword, out index))
|
||||
{
|
||||
return GetAt(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return base[keyword];
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
ADP.CheckArgumentNull(keyword, "keyword");
|
||||
if (null != value)
|
||||
{
|
||||
Keywords index;
|
||||
if (s_keywords.TryGetValue(keyword, out index))
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case Keywords.Driver: Driver = ConvertToString(value); break;
|
||||
case Keywords.Dsn: Dsn = ConvertToString(value); break;
|
||||
// case Keywords.NamedConnection: NamedConnection = ConvertToString(value); break;
|
||||
default:
|
||||
Debug.Assert(false, "unexpected keyword");
|
||||
throw ADP.KeywordNotSupported(keyword);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base[keyword] = value;
|
||||
ClearPropertyDescriptors();
|
||||
_knownKeywords = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Remove(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DisplayName(DbConnectionStringKeywords.Driver)]
|
||||
[ResCategoryAttribute(Res.DataCategory_Source)]
|
||||
[ResDescriptionAttribute(Res.DbConnectionString_Driver)]
|
||||
[RefreshPropertiesAttribute(RefreshProperties.All)]
|
||||
public string Driver
|
||||
{
|
||||
get { return _driver; }
|
||||
set
|
||||
{
|
||||
SetValue(DbConnectionStringKeywords.Driver, value);
|
||||
_driver = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DisplayName(DbConnectionStringKeywords.Dsn)]
|
||||
[ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
|
||||
[ResDescriptionAttribute(Res.DbConnectionString_DSN)]
|
||||
[RefreshPropertiesAttribute(RefreshProperties.All)]
|
||||
public string Dsn
|
||||
{
|
||||
get { return _dsn; }
|
||||
set
|
||||
{
|
||||
SetValue(DbConnectionStringKeywords.Dsn, value);
|
||||
_dsn = value;
|
||||
}
|
||||
}
|
||||
/*
|
||||
[DisplayName(DbConnectionStringKeywords.NamedConnection)]
|
||||
[ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
|
||||
[ResDescriptionAttribute(Res.DbConnectionString_NamedConnection)]
|
||||
[RefreshPropertiesAttribute(RefreshProperties.All)]
|
||||
[TypeConverter(typeof(NamedConnectionStringConverter))]
|
||||
public string NamedConnection {
|
||||
get { return _namedConnection; }
|
||||
set {
|
||||
SetValue(DbConnectionStringKeywords.NamedConnection, value);
|
||||
_namedConnection = value;
|
||||
}
|
||||
}
|
||||
*/
|
||||
public override ICollection Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
string[] knownKeywords = _knownKeywords;
|
||||
if (null == knownKeywords)
|
||||
{
|
||||
knownKeywords = s_validKeywords;
|
||||
|
||||
int count = 0;
|
||||
foreach (string keyword in base.Keys)
|
||||
{
|
||||
bool flag = true;
|
||||
foreach (string s in knownKeywords)
|
||||
{
|
||||
if (s == keyword)
|
||||
{
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (0 < count)
|
||||
{
|
||||
string[] tmp = new string[knownKeywords.Length + count];
|
||||
knownKeywords.CopyTo(tmp, 0);
|
||||
|
||||
int index = knownKeywords.Length;
|
||||
foreach (string keyword in base.Keys)
|
||||
{
|
||||
bool flag = true;
|
||||
foreach (string s in knownKeywords)
|
||||
{
|
||||
if (s == keyword)
|
||||
{
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
tmp[index++] = keyword;
|
||||
}
|
||||
}
|
||||
knownKeywords = tmp;
|
||||
}
|
||||
_knownKeywords = knownKeywords;
|
||||
}
|
||||
return new System.Data.Common.ReadOnlyCollection<string>(knownKeywords);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
for (int i = 0; i < s_validKeywords.Length; ++i)
|
||||
{
|
||||
Reset((Keywords)i);
|
||||
}
|
||||
_knownKeywords = s_validKeywords;
|
||||
}
|
||||
|
||||
public override bool ContainsKey(string keyword)
|
||||
{
|
||||
ADP.CheckArgumentNull(keyword, "keyword");
|
||||
return s_keywords.ContainsKey(keyword) || base.ContainsKey(keyword);
|
||||
}
|
||||
|
||||
private static string ConvertToString(object value)
|
||||
{
|
||||
return DbConnectionStringBuilderUtil.ConvertToString(value);
|
||||
}
|
||||
|
||||
private object GetAt(Keywords index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case Keywords.Driver: return Driver;
|
||||
case Keywords.Dsn: return Dsn;
|
||||
// case Keywords.NamedConnection: return NamedConnection;
|
||||
default:
|
||||
Debug.Assert(false, "unexpected keyword");
|
||||
throw ADP.KeywordNotSupported(s_validKeywords[(int)index]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
protected override void GetProperties(Hashtable propertyDescriptors) {
|
||||
object value;
|
||||
if (TryGetValue(DbConnectionStringSynonyms.TRUSTEDCONNECTION, out value)) {
|
||||
bool trusted = false;
|
||||
if (value is bool) {
|
||||
trusted = (bool)value;
|
||||
}
|
||||
else if ((value is string) && !Boolean.TryParse((string)value, out trusted)) {
|
||||
trusted = false;
|
||||
}
|
||||
|
||||
if (trusted) {
|
||||
Attribute[] attributes = new Attribute[] {
|
||||
BrowsableAttribute.Yes,
|
||||
RefreshPropertiesAttribute.All,
|
||||
};
|
||||
DbConnectionStringBuilderDescriptor descriptor;
|
||||
descriptor = new DbConnectionStringBuilderDescriptor(DbConnectionStringSynonyms.TRUSTEDCONNECTION,
|
||||
this.GetType(), typeof(bool), false, attributes);
|
||||
descriptor.RefreshOnChange = true;
|
||||
propertyDescriptors[DbConnectionStringSynonyms.TRUSTEDCONNECTION] = descriptor;
|
||||
|
||||
if (ContainsKey(DbConnectionStringSynonyms.Pwd)) {
|
||||
descriptor = new DbConnectionStringBuilderDescriptor(DbConnectionStringSynonyms.Pwd,
|
||||
this.GetType(), typeof(string), true, attributes);
|
||||
propertyDescriptors[DbConnectionStringSynonyms.Pwd] = descriptor;
|
||||
}
|
||||
if (ContainsKey(DbConnectionStringSynonyms.UID)) {
|
||||
descriptor = new DbConnectionStringBuilderDescriptor(DbConnectionStringSynonyms.UID,
|
||||
this.GetType(), typeof(string), true, attributes);
|
||||
propertyDescriptors[DbConnectionStringSynonyms.UID] = descriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
base.GetProperties(propertyDescriptors);
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool Remove(string keyword)
|
||||
{
|
||||
ADP.CheckArgumentNull(keyword, "keyword");
|
||||
if (base.Remove(keyword))
|
||||
{
|
||||
Keywords index;
|
||||
if (s_keywords.TryGetValue(keyword, out index))
|
||||
{
|
||||
Reset(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearPropertyDescriptors();
|
||||
_knownKeywords = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private void Reset(Keywords index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case Keywords.Driver:
|
||||
_driver = DbConnectionStringDefaults.Driver;
|
||||
break;
|
||||
case Keywords.Dsn:
|
||||
_dsn = DbConnectionStringDefaults.Dsn;
|
||||
break;
|
||||
// case Keywords.NamedConnection:
|
||||
// _namedConnection = DbConnectionStringDefaults.NamedConnection;
|
||||
// break;
|
||||
default:
|
||||
Debug.Assert(false, "unexpected keyword");
|
||||
throw ADP.KeywordNotSupported(s_validKeywords[(int)index]);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetValue(string keyword, string value)
|
||||
{
|
||||
ADP.CheckArgumentNull(value, keyword);
|
||||
base[keyword] = value;
|
||||
}
|
||||
|
||||
public override bool TryGetValue(string keyword, out object value)
|
||||
{
|
||||
ADP.CheckArgumentNull(keyword, "keyword");
|
||||
Keywords index;
|
||||
if (s_keywords.TryGetValue(keyword, out index))
|
||||
{
|
||||
value = GetAt(index);
|
||||
return true;
|
||||
}
|
||||
return base.TryGetValue(keyword, out value);
|
||||
}
|
||||
|
||||
internal sealed class OdbcConnectionStringBuilderConverter : ExpandableObjectConverter
|
||||
{
|
||||
// converter classes should have public ctor
|
||||
public OdbcConnectionStringBuilderConverter()
|
||||
{
|
||||
}
|
||||
|
||||
override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||
{
|
||||
if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == null)
|
||||
{
|
||||
throw ADP.ArgumentNull("destinationType");
|
||||
}
|
||||
if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType)
|
||||
{
|
||||
OdbcConnectionStringBuilder obj = (value as OdbcConnectionStringBuilder);
|
||||
if (null != obj)
|
||||
{
|
||||
return ConvertToInstanceDescriptor(obj);
|
||||
}
|
||||
}
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToInstanceDescriptor(OdbcConnectionStringBuilder options)
|
||||
{
|
||||
Type[] ctorParams = new Type[] { typeof(string) };
|
||||
object[] ctorValues = new object[] { options.ConnectionString };
|
||||
System.Reflection.ConstructorInfo ctor = typeof(OdbcConnectionStringBuilder).GetConstructor(ctorParams);
|
||||
return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
204
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs
vendored
Normal file
204
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcDataAdapter.cs
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
[
|
||||
DefaultEvent("RowUpdated"),
|
||||
ToolboxItem("Microsoft.VSDesigner.Data.VS.OdbcDataAdapterToolboxItem, " + AssemblyRef.MicrosoftVSDesigner), // WebData 97832
|
||||
Designer("Microsoft.VSDesigner.Data.VS.OdbcDataAdapterDesigner, " + AssemblyRef.MicrosoftVSDesigner)
|
||||
]
|
||||
public sealed class OdbcDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable
|
||||
{
|
||||
static private readonly object s_eventRowUpdated = new object();
|
||||
static private readonly object s_eventRowUpdating = new object();
|
||||
|
||||
private OdbcCommand _deleteCommand, _insertCommand, _selectCommand, _updateCommand;
|
||||
|
||||
public OdbcDataAdapter() : base()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public OdbcDataAdapter(OdbcCommand selectCommand) : this()
|
||||
{
|
||||
SelectCommand = selectCommand;
|
||||
}
|
||||
|
||||
public OdbcDataAdapter(string selectCommandText, OdbcConnection selectConnection) : this()
|
||||
{
|
||||
SelectCommand = new OdbcCommand(selectCommandText, selectConnection);
|
||||
}
|
||||
|
||||
public OdbcDataAdapter(string selectCommandText, string selectConnectionString) : this()
|
||||
{
|
||||
OdbcConnection connection = new OdbcConnection(selectConnectionString);
|
||||
SelectCommand = new OdbcCommand(selectCommandText, connection);
|
||||
}
|
||||
|
||||
private OdbcDataAdapter(OdbcDataAdapter from) : base(from)
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(null),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbDataAdapter_DeleteCommand),
|
||||
Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
|
||||
]
|
||||
new public OdbcCommand DeleteCommand
|
||||
{
|
||||
get { return _deleteCommand; }
|
||||
set { _deleteCommand = value; }
|
||||
}
|
||||
|
||||
IDbCommand IDbDataAdapter.DeleteCommand
|
||||
{
|
||||
get { return _deleteCommand; }
|
||||
set { _deleteCommand = (OdbcCommand)value; }
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(null),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbDataAdapter_InsertCommand),
|
||||
Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
|
||||
]
|
||||
new public OdbcCommand InsertCommand
|
||||
{
|
||||
get { return _insertCommand; }
|
||||
set { _insertCommand = value; }
|
||||
}
|
||||
|
||||
IDbCommand IDbDataAdapter.InsertCommand
|
||||
{
|
||||
get { return _insertCommand; }
|
||||
set { _insertCommand = (OdbcCommand)value; }
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(null),
|
||||
ResCategoryAttribute(Res.DataCategory_Fill),
|
||||
ResDescriptionAttribute(Res.DbDataAdapter_SelectCommand),
|
||||
Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
|
||||
]
|
||||
new public OdbcCommand SelectCommand
|
||||
{
|
||||
get { return _selectCommand; }
|
||||
set { _selectCommand = value; }
|
||||
}
|
||||
|
||||
IDbCommand IDbDataAdapter.SelectCommand
|
||||
{
|
||||
get { return _selectCommand; }
|
||||
set { _selectCommand = (OdbcCommand)value; }
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(null),
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbDataAdapter_UpdateCommand),
|
||||
Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
|
||||
]
|
||||
new public OdbcCommand UpdateCommand
|
||||
{
|
||||
get { return _updateCommand; }
|
||||
set { _updateCommand = value; }
|
||||
}
|
||||
|
||||
IDbCommand IDbDataAdapter.UpdateCommand
|
||||
{
|
||||
get { return _updateCommand; }
|
||||
set { _updateCommand = (OdbcCommand)value; }
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbDataAdapter_RowUpdated),
|
||||
]
|
||||
public event OdbcRowUpdatedEventHandler RowUpdated
|
||||
{
|
||||
add
|
||||
{
|
||||
Events.AddHandler(s_eventRowUpdated, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
Events.RemoveHandler(s_eventRowUpdated, value);
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
ResCategoryAttribute(Res.DataCategory_Update),
|
||||
ResDescriptionAttribute(Res.DbDataAdapter_RowUpdating),
|
||||
]
|
||||
public event OdbcRowUpdatingEventHandler RowUpdating
|
||||
{
|
||||
add
|
||||
{
|
||||
OdbcRowUpdatingEventHandler handler = (OdbcRowUpdatingEventHandler)Events[s_eventRowUpdating];
|
||||
|
||||
// MDAC 58177, 64513
|
||||
// prevent someone from registering two different command builders on the adapter by
|
||||
// silently removing the old one
|
||||
if ((null != handler) && (value.Target is OdbcCommandBuilder))
|
||||
{
|
||||
OdbcRowUpdatingEventHandler d = (OdbcRowUpdatingEventHandler)ADP.FindBuilder(handler);
|
||||
if (null != d)
|
||||
{
|
||||
Events.RemoveHandler(s_eventRowUpdating, d);
|
||||
}
|
||||
}
|
||||
Events.AddHandler(s_eventRowUpdating, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
Events.RemoveHandler(s_eventRowUpdating, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object ICloneable.Clone()
|
||||
{
|
||||
return new OdbcDataAdapter(this);
|
||||
}
|
||||
|
||||
override protected RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
|
||||
{
|
||||
return new OdbcRowUpdatedEventArgs(dataRow, command, statementType, tableMapping);
|
||||
}
|
||||
|
||||
override protected RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
|
||||
{
|
||||
return new OdbcRowUpdatingEventArgs(dataRow, command, statementType, tableMapping);
|
||||
}
|
||||
|
||||
override protected void OnRowUpdated(RowUpdatedEventArgs value)
|
||||
{
|
||||
OdbcRowUpdatedEventHandler handler = (OdbcRowUpdatedEventHandler)Events[s_eventRowUpdated];
|
||||
if ((null != handler) && (value is OdbcRowUpdatedEventArgs))
|
||||
{
|
||||
handler(this, (OdbcRowUpdatedEventArgs)value);
|
||||
}
|
||||
base.OnRowUpdated(value);
|
||||
}
|
||||
|
||||
override protected void OnRowUpdating(RowUpdatingEventArgs value)
|
||||
{
|
||||
OdbcRowUpdatingEventHandler handler = (OdbcRowUpdatingEventHandler)Events[s_eventRowUpdating];
|
||||
if ((null != handler) && (value is OdbcRowUpdatingEventArgs))
|
||||
{
|
||||
handler(this, (OdbcRowUpdatingEventArgs)value);
|
||||
}
|
||||
base.OnRowUpdating(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcDataReader.cs.REMOVED.git-id
vendored
Normal file
1
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcDataReader.cs.REMOVED.git-id
vendored
Normal file
@@ -0,0 +1 @@
|
||||
45635e64b6a743f5bd7da2ff96b0cbe64f17770c
|
||||
49
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironment.cs
vendored
Normal file
49
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironment.cs
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcEnvironment
|
||||
{
|
||||
static private object s_globalEnvironmentHandle;
|
||||
static private object s_globalEnvironmentHandleLock = new object();
|
||||
|
||||
private OdbcEnvironment() { } // default const.
|
||||
|
||||
static internal OdbcEnvironmentHandle GetGlobalEnvironmentHandle()
|
||||
{
|
||||
OdbcEnvironmentHandle globalEnvironmentHandle = s_globalEnvironmentHandle as OdbcEnvironmentHandle;
|
||||
if (null == globalEnvironmentHandle)
|
||||
{
|
||||
ADP.CheckVersionMDAC(true);
|
||||
|
||||
lock (s_globalEnvironmentHandleLock)
|
||||
{
|
||||
globalEnvironmentHandle = s_globalEnvironmentHandle as OdbcEnvironmentHandle;
|
||||
if (null == globalEnvironmentHandle)
|
||||
{
|
||||
globalEnvironmentHandle = new OdbcEnvironmentHandle();
|
||||
s_globalEnvironmentHandle = globalEnvironmentHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
return globalEnvironmentHandle;
|
||||
}
|
||||
|
||||
static internal void ReleaseObjectPool()
|
||||
{
|
||||
object globalEnvironmentHandle = Interlocked.Exchange(ref s_globalEnvironmentHandle, null);
|
||||
if (null != globalEnvironmentHandle)
|
||||
{
|
||||
(globalEnvironmentHandle as OdbcEnvironmentHandle).Dispose(); // internally refcounted so will happen correctly
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
62
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironmentHandle.cs
vendored
Normal file
62
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcEnvironmentHandle.cs
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal sealed class OdbcEnvironmentHandle : OdbcHandle
|
||||
{
|
||||
// SxS: this method uses SQLSetEnvAttr to setup ODBC environment handle settings. Environment handle is safe in SxS.
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
|
||||
internal OdbcEnvironmentHandle() : base(ODBC32.SQL_HANDLE.ENV, null)
|
||||
{
|
||||
ODBC32.RetCode retcode;
|
||||
|
||||
//Set the expected driver manager version
|
||||
//
|
||||
retcode = UnsafeNativeMethods.SQLSetEnvAttr(
|
||||
this,
|
||||
ODBC32.SQL_ATTR.ODBC_VERSION,
|
||||
ODBC32.SQL_OV_ODBC3,
|
||||
ODBC32.SQL_IS.INTEGER);
|
||||
// ignore retcode
|
||||
|
||||
//Turn on connection pooling
|
||||
//Note: the env handle controls pooling. Only those connections created under that
|
||||
//handle are pooled. So we have to keep it alive and not create a new environment
|
||||
//for every connection.
|
||||
//
|
||||
retcode = UnsafeNativeMethods.SQLSetEnvAttr(
|
||||
this,
|
||||
ODBC32.SQL_ATTR.CONNECTION_POOLING,
|
||||
ODBC32.SQL_CP_ONE_PER_HENV,
|
||||
ODBC32.SQL_IS.INTEGER);
|
||||
|
||||
switch (retcode)
|
||||
{
|
||||
case ODBC32.RetCode.SUCCESS:
|
||||
case ODBC32.RetCode.SUCCESS_WITH_INFO:
|
||||
break;
|
||||
default:
|
||||
Dispose();
|
||||
throw ODBC.CantEnableConnectionpooling(retcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
69
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs
vendored
Normal file
69
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class OdbcError
|
||||
{
|
||||
//Data
|
||||
internal string _message;
|
||||
internal string _state;
|
||||
internal int _nativeerror;
|
||||
internal string _source;
|
||||
|
||||
internal OdbcError(string source, string message, string state, int nativeerror)
|
||||
{
|
||||
_source = source;
|
||||
_message = message;
|
||||
_state = state;
|
||||
_nativeerror = nativeerror;
|
||||
}
|
||||
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((null != _message) ? _message : String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public string SQLState
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
public int NativeError
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nativeerror;
|
||||
}
|
||||
}
|
||||
|
||||
public string Source
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((null != _source) ? _source : String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetSource(string Source)
|
||||
{
|
||||
_source = Source;
|
||||
}
|
||||
|
||||
override public string ToString()
|
||||
{
|
||||
return Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcErrorCollection.cs
vendored
Normal file
74
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcErrorCollection.cs
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class OdbcErrorCollection : ICollection
|
||||
{
|
||||
private ArrayList _items = new ArrayList();
|
||||
|
||||
internal OdbcErrorCollection()
|
||||
{
|
||||
}
|
||||
|
||||
Object System.Collections.ICollection.SyncRoot
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
bool System.Collections.ICollection.IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _items.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public OdbcError this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (OdbcError)_items[i];
|
||||
}
|
||||
}
|
||||
|
||||
internal void Add(OdbcError error)
|
||||
{
|
||||
_items.Add(error);
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int i)
|
||||
{
|
||||
_items.CopyTo(array, i);
|
||||
}
|
||||
|
||||
public void CopyTo(OdbcError[] array, int i)
|
||||
{
|
||||
_items.CopyTo(array, i);
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return _items.GetEnumerator();
|
||||
}
|
||||
|
||||
internal void SetSource(string Source)
|
||||
{
|
||||
foreach (object error in _items)
|
||||
{
|
||||
((OdbcError)error).SetSource(Source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs
vendored
Normal file
89
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections; //ICollection
|
||||
using System.ComponentModel; //Component
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class OdbcException : System.Data.Common.DbException
|
||||
{
|
||||
private OdbcErrorCollection _odbcErrors = new OdbcErrorCollection();
|
||||
|
||||
private ODBC32.RETCODE _retcode; // DO NOT REMOVE! only needed for serialization purposes, because Everett had it.
|
||||
|
||||
static internal OdbcException CreateException(OdbcErrorCollection errors, ODBC32.RetCode retcode)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
foreach (OdbcError error in errors)
|
||||
{
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
builder.Append(Environment.NewLine);
|
||||
}
|
||||
|
||||
builder.Append(Res.GetString(Res.Odbc_ExceptionMessage, ODBC32.RetcodeToString(retcode), error.SQLState, error.Message)); // MDAC 68337
|
||||
}
|
||||
OdbcException exception = new OdbcException(builder.ToString(), errors);
|
||||
return exception;
|
||||
}
|
||||
|
||||
internal OdbcException(string message, OdbcErrorCollection errors) : base(message)
|
||||
{
|
||||
_odbcErrors = errors;
|
||||
HResult = HResults.OdbcException;
|
||||
}
|
||||
|
||||
// runtime will call even if private...
|
||||
private OdbcException(SerializationInfo si, StreamingContext sc) : base(si, sc)
|
||||
{
|
||||
_retcode = (ODBC32.RETCODE)si.GetValue("odbcRetcode", typeof(ODBC32.RETCODE));
|
||||
_odbcErrors = (OdbcErrorCollection)si.GetValue("odbcErrors", typeof(OdbcErrorCollection));
|
||||
HResult = HResults.OdbcException;
|
||||
}
|
||||
|
||||
public OdbcErrorCollection Errors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _odbcErrors;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
|
||||
override public void GetObjectData(SerializationInfo si, StreamingContext context)
|
||||
{
|
||||
// MDAC 72003
|
||||
if (null == si)
|
||||
{
|
||||
throw new ArgumentNullException("si");
|
||||
}
|
||||
si.AddValue("odbcRetcode", _retcode, typeof(ODBC32.RETCODE));
|
||||
si.AddValue("odbcErrors", _odbcErrors, typeof(OdbcErrorCollection));
|
||||
base.GetObjectData(si, context);
|
||||
}
|
||||
|
||||
// mdac bug 62559 - if we don't have it return nothing (empty string)
|
||||
override public string Source
|
||||
{
|
||||
get
|
||||
{
|
||||
if (0 < Errors.Count)
|
||||
{
|
||||
string source = Errors[0].Source;
|
||||
return ADP.IsEmpty(source) ? "" : source; // base.Source;
|
||||
}
|
||||
return ""; // base.Source;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcFactory.cs
vendored
Normal file
56
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcFactory.cs
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
public sealed class OdbcFactory : DbProviderFactory
|
||||
{
|
||||
public static readonly OdbcFactory Instance = new OdbcFactory();
|
||||
|
||||
private OdbcFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public override DbCommand CreateCommand()
|
||||
{
|
||||
return new OdbcCommand();
|
||||
}
|
||||
|
||||
public override DbCommandBuilder CreateCommandBuilder()
|
||||
{
|
||||
return new OdbcCommandBuilder();
|
||||
}
|
||||
|
||||
public override DbConnection CreateConnection()
|
||||
{
|
||||
return new OdbcConnection();
|
||||
}
|
||||
|
||||
public override DbConnectionStringBuilder CreateConnectionStringBuilder()
|
||||
{
|
||||
return new OdbcConnectionStringBuilder();
|
||||
}
|
||||
|
||||
public override DbDataAdapter CreateDataAdapter()
|
||||
{
|
||||
return new OdbcDataAdapter();
|
||||
}
|
||||
|
||||
public override DbParameter CreateParameter()
|
||||
{
|
||||
return new OdbcParameter();
|
||||
}
|
||||
|
||||
public override CodeAccessPermission CreatePermission(PermissionState state)
|
||||
{
|
||||
return new OdbcPermission(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
263
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcHandle.cs
vendored
Normal file
263
external/corefx/src/System.Data.Odbc/src/System/Data/Odbc/OdbcHandle.cs
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Data.Odbc
|
||||
{
|
||||
internal abstract class OdbcHandle : SafeHandle
|
||||
{
|
||||
private ODBC32.SQL_HANDLE _handleType;
|
||||
private OdbcHandle _parentHandle;
|
||||
|
||||
protected OdbcHandle(ODBC32.SQL_HANDLE handleType, OdbcHandle parentHandle) : base(IntPtr.Zero, true)
|
||||
{
|
||||
_handleType = handleType;
|
||||
|
||||
bool mustRelease = false;
|
||||
ODBC32.RetCode retcode = ODBC32.RetCode.SUCCESS;
|
||||
|
||||
// using ConstrainedRegions to make the native ODBC call and AddRef the parent
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
// validate handleType
|
||||
switch (handleType)
|
||||
{
|
||||
case ODBC32.SQL_HANDLE.ENV:
|
||||
Debug.Assert(null == parentHandle, "did not expect a parent handle");
|
||||
retcode = UnsafeNativeMethods.SQLAllocHandle(handleType, IntPtr.Zero, out base.handle);
|
||||
break;
|
||||
case ODBC32.SQL_HANDLE.DBC:
|
||||
case ODBC32.SQL_HANDLE.STMT:
|
||||
// must addref before calling native so it won't be released just after
|
||||
Debug.Assert(null != parentHandle, "expected a parent handle"); // safehandle can't be null
|
||||
parentHandle.DangerousAddRef(ref mustRelease);
|
||||
|
||||
retcode = UnsafeNativeMethods.SQLAllocHandle(handleType, parentHandle, out base.handle);
|
||||
break;
|
||||
// case ODBC32.SQL_HANDLE.DESC:
|
||||
default:
|
||||
Debug.Assert(false, "unexpected handleType");
|
||||
break;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mustRelease)
|
||||
{
|
||||
switch (handleType)
|
||||
{
|
||||
case ODBC32.SQL_HANDLE.DBC:
|
||||
case ODBC32.SQL_HANDLE.STMT:
|
||||
if (IntPtr.Zero != base.handle)
|
||||
{
|
||||
// must assign _parentHandle after a handle is actually created
|
||||
// since ReleaseHandle will only call DangerousRelease if a handle exists
|
||||
_parentHandle = parentHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
// without a handle, ReleaseHandle may not be called
|
||||
parentHandle.DangerousRelease();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Bid.TraceSqlReturn("<odbc.SQLAllocHandle|API|ODBC|RET> %08X{SQLRETURN}\n", retcode);
|
||||
|
||||
if ((ADP.PtrZero == base.handle) || (ODBC32.RetCode.SUCCESS != retcode))
|
||||
{
|
||||
//
|
||||
throw ODBC.CantAllocateEnvironmentHandle(retcode);
|
||||
}
|
||||
}
|
||||
|
||||
internal OdbcHandle(OdbcStatementHandle parentHandle, ODBC32.SQL_ATTR attribute) : base(IntPtr.Zero, true)
|
||||
{
|
||||
Debug.Assert((ODBC32.SQL_ATTR.APP_PARAM_DESC == attribute) || (ODBC32.SQL_ATTR.APP_ROW_DESC == attribute), "invalid attribute");
|
||||
_handleType = ODBC32.SQL_HANDLE.DESC;
|
||||
|
||||
int cbActual;
|
||||
ODBC32.RetCode retcode;
|
||||
bool mustRelease = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
// must addref before calling native so it won't be released just after
|
||||
parentHandle.DangerousAddRef(ref mustRelease);
|
||||
|
||||
retcode = parentHandle.GetStatementAttribute(attribute, out base.handle, out cbActual);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mustRelease)
|
||||
{
|
||||
if (IntPtr.Zero != base.handle)
|
||||
{
|
||||
// must call DangerousAddRef after a handle is actually created
|
||||
// since ReleaseHandle will only call DangerousRelease if a handle exists
|
||||
_parentHandle = parentHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
// without a handle, ReleaseHandle may not be called
|
||||
parentHandle.DangerousRelease();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ADP.PtrZero == base.handle)
|
||||
{
|
||||
throw ODBC.FailedToGetDescriptorHandle(retcode);
|
||||
}
|
||||
// no info-message handle on getting a descriptor handle
|
||||
}
|
||||
|
||||
internal ODBC32.SQL_HANDLE HandleType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _handleType;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get
|
||||
{
|
||||
// we should not have a parent if we do not have a handle
|
||||
return (IntPtr.Zero == base.handle);
|
||||
}
|
||||
}
|
||||
|
||||
override protected bool ReleaseHandle()
|
||||
{
|
||||
// NOTE: The SafeHandle class guarantees this will be called exactly once and is non-interrutible.
|
||||
IntPtr handle = base.handle;
|
||||
base.handle = IntPtr.Zero;
|
||||
|
||||
if (IntPtr.Zero != handle)
|
||||
{
|
||||
ODBC32.SQL_HANDLE handleType = HandleType;
|
||||
|
||||
switch (handleType)
|
||||
{
|
||||
case ODBC32.SQL_HANDLE.DBC:
|
||||
// Disconnect happens in OdbcConnectionHandle.ReleaseHandle
|
||||
case ODBC32.SQL_HANDLE.ENV:
|
||||
case ODBC32.SQL_HANDLE.STMT:
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLFreeHandle(handleType, handle);
|
||||
Bid.TraceSqlReturn("<odbc.SQLFreeHandle|API|ODBC|RET> %08X{SQLRETURN}\n", retcode);
|
||||
break;
|
||||
|
||||
case ODBC32.SQL_HANDLE.DESC:
|
||||
// nothing to free on the handle
|
||||
break;
|
||||
|
||||
// case 0: ThreadAbortException setting handle before HandleType
|
||||
default:
|
||||
Debug.Assert(ADP.PtrZero == handle, "unknown handle type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we ended up getting released, then we have to release
|
||||
// our reference on our parent.
|
||||
OdbcHandle parentHandle = _parentHandle;
|
||||
_parentHandle = null;
|
||||
if (null != parentHandle)
|
||||
{
|
||||
parentHandle.DangerousRelease();
|
||||
parentHandle = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetDiagnosticField(out string sqlState)
|
||||
{
|
||||
short cbActual;
|
||||
// ODBC (MSDN) documents it expects a buffer large enough to hold 5(+L'\0') unicode characters
|
||||
StringBuilder sb = new StringBuilder(6);
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDiagFieldW(
|
||||
HandleType,
|
||||
this,
|
||||
(short)1,
|
||||
ODBC32.SQL_DIAG_SQLSTATE,
|
||||
sb,
|
||||
checked((short)(2 * sb.Capacity)), // expects number of bytes, see \\kbinternal\kb\articles\294\1\69.HTM
|
||||
out cbActual);
|
||||
ODBC.TraceODBC(3, "SQLGetDiagFieldW", retcode);
|
||||
if ((retcode == ODBC32.RetCode.SUCCESS) || (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO))
|
||||
{
|
||||
sqlState = sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlState = ADP.StrEmpty;
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetDiagnosticRecord(short record, out string sqlState, StringBuilder message, out int nativeError, out short cchActual)
|
||||
{
|
||||
// ODBC (MSDN) documents it expects a buffer large enough to hold 4(+L'\0') unicode characters
|
||||
StringBuilder sb = new StringBuilder(5);
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDiagRecW(HandleType, this, record, sb, out nativeError, message, checked((short)message.Capacity), out cchActual);
|
||||
ODBC.TraceODBC(3, "SQLGetDiagRecW", retcode);
|
||||
|
||||
if ((retcode == ODBC32.RetCode.SUCCESS) || (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO))
|
||||
{
|
||||
sqlState = sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlState = ADP.StrEmpty;
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class OdbcDescriptorHandle : OdbcHandle
|
||||
{
|
||||
internal OdbcDescriptorHandle(OdbcStatementHandle statementHandle, ODBC32.SQL_ATTR attribute) : base(statementHandle, attribute)
|
||||
{
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode GetDescriptionField(int i, ODBC32.SQL_DESC attribute, CNativeBuffer buffer, out int numericAttribute)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLGetDescFieldW(this, checked((short)i), attribute, buffer, buffer.ShortLength, out numericAttribute);
|
||||
ODBC.TraceODBC(3, "SQLGetDescFieldW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode SetDescriptionField1(short ordinal, ODBC32.SQL_DESC type, IntPtr value)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetDescFieldW(this, ordinal, type, value, 0);
|
||||
ODBC.TraceODBC(3, "SQLSetDescFieldW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
internal ODBC32.RetCode SetDescriptionField2(short ordinal, ODBC32.SQL_DESC type, HandleRef value)
|
||||
{
|
||||
ODBC32.RetCode retcode = UnsafeNativeMethods.SQLSetDescFieldW(this, ordinal, type, value, 0);
|
||||
ODBC.TraceODBC(3, "SQLSetDescFieldW", retcode);
|
||||
return retcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user