using Apewer; using Apewer.Internals; using System; using System.Collections.Generic; using System.Data; using System.Runtime.CompilerServices; namespace Apewer.Source { /// 查询数据表。 public class Query : IQuery, IDisposable { private bool _disposed = false; private bool _success = false; private string _error = ""; private string _message = ""; private Exception _exception = null; private List _tables = new List(); #region Property /// 语句执行成功。 public bool Success { get { if (_disposed) return false; return _success; } set { if (_disposed) return; _success = value; } } /// 错误信息。 public string Error { get { if (_disposed) return ""; if (!string.IsNullOrEmpty(_error)) return _error; if (_exception == null) return ""; var error = ""; try { error = _exception.Message; } finally { } return error; } set { if (_disposed) return; _error = value ?? ""; } } /// 消息。 public string Message { get { if (_disposed) return ""; return _message ?? ""; } set { if (_disposed) return; _message = value ?? ""; } } /// 语句执行失败时的 Exception 对象。 public Exception Exception { get { if (_disposed) return null; return _exception; } set { if (_disposed) return; _exception = value; } } /// 所有结果表。 public List Tables { get { if (_disposed) return new List(); return _tables; } } /// 获取默认结果表。如果设置默认结果表,会丢失设置前的所有结果表。 public DataTable Table { get { if (_disposed) return null; if (_tables.Count < 1) return null; return _tables[0]; } set { if (_disposed) return; Clear(); if (_disposed) return; _tables.Add(value); } } /// 所有表中不含内容行。 public bool Empty { get { if (_disposed) return true; if (_tables.Count < 1) return true; foreach (var table in _tables) { if (table == null) continue; try { if (table.Rows.Count > 0) return false; } finally { } } return true; } } /// 默认表中的数据总行数。 public int Rows { get { if (_disposed) return 0; if (Table != null) return Table.Rows.Count; else return 0; } } /// 默认表中的数据总列数。 public int Columns { get { if (_disposed) return 0; if (Table != null) return Table.Columns.Count; else return 0; } } #endregion #region Text /// 获取默认表中第 0 行、第 0 列的单元格内容。 public string Text() { if (_disposed) return Constant.EmptyString; var value = Value(); return Text(value); } /// 获取默认表中指定行中第 0 列的内容。 /// 行索引,从 0 开始。 public string Text(int rowIndex) { if (_disposed) return Constant.EmptyString; var value = Value(rowIndex); return Text(value); } /// 获取默认表中第 0 行指定列的内容。 /// 列名称。 public string Text(string columnName) { if (_disposed) return Constant.EmptyString; var value = Value(columnName); return Text(value); } /// 获取默认表中指定单元格的内容。 /// 行索引,从 0 开始。 /// 列索引,从 0 开始。 public string Text(int rowIndex, int columnIndex) { if (_disposed) return Constant.EmptyString; var value = Value(rowIndex, columnIndex); return Text(value); } /// 获取默认表中指定单元的内容。 /// 行索引,从 0 开始。 /// 列名称。 public string Text(int rowIndex, string columnName) { if (_disposed) return Constant.EmptyString; var value = Value(rowIndex, columnName); return Text(value); } /// 搜索默认表。 /// 搜索条件:列名。 /// 搜索条件:列值。 /// 搜索结果。 public string Text(string conditionColumn, string conditionValue, string resultColumn) { if (_disposed) return Constant.EmptyString; var value = Value(conditionColumn, conditionValue, resultColumn); return Text(value); } /// 搜索默认表。 /// 搜索条件:列名。 /// 搜索条件:列值。 /// 搜索结果。 public string Text(int conditionColumn, string conditionValue, int resultColumn) { if (_disposed) return Constant.EmptyString; var value = Value(conditionColumn, conditionValue, resultColumn); return Text(value); } #endregion #region Value /// 获取默认表中第 0 行、第 0 列的单元格内容。 public object Value() { if (_disposed) return null; return Value(0, 0); } /// 获取默认表中指定行中第 0 列的内容。 /// 行索引,从 0 开始。 public object Value(int rowIndex) { if (_disposed) return null; return Value(rowIndex, 0); } /// 获取默认表中第 0 行指定列的内容。 /// 列名称。 public object Value(string columnName) { if (_disposed) return null; return Value(0, columnName); } /// 获取默认表中指定单元格的内容。 /// 行索引,从 0 开始。 /// 列索引,从 0 开始。 public object Value(int rowIndex, int columnIndex) { if (_disposed) return null; if (Table != null) { if (rowIndex >= 0 && rowIndex < Table.Rows.Count) { if (columnIndex >= 0 && columnIndex < Table.Columns.Count) { return Table.Rows[rowIndex][columnIndex]; } } } return null; } /// 获取默认表中指定单元的内容。 /// 行索引,从 0 开始。 /// 列名称。 public object Value(int rowIndex, string columnName) { if (_disposed) return null; if ((Table != null) && !string.IsNullOrEmpty(columnName)) { if ((rowIndex < Table.Rows.Count) && (rowIndex >= 0)) { try { return Table.Rows[rowIndex][columnName]; } catch { } } } return null; } /// 搜索默认表。 /// 搜索条件:列名。 /// 搜索条件:列值。 /// 搜索结果。 public object Value(string conditionColumn, string conditionValue, string resultColumn) { if (_disposed) return null; if ((Table != null) && (!string.IsNullOrEmpty(conditionColumn)) && (conditionValue != null) && (!string.IsNullOrEmpty(resultColumn))) { for (int i = 0; i < Table.Rows.Count; i++) { try { if (Table.Rows[i][conditionColumn].ToString() == conditionValue) return Table.Rows[i][resultColumn]; } catch { } } } return null; } /// 搜索默认表。 /// 搜索条件:列名。 /// 搜索条件:列值。 /// 搜索结果。 public object Value(int conditionColumn, string conditionValue, int resultColumn) { if (_disposed) return null; if ((Table != null) && (conditionColumn >= 0) && (conditionValue != null) && (resultColumn >= 0)) { if ((conditionColumn < Table.Columns.Count) && (resultColumn < Table.Columns.Count)) { for (int i = 0; i < Table.Rows.Count; i++) { try { if (Table.Rows[i][conditionColumn].ToString() == conditionValue) return Table.Rows[i][resultColumn]; } catch { } } } } return null; } #endregion #region Method /// 拆分表组,单独查询。 public List Split() { var list = new List(); if (_disposed) return list; foreach (var table in _tables) { if (table == null) continue; var query = new Query(); query._success = true; query._tables.Add(table); list.Add(query); } return list; } /// 添加数据表。 public bool Add(DataTable tables) { if (_disposed) return false; if (tables == null) return false; _tables.Add(tables); return true; } /// 添加数据表。 public int Add(IEnumerable tables) { var count = 0; if (_disposed) return count; if (tables == null) return count; foreach (var table in tables) { if (table == null) continue; _tables.Add(table); count = count + 1; } return count; } /// 清除所有表,并释放系统资源。 public virtual void Clear() { if (_tables != null) { foreach (var table in _tables) { if (table != null) { try { table.Dispose(); } catch { } } } _tables.Clear(); } if (_exception != null) _exception = null; _success = false; } /// 释放系统资源。 public virtual void Dispose() { Clear(); _disposed = true; // GC.SuppressFinalize(this); } /// /// public List Fill() where T : Record { var list = new List(); var type = typeof(T); for (int r = 0; r < Rows; r++) { list.Capacity = Rows; var entity = type.Assembly.CreateInstance(type.FullName); var ts = TableStructure.ParseModel(type); var properties = type.GetProperties(); foreach (var property in properties) { if (ts.Columns.ContainsKey(property.Name) == false) continue; var setter = property.GetSetMethod(); if (setter == null) continue; var attribute = ts.Columns[property.Name]; var pt = property.PropertyType; if (pt.Equals(typeof(object)) || pt.Equals(typeof(Nullable))) { setter.Invoke(entity, new object[] { Value(r, attribute.Field) }); } else if (pt.Equals(typeof(DateTime))) { var value = Value(r, attribute.Field); if (value != null) setter.Invoke(entity, new object[] { Value(r, attribute.Field) }); } else if (pt.Equals(typeof(byte[]))) { setter.Invoke(entity, new object[] { (byte[])Value(r, attribute.Field) }); } else if (pt.Equals(typeof(byte))) { setter.Invoke(entity, new object[] { TextConverter.GetByte(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(sbyte))) { setter.Invoke(entity, new object[] { TextConverter.GetSByte(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(short))) { setter.Invoke(entity, new object[] { TextConverter.GetInt16(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(ushort))) { setter.Invoke(entity, new object[] { TextConverter.GetUInt16(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(int))) { setter.Invoke(entity, new object[] { TextConverter.GetInt32(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(uint))) { setter.Invoke(entity, new object[] { TextConverter.GetUInt32(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(long))) { setter.Invoke(entity, new object[] { TextConverter.GetInt64(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(ulong))) { setter.Invoke(entity, new object[] { TextConverter.GetUInt64(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(float))) { setter.Invoke(entity, new object[] { TextConverter.GetSingle(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(double))) { setter.Invoke(entity, new object[] { TextConverter.GetDouble(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(decimal))) { setter.Invoke(entity, new object[] { TextConverter.GetDecimal(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(string))) { setter.Invoke(entity, new object[] { Text(r, attribute.Field) }); } else { try { setter.Invoke(entity, new object[] { Value(r, attribute.Field) }); } catch { } } } list.Add((T)entity); } return list; } /// 获取指定列的所有值,无效值不加入结果。 /// public List ReadColumn(Func filler) { var list = new List(); if (filler == null) throw new ArgumentNullException(nameof(filler)); var rows = Rows; if (rows > 0) { list.Capacity = rows; var added = 0; for (int r = 0; r < rows; r++) { var value = filler(r); if (value == null) continue; if (value is string) { var valueString = value as string; if (string.IsNullOrEmpty(valueString)) continue; } list.Add(value); added++; } list.Capacity = added; } return list; } /// 当不指定格式化程序时,自动根据类型选择预置的格式化程序。 private static Func GetValueFormatter() { var type = typeof(T); if (type.Equals(typeof(string))) return TextFormatter; else return ForceFormatter; } /// 获取指定列的所有值,无效值不加入结果。 public List ReadColumn(int column = 0, Func formatter = null) => ReadColumn((r) => (formatter ?? GetValueFormatter()).Invoke(Value(r, column))); /// 获取指定列的所有值,无效值不加入结果。 /// public List ReadColumn(string column, Func formatter = null) => ReadColumn((r) => (formatter ?? GetValueFormatter()).Invoke(Value(r, column))); /// 获取指定列的所有值,无效值不加入结果。 public List ReadColumn(int column = 0) => ReadColumn((r) => Text(r, column)); /// 获取指定列的所有值,无效值不加入结果。 /// public List ReadColumn(string column) => ReadColumn((r) => Text(r, column)); #endregion #region Static private static string Text(object value) { var result = Constant.EmptyString; if (value != null) { if (!value.Equals(DBNull.Value)) { try { result = value.ToString(); } finally { } } } return result; } private static T ForceFormatter(object input) => (T)input; private static T TextFormatter(object input) => (T)(Text(input) as object); private static ObjectDisposedException DisposedException { get { return new ObjectDisposedException(typeof(Query).FullName); } } /// 简单查询:取结果中第 0 列所有单元格的文本形式,可指定查询后关闭服务器连接,返回结果中不包含无效文本。 public static List SimpleColumn(IDatabase database, string statement, bool close = false) { var list = new List(); if (database == null) return list; if (!database.Connect()) return list; using (var query = database.Query(statement)) { var rows = query.Rows; if (rows > 0) { list.Capacity = query.Rows; var added = 0; for (int i = 0; i < rows; i++) { var cell = TextModifier.Trim(query.Text(i)); if (string.IsNullOrEmpty(cell)) continue; list.Add(cell); added++; } list.Capacity = added; } } if (close) database.Close(); return list; } /// 简单查询:取结果中第 0 行、第 0 列单元格中的文本,可指定查询后关闭服务器连接。 public static string SimpleCell(IDatabase database, string statement, bool close = false) { if (database == null) return ""; if (!database.Connect()) return ""; var vquery = database.Query(statement); var vcell = TextModifier.Trim(vquery.Text()); vquery.Dispose(); if (close) database.Close(); return vcell; } #endregion #region Extension /// internal static DateTime DateTime(IQuery query, int row, string column) { if (query == null) return DateTimeUtility.Origin; var value = query.Value(row, column); if (value == null) return DateTimeUtility.Origin; if (value is DateTime) return (DateTime)value; DateTime result; var parsed = System.DateTime.TryParse(value.ToString(), out result); return parsed ? result : DateTimeUtility.Origin; } #endregion } }