2 // Mono.Data.SqliteClient.SqliteDataReader.cs
4 // Provides a means of reading a forward-only stream of rows from a Sqlite
7 // Author(s): Vladimir Vukicevic <vladimir@pobox.com>
8 // Everaldo Canuto <everaldo_canuto@yahoo.com.br>
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
33 using System
.Runtime
.InteropServices
;
34 using System
.Collections
;
36 using System
.Data
.Common
;
38 namespace Mono
.Data
.SqliteClient
40 public class SqliteDataReader
: MarshalByRefObject
, IEnumerable
, IDataReader
, IDisposable
, IDataRecord
45 private SqliteCommand command
;
46 private ArrayList rows
;
47 private ArrayList columns
;
48 private Hashtable column_names
;
49 private int current_row
;
52 private int records_affected
;
56 #region Constructors and destructors
58 internal SqliteDataReader (SqliteCommand cmd
)
61 rows
= new ArrayList ();
62 columns
= new ArrayList ();
63 column_names
= new Hashtable ();
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; }
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
]);
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
]));
124 internal void ReadingDone ()
126 records_affected
= command
.NumChanges ();
132 #region Public Methods
139 public void Dispose ()
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 ()
216 return (current_row
< rows
.Count
);
221 return NextResult ();
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
];
335 values
[i
] = DBNull
.Value
;
341 public bool IsDBNull (int i
)
343 return (((ArrayList
) rows
[current_row
])[i
] == null);