ReaderCache.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. //
  2. // System.Data.ProviderBase.ReaderCache.cs
  3. //
  4. // Authors:
  5. // Konstantin Triger <[email protected]>
  6. // Boris Kirzner <[email protected]>
  7. //
  8. // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
  9. //
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. using System;
  31. using java.sql;
  32. namespace System.Data.ProviderBase
  33. {
  34. public interface IReaderCacheContainer
  35. {
  36. void Fetch(ResultSet rs, int columnIndex, bool isSequential);
  37. bool IsNull();
  38. bool IsNumeric();
  39. object GetValue();
  40. }
  41. public abstract class ReaderCacheContainerBase : IReaderCacheContainer
  42. {
  43. #region Fields
  44. bool _isNull;
  45. #endregion // Fields
  46. #region Methods
  47. protected abstract void FetchInternal(ResultSet rs, int columnIndex);
  48. protected virtual void FetchInternal(ResultSet rs, int columnIndex, bool isSequential) {
  49. FetchInternal(rs, columnIndex);
  50. }
  51. public virtual bool IsNumeric() {
  52. return false;
  53. }
  54. public abstract object GetValue();
  55. public void Fetch(ResultSet rs, int columnIndex, bool isSequential)
  56. {
  57. FetchInternal(rs, columnIndex + 1, isSequential);
  58. _isNull = rs.wasNull();
  59. }
  60. public bool IsNull()
  61. {
  62. return _isNull;
  63. }
  64. #endregion // Methods
  65. }
  66. internal sealed class ArrayReaderCacheContainer : ReaderCacheContainerBase // Types.ARRAY
  67. {
  68. #region Fields
  69. object _a;
  70. #endregion // Fields
  71. #region Methods
  72. protected override void FetchInternal(ResultSet rs, int columnIndex)
  73. {
  74. _a = rs.getArray(columnIndex).getArray();
  75. }
  76. public override object GetValue()
  77. {
  78. return _a;
  79. }
  80. #endregion // Methods
  81. }
  82. internal sealed class Int64ReaderCacheContainer : ReaderCacheContainerBase // Types.BIGINT
  83. {
  84. #region Fields
  85. long _l;
  86. #endregion // Fields
  87. #region Methods
  88. protected override void FetchInternal(ResultSet rs, int columnIndex)
  89. {
  90. _l = rs.getLong(columnIndex);
  91. }
  92. public override bool IsNumeric() {
  93. return true;
  94. }
  95. public override object GetValue()
  96. {
  97. return _l;
  98. }
  99. internal long GetInt64()
  100. {
  101. return _l;
  102. }
  103. #endregion // Methods
  104. }
  105. internal class BytesReaderCacheContainer : ReaderCacheContainerBase // Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY
  106. {
  107. #region Fields
  108. protected byte[] _b;
  109. #endregion // Fields
  110. #region Methods
  111. protected override void FetchInternal(ResultSet rs, int columnIndex)
  112. {
  113. sbyte[] sbyteArray = rs.getBytes(columnIndex);
  114. if (sbyteArray != null) {
  115. _b = (byte[])vmw.common.TypeUtils.ToByteArray(sbyteArray);
  116. }
  117. }
  118. public override object GetValue()
  119. {
  120. return _b;
  121. }
  122. internal byte[] GetBytes()
  123. {
  124. return (byte[])GetValue();
  125. }
  126. internal virtual long GetBytes(
  127. long dataIndex,
  128. byte[] buffer,
  129. int bufferIndex,
  130. int length) {
  131. if (_b == null)
  132. return 0;
  133. if (buffer == null)
  134. return _b.LongLength;
  135. long actualLength = ((dataIndex + length) >= _b.LongLength) ? (_b.LongLength - dataIndex) : length;
  136. Array.Copy(_b,dataIndex,buffer,bufferIndex,actualLength);
  137. return actualLength;
  138. }
  139. #endregion // Methods
  140. }
  141. internal sealed class BooleanReaderCacheContainer : ReaderCacheContainerBase // Types.BIT
  142. {
  143. #region Fields
  144. bool _b;
  145. #endregion // Fields
  146. #region Methods
  147. protected override void FetchInternal(ResultSet rs, int columnIndex)
  148. {
  149. _b = rs.getBoolean(columnIndex);
  150. }
  151. public override bool IsNumeric() {
  152. return true;
  153. }
  154. public override object GetValue()
  155. {
  156. return _b;
  157. }
  158. internal bool GetBoolean()
  159. {
  160. return _b;
  161. }
  162. #endregion // Methods
  163. }
  164. internal sealed class BlobReaderCacheContainer : BytesReaderCacheContainer // Types.BLOB
  165. {
  166. #region Fields
  167. static readonly byte[] _emptyByteArr = new byte[0];
  168. java.sql.Blob _blob;
  169. #endregion // Fields
  170. #region Methods
  171. protected override void FetchInternal(ResultSet rs, int columnIndex) {
  172. throw new NotImplementedException("Should not be called");
  173. }
  174. protected override void FetchInternal(ResultSet rs, int columnIndex, bool isSequential)
  175. {
  176. _blob = rs.getBlob(columnIndex);
  177. if (!isSequential)
  178. ReadAll();
  179. }
  180. void ReadAll() {
  181. if (_blob != null) {
  182. long length = _blob.length();
  183. if (length == 0) {
  184. _b = _emptyByteArr;
  185. }
  186. else {
  187. java.io.InputStream input = _blob.getBinaryStream();
  188. byte[] byteValue = new byte[length];
  189. sbyte[] sbyteValue = vmw.common.TypeUtils.ToSByteArray(byteValue);
  190. input.read(sbyteValue);
  191. _b = byteValue;
  192. }
  193. }
  194. }
  195. public override object GetValue()
  196. {
  197. if (_b == null)
  198. ReadAll();
  199. return base.GetValue();
  200. }
  201. internal override long GetBytes(long dataIndex, byte[] buffer, int bufferIndex, int length) {
  202. if (_b != null)
  203. return base.GetBytes (dataIndex, buffer, bufferIndex, length);
  204. if (_blob == null)
  205. return 0;
  206. if (buffer == null)
  207. return _blob.length();
  208. java.io.InputStream input = _blob.getBinaryStream();
  209. input.skip(dataIndex);
  210. return input.read(vmw.common.TypeUtils.ToSByteArray(buffer), bufferIndex, length);
  211. }
  212. #endregion // Methods
  213. }
  214. internal abstract class CharsReaderCacheContainer : ReaderCacheContainerBase //
  215. {
  216. #region Fields
  217. #endregion // Fields
  218. #region Methods
  219. internal abstract long GetChars(
  220. long dataIndex,
  221. char[] buffer,
  222. int bufferIndex,
  223. int length);
  224. #endregion // Methods
  225. }
  226. internal sealed class GuidReaderCacheContainer : ReaderCacheContainerBase // Types.CHAR
  227. {
  228. #region Fields
  229. Guid _g;
  230. #endregion // Fields
  231. #region Methods
  232. protected override void FetchInternal(ResultSet rs, int columnIndex)
  233. {
  234. string s = rs.getString(columnIndex);
  235. if (s != null)
  236. _g = new Guid(s);
  237. }
  238. public override object GetValue()
  239. {
  240. return _g;
  241. }
  242. internal Guid GetGuid()
  243. {
  244. return _g;
  245. }
  246. #endregion // Methods
  247. }
  248. internal sealed class ClobReaderCacheContainer : StringReaderCacheContainer // Types.CLOB
  249. {
  250. #region Fields
  251. java.sql.Clob _clob;
  252. #endregion // Fields
  253. #region Methods
  254. protected override void FetchInternal(ResultSet rs, int columnIndex, bool isSequential)
  255. {
  256. _clob = rs.getClob(columnIndex);
  257. if (!isSequential)
  258. ReadAll();
  259. }
  260. void ReadAll() {
  261. if (_clob != null) {
  262. long length = _clob.length();
  263. if (length == 0) {
  264. _s = String.Empty;
  265. }
  266. else {
  267. java.io.Reader reader = _clob.getCharacterStream();
  268. char[] charValue = new char[length];
  269. reader.read(charValue);
  270. if (charValue != null)
  271. _s = new String(charValue);
  272. }
  273. }
  274. }
  275. public override object GetValue()
  276. {
  277. if (_s == null)
  278. ReadAll();
  279. return base.GetValue();
  280. }
  281. internal override long GetChars(long dataIndex, char[] buffer, int bufferIndex, int length) {
  282. if (_s != null)
  283. return base.GetChars (dataIndex, buffer, bufferIndex, length);
  284. if (_clob == null)
  285. return 0;
  286. if (buffer == null)
  287. return _clob.length();
  288. java.io.Reader reader = _clob.getCharacterStream();
  289. reader.skip(dataIndex);
  290. return reader.read(buffer, bufferIndex, length);
  291. }
  292. #endregion // Methods
  293. }
  294. internal sealed class TimeSpanReaderCacheContainer : ReaderCacheContainerBase // Types.TIME
  295. {
  296. #region Fields
  297. TimeSpan _t;
  298. #endregion // Fields
  299. #region Methods
  300. protected override void FetchInternal(ResultSet rs, int columnIndex)
  301. {
  302. Time t = rs.getTime(columnIndex);
  303. if (t != null) {
  304. _t = new TimeSpan(DbConvert.JavaTimeToClrTicks(t));
  305. }
  306. }
  307. public override object GetValue()
  308. {
  309. return _t;
  310. }
  311. internal TimeSpan GetTimeSpan()
  312. {
  313. return _t;
  314. }
  315. #endregion // Methods
  316. }
  317. internal class DateTimeReaderCacheContainer : ReaderCacheContainerBase // Types.TIMESTAMP
  318. {
  319. #region Fields
  320. protected DateTime _d;
  321. #endregion // Fields
  322. #region Methods
  323. protected override void FetchInternal(ResultSet rs, int columnIndex)
  324. {
  325. Date d = rs.getDate(columnIndex);
  326. if (d != null) {
  327. _d = new DateTime(DbConvert.JavaDateToClrTicks(d));
  328. }
  329. }
  330. public override object GetValue()
  331. {
  332. return _d;
  333. }
  334. internal DateTime GetDateTime()
  335. {
  336. return _d;
  337. }
  338. #endregion // Methods
  339. }
  340. internal sealed class TimestampReaderCacheContainer : DateTimeReaderCacheContainer // Types.DATE
  341. {
  342. protected override void FetchInternal(ResultSet rs, int columnIndex) {
  343. Timestamp ts = rs.getTimestamp(columnIndex);
  344. if (ts != null) {
  345. _d = new DateTime(DbConvert.JavaTimestampToClrTicks(ts));
  346. }
  347. }
  348. }
  349. internal sealed class DecimalReaderCacheContainer : ReaderCacheContainerBase // Types.DECIMAL, Types.NUMERIC
  350. {
  351. #region Fields
  352. decimal _d;
  353. #endregion // Fields
  354. #region Methods
  355. protected override void FetchInternal(ResultSet rs, int columnIndex)
  356. {
  357. java.math.BigDecimal bigDecimal = rs.getBigDecimal(columnIndex);
  358. if (bigDecimal != null) {
  359. _d = (decimal)vmw.common.PrimitiveTypeUtils.BigDecimalToDecimal(bigDecimal);
  360. }
  361. }
  362. public override bool IsNumeric() {
  363. return true;
  364. }
  365. public override object GetValue()
  366. {
  367. return _d;
  368. }
  369. internal decimal GetDecimal()
  370. {
  371. return _d;
  372. }
  373. #endregion // Methods
  374. }
  375. internal sealed class DoubleReaderCacheContainer : ReaderCacheContainerBase // Types.DOUBLE, Types.Float, Types.NUMERIC for Oracle with scale = -127
  376. {
  377. #region Fields
  378. double _d;
  379. #endregion // Fields
  380. #region Methods
  381. protected override void FetchInternal(ResultSet rs, int columnIndex)
  382. {
  383. _d = rs.getDouble(columnIndex);
  384. }
  385. public override bool IsNumeric() {
  386. return true;
  387. }
  388. public override object GetValue()
  389. {
  390. return _d;
  391. }
  392. internal double GetDouble()
  393. {
  394. return _d;
  395. }
  396. #endregion // Methods
  397. }
  398. internal sealed class Int32ReaderCacheContainer : ReaderCacheContainerBase // Types.INTEGER
  399. {
  400. #region Fields
  401. int _i;
  402. #endregion // Fields
  403. #region Methods
  404. protected override void FetchInternal(ResultSet rs, int columnIndex)
  405. {
  406. _i = rs.getInt(columnIndex);
  407. }
  408. public override bool IsNumeric() {
  409. return true;
  410. }
  411. public override object GetValue()
  412. {
  413. return _i;
  414. }
  415. internal int GetInt32()
  416. {
  417. return _i;
  418. }
  419. #endregion // Methods
  420. }
  421. internal class StringReaderCacheContainer : CharsReaderCacheContainer // Types.LONGVARCHAR, Types.VARCHAR, Types.CHAR
  422. {
  423. #region Fields
  424. protected string _s;
  425. #endregion // Fields
  426. #region Methods
  427. protected override void FetchInternal(ResultSet rs, int columnIndex)
  428. {
  429. _s = rs.getString(columnIndex);
  430. // Oracle Jdbc driver returns extra trailing 0 chars for NCHAR columns
  431. // if ((_s != null) && (_jdbcType == 1)) {
  432. // Console.WriteLine(_jdbcType);
  433. // int zeroIndex = ((string)_s).IndexOf((char)0);
  434. // if (zeroIndex > 0) {
  435. // Console.WriteLine("zero-padded");
  436. // _s = ((string)_s).Substring(0,zeroIndex);
  437. // }
  438. // else {
  439. // // Oracle sometimes pads with blanks (32)
  440. // int blankIndex = ((string)_s).IndexOf((char)32);
  441. // if (blankIndex > 0) {
  442. // Console.WriteLine("blank-padded");
  443. // _s = ((string)_s).Substring(0,blankIndex);
  444. // }
  445. // }
  446. // }
  447. }
  448. public override object GetValue()
  449. {
  450. return _s;
  451. }
  452. internal string GetString()
  453. {
  454. return _s;
  455. }
  456. internal override long GetChars(long dataIndex, char[] buffer, int bufferIndex, int length) {
  457. if (_s == null)
  458. return 0;
  459. if (buffer == null)
  460. return _s.Length;
  461. int actualLength = ((dataIndex + length) >= _s.Length) ? (_s.Length - (int)dataIndex) : length;
  462. _s.CopyTo((int)dataIndex, buffer, bufferIndex, actualLength);
  463. return actualLength;
  464. }
  465. #endregion // Methods
  466. }
  467. internal sealed class NullReaderCacheContainer : ReaderCacheContainerBase // Types.NULL
  468. {
  469. #region Fields
  470. #endregion // Fields
  471. #region Methods
  472. protected override void FetchInternal(ResultSet rs, int columnIndex)
  473. {
  474. }
  475. public override object GetValue()
  476. {
  477. return DBNull.Value;
  478. }
  479. #endregion // Methods
  480. }
  481. internal sealed class FloatReaderCacheContainer : ReaderCacheContainerBase // Types.REAL
  482. {
  483. #region Fields
  484. float _f;
  485. #endregion // Fields
  486. #region Methods
  487. protected override void FetchInternal(ResultSet rs, int columnIndex)
  488. {
  489. _f = rs.getFloat(columnIndex);
  490. }
  491. public override bool IsNumeric() {
  492. return true;
  493. }
  494. public override object GetValue()
  495. {
  496. return _f;
  497. }
  498. internal float GetFloat()
  499. {
  500. return _f;
  501. }
  502. #endregion // Methods
  503. }
  504. internal sealed class RefReaderCacheContainer : ReaderCacheContainerBase // Types.REF
  505. {
  506. #region Fields
  507. java.sql.Ref _r;
  508. #endregion // Fields
  509. #region Methods
  510. protected override void FetchInternal(ResultSet rs, int columnIndex)
  511. {
  512. _r = rs.getRef(columnIndex);
  513. }
  514. public override object GetValue()
  515. {
  516. return _r;
  517. }
  518. #endregion // Methods
  519. }
  520. internal sealed class Int16ReaderCacheContainer : ReaderCacheContainerBase // Types.SMALLINT
  521. {
  522. #region Fields
  523. short _s;
  524. #endregion // Fields
  525. #region Methods
  526. protected override void FetchInternal(ResultSet rs, int columnIndex)
  527. {
  528. _s = rs.getShort(columnIndex);
  529. }
  530. public override bool IsNumeric() {
  531. return true;
  532. }
  533. public override object GetValue()
  534. {
  535. return _s;
  536. }
  537. internal short GetInt16()
  538. {
  539. return _s;
  540. }
  541. #endregion // Methods
  542. }
  543. internal sealed class ByteReaderCacheContainer : ReaderCacheContainerBase // Types.TINYINT
  544. {
  545. #region Fields
  546. byte _b;
  547. #endregion // Fields
  548. #region Methods
  549. protected override void FetchInternal(ResultSet rs, int columnIndex)
  550. {
  551. _b = (byte)rs.getByte(columnIndex);
  552. }
  553. public override bool IsNumeric() {
  554. return true;
  555. }
  556. public override object GetValue()
  557. {
  558. return _b;
  559. }
  560. internal byte GetByte()
  561. {
  562. return _b;
  563. }
  564. #endregion // Methods
  565. }
  566. internal sealed class ObjectReaderCacheContainer : ReaderCacheContainerBase // Types.Distinct, Types.JAVA_OBJECT, Types.OTHER, Types.STRUCT
  567. {
  568. #region Fields
  569. object o;
  570. #endregion // Fields
  571. #region Methods
  572. protected override void FetchInternal(ResultSet rs, int columnIndex)
  573. {
  574. o = rs.getObject(columnIndex);
  575. }
  576. public override object GetValue()
  577. {
  578. return o;
  579. }
  580. #endregion // Methods
  581. }
  582. }