OciHandle.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. //
  2. // OciHandle.cs
  3. //
  4. // Part of managed C#/.NET library System.Data.OracleClient.dll
  5. //
  6. // Part of the Mono class libraries at
  7. // mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci
  8. //
  9. // Assembly: System.Data.OracleClient.dll
  10. // Namespace: System.Data.OracleClient.Oci
  11. //
  12. // Author:
  13. // Tim Coleman <[email protected]>
  14. // Daniel Morgan <[email protected]>
  15. //
  16. // Copyright (C) Tim Coleman, 2003
  17. // Copyright (C) Daniel Morgan, 2005
  18. //
  19. using System;
  20. using System.Runtime.InteropServices;
  21. using System.Text;
  22. using System.Security.Cryptography;
  23. using System.Globalization;
  24. namespace System.Data.OracleClient.Oci {
  25. internal abstract class OciHandle : IDisposable {
  26. #region Fields
  27. bool disposed = false;
  28. protected internal IntPtr handle = IntPtr.Zero;
  29. OciHandle parent = null;
  30. OciHandleType type;
  31. #endregion // Fields
  32. #region Constructors
  33. internal OciHandle (OciHandleType type, OciHandle parent, IntPtr newHandle) {
  34. this.type = type;
  35. this.parent = parent;
  36. this.handle = newHandle;
  37. }
  38. ~OciHandle () {
  39. Dispose (false);
  40. }
  41. #endregion // Constructors
  42. #region Properties
  43. internal OciHandle Parent {
  44. get { return parent; }
  45. }
  46. internal IntPtr Handle {
  47. get { return handle; }
  48. }
  49. internal OciHandleType HandleType {
  50. get { return type; }
  51. }
  52. #endregion // Properties
  53. #region Methods
  54. internal OciHandle Allocate (OciHandleType type) {
  55. int status = 0;
  56. IntPtr newHandle = IntPtr.Zero;
  57. if (type < OciHandleType.LobLocator)
  58. status = OciCalls.OCIHandleAlloc (this,
  59. out newHandle,
  60. type,
  61. 0,
  62. IntPtr.Zero);
  63. else
  64. status = OciCalls.OCIDescriptorAlloc (this,
  65. out newHandle,
  66. type,
  67. 0,
  68. IntPtr.Zero);
  69. if (status != 0 && status != 1)
  70. throw new Exception (String.Format ("Could not allocate new OCI Handle of type {0}", type));
  71. switch (type) {
  72. case OciHandleType.Service:
  73. return new OciServiceHandle (this, newHandle);
  74. case OciHandleType.Error:
  75. return new OciErrorHandle (this, newHandle);
  76. case OciHandleType.Server:
  77. return new OciServerHandle (this, newHandle);
  78. case OciHandleType.Session:
  79. return new OciSessionHandle (this, newHandle);
  80. case OciHandleType.Statement:
  81. return new OciStatementHandle (this, newHandle);
  82. case OciHandleType.Transaction:
  83. return new OciTransactionHandle (this, newHandle);
  84. case OciHandleType.LobLocator:
  85. return new OciLobLocator (this, newHandle);
  86. case OciHandleType.RowId:
  87. return new OciRowIdDescriptor (this, newHandle);
  88. case OciHandleType.TimeStamp:
  89. return new OciDateTimeDescriptor (this, newHandle);
  90. }
  91. return null;
  92. }
  93. protected virtual void Dispose (bool disposing) {
  94. if (!disposed) {
  95. FreeHandle ();
  96. if (disposing) {
  97. parent = null;
  98. }
  99. disposed = true;
  100. }
  101. }
  102. public void Dispose () {
  103. Dispose (true);
  104. GC.SuppressFinalize (this);
  105. }
  106. protected virtual void FreeHandle ()
  107. {
  108. if (type < OciHandleType.LobLocator) {
  109. switch (type) {
  110. case OciHandleType.Bind:
  111. case OciHandleType.Define:
  112. // Bind and Define handles are freed when Statement handle is disposed
  113. break;
  114. case OciHandleType.Environment:
  115. if (handle != IntPtr.Zero) {
  116. OciCalls.OCIHandleFree (handle, type);
  117. }
  118. break;
  119. default:
  120. if ( handle != IntPtr.Zero &&
  121. parent != null &&
  122. parent.Handle != IntPtr.Zero ) {
  123. OciCalls.OCIHandleFree (handle, type);
  124. }
  125. break;
  126. }
  127. handle = IntPtr.Zero;
  128. }
  129. }
  130. internal bool GetAttributeBool (OciAttributeType attrType, OciErrorHandle errorHandle) {
  131. return (GetAttributeInt32 (attrType, errorHandle) != 0);
  132. }
  133. internal sbyte GetAttributeSByte (OciAttributeType attrType, OciErrorHandle errorHandle) {
  134. int status = 0;
  135. sbyte output;
  136. status = OciCalls.OCIAttrGetSByte (Handle,
  137. HandleType,
  138. out output,
  139. IntPtr.Zero,
  140. attrType,
  141. errorHandle);
  142. if (status != 0) {
  143. OciErrorInfo info = errorHandle.HandleError ();
  144. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  145. }
  146. return output;
  147. }
  148. internal byte GetAttributeByte (OciAttributeType attrType, OciErrorHandle errorHandle) {
  149. int status = 0;
  150. byte output;
  151. status = OciCalls.OCIAttrGetByte (Handle,
  152. HandleType,
  153. out output,
  154. IntPtr.Zero,
  155. attrType,
  156. errorHandle);
  157. if (status != 0) {
  158. OciErrorInfo info = errorHandle.HandleError ();
  159. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  160. }
  161. return output;
  162. }
  163. internal ushort GetAttributeUInt16 (OciAttributeType attrType, OciErrorHandle errorHandle) {
  164. int status = 0;
  165. ushort output;
  166. status = OciCalls.OCIAttrGetUInt16 (Handle,
  167. HandleType,
  168. out output,
  169. IntPtr.Zero,
  170. attrType,
  171. errorHandle);
  172. if (status != 0) {
  173. OciErrorInfo info = errorHandle.HandleError ();
  174. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  175. }
  176. return output;
  177. }
  178. internal int GetAttributeInt32 (OciAttributeType attrType, OciErrorHandle errorHandle) {
  179. int status = 0;
  180. int output;
  181. status = OciCalls.OCIAttrGetInt32 (Handle,
  182. HandleType,
  183. out output,
  184. IntPtr.Zero,
  185. attrType,
  186. errorHandle);
  187. if (status != 0) {
  188. OciErrorInfo info = OciErrorHandle.HandleError (errorHandle, status);
  189. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  190. }
  191. return output;
  192. }
  193. [DllImport ("oci", EntryPoint = "OCIAttrGet")]
  194. internal static extern int OCIAttrGetRowIdDesc (IntPtr trgthndlp,
  195. [MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
  196. IntPtr attributep,
  197. ref uint sizep,
  198. [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
  199. IntPtr errhp);
  200. internal OciRowIdDescriptor GetAttributeRowIdDescriptor (OciErrorHandle errorHandle, OciHandle env)
  201. {
  202. OciRowIdDescriptor descriptor = null;
  203. IntPtr outputPtr = IntPtr.Zero;
  204. int outSize = 16;
  205. int status = 0;
  206. OciAttributeType attrType = OciAttributeType.RowId;
  207. outputPtr = OciCalls.AllocateClear (outSize);
  208. uint siz = (uint) outSize;
  209. status = OCIAttrGetRowIdDesc (Handle,
  210. HandleType,
  211. outputPtr,
  212. ref siz,
  213. attrType,
  214. errorHandle);
  215. if (status != 0) {
  216. OciErrorInfo info = errorHandle.HandleError ();
  217. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  218. }
  219. if (outputPtr != IntPtr.Zero && siz > 0) {
  220. descriptor = (OciRowIdDescriptor) env.Allocate(OciHandleType.RowId);
  221. descriptor.SetHandle (outputPtr);
  222. }
  223. return descriptor;
  224. }
  225. internal IntPtr GetAttributeIntPtr (OciAttributeType attrType, OciErrorHandle errorHandle) {
  226. int status = 0;
  227. IntPtr output = IntPtr.Zero;
  228. status = OciCalls.OCIAttrGetIntPtr (Handle,
  229. HandleType,
  230. out output,
  231. IntPtr.Zero,
  232. attrType,
  233. errorHandle);
  234. if (status != 0) {
  235. OciErrorInfo info = errorHandle.HandleError ();
  236. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  237. }
  238. return output;
  239. }
  240. internal string GetAttributeString (OciAttributeType attrType, OciErrorHandle errorHandle) {
  241. string output = String.Empty;
  242. IntPtr outputPtr = IntPtr.Zero;
  243. int outSize;
  244. int status = 0;
  245. status = OciCalls.OCIAttrGet (Handle,
  246. HandleType,
  247. out outputPtr,
  248. out outSize,
  249. attrType,
  250. errorHandle);
  251. if (status != 0) {
  252. OciErrorInfo info = errorHandle.HandleError ();
  253. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  254. }
  255. if (outputPtr != IntPtr.Zero && outSize > 0) {
  256. object str = Marshal.PtrToStringAnsi (outputPtr, outSize);
  257. if (str != null)
  258. output = String.Copy ((string) str);
  259. }
  260. return output;
  261. }
  262. internal void SetAttributeString (string attribute, OciAttributeType attrType, OciErrorHandle errorHandle)
  263. {
  264. int status = 0;
  265. status = OciCalls.OCIAttrSetString (Handle,
  266. HandleType,
  267. attribute,
  268. (uint) attribute.Length,
  269. attrType,
  270. errorHandle);
  271. if (status != 0) {
  272. OciErrorInfo info = errorHandle.HandleError ();
  273. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  274. }
  275. }
  276. internal void SetHandle (IntPtr h)
  277. {
  278. handle = h;
  279. }
  280. #endregion // Methods
  281. #region Operators and Type Conversions
  282. public static implicit operator IntPtr (OciHandle h)
  283. {
  284. return h.Handle;
  285. }
  286. #endregion // Operators and Type Conversions
  287. }
  288. }