//
// OciHandle.cs
//
// Part of managed C#/.NET library System.Data.OracleClient.dll
//
// Part of the Mono class libraries at
// mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci
//
// Assembly: System.Data.OracleClient.dll
// Namespace: System.Data.OracleClient.Oci
//
// Author:
// Tim Coleman <tim@timcoleman.com>
// Daniel Morgan <danielmorgan@verizon.net>
//
// Copyright (C) Tim Coleman, 2003
// Copyright (C) Daniel Morgan, 2005
//
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Security.Cryptography;
using System.Globalization;
namespace System.Data.OracleClient.Oci{
internal abstract class OciHandle : IDisposable {
#region Fields
bool disposed = false;
protected internal IntPtr handle = IntPtr.Zero;
OciHandle parent = null;
OciHandleType type;
#endregion // Fields
#region Constructors
internal OciHandle (OciHandleType type, OciHandle parent, IntPtr newHandle) {
this.type = type;
this.parent = parent;
this.handle = newHandle;
}
~OciHandle () {
Dispose (false);
}
#endregion // Constructors
#region Properties
internal OciHandle Parent {
get { return parent; }
}
internal IntPtr Handle {
get { return handle; }
}
internal OciHandleType HandleType {
get { return type; }
}
#endregion // Properties
#region Methods
internal OciHandle Allocate (OciHandleType type) {
int status = 0;
IntPtr newHandle = IntPtr.Zero;
if (type < OciHandleType.LobLocator)
status = OciCalls.OCIHandleAlloc (this,
out newHandle,
type,
0,
IntPtr.Zero);
else
status = OciCalls.OCIDescriptorAlloc (this,
out newHandle,
type,
0,
IntPtr.Zero);
if (status != 0 && status != 1)
throw new Exception (String.Format ("Could not allocate new OCI Handle of type {0}", type));
switch (type) {
case OciHandleType.Service:
return new OciServiceHandle (this, newHandle);
case OciHandleType.Error:
return new OciErrorHandle (this, newHandle);
case OciHandleType.Server:
return new OciServerHandle (this, newHandle);
case OciHandleType.Session:
return new OciSessionHandle (this, newHandle);
case OciHandleType.Statement:
return new OciStatementHandle (this, newHandle);
case OciHandleType.Transaction:
return new OciTransactionHandle (this, newHandle);
case OciHandleType.LobLocator:
return new OciLobLocator (this, newHandle);
case OciHandleType.RowId:
return new OciRowIdDescriptor (this, newHandle);
case OciHandleType.TimeStamp:
return new OciDateTimeDescriptor (this, newHandle);
case OciHandleType.IntervalDayToSecond:
case OciHandleType.IntervalYearToMonth:
return new OciIntervalDescriptor (this, type, newHandle);
}
return null;
}
protected virtual void Dispose (bool disposing) {
if (!disposed) {
FreeHandle ();
if (disposing) {
parent = null;
}
disposed = true;
}
}
public void Dispose () {
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void FreeHandle ()
{
if (type < OciHandleType.LobLocator) {
switch (type) {
case OciHandleType.Bind:
case OciHandleType.Define:
// Bind and Define handles are freed when Statement handle is disposed
break;
case OciHandleType.Environment:
if (handle != IntPtr.Zero) {
OciCalls.OCIHandleFree (handle, type);
}
break;
default:
if ( handle != IntPtr.Zero &&
parent != null &&
parent.Handle != IntPtr.Zero ) {
OciCalls.OCIHandleFree (handle, type);
}
break;
}
handle = IntPtr.Zero;
}
}
internal bool GetAttributeBool (OciAttributeType attrType, OciErrorHandle errorHandle) {
return (GetAttributeInt32 (attrType, errorHandle) != 0);
}
internal sbyte GetAttributeSByte (OciAttributeType attrType, OciErrorHandle errorHandle) {
int status = 0;
sbyte output;
status = OciCalls.OCIAttrGetSByte (Handle,
HandleType,
out output,
IntPtr.Zero,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
return output;
}
internal byte GetAttributeByte (OciAttributeType attrType, OciErrorHandle errorHandle) {
int status = 0;
byte output;
status = OciCalls.OCIAttrGetByte (Handle,
HandleType,
out output,
IntPtr.Zero,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
return output;
}
internal ushort GetAttributeUInt16 (OciAttributeType attrType, OciErrorHandle errorHandle) {
int status = 0;
ushort output;
status = OciCalls.OCIAttrGetUInt16 (Handle,
HandleType,
out output,
IntPtr.Zero,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
return output;
}
internal int GetAttributeInt32 (OciAttributeType attrType, OciErrorHandle errorHandle) {
int status = 0;
int output;
status = OciCalls.OCIAttrGetInt32 (Handle,
HandleType,
out output,
IntPtr.Zero,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = OciErrorHandle.HandleError (errorHandle, status);
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
return output;
}
[DllImport ("oci", EntryPoint = "OCIAttrGet")]
internal static extern int OCIAttrGetRowIdDesc (IntPtr trgthndlp,
[MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
IntPtr attributep,
ref uint sizep,
[MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
IntPtr errhp);
internal OciRowIdDescriptor GetAttributeRowIdDescriptor (OciErrorHandle errorHandle, OciHandle env)
{
OciRowIdDescriptor descriptor = null;
IntPtr outputPtr = IntPtr.Zero;
int outSize = 16;
int status = 0;
OciAttributeType attrType = OciAttributeType.RowId;
outputPtr = OciCalls.AllocateClear (outSize);
uint siz = (uint) outSize;
status = OCIAttrGetRowIdDesc (Handle,
HandleType,
outputPtr,
ref siz,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
if (outputPtr != IntPtr.Zero && siz > 0) {
descriptor = (OciRowIdDescriptor) env.Allocate(OciHandleType.RowId);
descriptor.SetHandle (outputPtr);
}
return descriptor;
}
internal IntPtr GetAttributeIntPtr (OciAttributeType attrType, OciErrorHandle errorHandle) {
int status = 0;
IntPtr output = IntPtr.Zero;
status = OciCalls.OCIAttrGetIntPtr (Handle,
HandleType,
out output,
IntPtr.Zero,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
return output;
}
internal string GetAttributeString (OciAttributeType attrType, OciErrorHandle errorHandle) {
string output = String.Empty;
IntPtr outputPtr = IntPtr.Zero;
int outSize;
int status = 0;
status = OciCalls.OCIAttrGet (Handle,
HandleType,
out outputPtr,
out outSize,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
if (outputPtr != IntPtr.Zero && outSize > 0) {
object str = Marshal.PtrToStringAnsi (outputPtr, outSize);
if (str != null)
output = String.Copy ((string) str);
}
return output;
}
internal void SetAttributeString (string attribute, OciAttributeType attrType, OciErrorHandle errorHandle)
{
int status = 0;
status = OciCalls.OCIAttrSetString (Handle,
HandleType,
attribute,
(uint) attribute.Length,
attrType,
errorHandle);
if (status != 0) {
OciErrorInfo info = errorHandle.HandleError ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
}
internal void SetHandle (IntPtr h)
{
handle = h;
}
#endregion // Methods
#region Operators and Type Conversions
public static implicit operator IntPtr (OciHandle h)
{
return h.Handle;
}
#endregion // Operators and Type Conversions
}
}
|