Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / DataOracleClient / System / Data / OracleClient / OciHandle.cs / 1 / OciHandle.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace System.Data.OracleClient
{
using System;
using System.Data.Common;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Runtime.ConstrainedExecution;
//---------------------------------------------------------------------
// OciHandle
//
// Class to manage the lifetime of Oracle Call Interface handles, and
// to simplify a number of handle-related operations
//
abstract internal class OciHandle : SafeHandle {
[Flags]
protected enum HANDLEFLAG {
DEFAULT = 0,
UNICODE = 1<<0,
NLS = 1<<1,
}
private OCI.HTYPE _handleType;
private int _refCount;
private OciHandle _parentHandle;
private bool _isUnicode;
// default constructor
protected OciHandle() : base(IntPtr.Zero, true) {
}
// OciSimpleHandle constructor
protected OciHandle(OCI.HTYPE handleType) : base(IntPtr.Zero, false) {
_handleType = handleType;
}
protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType) : this(parentHandle, handleType, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {
}
protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType, OCI.MODE ocimode, HANDLEFLAG handleflags) : this() {
int rc;
Debug.Assert (!(parentHandle is OciSimpleHandle), "Must not create handle on top of OciSimpleHandle");
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
_handleType = handleType;
_parentHandle = parentHandle;
_refCount = 1;
//
switch (handleType) {
case OCI.HTYPE.OCI_HTYPE_ENV:
Debug.Assert(null == parentHandle, "not null parentHandle?");
if ((handleflags & HANDLEFLAG.NLS) == HANDLEFLAG.NLS) {
rc = TracedNativeMethods.OCIEnvNlsCreate(
out base.handle,
ocimode,
0,
0);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIEnvNlsCreate", rc);
}
}
else {
rc = TracedNativeMethods.OCIEnvCreate(
out base.handle,
ocimode);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIEnvCreate", rc);
}
}
break;
case OCI.HTYPE.OCI_HTYPE_ERROR:
case OCI.HTYPE.OCI_HTYPE_SERVER:
case OCI.HTYPE.OCI_HTYPE_SVCCTX:
case OCI.HTYPE.OCI_HTYPE_SESSION:
case OCI.HTYPE.OCI_HTYPE_STMT:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIHandleAlloc(
parentHandle.EnvironmentHandle,
out base.handle,
handleType);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIHandleAlloc", rc);
}
break;
case OCI.HTYPE.OCI_DTYPE_LOB:
case OCI.HTYPE.OCI_DTYPE_FILE:
case OCI.HTYPE.OCI_DTYPE_ROWID:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ:
case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIDescriptorAlloc(
parentHandle.EnvironmentHandle,
out base.handle,
handleType);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIDescriptorAlloc", rc);
}
break;
case OCI.HTYPE.OCI_HTYPE_BIND:
case OCI.HTYPE.OCI_HTYPE_DEFINE:
case OCI.HTYPE.OCI_DTYPE_PARAM:
Debug.Assert(null != parentHandle, "null parentHandle?");
// These three handles are Simple OCI handles -- they do not
// need to be freed.
break;
default:
Debug.Assert(false, "unexpected handleType");
break;
}
// If we get here, we successfully allocated the handle, so we had
// better better up the parent's ref count.
if (null != parentHandle) {
parentHandle.AddRef();
_isUnicode = parentHandle.IsUnicode;
}
else {
_isUnicode = (handleflags & HANDLEFLAG.UNICODE) == HANDLEFLAG.UNICODE;
}
}
}
internal OciHandle EnvironmentHandle {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
OciHandle value;
if (HandleType == OCI.HTYPE.OCI_HTYPE_ENV) {
value = this;
}
else {
value = ParentHandle.EnvironmentHandle;
}
return value;
}
}
internal OCI.HTYPE HandleType {
get {
return _handleType;
}
}
public override bool IsInvalid {
get {
return (IntPtr.Zero == base.handle);
}
}
internal bool IsUnicode {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
return _isUnicode;
}
}
internal OciHandle ParentHandle {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
return _parentHandle;
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal int AddRef() {
int refCount = Interlocked.Increment(ref _refCount);
return refCount;
}
// Wrap the OCIAttrGet calls. We do not expect OCIAttrGet to fail,
// so we will throw if it does. There are multiple overloads here,
// one for each type of parameter that Oracle supports
internal void GetAttribute(OCI.ATTR attribute, out byte value, OciErrorHandle errorHandle) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void GetAttribute(OCI.ATTR attribute, out short value, OciErrorHandle errorHandle) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void GetAttribute(OCI.ATTR attribute, out int value, OciErrorHandle errorHandle) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void GetAttribute(OCI.ATTR attribute, out string value, OciErrorHandle errorHandle, OracleConnection connection) {
IntPtr tempptr = IntPtr.Zero; // note: no need to clean up tempptr pointer
uint tempub4 = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, ref tempptr, ref tempub4, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
byte[] bytearray = new byte[tempub4];
Marshal.Copy(tempptr, bytearray, 0, checked((int)tempub4));
value = connection.GetString(bytearray);
}
internal byte[] GetBytes(string value) {
byte[] result;
uint valueLength = (uint)value.Length;
if (IsUnicode) {
result = new byte[valueLength * ADP.CharSize];
GetBytes(value.ToCharArray(), 0, valueLength, result, 0);
}
else {
byte[] temp = new byte[valueLength * 4]; // one Unicode character can map to up to 4 bytes
uint tempLength = GetBytes(value.ToCharArray(), 0, valueLength, temp, 0);
result = new byte[tempLength];
Buffer.BlockCopy(temp, 0, result, 0, checked ((int)tempLength));
}
return result;
}
internal uint GetBytes(char[] chars, int charIndex, uint charCount, byte[] bytes, int byteIndex) {
uint byteCount;
if (IsUnicode) {
byteCount = checked ((uint)(charCount * ADP.CharSize));
Buffer.BlockCopy(chars, charIndex*ADP.CharSize, bytes, byteIndex, checked ((int)byteCount));
}
else {
OciHandle environmentHandle = EnvironmentHandle;
GCHandle charsHandle = new GCHandle();
GCHandle bytesHandle = new GCHandle();
int rc;
try {
charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned);
IntPtr charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex);
IntPtr bytesPtr;
if (null == bytes) {
bytesPtr = IntPtr.Zero;
byteCount = 0;
}
else {
bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex);
byteCount = checked((uint)(bytes.Length-byteIndex));
}
rc = UnsafeNativeMethods.OCIUnicodeToCharSet(
environmentHandle,
bytesPtr,
byteCount,
charsPtr,
charCount,
out byteCount
);
}
finally {
charsHandle.Free();
if (bytesHandle.IsAllocated)
bytesHandle.Free();
}
if (0 != rc) {
throw ADP.OperationFailed("OCIUnicodeToCharSet", rc);
}
}
return byteCount;
}
internal uint GetChars(byte[] bytes, int byteIndex, uint byteCount, char[] chars, int charIndex) {
uint charCount;
if (IsUnicode) {
Debug.Assert(0 == (byteCount & 0x1), "Odd Number of Unicode Bytes?");
charCount = checked ((uint)(byteCount / ADP.CharSize));
Buffer.BlockCopy(bytes, byteIndex, chars, charIndex*ADP.CharSize, checked((int)byteCount));
}
else {
OciHandle environmentHandle = EnvironmentHandle;
GCHandle bytesHandle = new GCHandle();
GCHandle charsHandle = new GCHandle();
int rc;
try {
bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
IntPtr bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex);
IntPtr charsPtr;
if (null == chars) {
charsPtr = IntPtr.Zero;
charCount = 0;
}
else {
charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned);
charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex);
charCount = checked((uint)(chars.Length-charIndex));
}
rc = UnsafeNativeMethods.OCICharSetToUnicode(
environmentHandle,
charsPtr,
charCount,
bytesPtr,
byteCount,
out charCount
);
}
finally {
bytesHandle.Free();
if (charsHandle.IsAllocated)
charsHandle.Free();
}
if (0 != rc) {
throw ADP.OperationFailed("OCICharSetToUnicode", rc);
}
}
return charCount;
}
//---------------------------------------------------------------------
static internal string GetAttributeName
(
OciHandle handle,
OCI.ATTR atype
)
{
if (OCI.HTYPE.OCI_DTYPE_PARAM == handle.HandleType)
return ((OCI.PATTR)atype).ToString();
return atype.ToString();
}
//----------------------------------------------------------------------
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
static internal IntPtr HandleValueToTrace ( OciHandle handle )
{
return handle.DangerousGetHandle(); // for tracing purposes, it's safe to just print this -- no handle recycling issues.
}
internal string PtrToString(NativeBuffer buf) {
string result = null;
if (IsUnicode)
result = buf.PtrToStringUni(0);
else
result = buf.PtrToStringAnsi(0);
return result;
}
internal string PtrToString(IntPtr buf, int len) {
string result;
if (IsUnicode)
result = Marshal.PtrToStringUni(buf, len);
else
result = Marshal.PtrToStringAnsi(buf, len);
return result;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal int Release() {
int refCount;
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
refCount = Interlocked.Decrement(ref _refCount);
Debug.Assert (0 <= refCount, "refCount is negative?");
if (0 == refCount) {
//Debug.WriteLine(String.Format("Releasing hande={0} value={1}", HandleTypeToString(this), HandleValueToString(base.handle)));
IntPtr handle = Interlocked.CompareExchange(ref base.handle, IntPtr.Zero, base.handle);
if (IntPtr.Zero != handle) {
OCI.HTYPE handleType = HandleType;
OciHandle parentHandle = ParentHandle;
int rc;
switch (handleType) {
case OCI.HTYPE.OCI_HTYPE_ENV:
Debug.Assert(null == parentHandle, "not null parentHandle?");
rc = TracedNativeMethods.OCIHandleFree(handle, handleType);
if (0 != rc) {
throw ADP.OperationFailed("OCIHandleFree", rc);
}
break;
case OCI.HTYPE.OCI_HTYPE_SERVER:
Debug.Assert(null != parentHandle, "null parentHandle?");
Debug.Assert(OCI.HTYPE.OCI_HTYPE_ERROR == parentHandle.HandleType, "parentHandle of server handle must be the error handle!");
// NOTE: while it might seem to be a problem here that
// we are using DangerousGetHandle on the parent
// handle here, the reason that we're doing it is
// that we're in shutdown mode and the handle may
// have already been released -- attempting to use
// it any other way would cause the CLR to throw
// an ObjectDisposedException wit the message
// "Safe handle has been closed". The reasons for
// this are that we're using our ref-counting
// to enforce a specific release order, but the
// GC will let the safehandle be closed long
// before all of the handles that have a ref-
// counts on this handle are closed, which means
// that the last one will cause the server detach
// call.
//
// There is no likelihood of having a handle
// recycling attack here, because we're making
// the call that we would have been making in
// ReleaseHandle -- we still own the handle
// until ServerDetach is called.
TracedNativeMethods.OCIServerDetach(handle, parentHandle.DangerousGetHandle(), OCI.MODE.OCI_DEFAULT);
// we eat failures here -- what would you suggest we do otherwise?
goto case OCI.HTYPE.OCI_HTYPE_SESSION;
case OCI.HTYPE.OCI_HTYPE_SVCCTX:
// NOTE: while it might seem to be a problem here that
// we are using DangerousGetHandle on the parent
// handle here, the reason that we're doing it is
// that we're in shutdown mode and the handle may
// have already been released -- attempting to use
// it any other way would cause the CLR to throw
// an ObjectDisposedException wit the message
// "Safe handle has been closed". The reasons for
// this are that we're using our ref-counting
// to enforce a specific release order, but the
// GC will let the safehandle be closed long
// before all of the handles that have a ref-
// counts on this handle are closed, which means
// that the last one will cause the server detach
// call.
//
// There is no likelihood of having a handle
// recycling attack here, because we're making
// the call that we would have been making in
// ReleaseHandle -- we still own the handle
// until they are freed, and our ref counting
// prevents them from being freed out of order.
OciHandle sessionHandle = parentHandle;
if (null != sessionHandle) {
OciHandle serverHandle = sessionHandle.ParentHandle;
if (null != serverHandle) {
OciHandle errorHandle = serverHandle.ParentHandle;
if (null != errorHandle) {
rc = TracedNativeMethods.OCISessionEnd(
handle, // svchp
errorHandle.DangerousGetHandle(), // errhp
sessionHandle.DangerousGetHandle(), // usrhp
OCI.MODE.OCI_DEFAULT // mode
);
}
}
}
// we eat failures here -- what would you suggest we do otherwise?
goto case OCI.HTYPE.OCI_HTYPE_ERROR;
case OCI.HTYPE.OCI_HTYPE_ERROR:
case OCI.HTYPE.OCI_HTYPE_SESSION:
case OCI.HTYPE.OCI_HTYPE_STMT:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIHandleFree(handle, handleType);
if (0 != rc) {
throw ADP.OperationFailed("OCIHandleFree", rc);
}
break;
case OCI.HTYPE.OCI_DTYPE_LOB:
case OCI.HTYPE.OCI_DTYPE_FILE:
case OCI.HTYPE.OCI_DTYPE_ROWID:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ:
case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIDescriptorFree(handle, handleType);
if (0 != rc) {
throw ADP.OperationFailed("OCIDescriptorFree", rc);
}
break;
default:
Debug.Assert(false, "unexpected handleType");
break;
}
// If we ended up getting released, then we have to release
// our reference on our parent.
if (null != parentHandle) {
parentHandle.Release();
}
}
}
}
return refCount;
}
override protected bool ReleaseHandle() {
//Debug.WriteLine(String.Format("ReleaseHandle type={0} value={1}", HandleTypeToString(this), HandleValueToString(this)));
// NOTE: The SafeHandle class guarantees this will be called exactly once.
Release();
return true;
}
static internal void SafeDispose(ref OciHandle handle) {
// Safely disposes of the handle (even if it is already null) and
// then nulls it out.
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciEnvironmentHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciErrorHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciRowidDescriptor handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciStatementHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciSessionHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciServiceContextHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciServerHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciDefineHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciBindHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciParameterDescriptor handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciDateTimeDescriptor handle)
{
if (handle != null)
{
handle.Dispose();
}
handle = null;
}
// Wrap the OCIAttrSet calls. We do not expect OCIAttrSet to fail,
// so we will throw if it does. There are multiple overloads here,
// one for each type of parameter that Oracle supports
internal void SetAttribute(OCI.ATTR attribute, int value, OciErrorHandle errorHandle) {
int rc = TracedNativeMethods.OCIAttrSet(
this, // trgthndlp/trghndltyp
ref value, // attributep
0, // size
attribute, // attrtype
errorHandle // errhp
);
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void SetAttribute(OCI.ATTR attribute, OciHandle value, OciErrorHandle errorHandle) {
int rc = TracedNativeMethods.OCIAttrSet(
this, // trgthndlp/trghndltyp
value, // attributep
0, // size
attribute, // attrtype
errorHandle // errhp
);
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void SetAttribute(OCI.ATTR attribute, string value, OciErrorHandle errorHandle) {
uint valueLengthAsChars = unchecked((uint)value.Length);
byte[] valueAsBytes = new byte[valueLengthAsChars * 4];
uint valueLengthAsBytes = GetBytes(value.ToCharArray(), 0, valueLengthAsChars, valueAsBytes, 0);
int rc = TracedNativeMethods.OCIAttrSet(
this, // trgthndlp/trghndltyp
valueAsBytes, // attributep
valueLengthAsBytes, // size
attribute, // attrtype
errorHandle // errhp
);
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
}
sealed internal class OciEnvironmentHandle : OciHandle {
internal OciEnvironmentHandle(OCI.MODE environmentMode, bool unicode)
: base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, unicode?HANDLEFLAG.UNICODE:HANDLEFLAG.DEFAULT) {}
}
sealed internal class OciErrorHandle : OciHandle {
bool _connectionIsBroken;
internal OciErrorHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_ERROR) {}
internal bool ConnectionIsBroken {
get {
return _connectionIsBroken;
}
set {
_connectionIsBroken = value;
}
}
}
sealed internal class OciDateTimeDescriptor : OciHandle {
internal OciDateTimeDescriptor(OciHandle parent, OCI.HTYPE dateTimeType)
: base(parent, AssertDateTimeType(dateTimeType))
{
}
static OCI.HTYPE AssertDateTimeType(OCI.HTYPE dateTimeType)
{
Debug.Assert(
dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP ||
dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ ||
dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ,
"unexpected OciDateTime handleType");
return dateTimeType;
}
}
sealed internal class OciFileDescriptor : OciHandle {
internal OciFileDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_FILE) {}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal int OCILobFileSetNameWrapper( OciHandle envhp, OciHandle errhp, byte[] dirAlias, ushort dirAliasLength, byte[] fileName, ushort fileNameLength) {
int rc;
bool mustRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
DangerousAddRef(ref mustRelease);
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
IntPtr bfileDescriptor = DangerousGetHandle();
rc = UnsafeNativeMethods.OCILobFileSetName(
envhp,
errhp,
ref bfileDescriptor,
dirAlias,
dirAliasLength,
fileName,
fileNameLength);
base.handle = bfileDescriptor;
}
}
finally {
if (mustRelease) {
DangerousRelease();
}
}
return rc;
}
};
sealed internal class OciIntervalDescriptor : OciHandle {
internal OciIntervalDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_INTERVAL_DS) {
}
}
sealed internal class OciLobDescriptor : OciHandle {
internal OciLobDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_LOB) {}
}
sealed internal class OciNlsEnvironmentHandle : OciHandle {
internal OciNlsEnvironmentHandle(OCI.MODE environmentMode )
: base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, HANDLEFLAG.NLS) {}
}
sealed internal class OciRowidDescriptor : OciHandle {
internal OciRowidDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_ROWID) {}
internal void GetRowid( OciStatementHandle statementHandle, OciErrorHandle errorHandle ) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( statementHandle, this, out zero, OCI.ATTR.OCI_ATTR_ROWID, errorHandle );
if ((int)OCI.RETURNCODE.OCI_NO_DATA == rc) {
Dispose();
}
else if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
}
sealed internal class OciServerHandle : OciHandle {
internal OciServerHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SERVER, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {}
}
sealed internal class OciServiceContextHandle : OciHandle {
internal OciServiceContextHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SVCCTX, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {}
}
sealed internal class OciSessionHandle:OciHandle{
internal OciSessionHandle(OciHandle parent):base(parent, OCI.HTYPE.OCI_HTYPE_SESSION, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT){}
}
sealed internal class OciStatementHandle : OciHandle {
internal OciStatementHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_STMT) {
}
internal OciParameterDescriptor GetDescriptor(int i, OciErrorHandle errorHandle) {
// Wraps the OCIParamGet call. We do not expect it to fail, so we
// will throw if it does.
IntPtr paramdesc;
int rc = TracedNativeMethods.OCIParamGet(this, HandleType, errorHandle, out paramdesc, i+1 ); // NOTE: Oracle is 1-based, but we're zero-based.
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
OciParameterDescriptor result = new OciParameterDescriptor(this, paramdesc);
return result;
}
internal OciRowidDescriptor GetRowid( OciHandle environmentHandle, OciErrorHandle errorHandle ) {
OciRowidDescriptor rowidHandle = new OciRowidDescriptor(environmentHandle);
rowidHandle.GetRowid(this, errorHandle);
return rowidHandle;
}
}
/*+---------------------------------------------------------------------------------------------------+*/
// should be moved to a separate file
abstract internal class OciSimpleHandle : OciHandle {
// This class implements OciHandle for handle types that do not require
// cricial finalization.
internal OciSimpleHandle(OciHandle parent, OCI.HTYPE handleType, IntPtr value) : base(handleType) {
base.handle = value;
}
public override bool IsInvalid {
get {
return true; // guarantees we never try and release this...
}
}
}
sealed internal class OciBindHandle : OciSimpleHandle {
internal OciBindHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_BIND, value) {
}
};
sealed internal class OciDefineHandle : OciSimpleHandle {
internal OciDefineHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_DEFINE, value) {
}
};
sealed internal class OciParameterDescriptor : OciSimpleHandle {
internal OciParameterDescriptor(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_DTYPE_PARAM, value) {
}
};
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace System.Data.OracleClient
{
using System;
using System.Data.Common;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Runtime.ConstrainedExecution;
//---------------------------------------------------------------------
// OciHandle
//
// Class to manage the lifetime of Oracle Call Interface handles, and
// to simplify a number of handle-related operations
//
abstract internal class OciHandle : SafeHandle {
[Flags]
protected enum HANDLEFLAG {
DEFAULT = 0,
UNICODE = 1<<0,
NLS = 1<<1,
}
private OCI.HTYPE _handleType;
private int _refCount;
private OciHandle _parentHandle;
private bool _isUnicode;
// default constructor
protected OciHandle() : base(IntPtr.Zero, true) {
}
// OciSimpleHandle constructor
protected OciHandle(OCI.HTYPE handleType) : base(IntPtr.Zero, false) {
_handleType = handleType;
}
protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType) : this(parentHandle, handleType, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {
}
protected OciHandle(OciHandle parentHandle, OCI.HTYPE handleType, OCI.MODE ocimode, HANDLEFLAG handleflags) : this() {
int rc;
Debug.Assert (!(parentHandle is OciSimpleHandle), "Must not create handle on top of OciSimpleHandle");
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
_handleType = handleType;
_parentHandle = parentHandle;
_refCount = 1;
//
switch (handleType) {
case OCI.HTYPE.OCI_HTYPE_ENV:
Debug.Assert(null == parentHandle, "not null parentHandle?");
if ((handleflags & HANDLEFLAG.NLS) == HANDLEFLAG.NLS) {
rc = TracedNativeMethods.OCIEnvNlsCreate(
out base.handle,
ocimode,
0,
0);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIEnvNlsCreate", rc);
}
}
else {
rc = TracedNativeMethods.OCIEnvCreate(
out base.handle,
ocimode);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIEnvCreate", rc);
}
}
break;
case OCI.HTYPE.OCI_HTYPE_ERROR:
case OCI.HTYPE.OCI_HTYPE_SERVER:
case OCI.HTYPE.OCI_HTYPE_SVCCTX:
case OCI.HTYPE.OCI_HTYPE_SESSION:
case OCI.HTYPE.OCI_HTYPE_STMT:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIHandleAlloc(
parentHandle.EnvironmentHandle,
out base.handle,
handleType);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIHandleAlloc", rc);
}
break;
case OCI.HTYPE.OCI_DTYPE_LOB:
case OCI.HTYPE.OCI_DTYPE_FILE:
case OCI.HTYPE.OCI_DTYPE_ROWID:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ:
case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIDescriptorAlloc(
parentHandle.EnvironmentHandle,
out base.handle,
handleType);
if (0 != rc || IntPtr.Zero == base.handle) {
throw ADP.OperationFailed("OCIDescriptorAlloc", rc);
}
break;
case OCI.HTYPE.OCI_HTYPE_BIND:
case OCI.HTYPE.OCI_HTYPE_DEFINE:
case OCI.HTYPE.OCI_DTYPE_PARAM:
Debug.Assert(null != parentHandle, "null parentHandle?");
// These three handles are Simple OCI handles -- they do not
// need to be freed.
break;
default:
Debug.Assert(false, "unexpected handleType");
break;
}
// If we get here, we successfully allocated the handle, so we had
// better better up the parent's ref count.
if (null != parentHandle) {
parentHandle.AddRef();
_isUnicode = parentHandle.IsUnicode;
}
else {
_isUnicode = (handleflags & HANDLEFLAG.UNICODE) == HANDLEFLAG.UNICODE;
}
}
}
internal OciHandle EnvironmentHandle {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
OciHandle value;
if (HandleType == OCI.HTYPE.OCI_HTYPE_ENV) {
value = this;
}
else {
value = ParentHandle.EnvironmentHandle;
}
return value;
}
}
internal OCI.HTYPE HandleType {
get {
return _handleType;
}
}
public override bool IsInvalid {
get {
return (IntPtr.Zero == base.handle);
}
}
internal bool IsUnicode {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
return _isUnicode;
}
}
internal OciHandle ParentHandle {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
return _parentHandle;
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal int AddRef() {
int refCount = Interlocked.Increment(ref _refCount);
return refCount;
}
// Wrap the OCIAttrGet calls. We do not expect OCIAttrGet to fail,
// so we will throw if it does. There are multiple overloads here,
// one for each type of parameter that Oracle supports
internal void GetAttribute(OCI.ATTR attribute, out byte value, OciErrorHandle errorHandle) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void GetAttribute(OCI.ATTR attribute, out short value, OciErrorHandle errorHandle) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void GetAttribute(OCI.ATTR attribute, out int value, OciErrorHandle errorHandle) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, out value, out zero, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void GetAttribute(OCI.ATTR attribute, out string value, OciErrorHandle errorHandle, OracleConnection connection) {
IntPtr tempptr = IntPtr.Zero; // note: no need to clean up tempptr pointer
uint tempub4 = 0;
int rc = TracedNativeMethods.OCIAttrGet( this, ref tempptr, ref tempub4, attribute, errorHandle );
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
byte[] bytearray = new byte[tempub4];
Marshal.Copy(tempptr, bytearray, 0, checked((int)tempub4));
value = connection.GetString(bytearray);
}
internal byte[] GetBytes(string value) {
byte[] result;
uint valueLength = (uint)value.Length;
if (IsUnicode) {
result = new byte[valueLength * ADP.CharSize];
GetBytes(value.ToCharArray(), 0, valueLength, result, 0);
}
else {
byte[] temp = new byte[valueLength * 4]; // one Unicode character can map to up to 4 bytes
uint tempLength = GetBytes(value.ToCharArray(), 0, valueLength, temp, 0);
result = new byte[tempLength];
Buffer.BlockCopy(temp, 0, result, 0, checked ((int)tempLength));
}
return result;
}
internal uint GetBytes(char[] chars, int charIndex, uint charCount, byte[] bytes, int byteIndex) {
uint byteCount;
if (IsUnicode) {
byteCount = checked ((uint)(charCount * ADP.CharSize));
Buffer.BlockCopy(chars, charIndex*ADP.CharSize, bytes, byteIndex, checked ((int)byteCount));
}
else {
OciHandle environmentHandle = EnvironmentHandle;
GCHandle charsHandle = new GCHandle();
GCHandle bytesHandle = new GCHandle();
int rc;
try {
charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned);
IntPtr charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex);
IntPtr bytesPtr;
if (null == bytes) {
bytesPtr = IntPtr.Zero;
byteCount = 0;
}
else {
bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex);
byteCount = checked((uint)(bytes.Length-byteIndex));
}
rc = UnsafeNativeMethods.OCIUnicodeToCharSet(
environmentHandle,
bytesPtr,
byteCount,
charsPtr,
charCount,
out byteCount
);
}
finally {
charsHandle.Free();
if (bytesHandle.IsAllocated)
bytesHandle.Free();
}
if (0 != rc) {
throw ADP.OperationFailed("OCIUnicodeToCharSet", rc);
}
}
return byteCount;
}
internal uint GetChars(byte[] bytes, int byteIndex, uint byteCount, char[] chars, int charIndex) {
uint charCount;
if (IsUnicode) {
Debug.Assert(0 == (byteCount & 0x1), "Odd Number of Unicode Bytes?");
charCount = checked ((uint)(byteCount / ADP.CharSize));
Buffer.BlockCopy(bytes, byteIndex, chars, charIndex*ADP.CharSize, checked((int)byteCount));
}
else {
OciHandle environmentHandle = EnvironmentHandle;
GCHandle bytesHandle = new GCHandle();
GCHandle charsHandle = new GCHandle();
int rc;
try {
bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
IntPtr bytesPtr = new IntPtr((long)bytesHandle.AddrOfPinnedObject() + byteIndex);
IntPtr charsPtr;
if (null == chars) {
charsPtr = IntPtr.Zero;
charCount = 0;
}
else {
charsHandle = GCHandle.Alloc(chars, GCHandleType.Pinned);
charsPtr = new IntPtr((long)charsHandle.AddrOfPinnedObject() + charIndex);
charCount = checked((uint)(chars.Length-charIndex));
}
rc = UnsafeNativeMethods.OCICharSetToUnicode(
environmentHandle,
charsPtr,
charCount,
bytesPtr,
byteCount,
out charCount
);
}
finally {
bytesHandle.Free();
if (charsHandle.IsAllocated)
charsHandle.Free();
}
if (0 != rc) {
throw ADP.OperationFailed("OCICharSetToUnicode", rc);
}
}
return charCount;
}
//---------------------------------------------------------------------
static internal string GetAttributeName
(
OciHandle handle,
OCI.ATTR atype
)
{
if (OCI.HTYPE.OCI_DTYPE_PARAM == handle.HandleType)
return ((OCI.PATTR)atype).ToString();
return atype.ToString();
}
//----------------------------------------------------------------------
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
static internal IntPtr HandleValueToTrace ( OciHandle handle )
{
return handle.DangerousGetHandle(); // for tracing purposes, it's safe to just print this -- no handle recycling issues.
}
internal string PtrToString(NativeBuffer buf) {
string result = null;
if (IsUnicode)
result = buf.PtrToStringUni(0);
else
result = buf.PtrToStringAnsi(0);
return result;
}
internal string PtrToString(IntPtr buf, int len) {
string result;
if (IsUnicode)
result = Marshal.PtrToStringUni(buf, len);
else
result = Marshal.PtrToStringAnsi(buf, len);
return result;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal int Release() {
int refCount;
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
refCount = Interlocked.Decrement(ref _refCount);
Debug.Assert (0 <= refCount, "refCount is negative?");
if (0 == refCount) {
//Debug.WriteLine(String.Format("Releasing hande={0} value={1}", HandleTypeToString(this), HandleValueToString(base.handle)));
IntPtr handle = Interlocked.CompareExchange(ref base.handle, IntPtr.Zero, base.handle);
if (IntPtr.Zero != handle) {
OCI.HTYPE handleType = HandleType;
OciHandle parentHandle = ParentHandle;
int rc;
switch (handleType) {
case OCI.HTYPE.OCI_HTYPE_ENV:
Debug.Assert(null == parentHandle, "not null parentHandle?");
rc = TracedNativeMethods.OCIHandleFree(handle, handleType);
if (0 != rc) {
throw ADP.OperationFailed("OCIHandleFree", rc);
}
break;
case OCI.HTYPE.OCI_HTYPE_SERVER:
Debug.Assert(null != parentHandle, "null parentHandle?");
Debug.Assert(OCI.HTYPE.OCI_HTYPE_ERROR == parentHandle.HandleType, "parentHandle of server handle must be the error handle!");
// NOTE: while it might seem to be a problem here that
// we are using DangerousGetHandle on the parent
// handle here, the reason that we're doing it is
// that we're in shutdown mode and the handle may
// have already been released -- attempting to use
// it any other way would cause the CLR to throw
// an ObjectDisposedException wit the message
// "Safe handle has been closed". The reasons for
// this are that we're using our ref-counting
// to enforce a specific release order, but the
// GC will let the safehandle be closed long
// before all of the handles that have a ref-
// counts on this handle are closed, which means
// that the last one will cause the server detach
// call.
//
// There is no likelihood of having a handle
// recycling attack here, because we're making
// the call that we would have been making in
// ReleaseHandle -- we still own the handle
// until ServerDetach is called.
TracedNativeMethods.OCIServerDetach(handle, parentHandle.DangerousGetHandle(), OCI.MODE.OCI_DEFAULT);
// we eat failures here -- what would you suggest we do otherwise?
goto case OCI.HTYPE.OCI_HTYPE_SESSION;
case OCI.HTYPE.OCI_HTYPE_SVCCTX:
// NOTE: while it might seem to be a problem here that
// we are using DangerousGetHandle on the parent
// handle here, the reason that we're doing it is
// that we're in shutdown mode and the handle may
// have already been released -- attempting to use
// it any other way would cause the CLR to throw
// an ObjectDisposedException wit the message
// "Safe handle has been closed". The reasons for
// this are that we're using our ref-counting
// to enforce a specific release order, but the
// GC will let the safehandle be closed long
// before all of the handles that have a ref-
// counts on this handle are closed, which means
// that the last one will cause the server detach
// call.
//
// There is no likelihood of having a handle
// recycling attack here, because we're making
// the call that we would have been making in
// ReleaseHandle -- we still own the handle
// until they are freed, and our ref counting
// prevents them from being freed out of order.
OciHandle sessionHandle = parentHandle;
if (null != sessionHandle) {
OciHandle serverHandle = sessionHandle.ParentHandle;
if (null != serverHandle) {
OciHandle errorHandle = serverHandle.ParentHandle;
if (null != errorHandle) {
rc = TracedNativeMethods.OCISessionEnd(
handle, // svchp
errorHandle.DangerousGetHandle(), // errhp
sessionHandle.DangerousGetHandle(), // usrhp
OCI.MODE.OCI_DEFAULT // mode
);
}
}
}
// we eat failures here -- what would you suggest we do otherwise?
goto case OCI.HTYPE.OCI_HTYPE_ERROR;
case OCI.HTYPE.OCI_HTYPE_ERROR:
case OCI.HTYPE.OCI_HTYPE_SESSION:
case OCI.HTYPE.OCI_HTYPE_STMT:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIHandleFree(handle, handleType);
if (0 != rc) {
throw ADP.OperationFailed("OCIHandleFree", rc);
}
break;
case OCI.HTYPE.OCI_DTYPE_LOB:
case OCI.HTYPE.OCI_DTYPE_FILE:
case OCI.HTYPE.OCI_DTYPE_ROWID:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ:
case OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ:
case OCI.HTYPE.OCI_DTYPE_INTERVAL_DS:
Debug.Assert(null != parentHandle, "null parentHandle?");
rc = TracedNativeMethods.OCIDescriptorFree(handle, handleType);
if (0 != rc) {
throw ADP.OperationFailed("OCIDescriptorFree", rc);
}
break;
default:
Debug.Assert(false, "unexpected handleType");
break;
}
// If we ended up getting released, then we have to release
// our reference on our parent.
if (null != parentHandle) {
parentHandle.Release();
}
}
}
}
return refCount;
}
override protected bool ReleaseHandle() {
//Debug.WriteLine(String.Format("ReleaseHandle type={0} value={1}", HandleTypeToString(this), HandleValueToString(this)));
// NOTE: The SafeHandle class guarantees this will be called exactly once.
Release();
return true;
}
static internal void SafeDispose(ref OciHandle handle) {
// Safely disposes of the handle (even if it is already null) and
// then nulls it out.
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciEnvironmentHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciErrorHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciRowidDescriptor handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciStatementHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciSessionHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciServiceContextHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciServerHandle handle) {
if (null != handle) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciDefineHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciBindHandle handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose (ref OciParameterDescriptor handle) {
if (handle != null) {
handle.Dispose();
}
handle = null;
}
static internal void SafeDispose(ref OciDateTimeDescriptor handle)
{
if (handle != null)
{
handle.Dispose();
}
handle = null;
}
// Wrap the OCIAttrSet calls. We do not expect OCIAttrSet to fail,
// so we will throw if it does. There are multiple overloads here,
// one for each type of parameter that Oracle supports
internal void SetAttribute(OCI.ATTR attribute, int value, OciErrorHandle errorHandle) {
int rc = TracedNativeMethods.OCIAttrSet(
this, // trgthndlp/trghndltyp
ref value, // attributep
0, // size
attribute, // attrtype
errorHandle // errhp
);
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void SetAttribute(OCI.ATTR attribute, OciHandle value, OciErrorHandle errorHandle) {
int rc = TracedNativeMethods.OCIAttrSet(
this, // trgthndlp/trghndltyp
value, // attributep
0, // size
attribute, // attrtype
errorHandle // errhp
);
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
internal void SetAttribute(OCI.ATTR attribute, string value, OciErrorHandle errorHandle) {
uint valueLengthAsChars = unchecked((uint)value.Length);
byte[] valueAsBytes = new byte[valueLengthAsChars * 4];
uint valueLengthAsBytes = GetBytes(value.ToCharArray(), 0, valueLengthAsChars, valueAsBytes, 0);
int rc = TracedNativeMethods.OCIAttrSet(
this, // trgthndlp/trghndltyp
valueAsBytes, // attributep
valueLengthAsBytes, // size
attribute, // attrtype
errorHandle // errhp
);
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
}
sealed internal class OciEnvironmentHandle : OciHandle {
internal OciEnvironmentHandle(OCI.MODE environmentMode, bool unicode)
: base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, unicode?HANDLEFLAG.UNICODE:HANDLEFLAG.DEFAULT) {}
}
sealed internal class OciErrorHandle : OciHandle {
bool _connectionIsBroken;
internal OciErrorHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_ERROR) {}
internal bool ConnectionIsBroken {
get {
return _connectionIsBroken;
}
set {
_connectionIsBroken = value;
}
}
}
sealed internal class OciDateTimeDescriptor : OciHandle {
internal OciDateTimeDescriptor(OciHandle parent, OCI.HTYPE dateTimeType)
: base(parent, AssertDateTimeType(dateTimeType))
{
}
static OCI.HTYPE AssertDateTimeType(OCI.HTYPE dateTimeType)
{
Debug.Assert(
dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP ||
dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_TZ ||
dateTimeType == OCI.HTYPE.OCI_DTYPE_TIMESTAMP_LTZ,
"unexpected OciDateTime handleType");
return dateTimeType;
}
}
sealed internal class OciFileDescriptor : OciHandle {
internal OciFileDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_FILE) {}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal int OCILobFileSetNameWrapper( OciHandle envhp, OciHandle errhp, byte[] dirAlias, ushort dirAliasLength, byte[] fileName, ushort fileNameLength) {
int rc;
bool mustRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
DangerousAddRef(ref mustRelease);
RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
IntPtr bfileDescriptor = DangerousGetHandle();
rc = UnsafeNativeMethods.OCILobFileSetName(
envhp,
errhp,
ref bfileDescriptor,
dirAlias,
dirAliasLength,
fileName,
fileNameLength);
base.handle = bfileDescriptor;
}
}
finally {
if (mustRelease) {
DangerousRelease();
}
}
return rc;
}
};
sealed internal class OciIntervalDescriptor : OciHandle {
internal OciIntervalDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_INTERVAL_DS) {
}
}
sealed internal class OciLobDescriptor : OciHandle {
internal OciLobDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_LOB) {}
}
sealed internal class OciNlsEnvironmentHandle : OciHandle {
internal OciNlsEnvironmentHandle(OCI.MODE environmentMode )
: base(null, OCI.HTYPE.OCI_HTYPE_ENV, environmentMode, HANDLEFLAG.NLS) {}
}
sealed internal class OciRowidDescriptor : OciHandle {
internal OciRowidDescriptor(OciHandle parent) : base(parent, OCI.HTYPE.OCI_DTYPE_ROWID) {}
internal void GetRowid( OciStatementHandle statementHandle, OciErrorHandle errorHandle ) {
uint zero = 0;
int rc = TracedNativeMethods.OCIAttrGet( statementHandle, this, out zero, OCI.ATTR.OCI_ATTR_ROWID, errorHandle );
if ((int)OCI.RETURNCODE.OCI_NO_DATA == rc) {
Dispose();
}
else if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
}
}
sealed internal class OciServerHandle : OciHandle {
internal OciServerHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SERVER, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {}
}
sealed internal class OciServiceContextHandle : OciHandle {
internal OciServiceContextHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_SVCCTX, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT) {}
}
sealed internal class OciSessionHandle:OciHandle{
internal OciSessionHandle(OciHandle parent):base(parent, OCI.HTYPE.OCI_HTYPE_SESSION, OCI.MODE.OCI_DEFAULT, HANDLEFLAG.DEFAULT){}
}
sealed internal class OciStatementHandle : OciHandle {
internal OciStatementHandle(OciHandle parent) : base(parent, OCI.HTYPE.OCI_HTYPE_STMT) {
}
internal OciParameterDescriptor GetDescriptor(int i, OciErrorHandle errorHandle) {
// Wraps the OCIParamGet call. We do not expect it to fail, so we
// will throw if it does.
IntPtr paramdesc;
int rc = TracedNativeMethods.OCIParamGet(this, HandleType, errorHandle, out paramdesc, i+1 ); // NOTE: Oracle is 1-based, but we're zero-based.
if (0 != rc) {
OracleException.Check(errorHandle, rc);
}
OciParameterDescriptor result = new OciParameterDescriptor(this, paramdesc);
return result;
}
internal OciRowidDescriptor GetRowid( OciHandle environmentHandle, OciErrorHandle errorHandle ) {
OciRowidDescriptor rowidHandle = new OciRowidDescriptor(environmentHandle);
rowidHandle.GetRowid(this, errorHandle);
return rowidHandle;
}
}
/*+---------------------------------------------------------------------------------------------------+*/
// should be moved to a separate file
abstract internal class OciSimpleHandle : OciHandle {
// This class implements OciHandle for handle types that do not require
// cricial finalization.
internal OciSimpleHandle(OciHandle parent, OCI.HTYPE handleType, IntPtr value) : base(handleType) {
base.handle = value;
}
public override bool IsInvalid {
get {
return true; // guarantees we never try and release this...
}
}
}
sealed internal class OciBindHandle : OciSimpleHandle {
internal OciBindHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_BIND, value) {
}
};
sealed internal class OciDefineHandle : OciSimpleHandle {
internal OciDefineHandle(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_HTYPE_DEFINE, value) {
}
};
sealed internal class OciParameterDescriptor : OciSimpleHandle {
internal OciParameterDescriptor(OciHandle parent, IntPtr value) : base(parent, OCI.HTYPE.OCI_DTYPE_PARAM, value) {
}
};
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PersonalizationStateInfo.cs
- DbDataReader.cs
- SoapCodeExporter.cs
- MetaData.cs
- MimePart.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- QilExpression.cs
- SqlOuterApplyReducer.cs
- Brushes.cs
- CardSpacePolicyElement.cs
- SelectionListComponentEditor.cs
- LingerOption.cs
- FixedSOMTextRun.cs
- PagePropertiesChangingEventArgs.cs
- DocumentCollection.cs
- SecurityResources.cs
- ListCollectionView.cs
- NativeMethods.cs
- SourceFilter.cs
- DataServiceRequest.cs
- LinqDataSourceContextEventArgs.cs
- DependencyPropertyDescriptor.cs
- TextRange.cs
- CancelEventArgs.cs
- CheckBoxFlatAdapter.cs
- TextParaClient.cs
- WbemProvider.cs
- CodeDelegateCreateExpression.cs
- MaterialGroup.cs
- KoreanCalendar.cs
- XmlParserContext.cs
- SerializationInfoEnumerator.cs
- LicenseContext.cs
- RegexMatchCollection.cs
- FormViewDeleteEventArgs.cs
- DesignerToolboxInfo.cs
- CatalogZoneBase.cs
- LinkGrep.cs
- SamlAttribute.cs
- ZoneLinkButton.cs
- ECDiffieHellman.cs
- RectIndependentAnimationStorage.cs
- SiteMapProvider.cs
- PrivilegeNotHeldException.cs
- SecurityUtils.cs
- Light.cs
- Shape.cs
- StackSpiller.Temps.cs
- SerializationInfoEnumerator.cs
- ToolboxItemLoader.cs
- ExpressionPrefixAttribute.cs
- ConfigsHelper.cs
- HtmlInputSubmit.cs
- FactoryGenerator.cs
- DataGridViewControlCollection.cs
- SecurityUtils.cs
- XmlAttributes.cs
- CategoryGridEntry.cs
- PackWebResponse.cs
- OneOfScalarConst.cs
- UrlAuthorizationModule.cs
- SupportingTokenSecurityTokenResolver.cs
- SQLBinaryStorage.cs
- Timer.cs
- TreeViewAutomationPeer.cs
- DefaultTextStoreTextComposition.cs
- MetadataConversionError.cs
- SimpleMailWebEventProvider.cs
- PasswordTextContainer.cs
- BitmapFrameDecode.cs
- MarkupExtensionSerializer.cs
- DataGridViewColumnHeaderCell.cs
- SinglePageViewer.cs
- MimePart.cs
- PrintControllerWithStatusDialog.cs
- Camera.cs
- QuaternionAnimation.cs
- HeaderUtility.cs
- ProbeMatchesMessage11.cs
- NavigationHelper.cs
- ProcessStartInfo.cs
- WebPartEventArgs.cs
- EntityClassGenerator.cs
- QuotedPrintableStream.cs
- SqlEnums.cs
- RefreshResponseInfo.cs
- BamlBinaryWriter.cs
- StylusPointPropertyInfoDefaults.cs
- SparseMemoryStream.cs
- PartialToken.cs
- EntityProxyTypeInfo.cs
- StdValidatorsAndConverters.cs
- _AutoWebProxyScriptHelper.cs
- PixelShader.cs
- CodeSubDirectoriesCollection.cs
- DesignTimeType.cs
- PropertyKey.cs
- TreeWalkHelper.cs
- WindowCollection.cs
- SiteMapHierarchicalDataSourceView.cs