**** Merged from MCS ****
[mono-project.git] / mcs / class / Mono.Data.SqliteClient / Mono.Data.SqliteClient / SqliteDataReader.cs
blob8d5dc81e8c32de32b3fff43c985cdefe8f675bf8
1 //
2 // Mono.Data.SqliteClient.SqliteDataReader.cs
3 //
4 // Provides a means of reading a forward-only stream of rows from a Sqlite
5 // database file.
6 //
7 // Author(s): Vladimir Vukicevic <vladimir@pobox.com>
8 // Everaldo Canuto <everaldo_canuto@yahoo.com.br>
9 //
10 // Copyright (C) 2002 Vladimir Vukicevic
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.
32 using System;
33 using System.Runtime.InteropServices;
34 using System.Collections;
35 using System.Data;
36 using System.Data.Common;
38 namespace Mono.Data.SqliteClient
40 public class SqliteDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
43 #region Fields
45 private SqliteCommand command;
46 private ArrayList rows;
47 private ArrayList columns;
48 private Hashtable column_names;
49 private int current_row;
50 private bool closed;
51 private bool reading;
52 private int records_affected;
54 #endregion
56 #region Constructors and destructors
58 internal SqliteDataReader (SqliteCommand cmd)
60 command = cmd;
61 rows = new ArrayList ();
62 columns = new ArrayList ();
63 column_names = new Hashtable ();
64 closed = false;
65 current_row = -1;
66 reading = true;
69 #endregion
71 #region Properties
73 public int Depth {
74 get { return 0; }
77 public int FieldCount {
78 get { return columns.Count; }
81 public object this[string name] {
82 get { return ((ArrayList) rows[current_row])[(int) column_names[name]]; }
85 public object this[int i] {
86 get { return ((ArrayList) rows[current_row])[i]; }
89 public bool IsClosed {
90 get { return closed; }
93 public int RecordsAffected {
94 get { return records_affected; }
97 #endregion
99 #region Internal Methods
101 internal unsafe int SqliteCallback (ref object o, int argc, sbyte **argv, sbyte **colnames)
103 // cache names of columns if we need to
104 if (column_names.Count == 0) {
105 for (int i = 0; i < argc; i++) {
106 string col = new String (colnames[i]);
107 columns.Add (col);
108 column_names[col.ToLower ()] = i;
112 ArrayList data_row = new ArrayList (argc);
113 for (int i = 0; i < argc; i++) {
114 if (argv[i] != ((sbyte *)0)) {
115 data_row.Add(new String (argv[i]));
116 } else {
117 data_row.Add(null);
120 rows.Add (data_row);
121 return 0;
124 internal void ReadingDone ()
126 records_affected = command.NumChanges ();
127 reading = false;
130 #endregion
132 #region Public Methods
134 public void Close ()
136 closed = true;
139 public void Dispose ()
141 Close ();
144 IEnumerator IEnumerable.GetEnumerator ()
146 return new DbEnumerator (this);
149 public DataTable GetSchemaTable ()
151 DataTable dataTableSchema = new DataTable ();
153 dataTableSchema.Columns.Add ("ColumnName", typeof (String));
154 dataTableSchema.Columns.Add ("ColumnOrdinal", typeof (Int32));
155 dataTableSchema.Columns.Add ("ColumnSize", typeof (Int32));
156 dataTableSchema.Columns.Add ("NumericPrecision", typeof (Int32));
157 dataTableSchema.Columns.Add ("NumericScale", typeof (Int32));
158 dataTableSchema.Columns.Add ("IsUnique", typeof (Boolean));
159 dataTableSchema.Columns.Add ("IsKey", typeof (Boolean));
160 dataTableSchema.Columns.Add ("BaseCatalogName", typeof (String));
161 dataTableSchema.Columns.Add ("BaseColumnName", typeof (String));
162 dataTableSchema.Columns.Add ("BaseSchemaName", typeof (String));
163 dataTableSchema.Columns.Add ("BaseTableName", typeof (String));
164 dataTableSchema.Columns.Add ("DataType", typeof(Type));
165 dataTableSchema.Columns.Add ("AllowDBNull", typeof (Boolean));
166 dataTableSchema.Columns.Add ("ProviderType", typeof (Int32));
167 dataTableSchema.Columns.Add ("IsAliased", typeof (Boolean));
168 dataTableSchema.Columns.Add ("IsExpression", typeof (Boolean));
169 dataTableSchema.Columns.Add ("IsIdentity", typeof (Boolean));
170 dataTableSchema.Columns.Add ("IsAutoIncrement", typeof (Boolean));
171 dataTableSchema.Columns.Add ("IsRowVersion", typeof (Boolean));
172 dataTableSchema.Columns.Add ("IsHidden", typeof (Boolean));
173 dataTableSchema.Columns.Add ("IsLong", typeof (Boolean));
174 dataTableSchema.Columns.Add ("IsReadOnly", typeof (Boolean));
176 dataTableSchema.BeginLoadData();
177 for (int i = 0; i < this.FieldCount; i += 1 ) {
179 DataRow schemaRow = dataTableSchema.NewRow ();
181 schemaRow["ColumnName"] = columns[i];
182 schemaRow["ColumnOrdinal"] = i;
183 schemaRow["ColumnSize"] = 0;
184 schemaRow["NumericPrecision"] = 0;
185 schemaRow["NumericScale"] = 0;
186 schemaRow["IsUnique"] = false;
187 schemaRow["IsKey"] = false;
188 schemaRow["BaseCatalogName"] = "";
189 schemaRow["BaseColumnName"] = columns[i];
190 schemaRow["BaseSchemaName"] = "";
191 schemaRow["BaseTableName"] = "";
192 schemaRow["DataType"] = typeof(string);
193 schemaRow["AllowDBNull"] = true;
194 schemaRow["ProviderType"] = 0;
195 schemaRow["IsAliased"] = false;
196 schemaRow["IsExpression"] = false;
197 schemaRow["IsIdentity"] = false;
198 schemaRow["IsAutoIncrement"] = false;
199 schemaRow["IsRowVersion"] = false;
200 schemaRow["IsHidden"] = false;
201 schemaRow["IsLong"] = false;
202 schemaRow["IsReadOnly"] = false;
204 dataTableSchema.Rows.Add (schemaRow);
205 schemaRow.AcceptChanges();
207 dataTableSchema.EndLoadData();
209 return dataTableSchema;
212 public bool NextResult ()
214 current_row++;
216 return (current_row < rows.Count);
219 public bool Read ()
221 return NextResult ();
224 #endregion
226 #region IDataRecord getters
228 public bool GetBoolean (int i)
230 return Convert.ToBoolean ((string) ((ArrayList) rows[current_row])[i]);
233 public byte GetByte (int i)
235 return Convert.ToByte ((string) ((ArrayList) rows[current_row])[i]);
238 public long GetBytes (int i, long fieldOffset, byte[] buffer, int bufferOffset, int length)
240 throw new NotImplementedException ();
243 public char GetChar (int i)
245 return Convert.ToChar ((string) ((ArrayList) rows[current_row])[i]);
248 public long GetChars (int i, long fieldOffset, char[] buffer, int bufferOffset, int length)
250 throw new NotImplementedException ();
253 public IDataReader GetData (int i)
255 throw new NotImplementedException ();
258 public string GetDataTypeName (int i)
260 return "text"; // SQL Lite data type
263 public DateTime GetDateTime (int i)
265 return Convert.ToDateTime ((string) ((ArrayList) rows[current_row])[i]);
268 public decimal GetDecimal (int i)
270 return Convert.ToDecimal ((string) ((ArrayList) rows[current_row])[i]);
273 public double GetDouble (int i)
275 return Convert.ToDouble ((string) ((ArrayList) rows[current_row])[i]);
278 public Type GetFieldType (int i)
280 return System.Type.GetType ("System.String"); // .NET data type
283 public float GetFloat (int i)
285 return Convert.ToSingle ((string) ((ArrayList) rows[current_row])[i]);
288 public Guid GetGuid (int i)
290 throw new NotImplementedException ();
293 public short GetInt16 (int i)
295 return Convert.ToInt16 ((string) ((ArrayList) rows[current_row])[i]);
298 public int GetInt32 (int i)
300 return Convert.ToInt32 ((string) ((ArrayList) rows[current_row])[i]);
303 public long GetInt64 (int i)
305 return Convert.ToInt64 ((string) ((ArrayList) rows[current_row])[i]);
308 public string GetName (int i)
310 return (string) columns[i];
313 public int GetOrdinal (string name)
315 return (int) column_names[name];
318 public string GetString (int i)
320 return ((string) ((ArrayList) rows[current_row])[i]);
323 public object GetValue (int i)
325 return ((ArrayList) rows[current_row])[i];
328 public int GetValues (object[] values)
330 int num_to_fill = System.Math.Min (values.Length, columns.Count);
331 for (int i = 0; i < num_to_fill; i++) {
332 if (((ArrayList) rows[current_row])[i] != null) {
333 values[i] = ((ArrayList) rows[current_row])[i];
334 } else {
335 values[i] = DBNull.Value;
338 return num_to_fill;
341 public bool IsDBNull (int i)
343 return (((ArrayList) rows[current_row])[i] == null);
346 #endregion