using System; using System.Data; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Xml; namespace Xpace { public class SchemaTable : DataTable { private List _readers; public SchemaTable(TableCursor tc) { _readers = new List(); for (uint col = 0; col < tc.columnCount; ++col) { string config = tc.getColumnConfig(col); DataColumn column = new DataColumn(); column.ReadOnly = true; column.Unique = false; XmlDocument doc = new XmlDocument(); doc.LoadXml(config); XmlElement node = doc["field"]; column.ColumnName = node.GetAttribute("name"); string type = node.GetAttribute("type"); if (type == "text") { column.DataType = System.Type.GetType("System.String"); _readers.Add(new TextResultReader()); } else if (type == "unsigned") { column.DataType = System.Type.GetType("System.UInt64"); _readers.Add(new UInt64ResultReader()); } else if ((type == "date") || (type == "time")) { column.DataType = System.Type.GetType("System.Int32"); _readers.Add(new Int32ResultReader()); } else throw new UnknownDataTypeException(type, "Quotes"); Columns.Add(column); } } public List GetReaders { get { return _readers; } } } [Serializable] public class UnknownDataTypeException : ApplicationException { public UnknownDataTypeException () { } public UnknownDataTypeException (string dataType, string tableName) : base(make_msg(dataType, tableName)) { } public UnknownDataTypeException (string dataType, string tableName, Exception inner) : base(make_msg(dataType, tableName), inner) { } protected UnknownDataTypeException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } static private string make_msg (string dataType, string tableName) { StringBuilder ret = new StringBuilder("Unknown data type \""); ret.Append(dataType); ret.Append("\" in table \""); ret.Append(tableName); ret.Append("\"."); return ret.ToString(); } } public class DataReader : IDataReader { private Result _res; private readonly SchemaTable _schema_table; private object[] _row; public DataReader(Result res, SchemaTable schemaTable) { _res = res; _schema_table = schemaTable; _row = new object[schemaTable.Columns.Count]; } // IDataReader public int Depth { get { return 0; } } // For nested data. public bool IsClosed { get { return false; } } // Could have open/closed status. public int RecordsAffected { get { return 0; } } // Only for insert/delete/update. public void Dispose() { } // Cleanup, if necessary. public void Close() { } public bool NextResult() { return false; } // Only 1 result set returned. public DataTable GetSchemaTable() { return _schema_table; } public bool Read() { unsafe { int col = 0; foreach (IResultReader r in _schema_table.GetReaders) { r.read(ref _res); _row[col++] = r.Get; } } return !_res.isDone; } public int FieldCount { get { return _schema_table.Columns.Count; } } public string GetName(int i) { return _schema_table.Columns[i].ColumnName; } public string GetDataTypeName(int i) { return _schema_table.Columns[i].DataType.ToString(); } public System.Type GetFieldType(int i) { return _schema_table.Columns[i].DataType; } public int GetOrdinal(string name) { return _schema_table.Columns[name].Ordinal; } public IDataReader GetData(int i) { throw new NotSupportedException("GetData not supported."); } public bool IsDBNull(int i) { return _row[i] == null; } public int GetValues(object[] obs) { int col = 0; for (; col < Math.Min(obs.Length, _row.Length); ++col) obs[col] = _row[col]; return col; } public object this[int n] { get { return _row[n]; } } public object this[string s] { get { return _row[GetOrdinal(s)]; } } public object GetValue(int i) { return _row[i]; } public bool GetBoolean(int i) { return Convert.ToBoolean(_row[i]); } public byte GetByte(int i) { return Convert.ToByte(_row[i]); } public long GetBytes(int i, long off, byte[] buffer, int bufoff, int len) { throw new NotSupportedException(); } public char GetChar(int i) { return Convert.ToChar(_row[i]); } public long GetChars(int i, long off, char[] buffer, int bufoff, int len) { throw new NotSupportedException(); } public DateTime GetDateTime(int i) { throw new NotSupportedException(); } public System.Guid GetGuid(int i) { throw new NotSupportedException(); } public short GetInt16(int i) { return Convert.ToInt16(_row[i]); } public int GetInt32(int i) { return Convert.ToInt32(_row[i]); } public Int64 GetInt64(int i) { return Convert.ToInt64(_row[i]); } public float GetFloat(int i) { throw new NotSupportedException(); } public double GetDouble(int i) { return Convert.ToDouble(_row[i]); } public string GetString(int i) { return _row[i].ToString(); } public decimal GetDecimal(int i) { return Convert.ToDecimal(_row[i]); } } }