using System;
using System.Collections.Generic;
using System.Text;
using static Apewer.NumberUtility;
namespace Apewer.Source
{
/// ORM 帮助程序。
public static class OrmHelper
{
#region As
private static List As(List input) where T : IRecord
{
if (input == null) return null;
var output = new List(input.Count);
foreach (var record in input)
{
if (record == null) continue;
var t = (T)record;
output.Add(t);
}
return output;
}
private static Result As(Result input) where T : class, IRecord, new()
{
if (input == null) return null;
if (!input.HasValue) return new Result(input.Code, input.Message);
var value = input.Value as T;
return new Result(value);
}
private static Result> As(Result> input) where T : class, IRecord, new()
{
if (input == null) return null;
if (!input.HasValue) return new Result>(input.Code, input.Message);
var list = new List(input.Value.Count);
foreach (var inputItem in input.Value)
{
var value = inputItem as T;
list.Add(value);
}
return new Result>(list);
}
#endregion
#region IQuery -> IRecord
/// 读取所有行,生成列表。
public static List Fill(IQuery query) where T : class, IRecord, new() => As(Fill(query, typeof(T)));
/// 读取所有行填充到 T,组成 List<T>。
///
public static List Fill(IQuery query, Type model)
{
if (query == null) return new List();
if (model == null) return new List();
var list = new List(query.Rows);
var ts = TableStructure.ParseModel(model);
for (int r = 0; r < query.Rows; r++)
{
var record = Row(query, r, model, ts);
if (record != null) list.Add(record);
}
list.Capacity = list.Count;
return list;
}
/// 获取指定列的所有值,无效值不加入结果。
///
public static List Column(IQuery query, Func filler)
{
if (query == null) throw new ArgumentNullException(nameof(query));
if (filler == null) throw new ArgumentNullException(nameof(filler));
var rows = query.Rows;
var list = new List(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;
}
/// 填充指定行为记录实体。
/// 填充失败时返回 NULL 值。
///
///
///
public static IRecord Row(IQuery query, int rowIndex, Type model, TableStructure structure)
{
if (query == null) throw new ArgumentNullException(nameof(query));
if (model == null) throw new ArgumentNullException(nameof(model));
if (structure == null) throw new ArgumentNullException(nameof(structure));
if (rowIndex < 0 || rowIndex >= query.Rows) throw new ArgumentOutOfRangeException(nameof(rowIndex));
var record = Activator.CreateInstance(model);
var properties = model.GetProperties();
var ts = structure;
var r = rowIndex;
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(record, new object[] { query.Value(r, attribute.Field) });
}
else if (pt.Equals(typeof(DateTime)))
{
var value = query.Value(r, attribute.Field);
if (value != null) setter.Invoke(record, new object[] { query.Value(r, attribute.Field) });
}
else if (pt.Equals(typeof(byte[])))
{
setter.Invoke(record, new object[] { (byte[])query.Value(r, attribute.Field) });
}
else if (pt.Equals(typeof(byte)))
{
setter.Invoke(record, new object[] { Byte(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(sbyte)))
{
setter.Invoke(record, new object[] { SByte(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(short)))
{
setter.Invoke(record, new object[] { Int16(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(ushort)))
{
setter.Invoke(record, new object[] { UInt16(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(int)))
{
setter.Invoke(record, new object[] { Int32(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(uint)))
{
setter.Invoke(record, new object[] { UInt32(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(long)))
{
setter.Invoke(record, new object[] { Int64(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(ulong)))
{
setter.Invoke(record, new object[] { UInt64(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(float)))
{
setter.Invoke(record, new object[] { Single(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(double)))
{
setter.Invoke(record, new object[] { Double(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(decimal)))
{
setter.Invoke(record, new object[] { Decimal(query.Text(r, attribute.Field)) });
}
else if (pt.Equals(typeof(string)))
{
setter.Invoke(record, new object[] { query.Text(r, attribute.Field) });
}
else
{
try
{
setter.Invoke(record, new object[] { query.Value(r, attribute.Field) });
}
catch { }
}
}
var iRecord = record as IRecord;
return iRecord;
}
#endregion
#region IOrm
/// 查询记录。
/// 数据库对象。
/// 记录模型。
/// SQL 语句。
public static Result> Query(IDatabaseQuery database, Type model, string sql)
{
if (database == null) return new Result>("数据库无效。");
if (model == null) return new Result>("模型类型无效。");
if (string.IsNullOrEmpty(sql)) return new Result>("SQL 语句无效。");
using (var query = database.Query(sql) as Query)
{
if (query == null) return new Result>("查询实例无效。");
if (query.Exception != null) return new Result>(query.Exception);
try
{
var list = Fill(query, model);
return new Result>(list);
}
catch (Exception ex)
{
return new Result>(ex);
}
}
}
/// 查询记录。
/// 记录模型。
/// 数据库对象。
/// SQL 语句。
public static Result> Query(IDatabaseQuery database, string sql) where T : class, IRecord, new() => As(Query(database, typeof(T), sql));
/// 查询记录。
/// 数据库对象。
/// 记录模型。
/// 生成 SQL 语句的函数,传入参数为表名。
public static Result> Query(IDatabaseQuery database, Type model, Func sqlGetter)
{
if (sqlGetter == null) return new Result>("SQL 语句获取函数无效。");
try
{
var tableName = TableStructure.ParseModel(model).Table;
if (string.IsNullOrEmpty(tableName)) return new Result>("表名无效。");
return Query(database, model, sqlGetter(tableName));
}
catch (Exception ex)
{
return new Result>(ex);
}
}
/// 查询记录。
/// 记录模型。
/// 数据库对象。
/// 生成 SQL 语句的函数,传入参数为表名。
public static Result> Query(IDatabaseQuery database, Func sqlGetter) where T : class, IRecord, new() => As(Query(database, typeof(T), sqlGetter));
/// 获取具有指定主键的记录。
/// 数据库对象。
/// 记录模型。
/// 主键。
/// 生成 SQL 语句的函数,传入参数为表名和主键值。
public static Result Get(IDatabaseQuery database, Type model, string key, Func sqlGetter)
{
if (sqlGetter == null) return new Result("SQL 语句获取函数无效。");
var safetyKey = TextUtility.SafeKey(key);
if (string.IsNullOrEmpty(safetyKey)) return new Result("主键无效。");
var query = null as IQuery;
var record = null as IRecord;
try
{
var ts = TableStructure.ParseModel(model);
var tableName = ts.Table;
if (string.IsNullOrEmpty(tableName)) return new Result("表名无效。");
var sql = sqlGetter(tableName, safetyKey);
query = database.Query(sql);
if (query.Table == null) return new Result("没有获取到记录。");
record = Row(query, 0, model, ts);
}
catch (Exception ex)
{
RuntimeUtility.Dispose(query);
return new Result(ex);
}
RuntimeUtility.Dispose(query);
if (record == null) return new Result("没有获取到记录。");
return new Result(record);
}
/// 获取具有指定主键的记录。
/// 记录模型。
/// 数据库对象。
/// 主键。
/// 生成 SQL 语句的函数,传入参数为表名和主键值。
public static Result Get(IDatabaseQuery database, string key, Func sqlGetter) where T : class, IRecord, new() => As(Get(database, typeof(T), key, sqlGetter));
/// 获取主键。
/// 数据库对象。
/// 记录模型。
/// 生成 SQL 语句的函数,传入参数为表名。
public static Result> Keys(IDatabaseQuery database, Type model, Func sqlGetter)
{
if (database == null) return new Result>("数据库无效。");
if (model == null) return new Result>("模型类型无效。");
if (sqlGetter == null) return new Result>("SQL 语句获取函数无效。");
var tableStructure = null as TableStructure;
try
{
tableStructure = TableStructure.ParseModel(model);
}
catch (Exception ex)
{
return new Result>(ex);
}
var tableName = tableStructure.Table;
if (string.IsNullOrEmpty(tableName)) return new Result>("表名无效。");
// var keyName = null as string;
// foreach (var column in tableStructure.Columns)
// {
// if (column.Key == "Key")
// {
// keyName = column.Value.Field;
// break;
// }
// }
// if (string.IsNullOrEmpty(keyName)) return Result>.Error("主键字段无效。");
// var sql = sqlGetter(tableName, keyName);
var sql = sqlGetter(tableName);
var query = null as IQuery;
try
{
query = database.Query(sql);
if (query == null) return new Result>("查询实例无效。");
var list = new List(query.Rows);
for (var r = 0; r < query.Rows; r++)
{
var key = TextUtility.SafeKey(query.Text(r));
if (string.IsNullOrEmpty(key)) continue;
list.Add(key);
}
query.Dispose();
list.Capacity = list.Count;
return new Result>(list);
}
catch (Exception ex)
{
RuntimeUtility.Dispose(query);
return new Result>(ex);
}
}
/// 获取主键。
/// 记录模型。
/// 数据库对象。
/// 生成 SQL 语句的函数,传入参数为表名。
public static Result> Keys(IDatabaseQuery database, Func sqlGetter) where T : IRecord
{
return Keys(database, typeof(T), sqlGetter);
}
#endregion
}
}