DataContainer.cs 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. using System;
  2. using System.Collections;
  3. namespace System.Data.Common
  4. {
  5. internal abstract class AbstractDataContainer
  6. {
  7. #region Fields
  8. BitArray _nullValues;
  9. System.Type _type;
  10. DataColumn _column;
  11. #endregion //Fields
  12. #region Properties
  13. internal abstract object this[int index] {
  14. get;
  15. set;
  16. }
  17. internal virtual int Capacity {
  18. get {
  19. return (_nullValues != null) ? _nullValues.Count : 0;
  20. }
  21. set {
  22. if (_nullValues == null) {
  23. _nullValues = new BitArray(value);
  24. }
  25. else {
  26. _nullValues.Length = value;
  27. }
  28. }
  29. }
  30. internal Type Type {
  31. get {
  32. return _type;
  33. }
  34. }
  35. protected DataColumn Column {
  36. get {
  37. return _column;
  38. }
  39. }
  40. #endregion //Properties
  41. #region Methods
  42. internal static AbstractDataContainer CreateInstance(Type type, DataColumn column)
  43. {
  44. AbstractDataContainer container;
  45. switch (Type.GetTypeCode(type)) {
  46. case TypeCode.Int16 :
  47. container = new Int16DataContainer();
  48. break;
  49. case TypeCode.Int32 :
  50. container = new Int32DataContainer();
  51. break;
  52. case TypeCode.Int64 :
  53. container = new Int64DataContainer();
  54. break;
  55. case TypeCode.String :
  56. container = new StringDataContainer();
  57. break;
  58. case TypeCode.Boolean:
  59. container = new BitDataContainer();
  60. break;
  61. case TypeCode.Byte :
  62. container = new ByteDataContainer();
  63. break;
  64. //case TypeCode.Char :
  65. case TypeCode.DateTime :
  66. container = new DateTimeDataContainer();
  67. break;
  68. //case TypeCode.Decimal :
  69. case TypeCode.Double :
  70. container = new DoubleDataContainer();
  71. break;
  72. //case TypeCode.SByte :
  73. case TypeCode.Single :
  74. container = new SingleDataContainer();
  75. break;
  76. //case TypeCode.UInt16 :
  77. //case TypeCode.UInt32 :
  78. //case TypeCode.UInt64 :
  79. default :
  80. container = new ObjectDataContainer();
  81. break;
  82. }
  83. container._type = type;
  84. container._column = column;
  85. return container;
  86. }
  87. internal bool IsNull(int index)
  88. {
  89. return (_nullValues != null) ? _nullValues[index] : true;
  90. }
  91. protected void SetNull(int index,bool isNull)
  92. {
  93. _nullValues[index] = isNull;
  94. }
  95. internal virtual void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  96. {
  97. _nullValues[toIndex] = fromContainer._nullValues[fromIndex];
  98. }
  99. internal virtual void CopyValue(int fromIndex, int toIndex)
  100. {
  101. _nullValues[toIndex] = _nullValues[fromIndex];
  102. }
  103. internal virtual void SetItemFromDataRecord(int index, IDataRecord record, int field)
  104. {
  105. SetNull(index,record.IsDBNull(field));
  106. }
  107. protected int CompareNulls(int index1, int index2)
  108. {
  109. bool null1 = IsNull(index1);
  110. bool null2 = IsNull(index2);
  111. if ( null1 ^ null2 ) {
  112. return null1 ? -1 : 1;
  113. }
  114. else {
  115. return 0;
  116. }
  117. }
  118. internal abstract int CompareValues(int index1, int index2);
  119. #endregion //Methods
  120. sealed class Int16DataContainer : AbstractDataContainer
  121. {
  122. #region Fields
  123. short[] _values;
  124. #endregion //Fields
  125. #region Properties
  126. internal override object this[int index] {
  127. get {
  128. if (IsNull(index)) {
  129. return DBNull.Value;
  130. }
  131. else {
  132. return _values[index];
  133. }
  134. }
  135. set {
  136. bool isDbNull = (value == DBNull.Value);
  137. if (value == null || isDbNull) {
  138. SetValue(index,0);
  139. }
  140. else if( value is short ) {
  141. SetValue(index,(short)value);
  142. }
  143. else {
  144. SetValue(index,Convert.ToInt16(value));
  145. }
  146. SetNull(index,isDbNull);
  147. }
  148. }
  149. internal override int Capacity {
  150. set {
  151. base.Capacity = value;
  152. if (_values == null) {
  153. _values = new short[value];
  154. }
  155. else {
  156. short[] tmp = new short[value];
  157. Array.Copy(_values,0,tmp,0,_values.Length);
  158. _values = tmp;
  159. }
  160. }
  161. }
  162. #endregion //Properties
  163. #region Methods
  164. private void SetValue(int index, short value)
  165. {
  166. _values[index] = value;
  167. }
  168. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  169. {
  170. // if exception thrown, it should be caught
  171. // in the caller method
  172. SetValue(index,record.GetInt16(field));
  173. base.SetItemFromDataRecord(index,record,field);
  174. }
  175. internal override void CopyValue(int fromIndex, int toIndex)
  176. {
  177. base.CopyValue(fromIndex, toIndex);
  178. _values[toIndex] = _values[fromIndex];
  179. }
  180. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  181. {
  182. base.CopyValue(fromContainer, fromIndex, toIndex);
  183. _values[toIndex] = ((Int16DataContainer)fromContainer)._values[fromIndex];
  184. }
  185. internal override int CompareValues(int index1, int index2)
  186. {
  187. short s1 = _values[index1];
  188. short s2 = _values[index2];
  189. if ( s1 == 0 && s2 == 0 ) {
  190. int cn = CompareNulls(index1, index2);
  191. return cn;
  192. }
  193. bool b1 = IsNull(index1);
  194. bool b2 = IsNull(index2);
  195. if ( s1 == 0 && b1 ) {
  196. return -1;
  197. }
  198. if ( s2 == 0 && b2 ) {
  199. return 1;
  200. }
  201. if ( s1 <= s2 ) {
  202. return ( s1 != s2 ) ? -1 : 0;
  203. }
  204. return 1;
  205. }
  206. #endregion //Methods
  207. }
  208. sealed class Int32DataContainer : AbstractDataContainer
  209. {
  210. #region Fields
  211. int[] _values;
  212. #endregion //Fields
  213. #region Properties
  214. internal override object this[int index] {
  215. get {
  216. if (IsNull(index)) {
  217. return DBNull.Value;
  218. }
  219. else {
  220. return _values[index];
  221. }
  222. }
  223. set {
  224. bool isDbNull = (value == DBNull.Value);
  225. if (value == null || isDbNull) {
  226. SetValue(index,0);
  227. }
  228. else if( value is int ) {
  229. SetValue(index,(int)value);
  230. }
  231. else {
  232. SetValue(index,Convert.ToInt32(value));
  233. }
  234. SetNull(index,isDbNull);
  235. }
  236. }
  237. internal override int Capacity {
  238. set {
  239. base.Capacity = value;
  240. if (_values == null) {
  241. _values = new int[value];
  242. }
  243. else {
  244. int[] tmp = new int[value];
  245. Array.Copy(_values,0,tmp,0,_values.Length);
  246. _values = tmp;
  247. }
  248. }
  249. }
  250. #endregion //Properties
  251. #region Methods
  252. private void SetValue(int index, int value)
  253. {
  254. _values[index] = value;
  255. }
  256. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  257. {
  258. // if exception thrown, it should be caught
  259. // in the caller method
  260. SetValue(index,record.GetInt32(field));
  261. base.SetItemFromDataRecord(index,record,field);
  262. }
  263. internal override void CopyValue(int fromIndex, int toIndex)
  264. {
  265. base.CopyValue(fromIndex, toIndex);
  266. _values[toIndex] = _values[fromIndex];
  267. }
  268. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  269. {
  270. base.CopyValue(fromContainer, fromIndex, toIndex);
  271. _values[toIndex] = ((Int32DataContainer)fromContainer)._values[fromIndex];
  272. }
  273. internal override int CompareValues(int index1, int index2)
  274. {
  275. int i1 = _values[index1];
  276. int i2 = _values[index2];
  277. if ( i1 == 0 && i2 == 0 ) {
  278. int cn = CompareNulls(index1, index2);
  279. return cn;
  280. }
  281. bool b1 = IsNull(index1);
  282. bool b2 = IsNull(index2);
  283. if ( i1 == 0 && b1 ) {
  284. return -1;
  285. }
  286. if ( i2 == 0 && b2 ) {
  287. return 1;
  288. }
  289. if ( i1 <= i2 ) {
  290. return ( i1 != i2 ) ? -1 : 0;
  291. }
  292. return 1;
  293. }
  294. #endregion //Methods
  295. }
  296. sealed class Int64DataContainer : AbstractDataContainer
  297. {
  298. #region Fields
  299. long[] _values;
  300. #endregion //Fields
  301. #region Properties
  302. internal override object this[int index] {
  303. get {
  304. if (IsNull(index)) {
  305. return DBNull.Value;
  306. }
  307. else {
  308. return _values[index];
  309. }
  310. }
  311. set {
  312. bool isDbNull = (value == DBNull.Value);
  313. if (value == null || isDbNull) {
  314. SetValue(index,0);
  315. }
  316. else if( value is long ) {
  317. SetValue(index,(long)value);
  318. }
  319. else {
  320. SetValue(index,Convert.ToInt64(value));
  321. }
  322. SetNull(index,isDbNull);
  323. }
  324. }
  325. internal override int Capacity {
  326. set {
  327. base.Capacity = value;
  328. if (_values == null) {
  329. _values = new long[value];
  330. }
  331. else {
  332. long[] tmp = new long[value];
  333. Array.Copy(_values,0,tmp,0,_values.Length);
  334. _values = tmp;
  335. }
  336. }
  337. }
  338. #endregion //Properties
  339. #region Methods
  340. private void SetValue(int index, long value)
  341. {
  342. _values[index] = value;
  343. }
  344. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  345. {
  346. // if exception thrown, it should be caught
  347. // in the caller method
  348. SetValue(index,record.GetInt64(field));
  349. base.SetItemFromDataRecord(index,record,field);
  350. }
  351. internal override void CopyValue(int fromIndex, int toIndex)
  352. {
  353. base.CopyValue(fromIndex, toIndex);
  354. _values[toIndex] = _values[fromIndex];
  355. }
  356. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  357. {
  358. base.CopyValue(fromContainer, fromIndex, toIndex);
  359. _values[toIndex] = ((Int64DataContainer)fromContainer)._values[fromIndex];
  360. }
  361. internal override int CompareValues(int index1, int index2)
  362. {
  363. long l1 = _values[index1];
  364. long l2 = _values[index2];
  365. if ( l1 == 0 || l2 == 0 ) {
  366. int cn = CompareNulls(index1, index2);
  367. if (cn != 0) {
  368. return cn;
  369. }
  370. }
  371. if ( l1 <= l2 ) {
  372. return ( l1 != l2 ) ? -1 : 0;
  373. }
  374. return 1;
  375. }
  376. #endregion //Methods
  377. }
  378. sealed class SingleDataContainer : AbstractDataContainer
  379. {
  380. #region Fields
  381. float[] _values;
  382. #endregion //Fields
  383. #region Properties
  384. internal override object this[int index] {
  385. get {
  386. if (IsNull(index)) {
  387. return DBNull.Value;
  388. }
  389. else {
  390. return _values[index];
  391. }
  392. }
  393. set {
  394. bool isDbNull = (value == DBNull.Value);
  395. if (value == null || isDbNull) {
  396. SetValue(index,0);
  397. }
  398. else if( value is float ) {
  399. SetValue(index,(float)value);
  400. }
  401. else {
  402. SetValue(index,Convert.ToSingle(value));
  403. }
  404. SetNull(index,isDbNull);
  405. }
  406. }
  407. internal override int Capacity {
  408. set {
  409. base.Capacity = value;
  410. if (_values == null) {
  411. _values = new float[value];
  412. }
  413. else {
  414. float[] tmp = new float[value];
  415. Array.Copy(_values,0,tmp,0,_values.Length);
  416. _values = tmp;
  417. }
  418. }
  419. }
  420. #endregion //Properties
  421. #region Methods
  422. private void SetValue(int index, float value)
  423. {
  424. _values[index] = value;
  425. }
  426. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  427. {
  428. // if exception thrown, it should be caught
  429. // in the caller method
  430. SetValue(index,record.GetFloat(field));
  431. base.SetItemFromDataRecord(index,record,field);
  432. }
  433. internal override void CopyValue(int fromIndex, int toIndex)
  434. {
  435. base.CopyValue(fromIndex, toIndex);
  436. _values[toIndex] = _values[fromIndex];
  437. }
  438. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  439. {
  440. base.CopyValue(fromContainer, fromIndex, toIndex);
  441. _values[toIndex] = ((SingleDataContainer)fromContainer)._values[fromIndex];
  442. }
  443. internal override int CompareValues(int index1, int index2)
  444. {
  445. float f1 = _values[index1];
  446. float f2 = _values[index2];
  447. if ( f1 == 0 || f2 == 0 ) {
  448. int cn = CompareNulls(index1, index2);
  449. if (cn != 0) {
  450. return cn;
  451. }
  452. }
  453. if ( f1 <= f2 ) {
  454. return ( f1 != f2 ) ? -1 : 0;
  455. }
  456. return 1;
  457. }
  458. #endregion //Methods
  459. }
  460. sealed class DoubleDataContainer : AbstractDataContainer
  461. {
  462. #region Fields
  463. double[] _values;
  464. #endregion //Fields
  465. #region Properties
  466. internal override object this[int index] {
  467. get {
  468. if (IsNull(index)) {
  469. return DBNull.Value;
  470. }
  471. else {
  472. return _values[index];
  473. }
  474. }
  475. set {
  476. bool isDbNull = (value == DBNull.Value);
  477. if (value == null || isDbNull) {
  478. SetValue(index,0);
  479. }
  480. else if( value is double ) {
  481. SetValue(index,(double)value);
  482. }
  483. else {
  484. SetValue(index,Convert.ToDouble(value));
  485. }
  486. SetNull(index,isDbNull);
  487. }
  488. }
  489. internal override int Capacity {
  490. set {
  491. base.Capacity = value;
  492. if (_values == null) {
  493. _values = new double[value];
  494. }
  495. else {
  496. double[] tmp = new double[value];
  497. Array.Copy(_values,0,tmp,0,_values.Length);
  498. _values = tmp;
  499. }
  500. }
  501. }
  502. #endregion //Properties
  503. #region Methods
  504. private void SetValue(int index, double value)
  505. {
  506. _values[index] = value;
  507. }
  508. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  509. {
  510. // if exception thrown, it should be caught
  511. // in the caller method
  512. SetValue(index,record.GetDouble(field));
  513. base.SetItemFromDataRecord(index,record,field);
  514. }
  515. internal override void CopyValue(int fromIndex, int toIndex)
  516. {
  517. base.CopyValue(fromIndex, toIndex);
  518. _values[toIndex] = _values[fromIndex];
  519. }
  520. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  521. {
  522. base.CopyValue(fromContainer, fromIndex, toIndex);
  523. _values[toIndex] = ((DoubleDataContainer)fromContainer)._values[fromIndex];
  524. }
  525. internal override int CompareValues(int index1, int index2)
  526. {
  527. double d1 = _values[index1];
  528. double d2 = _values[index2];
  529. if ( d1 == 0 || d2 == 0 ) {
  530. int cn = CompareNulls(index1, index2);
  531. if (cn != 0) {
  532. return cn;
  533. }
  534. }
  535. if ( d1 <= d2 ) {
  536. return ( d1 != d2 ) ? -1 : 0;
  537. }
  538. return 1;
  539. }
  540. #endregion //Methods
  541. }
  542. sealed class ByteDataContainer : AbstractDataContainer
  543. {
  544. #region Fields
  545. byte[] _values;
  546. #endregion //Fields
  547. #region Properties
  548. internal override object this[int index] {
  549. get {
  550. if (IsNull(index)) {
  551. return DBNull.Value;
  552. }
  553. else {
  554. return _values[index];
  555. }
  556. }
  557. set {
  558. bool isDbNull = (value == DBNull.Value);
  559. if (value == null || isDbNull) {
  560. SetValue(index,0);
  561. }
  562. else if( value is byte ) {
  563. SetValue(index,(byte)value);
  564. }
  565. else {
  566. SetValue(index,Convert.ToByte(value));
  567. }
  568. SetNull(index,isDbNull);
  569. }
  570. }
  571. internal override int Capacity {
  572. set {
  573. base.Capacity = value;
  574. if (_values == null) {
  575. _values = new byte[value];
  576. }
  577. else {
  578. byte[] tmp = new byte[value];
  579. Array.Copy(_values,0,tmp,0,_values.Length);
  580. _values = tmp;
  581. }
  582. }
  583. }
  584. #endregion //Properties
  585. #region Methods
  586. private void SetValue(int index, byte value)
  587. {
  588. _values[index] = value;
  589. }
  590. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  591. {
  592. // if exception thrown, it should be caught
  593. // in the caller method
  594. SetValue(index,record.GetByte(field));
  595. base.SetItemFromDataRecord(index,record,field);
  596. }
  597. internal override void CopyValue(int fromIndex, int toIndex)
  598. {
  599. base.CopyValue(fromIndex, toIndex);
  600. _values[toIndex] = _values[fromIndex];
  601. }
  602. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  603. {
  604. base.CopyValue(fromContainer, fromIndex, toIndex);
  605. _values[toIndex] = ((ByteDataContainer)fromContainer)._values[fromIndex];
  606. }
  607. internal override int CompareValues(int index1, int index2)
  608. {
  609. byte b1 = _values[index1];
  610. byte b2 = _values[index2];
  611. if ( b1 == 0 || b2 == 0 ) {
  612. int cn = CompareNulls(index1, index2);
  613. if (cn != 0) {
  614. return cn;
  615. }
  616. }
  617. if ( b1 <= b2 ) {
  618. return ( b1 != b2 ) ? -1 : 0;
  619. }
  620. return 1;
  621. }
  622. #endregion //Methods
  623. }
  624. sealed class BitDataContainer : AbstractDataContainer
  625. {
  626. #region Fields
  627. bool[] _values;
  628. #endregion //Fields
  629. #region Properties
  630. internal override object this[int index] {
  631. get {
  632. bool isNull = IsNull(index);
  633. if (isNull) {
  634. return DBNull.Value;
  635. }
  636. else {
  637. return _values[index];
  638. }
  639. }
  640. set {
  641. bool isDbNull = (value == DBNull.Value);
  642. if (value == null || isDbNull) {
  643. SetValue(index,false);
  644. }
  645. else if( value is bool ) {
  646. SetValue(index,(bool)value);
  647. }
  648. else {
  649. SetValue(index,Convert.ToBoolean(value));
  650. }
  651. SetNull(index,isDbNull);
  652. }
  653. }
  654. internal override int Capacity {
  655. set {
  656. base.Capacity = value;
  657. if (_values == null) {
  658. _values = new bool[value];
  659. }
  660. else {
  661. bool[] tmp = new bool[value];
  662. Array.Copy(_values,0,tmp,0,_values.Length);
  663. _values = tmp;
  664. }
  665. }
  666. }
  667. #endregion //Properties
  668. #region Methods
  669. private void SetValue(int index, bool value)
  670. {
  671. _values[index] = value;
  672. }
  673. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  674. {
  675. // if exception thrown, it should be caught
  676. // in the caller method
  677. SetValue(index,record.GetBoolean(field));
  678. }
  679. internal override void CopyValue(int fromIndex, int toIndex)
  680. {
  681. base.CopyValue(fromIndex, toIndex);
  682. }
  683. internal override int CompareValues(int index1, int index2)
  684. {
  685. bool b1 = _values[index1];
  686. bool b2 = _values[index2];
  687. if ( b1 ^ b2 ) {
  688. return b1 ? 1 : -1;
  689. }
  690. if ( b1 ) {
  691. return 0;
  692. }
  693. return CompareNulls(index1, index2);
  694. }
  695. #endregion //Methods
  696. }
  697. class ObjectDataContainer : AbstractDataContainer
  698. {
  699. #region Fields
  700. object[] _values;
  701. #endregion //Fields
  702. #region Properties
  703. internal override object this[int index] {
  704. get {
  705. return _values[index];
  706. }
  707. set {
  708. SetValue(index,value);
  709. SetNull(index,value == DBNull.Value);
  710. }
  711. }
  712. internal override int Capacity {
  713. set {
  714. base.Capacity = value;
  715. if (_values == null) {
  716. _values = new object[value];
  717. }
  718. else {
  719. object[] tmp = new object[value];
  720. Array.Copy(_values,0,tmp,0,_values.Length);
  721. _values = tmp;
  722. }
  723. }
  724. }
  725. #endregion //Properties
  726. #region Methods
  727. protected virtual void SetValue(int index, object value)
  728. {
  729. if(value == null) {
  730. value = Column.DefaultValue;
  731. }
  732. _values[index] = value;
  733. }
  734. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  735. {
  736. // if exception thrown, it should be caught
  737. // in the caller method
  738. SetValue(index,record.GetValue(field));
  739. base.SetItemFromDataRecord(index,record,field);
  740. }
  741. internal override void CopyValue(int fromIndex, int toIndex)
  742. {
  743. base.CopyValue(fromIndex, toIndex);
  744. _values[toIndex] = _values[fromIndex];
  745. }
  746. internal override void CopyValue(AbstractDataContainer fromContainer, int fromIndex, int toIndex)
  747. {
  748. base.CopyValue(fromContainer, fromIndex, toIndex);
  749. _values[toIndex] = ((ObjectDataContainer)fromContainer)._values[fromIndex];
  750. }
  751. internal override int CompareValues(int index1, int index2)
  752. {
  753. object obj1 = _values[index1];
  754. object obj2 = _values[index2];
  755. if(obj1 == obj2) {
  756. return 0;
  757. }
  758. else if (obj1 is IComparable) {
  759. try {
  760. return ((IComparable)obj1).CompareTo(obj2);
  761. }
  762. catch {
  763. //just suppress
  764. }
  765. if (obj2 is IComparable) {
  766. obj2 = Convert.ChangeType(obj2, Type.GetTypeCode(obj1.GetType()));
  767. return ((IComparable)obj1).CompareTo(obj2);
  768. }
  769. }
  770. return String.Compare(obj1.ToString(), obj2.ToString());
  771. }
  772. #endregion //Methods
  773. }
  774. sealed class StringDataContainer : ObjectDataContainer
  775. {
  776. #region Methods
  777. private void SetValue(int index, string value)
  778. {
  779. if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length ) {
  780. throw new ArgumentException("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column.");
  781. }
  782. base.SetValue(index,value);
  783. }
  784. protected override void SetValue(int index, object value)
  785. {
  786. if ( value != null && value != DBNull.Value ) {
  787. if ( value is string ) {
  788. SetValue(index, (string) value);
  789. }
  790. else {
  791. SetValue(index, Convert.ToString(value));
  792. }
  793. return;
  794. }
  795. base.SetValue(index, value);
  796. }
  797. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  798. {
  799. // if exception thrown, it should be caught
  800. // in the caller method
  801. SetValue(index,record.GetString(field));
  802. base.SetItemFromDataRecord(index,record,field);
  803. }
  804. internal override int CompareValues(int index1, int index2)
  805. {
  806. bool isNull1 = IsNull(index1);
  807. bool isNull2 = IsNull(index2);
  808. if (isNull1) {
  809. return isNull2 ? 0 : -1;
  810. }
  811. else {
  812. if (isNull2) {
  813. return 1;
  814. }
  815. }
  816. return String.Compare((string)this[index1], (string)this[index2], !Column.Table.CaseSensitive);
  817. }
  818. #endregion //Methods
  819. }
  820. sealed class DateTimeDataContainer : ObjectDataContainer
  821. {
  822. #region Methods
  823. protected override void SetValue(int index, object value)
  824. {
  825. if ( value != null && value != DBNull.Value && !(value is DateTime)) {
  826. value = Convert.ToDateTime(value);
  827. }
  828. base.SetValue(index,value);
  829. }
  830. internal override void SetItemFromDataRecord(int index, IDataRecord record, int field)
  831. {
  832. // if exception thrown, it should be caught
  833. // in the caller method
  834. base.SetValue(index,record.GetDateTime(field));
  835. base.SetItemFromDataRecord(index,record,field);
  836. }
  837. internal override int CompareValues(int index1, int index2)
  838. {
  839. bool isNull1 = IsNull(index1);
  840. bool isNull2 = IsNull(index2);
  841. if (isNull1) {
  842. return isNull2 ? 0 : -1;
  843. }
  844. else {
  845. if (isNull2) {
  846. return 1;
  847. }
  848. }
  849. return DateTime.Compare((DateTime)this[index1], (DateTime)this[index2]);
  850. }
  851. #endregion //Methods
  852. }
  853. }
  854. }