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