SqlDataReader.cs 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. //
  2. // System.Data.SqlClient.SqlDataReader.cs
  3. //
  4. // Author:
  5. // Rodrigo Moya ([email protected])
  6. // Daniel Morgan ([email protected])
  7. // Tim Coleman ([email protected])
  8. //
  9. // (C) Ximian, Inc 2002
  10. // (C) Daniel Morgan 2002
  11. // Copyright (C) Tim Coleman, 2002
  12. //
  13. //
  14. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  15. //
  16. // Permission is hereby granted, free of charge, to any person obtaining
  17. // a copy of this software and associated documentation files (the
  18. // "Software"), to deal in the Software without restriction, including
  19. // without limitation the rights to use, copy, modify, merge, publish,
  20. // distribute, sublicense, and/or sell copies of the Software, and to
  21. // permit persons to whom the Software is furnished to do so, subject to
  22. // the following conditions:
  23. //
  24. // The above copyright notice and this permission notice shall be
  25. // included in all copies or substantial portions of the Software.
  26. //
  27. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  28. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  29. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  30. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  31. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  32. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  33. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  34. //
  35. using Mono.Data.Tds.Protocol;
  36. using System;
  37. using System.Collections;
  38. using System.ComponentModel;
  39. using System.Data;
  40. using System.Data.Common;
  41. using System.Data.SqlTypes;
  42. #if NET_2_0
  43. using System.Data.ProviderBase;
  44. #endif // NET_2_0
  45. namespace System.Data.SqlClient {
  46. #if NET_2_0
  47. public sealed class SqlDataReader : DbDataReaderBase, IEnumerable, IDataReader, IDisposable, IDataRecord
  48. #else
  49. public sealed class SqlDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
  50. #endif // NET_2_0
  51. {
  52. #region Fields
  53. SqlCommand command;
  54. ArrayList dataTypeNames;
  55. bool disposed = false;
  56. int fieldCount;
  57. bool isClosed;
  58. bool isSelect;
  59. bool moreResults;
  60. int resultsRead;
  61. int rowsRead;
  62. DataTable schemaTable;
  63. bool hasRows;
  64. bool haveRead;
  65. bool readResult;
  66. bool readResultUsed;
  67. #endregion // Fields
  68. #region Constructors
  69. internal SqlDataReader (SqlCommand command)
  70. #if NET_2_0
  71. : base (command.CommandBehavior)
  72. #endif // NET_2_0
  73. {
  74. readResult = false;
  75. haveRead = false;
  76. readResultUsed = false;
  77. this.command = command;
  78. schemaTable = ConstructSchemaTable ();
  79. resultsRead = 0;
  80. fieldCount = 0;
  81. isClosed = false;
  82. isSelect = (command.CommandText.Trim ().ToUpper ().StartsWith ("SELECT"));
  83. command.Tds.RecordsAffected = 0;
  84. NextResult ();
  85. }
  86. #endregion // Constructors
  87. #region Properties
  88. public
  89. #if NET_2_0
  90. override
  91. #endif // NET_2_0
  92. int Depth {
  93. get { return 0; }
  94. }
  95. public
  96. #if NET_2_0
  97. override
  98. #endif // NET_2_0
  99. int FieldCount {
  100. get { return fieldCount; }
  101. }
  102. public
  103. #if NET_2_0
  104. override
  105. #endif // NET_2_0
  106. bool IsClosed {
  107. get { return isClosed; }
  108. }
  109. public
  110. #if NET_2_0
  111. override
  112. #endif // NET_2_0
  113. object this [int i] {
  114. get { return GetValue (i); }
  115. }
  116. public
  117. #if NET_2_0
  118. override
  119. #endif // NET_2_0
  120. object this [string name] {
  121. get { return GetValue (GetOrdinal (name)); }
  122. }
  123. public
  124. #if NET_2_0
  125. override
  126. #endif // NET_2_0
  127. int RecordsAffected {
  128. get {
  129. if (isSelect)
  130. return -1;
  131. else
  132. return command.Tds.RecordsAffected;
  133. }
  134. }
  135. public
  136. #if NET_2_0
  137. override
  138. #endif // NET_2_0
  139. bool HasRows {
  140. get {
  141. if (haveRead)
  142. return readResult;
  143. haveRead = true;
  144. readResult = ReadRecord ();
  145. return readResult;
  146. }
  147. }
  148. #endregion // Properties
  149. #region Methods
  150. public
  151. #if NET_2_0
  152. override
  153. #endif // NET_2_0
  154. void Close ()
  155. {
  156. // skip to end & read output parameters.
  157. while (NextResult ())
  158. ;
  159. isClosed = true;
  160. command.Connection.DataReader = null;
  161. command.CloseDataReader (moreResults);
  162. }
  163. private static DataTable ConstructSchemaTable ()
  164. {
  165. Type booleanType = Type.GetType ("System.Boolean");
  166. Type stringType = Type.GetType ("System.String");
  167. Type intType = Type.GetType ("System.Int32");
  168. Type typeType = Type.GetType ("System.Type");
  169. Type shortType = Type.GetType ("System.Int16");
  170. DataTable schemaTable = new DataTable ("SchemaTable");
  171. schemaTable.Columns.Add ("ColumnName", stringType);
  172. schemaTable.Columns.Add ("ColumnOrdinal", intType);
  173. schemaTable.Columns.Add ("ColumnSize", intType);
  174. schemaTable.Columns.Add ("NumericPrecision", shortType);
  175. schemaTable.Columns.Add ("NumericScale", shortType);
  176. schemaTable.Columns.Add ("IsUnique", booleanType);
  177. schemaTable.Columns.Add ("IsKey", booleanType);
  178. schemaTable.Columns.Add ("BaseServerName", stringType);
  179. schemaTable.Columns.Add ("BaseCatalogName", stringType);
  180. schemaTable.Columns.Add ("BaseColumnName", stringType);
  181. schemaTable.Columns.Add ("BaseSchemaName", stringType);
  182. schemaTable.Columns.Add ("BaseTableName", stringType);
  183. schemaTable.Columns.Add ("DataType", typeType);
  184. schemaTable.Columns.Add ("AllowDBNull", booleanType);
  185. schemaTable.Columns.Add ("ProviderType", intType);
  186. schemaTable.Columns.Add ("IsAliased", booleanType);
  187. schemaTable.Columns.Add ("IsExpression", booleanType);
  188. schemaTable.Columns.Add ("IsIdentity", booleanType);
  189. schemaTable.Columns.Add ("IsAutoIncrement", booleanType);
  190. schemaTable.Columns.Add ("IsRowVersion", booleanType);
  191. schemaTable.Columns.Add ("IsHidden", booleanType);
  192. schemaTable.Columns.Add ("IsLong", booleanType);
  193. schemaTable.Columns.Add ("IsReadOnly", booleanType);
  194. return schemaTable;
  195. }
  196. private void Dispose (bool disposing)
  197. {
  198. if (!disposed) {
  199. if (disposing) {
  200. schemaTable.Dispose ();
  201. Close ();
  202. command = null;
  203. }
  204. disposed = true;
  205. }
  206. }
  207. public
  208. #if NET_2_0
  209. override
  210. #endif // NET_2_0
  211. bool GetBoolean (int i)
  212. {
  213. object value = GetValue (i);
  214. if (!(value is bool)) {
  215. if (value is DBNull) throw new SqlNullValueException ();
  216. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  217. }
  218. return (bool) value;
  219. }
  220. public
  221. #if NET_2_0
  222. override
  223. #endif // NET_2_0
  224. byte GetByte (int i)
  225. {
  226. object value = GetValue (i);
  227. if (!(value is byte)) {
  228. if (value is DBNull) throw new SqlNullValueException ();
  229. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  230. }
  231. return (byte) value;
  232. }
  233. public
  234. #if NET_2_0
  235. override
  236. #endif // NET_2_0
  237. long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
  238. {
  239. object value = GetValue (i);
  240. if (!(value is byte [])) {
  241. if (value is DBNull) throw new SqlNullValueException ();
  242. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  243. }
  244. if ( buffer == null )
  245. return ((byte []) value).Length; // Return length of data
  246. // Copy data into buffer
  247. int availLen = (int) ( ( (byte []) value).Length - dataIndex);
  248. if (availLen < length)
  249. length = availLen;
  250. Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
  251. return length; // return actual read count
  252. }
  253. [EditorBrowsableAttribute (EditorBrowsableState.Never)]
  254. public
  255. #if NET_2_0
  256. override
  257. #endif // NET_2_0
  258. char GetChar (int i)
  259. {
  260. object value = GetValue (i);
  261. if (!(value is char)) {
  262. if (value is DBNull) throw new SqlNullValueException ();
  263. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  264. }
  265. return (char) value;
  266. }
  267. public
  268. #if NET_2_0
  269. override
  270. #endif // NET_2_0
  271. long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
  272. {
  273. object value = GetValue (i);
  274. char [] valueBuffer;
  275. if (value is char[])
  276. valueBuffer = (char[])value;
  277. else if (value is string)
  278. valueBuffer = ((string)value).ToCharArray();
  279. else {
  280. if (value is DBNull) throw new SqlNullValueException ();
  281. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  282. }
  283. if ( buffer == null ) {
  284. // Return length of data
  285. return valueBuffer.Length;
  286. }
  287. else {
  288. // Copy data into buffer
  289. Array.Copy (valueBuffer, (int) dataIndex, buffer, bufferIndex, length);
  290. return valueBuffer.Length - dataIndex;
  291. }
  292. }
  293. [EditorBrowsableAttribute (EditorBrowsableState.Never)]
  294. public new IDataReader GetData (int i)
  295. {
  296. return ( (IDataReader) this [i]);
  297. }
  298. public
  299. #if NET_2_0
  300. override
  301. #endif // NET_2_0
  302. string GetDataTypeName (int i)
  303. {
  304. return (string) dataTypeNames [i];
  305. }
  306. public
  307. #if NET_2_0
  308. override
  309. #endif // NET_2_0
  310. DateTime GetDateTime (int i)
  311. {
  312. object value = GetValue (i);
  313. if (!(value is DateTime)) {
  314. if (value is DBNull) throw new SqlNullValueException ();
  315. else throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  316. }
  317. return (DateTime) value;
  318. }
  319. public
  320. #if NET_2_0
  321. override
  322. #endif // NET_2_0
  323. decimal GetDecimal (int i)
  324. {
  325. object value = GetValue (i);
  326. if (!(value is decimal)) {
  327. if (value is DBNull) throw new SqlNullValueException ();
  328. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  329. }
  330. return (decimal) value;
  331. }
  332. public
  333. #if NET_2_0
  334. override
  335. #endif // NET_2_0
  336. double GetDouble (int i)
  337. {
  338. object value = GetValue (i);
  339. if (!(value is double)) {
  340. if (value is DBNull) throw new SqlNullValueException ();
  341. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  342. }
  343. return (double) value;
  344. }
  345. public
  346. #if NET_2_0
  347. override
  348. #endif // NET_2_0
  349. Type GetFieldType (int i)
  350. {
  351. return (Type) schemaTable.Rows[i]["DataType"];
  352. }
  353. public
  354. #if NET_2_0
  355. override
  356. #endif // NET_2_0
  357. float GetFloat (int i)
  358. {
  359. object value = GetValue (i);
  360. if (!(value is float)) {
  361. if (value is DBNull) throw new SqlNullValueException ();
  362. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  363. }
  364. return (float) value;
  365. }
  366. public
  367. #if NET_2_0
  368. override
  369. #endif // NET_2_0
  370. Guid GetGuid (int i)
  371. {
  372. object value = GetValue (i);
  373. if (!(value is Guid)) {
  374. if (value is DBNull) throw new SqlNullValueException ();
  375. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  376. }
  377. return (Guid) value;
  378. }
  379. public
  380. #if NET_2_0
  381. override
  382. #endif // NET_2_0
  383. short GetInt16 (int i)
  384. {
  385. object value = GetValue (i);
  386. if (!(value is short)) {
  387. if (value is DBNull) throw new SqlNullValueException ();
  388. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  389. }
  390. return (short) value;
  391. }
  392. public
  393. #if NET_2_0
  394. override
  395. #endif // NET_2_0
  396. int GetInt32 (int i)
  397. {
  398. object value = GetValue (i);
  399. if (!(value is int)) {
  400. if (value is DBNull) throw new SqlNullValueException ();
  401. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  402. }
  403. return (int) value;
  404. }
  405. public
  406. #if NET_2_0
  407. override
  408. #endif // NET_2_0
  409. long GetInt64 (int i)
  410. {
  411. object value = GetValue (i);
  412. if (!(value is long)) {
  413. if (value is DBNull) throw new SqlNullValueException ();
  414. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  415. }
  416. return (long) value;
  417. }
  418. public
  419. #if NET_2_0
  420. override
  421. #endif // NET_2_0
  422. string GetName (int i)
  423. {
  424. return (string) schemaTable.Rows[i]["ColumnName"];
  425. }
  426. public
  427. #if NET_2_0
  428. override
  429. #endif // NET_2_0
  430. int GetOrdinal (string name)
  431. {
  432. foreach (DataRow schemaRow in schemaTable.Rows)
  433. if (((string) schemaRow ["ColumnName"]).Equals (name))
  434. return (int) schemaRow ["ColumnOrdinal"];
  435. foreach (DataRow schemaRow in schemaTable.Rows)
  436. if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
  437. return (int) schemaRow ["ColumnOrdinal"];
  438. throw new IndexOutOfRangeException ();
  439. }
  440. public
  441. #if NET_2_0
  442. override
  443. #endif // NET_2_0
  444. DataTable GetSchemaTable ()
  445. {
  446. if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
  447. return schemaTable;
  448. if (!moreResults)
  449. return null;
  450. fieldCount = 0;
  451. dataTypeNames = new ArrayList ();
  452. foreach (TdsDataColumn schema in command.Tds.Columns) {
  453. DataRow row = schemaTable.NewRow ();
  454. row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
  455. row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
  456. row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
  457. row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
  458. row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
  459. row ["IsUnique"] = GetSchemaValue (schema, "IsUnique");
  460. row ["IsKey"] = GetSchemaValue (schema, "IsKey");
  461. row ["BaseServerName"] = GetSchemaValue (schema, "BaseServerName");
  462. row ["BaseCatalogName"] = GetSchemaValue (schema, "BaseCatalogName");
  463. row ["BaseColumnName"] = GetSchemaValue (schema, "BaseColumnName");
  464. row ["BaseSchemaName"] = GetSchemaValue (schema, "BaseSchemaName");
  465. row ["BaseTableName"] = GetSchemaValue (schema, "BaseTableName");
  466. row ["AllowDBNull"] = GetSchemaValue (schema, "AllowDBNull");
  467. row ["IsAliased"] = GetSchemaValue (schema, "IsAliased");
  468. row ["IsExpression"] = GetSchemaValue (schema, "IsExpression");
  469. row ["IsIdentity"] = GetSchemaValue (schema, "IsIdentity");
  470. row ["IsAutoIncrement"] = GetSchemaValue (schema, "IsAutoIncrement");
  471. row ["IsRowVersion"] = GetSchemaValue (schema, "IsRowVersion");
  472. row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
  473. row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
  474. // We don't always get the base column name.
  475. if (row ["BaseColumnName"] == DBNull.Value)
  476. row ["BaseColumnName"] = row ["ColumnName"];
  477. switch ((TdsColumnType) schema ["ColumnType"]) {
  478. case TdsColumnType.Int1:
  479. case TdsColumnType.Int2:
  480. case TdsColumnType.Int4:
  481. case TdsColumnType.IntN:
  482. switch ((int) schema ["ColumnSize"]) {
  483. case 1:
  484. dataTypeNames.Add ("tinyint");
  485. row ["ProviderType"] = (int) SqlDbType.TinyInt;
  486. row ["DataType"] = typeof (byte);
  487. row ["IsLong"] = false;
  488. break;
  489. case 2:
  490. dataTypeNames.Add ("smallint");
  491. row ["ProviderType"] = (int) SqlDbType.SmallInt;
  492. row ["DataType"] = typeof (short);
  493. row ["IsLong"] = false;
  494. break;
  495. case 4:
  496. dataTypeNames.Add ("int");
  497. row ["ProviderType"] = (int) SqlDbType.Int;
  498. row ["DataType"] = typeof (int);
  499. row ["IsLong"] = false;
  500. break;
  501. case 8:
  502. dataTypeNames.Add ("bigint");
  503. row ["ProviderType"] = (int) SqlDbType.BigInt;
  504. row ["DataType"] = typeof (long);
  505. row ["IsLong"] = false;
  506. break;
  507. }
  508. break;
  509. case TdsColumnType.Real:
  510. case TdsColumnType.Float8:
  511. case TdsColumnType.FloatN:
  512. switch ((int) schema ["ColumnSize"]) {
  513. case 4:
  514. dataTypeNames.Add ("real");
  515. row ["ProviderType"] = (int) SqlDbType.Real;
  516. row ["DataType"] = typeof (float);
  517. row ["IsLong"] = false;
  518. break;
  519. case 8:
  520. dataTypeNames.Add ("float");
  521. row ["ProviderType"] = (int) SqlDbType.Float;
  522. row ["DataType"] = typeof (double);
  523. row ["IsLong"] = false;
  524. break;
  525. }
  526. break;
  527. case TdsColumnType.Image :
  528. dataTypeNames.Add ("image");
  529. row ["ProviderType"] = (int) SqlDbType.Image;
  530. row ["DataType"] = typeof (byte[]);
  531. row ["IsLong"] = true;
  532. break;
  533. case TdsColumnType.Text :
  534. dataTypeNames.Add ("text");
  535. row ["ProviderType"] = (int) SqlDbType.Text;
  536. row ["DataType"] = typeof (string);
  537. row ["IsLong"] = true;
  538. break;
  539. case TdsColumnType.UniqueIdentifier :
  540. dataTypeNames.Add ("uniqueidentifier");
  541. row ["ProviderType"] = (int) SqlDbType.UniqueIdentifier;
  542. row ["DataType"] = typeof (Guid);
  543. row ["IsLong"] = false;
  544. break;
  545. case TdsColumnType.VarBinary :
  546. case TdsColumnType.BigVarBinary :
  547. dataTypeNames.Add ("varbinary");
  548. row ["ProviderType"] = (int) SqlDbType.VarBinary;
  549. row ["DataType"] = typeof (byte[]);
  550. row ["IsLong"] = true;
  551. break;
  552. case TdsColumnType.VarChar :
  553. case TdsColumnType.BigVarChar :
  554. dataTypeNames.Add ("varchar");
  555. row ["ProviderType"] = (int) SqlDbType.VarChar;
  556. row ["DataType"] = typeof (string);
  557. row ["IsLong"] = false;
  558. break;
  559. case TdsColumnType.Binary :
  560. case TdsColumnType.BigBinary :
  561. dataTypeNames.Add ("binary");
  562. row ["ProviderType"] = (int) SqlDbType.Binary;
  563. row ["DataType"] = typeof (byte[]);
  564. row ["IsLong"] = true;
  565. break;
  566. case TdsColumnType.Char :
  567. case TdsColumnType.BigChar :
  568. dataTypeNames.Add ("char");
  569. row ["ProviderType"] = (int) SqlDbType.Char;
  570. row ["DataType"] = typeof (string);
  571. row ["IsLong"] = false;
  572. break;
  573. case TdsColumnType.Bit :
  574. case TdsColumnType.BitN :
  575. dataTypeNames.Add ("bit");
  576. row ["ProviderType"] = (int) SqlDbType.Bit;
  577. row ["DataType"] = typeof (bool);
  578. row ["IsLong"] = false;
  579. break;
  580. case TdsColumnType.DateTime4 :
  581. case TdsColumnType.DateTime :
  582. case TdsColumnType.DateTimeN :
  583. dataTypeNames.Add ("datetime");
  584. row ["ProviderType"] = (int) SqlDbType.DateTime;
  585. row ["DataType"] = typeof (DateTime);
  586. row ["IsLong"] = false;
  587. break;
  588. case TdsColumnType.Money :
  589. case TdsColumnType.MoneyN :
  590. case TdsColumnType.Money4 :
  591. dataTypeNames.Add ("money");
  592. row ["ProviderType"] = (int) SqlDbType.Money;
  593. row ["DataType"] = typeof (decimal);
  594. row ["IsLong"] = false;
  595. break;
  596. case TdsColumnType.NText :
  597. dataTypeNames.Add ("ntext");
  598. row ["ProviderType"] = (int) SqlDbType.NText;
  599. row ["DataType"] = typeof (string);
  600. row ["IsLong"] = true;
  601. break;
  602. case TdsColumnType.NVarChar :
  603. dataTypeNames.Add ("nvarchar");
  604. row ["ProviderType"] = (int) SqlDbType.NVarChar;
  605. row ["DataType"] = typeof (string);
  606. row ["IsLong"] = false;
  607. break;
  608. case TdsColumnType.Decimal :
  609. case TdsColumnType.Numeric :
  610. dataTypeNames.Add ("decimal");
  611. row ["ProviderType"] = (int) SqlDbType.Decimal;
  612. row ["DataType"] = typeof (decimal);
  613. row ["IsLong"] = false;
  614. break;
  615. case TdsColumnType.NChar :
  616. dataTypeNames.Add ("nchar");
  617. row ["ProviderType"] = (int) SqlDbType.NChar;
  618. row ["DataType"] = typeof (string);
  619. row ["IsLong"] = false;
  620. break;
  621. case TdsColumnType.SmallMoney :
  622. dataTypeNames.Add ("smallmoney");
  623. row ["ProviderType"] = (int) SqlDbType.SmallMoney;
  624. row ["DataType"] = typeof (decimal);
  625. row ["IsLong"] = false;
  626. break;
  627. default :
  628. dataTypeNames.Add ("variant");
  629. row ["ProviderType"] = (int) SqlDbType.Variant;
  630. row ["DataType"] = typeof (object);
  631. row ["IsLong"] = false;
  632. break;
  633. }
  634. schemaTable.Rows.Add (row);
  635. fieldCount += 1;
  636. }
  637. return schemaTable;
  638. }
  639. private static object GetSchemaValue (TdsDataColumn schema, object key)
  640. {
  641. if (schema.ContainsKey (key) && schema [key] != null)
  642. return schema [key];
  643. return DBNull.Value;
  644. }
  645. public SqlBinary GetSqlBinary (int i)
  646. {
  647. throw new NotImplementedException ();
  648. }
  649. public SqlBoolean GetSqlBoolean (int i)
  650. {
  651. object value = GetSqlValue (i);
  652. if (!(value is SqlBoolean))
  653. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  654. return (SqlBoolean) value;
  655. }
  656. public SqlByte GetSqlByte (int i)
  657. {
  658. object value = GetSqlValue (i);
  659. if (!(value is SqlByte))
  660. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  661. return (SqlByte) value;
  662. }
  663. public SqlDateTime GetSqlDateTime (int i)
  664. {
  665. object value = GetSqlValue (i);
  666. if (!(value is SqlDateTime))
  667. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  668. return (SqlDateTime) value;
  669. }
  670. public SqlDecimal GetSqlDecimal (int i)
  671. {
  672. object value = GetSqlValue (i);
  673. if (!(value is SqlDecimal))
  674. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  675. return (SqlDecimal) value;
  676. }
  677. public SqlDouble GetSqlDouble (int i)
  678. {
  679. object value = GetSqlValue (i);
  680. if (!(value is SqlDouble))
  681. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  682. return (SqlDouble) value;
  683. }
  684. public SqlGuid GetSqlGuid (int i)
  685. {
  686. object value = GetSqlValue (i);
  687. if (!(value is SqlGuid))
  688. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  689. return (SqlGuid) value;
  690. }
  691. public SqlInt16 GetSqlInt16 (int i)
  692. {
  693. object value = GetSqlValue (i);
  694. if (!(value is SqlInt16))
  695. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  696. return (SqlInt16) value;
  697. }
  698. public SqlInt32 GetSqlInt32 (int i)
  699. {
  700. object value = GetSqlValue (i);
  701. if (!(value is SqlInt32))
  702. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  703. return (SqlInt32) value;
  704. }
  705. public SqlInt64 GetSqlInt64 (int i)
  706. {
  707. object value = GetSqlValue (i);
  708. if (!(value is SqlInt64))
  709. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  710. return (SqlInt64) value;
  711. }
  712. public SqlMoney GetSqlMoney (int i)
  713. {
  714. object value = GetSqlValue (i);
  715. if (!(value is SqlMoney))
  716. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  717. return (SqlMoney) value;
  718. }
  719. public SqlSingle GetSqlSingle (int i)
  720. {
  721. object value = GetSqlValue (i);
  722. if (!(value is SqlSingle))
  723. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  724. return (SqlSingle) value;
  725. }
  726. public SqlString GetSqlString (int i)
  727. {
  728. object value = GetSqlValue (i);
  729. if (!(value is SqlString))
  730. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  731. return (SqlString) value;
  732. }
  733. public object GetSqlValue (int i)
  734. {
  735. SqlDbType type = (SqlDbType) (schemaTable.Rows [i]["ProviderType"]);
  736. object value = GetValue (i);
  737. switch (type) {
  738. case SqlDbType.BigInt:
  739. if (value == DBNull.Value)
  740. return SqlInt64.Null;
  741. return (SqlInt64) ((long) value);
  742. case SqlDbType.Binary:
  743. case SqlDbType.Image:
  744. case SqlDbType.VarBinary:
  745. case SqlDbType.Timestamp:
  746. if (value == DBNull.Value)
  747. return SqlBinary.Null;
  748. return (SqlBinary) ((byte[]) value);
  749. case SqlDbType.Bit:
  750. if (value == DBNull.Value)
  751. return SqlBoolean.Null;
  752. return (SqlBoolean) ((bool) value);
  753. case SqlDbType.Char:
  754. case SqlDbType.NChar:
  755. case SqlDbType.NText:
  756. case SqlDbType.NVarChar:
  757. case SqlDbType.Text:
  758. case SqlDbType.VarChar:
  759. if (value == DBNull.Value)
  760. return SqlString.Null;
  761. return (SqlString) ((string) value);
  762. case SqlDbType.DateTime:
  763. case SqlDbType.SmallDateTime:
  764. if (value == DBNull.Value)
  765. return SqlDateTime.Null;
  766. return (SqlDateTime) ((DateTime) value);
  767. case SqlDbType.Decimal:
  768. if (value == DBNull.Value)
  769. return SqlDecimal.Null;
  770. if (value is TdsBigDecimal)
  771. return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
  772. return (SqlDecimal) ((decimal) value);
  773. case SqlDbType.Float:
  774. if (value == DBNull.Value)
  775. return SqlDouble.Null;
  776. return (SqlDouble) ((double) value);
  777. case SqlDbType.Int:
  778. if (value == DBNull.Value)
  779. return SqlInt32.Null;
  780. return (SqlInt32) ((int) value);
  781. case SqlDbType.Money:
  782. case SqlDbType.SmallMoney:
  783. if (value == DBNull.Value)
  784. return SqlMoney.Null;
  785. return (SqlMoney) ((decimal) value);
  786. case SqlDbType.Real:
  787. if (value == DBNull.Value)
  788. return SqlSingle.Null;
  789. return (SqlSingle) ((float) value);
  790. case SqlDbType.UniqueIdentifier:
  791. if (value == DBNull.Value)
  792. return SqlGuid.Null;
  793. return (SqlGuid) ((Guid) value);
  794. case SqlDbType.SmallInt:
  795. if (value == DBNull.Value)
  796. return SqlInt16.Null;
  797. return (SqlInt16) ((short) value);
  798. case SqlDbType.TinyInt:
  799. if (value == DBNull.Value)
  800. return SqlByte.Null;
  801. return (SqlByte) ((byte) value);
  802. }
  803. throw new InvalidOperationException ("The type of this column is unknown.");
  804. }
  805. public int GetSqlValues (object[] values)
  806. {
  807. int count = 0;
  808. int columnCount = schemaTable.Rows.Count;
  809. int arrayCount = values.Length;
  810. if (arrayCount > columnCount)
  811. count = columnCount;
  812. else
  813. count = arrayCount;
  814. for (int i = 0; i < count; i += 1)
  815. values [i] = GetSqlValue (i);
  816. return count;
  817. }
  818. public
  819. #if NET_2_0
  820. override
  821. #endif // NET_2_0
  822. string GetString (int i)
  823. {
  824. object value = GetValue (i);
  825. if (!(value is string)) {
  826. if (value is DBNull) throw new SqlNullValueException ();
  827. throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
  828. }
  829. return (string) value;
  830. }
  831. public
  832. #if NET_2_0
  833. override
  834. #endif // NET_2_0
  835. object GetValue (int i)
  836. {
  837. return command.Tds.ColumnValues [i];
  838. }
  839. public
  840. #if NET_2_0
  841. override
  842. #endif // NET_2_0
  843. int GetValues (object[] values)
  844. {
  845. int len = values.Length;
  846. int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
  847. // If a four-byte decimal is stored, then we can't convert to
  848. // a native type. Throw an OverflowException.
  849. if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
  850. throw new OverflowException ();
  851. command.Tds.ColumnValues.CopyTo (0, values, 0, len);
  852. return (len > FieldCount ? len : FieldCount);
  853. }
  854. void IDisposable.Dispose ()
  855. {
  856. Dispose (true);
  857. GC.SuppressFinalize (this);
  858. }
  859. IEnumerator IEnumerable.GetEnumerator ()
  860. {
  861. return new DbEnumerator (this);
  862. }
  863. public
  864. #if NET_2_0
  865. override
  866. #endif // NET_2_0
  867. bool IsDBNull (int i)
  868. {
  869. return GetValue (i) == DBNull.Value;
  870. }
  871. public
  872. #if NET_2_0
  873. override
  874. #endif // NET_2_0
  875. bool NextResult ()
  876. {
  877. if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
  878. return false;
  879. schemaTable.Rows.Clear ();
  880. moreResults = command.Tds.NextResult ();
  881. if (!moreResults)
  882. command.GetOutputParameters ();
  883. GetSchemaTable ();
  884. rowsRead = 0;
  885. resultsRead += 1;
  886. return moreResults;
  887. }
  888. public
  889. #if NET_2_0
  890. override
  891. #endif // NET_2_0
  892. bool Read ()
  893. {
  894. if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
  895. return false;
  896. if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
  897. return false;
  898. if (!moreResults)
  899. return false;
  900. if ((haveRead) && (!readResultUsed))
  901. {
  902. readResultUsed = true;
  903. return true;
  904. }
  905. return (ReadRecord ());
  906. }
  907. internal bool ReadRecord ()
  908. {
  909. bool result = command.Tds.NextRow ();
  910. rowsRead += 1;
  911. return result;
  912. }
  913. #if NET_2_0
  914. [MonoTODO]
  915. protected override bool IsValidRow
  916. {
  917. get {throw new NotImplementedException ();}
  918. }
  919. [MonoTODO]
  920. public override Type GetFieldProviderSpecificType (int position)
  921. {
  922. throw new NotImplementedException ();
  923. }
  924. [MonoTODO]
  925. public override object GetProviderSpecificValue (int position)
  926. {
  927. throw new NotImplementedException ();
  928. }
  929. [MonoTODO]
  930. public override int GetProviderSpecificValues (object [] values)
  931. {
  932. throw new NotImplementedException ();
  933. }
  934. [MonoTODO]
  935. public override int VisibleFieldCount
  936. {
  937. get {throw new NotImplementedException ();}
  938. }
  939. #endif // NET_2_0
  940. #endregion // Methods
  941. }
  942. }