private static void CreateTableSchema(SchemaTable schema, DbBaseProvider dbprovider, string tableName) { var list = new List <DbColumn>(); foreach (var keypair in schema.Columns) { var field = keypair.Value; var column = new DbColumn(); column.Id = field.Id; column.Name = field.Name; column.Type = field.ColumnType; column.Length = field.ColumnLength; column.Scale = field.ColumnScale; column.Isnullable = field.Isnullable; column.IsKey = field.IsKey; column.IsUnique = field.IsUnique; column.DbType = field.DbType.ToString(); column.IsIdentity = field.IsIdentity; column.IdentityNo = field.IdentityNo; list.Add(column); } list.Sort((a, b) => a.Id.CompareTo(b.Id)); dbprovider.CreateTable(tableName, list.ToArray()); if (schema.Indexs != null && schema.Indexs.Length > 0) { dbprovider.CreateIndexs(tableName, schema.Indexs); } }
private static void SetPeriodTime(SchemaTable schema) { if (schema.AccessLevel == AccessLevel.ReadOnly || !schema.IsExpired) { schema.PeriodTime = 0; return; } switch (schema.CacheType) { case CacheType.None: break; case CacheType.Entity: schema.PeriodTime = CacheGlobalPeriod; break; case CacheType.Dictionary: schema.PeriodTime = CacheUserPeriod; break; case CacheType.Queue: schema.PeriodTime = CacheQueuePeriod; break; default: break; } }
/// <summary> /// Export entity schema for client sync. /// </summary> /// <param name="schema"></param> /// <returns></returns> public static string ExportSync(SchemaTable schema) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("g__schema[\"{0}\"] = ", schema.EntityName); sb.AppendLine("{"); var columns = schema.GetColumns(); int index = 0; int endIndex = columns.Count - 1; int depth = 1; foreach (var col in columns) { bool isEnd = index == endIndex; if (col.HasChild) { WriteChildSchema(sb, col, depth + 1, isEnd); } else { WriteColumnSchema(sb, col, depth, isEnd); } index++; } sb.AppendLine("}"); return(sb.ToString()); }
/// <summary> /// Get entity schema. /// </summary> /// <param name="type"></param> /// <param name="schema"></param> /// <returns></returns> public static bool TryGet(Type type, out SchemaTable schema) { if (type == null) { throw new ArgumentNullException("type"); } return(TryGet(type.FullName, out schema)); }
/// <summary> /// 增加架构配置表,存在则更新 /// </summary> /// <param name="type"></param> /// <param name="schema"></param> public static void AddSchema(Type type, SchemaTable schema) { if (type != null && !string.IsNullOrEmpty(type.FullName)) { SchemaTable oldValue; if (SchemaSet.TryGetValue(type.FullName, out oldValue)) { SchemaSet.TryUpdate(type.FullName, schema, oldValue); } else { SchemaSet.TryAdd(type.FullName, schema); } } }
/// <summary> /// 检测数据表结构变动 /// </summary> /// <param name="schema"></param> private static void CheckTableSchema(SchemaTable schema) { string tableName = schema.GetTableName(DateTime.Now); try { if (DbConnectionProvider.Count == 0) { //not seting connection. return; } DbBaseProvider dbprovider = DbConnectionProvider.CreateDbProvider(schema); if (dbprovider == null) { if (schema.StorageType.HasFlag(StorageType.ReadOnlyDB) || schema.StorageType.HasFlag(StorageType.ReadWriteDB) || schema.StorageType.HasFlag(StorageType.WriteOnlyDB)) { TraceLog.WriteError("Not found DB connection key \"{1}\" of the {0} entity.", schema.EntityName, schema.ConnectKey); } return; } DbColumn[] columns; if (dbprovider.CheckTable(tableName, out columns)) { ModifyTableSchema(schema, dbprovider, tableName, columns); } else { CreateTableSchema(schema, dbprovider, tableName); } } catch (Exception ex) { TraceLog.WriteError("CheckTableSchema {0} error:{1}", tableName, ex); } }
private static void ModifyTableSchema(SchemaTable schema, DbBaseProvider dbprovider, string tableName, DbColumn[] columns) { var list = new List <DbColumn>(); foreach (var keypair in schema.Columns) { var field = keypair.Value; string name = field.Name; var dbColumn = Array.Find(columns, p => MathUtils.IsEquals(p.Name, name, true)); if (dbColumn == null) { dbColumn = new DbColumn(); dbColumn.Id = field.Id; dbColumn.Name = name; dbColumn.Type = field.ColumnType; dbColumn.Length = field.ColumnLength; dbColumn.Scale = field.ColumnScale; dbColumn.Isnullable = field.Isnullable; dbColumn.IsKey = field.IsKey; dbColumn.IsUnique = field.IsUnique; dbColumn.DbType = field.DbType.ToString(); dbColumn.IsIdentity = field.IsIdentity; dbColumn.IdentityNo = field.IdentityNo; list.Add(dbColumn); } else { var fieldType = field.ColumnType; //no modify type: text,blob,byte[], enum,list,dict if ( //对象序列化类型 (field.IsSerialized && ( (field.DbType == ColumnDbType.Varchar && (dbColumn.Type != typeof(string) || (field.ColumnLength > 0 && dbColumn.Length != field.ColumnLength))) || (field.DbType != ColumnDbType.Varchar && (dbColumn.Type != typeof(string) || dbColumn.DbType.StartsWith("varchar"))) ) ) || //特殊值类型 (dbColumn.Type == typeof(decimal) && field.ColumnScale > 0 && dbColumn.Scale != field.ColumnScale) || (fieldType.IsEnum && dbColumn.Type != typeof(int)) || (fieldType == typeof(ushort) && dbColumn.Type != typeof(short)) || (fieldType == typeof(uint) && dbColumn.Type != typeof(int)) || (fieldType == typeof(ulong) && dbColumn.Type != typeof(long)) || (fieldType == typeof(string) && field.ColumnLength > 0 && dbColumn.Length != field.ColumnLength) || //非对象类型 (!field.IsSerialized && !fieldType.IsEnum && !field.IsDictionary && !field.IsList && fieldType != typeof(byte[]) && fieldType != typeof(ushort) && fieldType != typeof(uint) && fieldType != typeof(ulong) && dbColumn.Type != fieldType ) || //check key ((field.IsKey && dbColumn.KeyNo == 0) || (!field.IsKey && dbColumn.KeyNo > 0)) ) { dbColumn.Type = fieldType; dbColumn.Length = field.ColumnLength; dbColumn.Scale = field.ColumnScale; dbColumn.Isnullable = field.Isnullable; dbColumn.IsKey = field.IsKey; dbColumn.DbType = field.DbType.ToString(); dbColumn.IsIdentity = field.IsIdentity; dbColumn.IdentityNo = field.IdentityNo; dbColumn.IsModify = true; list.Add(dbColumn); } } } if (list.Count > 0) { list.Sort((a, b) => a.Id.CompareTo(b.Id)); dbprovider.CreateColumn(tableName, list.ToArray()); } }
/// <summary> /// Get schema for typename /// </summary> /// <param name="typeName"></param> /// <param name="schema"></param> /// <returns></returns> public static bool TryGet(string typeName, out SchemaTable schema) { typeName = RedisConnectionPool.DecodeTypeName(typeName); return(SchemaSet.TryGetValue(typeName, out schema)); }
/// <summary> /// Get entity schema. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="schema"></param> /// <returns></returns> public static bool TryGet <T>(out SchemaTable schema) { return(TryGet(typeof(T).FullName, out schema)); }
/// <summary> /// 初始化架构信息 /// </summary> /// <param name="type"></param> /// <param name="schema"></param> public static void InitSchema(Type type, SchemaTable schema) { var section = GetEntitySection(); if (type == null) { throw new ArgumentNullException("type"); } if (type.IsSubclassOf(typeof(LogEntity)) && string.IsNullOrEmpty(schema.NameFormat)) { schema.NameFormat = section.LogTableNameFormat; } if (!string.IsNullOrEmpty(schema.NameFormat) && !Exits(type)) { _dynamicTables.Enqueue(schema); } //加载成员属性 HashSet <string> keySet = new HashSet <string>(); PropertyInfo[] propertyList = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); SchemaColumn column; int number = 0; foreach (PropertyInfo property in propertyList) { number++; //Ignore parent property bool isExtend = property.GetCustomAttributes <EntityFieldExtendAttribute>(false).Count() > 0; if (!isExtend && property.DeclaringType != property.ReflectedType) { continue; } column = new SchemaColumn(); var entityField = FindAttribute <EntityFieldAttribute>(property.GetCustomAttributes(false)); if (entityField != null) { column.Id = number; column.Name = string.IsNullOrEmpty(entityField.FieldName) ? property.Name : entityField.FieldName; column.IsIdentity = entityField.IsIdentity; column.IdentityNo = entityField.IdentityNo; column.IsKey = entityField.IsKey; column.IsUnique = entityField.IsUnique; column.ColumnLength = entityField.ColumnLength; column.ColumnScale = entityField.ColumnScale; column.Isnullable = entityField.Isnullable; column.FieldModel = entityField.FieldModel; column.Disable = entityField.Disable; column.MinRange = entityField.MinRange; column.MaxRange = entityField.MaxRange; column.IsSerialized = entityField.IsJsonSerialize; column.JsonDateTimeFormat = entityField.JsonDateTimeFormat; column.ColumnType = property.PropertyType; column.DbType = entityField.DbType; column.CanRead = property.CanRead; column.CanWrite = property.CanWrite; AddChildType(column); } else { //必须要加EntityField标识 continue; //column.Id = number; //column.Name = property.Name; //column.IsIdentity = false; //column.IsKey = string.Compare(property.Name, "id", true) == 0; //column.FieldModel = FieldModel.All; //column.ColumnType = property.PropertyType; //column.DbType = ColumnDbType.Varchar; } schema.Columns.TryAdd(column.Name, column); if (column.IsSerialized) { schema.HasObjectColumns = true; } if (column.IsKey) { keySet.Add(column.Name); } } //add modify time field if (section.EnableModifyTimeField && schema.AccessLevel == AccessLevel.ReadWrite) { column = new SchemaColumn(); column.Id = number; column.Name = "TempTimeModify"; column.Isnullable = true; column.FieldModel = FieldModel.All; column.ColumnType = typeof(DateTime); column.DbType = ColumnDbType.DateTime; column.JsonDateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss"; schema.Columns.TryAdd(column.Name, column); } schema.Keys = new string[keySet.Count]; keySet.CopyTo(schema.Keys, 0); CheckTableSchema(schema); AddSchema(type, schema); }
/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="isReset"></param> public static SchemaTable InitSchema(Type type, bool isReset = false) { SchemaTable schema; if (!isReset && TryGet(type, out schema)) { return(schema); } schema = new SchemaTable(); try { schema.IsEntitySync = type.GetCustomAttributes(typeof(EntitySyncAttribute), false).Length > 0; schema.EntityType = type; //加载表 var entityTable = FindAttribute <EntityTableAttribute>(type.GetCustomAttributes(false)); if (entityTable != null) { schema.AccessLevel = entityTable.AccessLevel; schema.StorageType |= entityTable.StorageType; schema.CacheType = entityTable.CacheType; schema.IncreaseStartNo = entityTable.IncreaseStartNo; schema.IsExpired = entityTable.IsExpired; schema.EntityName = string.IsNullOrEmpty(entityTable.TableName) ? type.Name : entityTable.TableName; schema.ConnectKey = string.IsNullOrEmpty(entityTable.ConnectKey) ? "" : entityTable.ConnectKey; schema.Indexs = entityTable.Indexs; schema.Condition = entityTable.Condition; schema.OrderColumn = entityTable.OrderColumn; //schema.DelayLoad = entityTable.DelayLoad; schema.NameFormat = entityTable.TableNameFormat; SetPeriodTime(schema); //model other set if (entityTable.IsExpired && entityTable.PeriodTime > 0) { schema.PeriodTime = entityTable.PeriodTime; } schema.Capacity = entityTable.Capacity; schema.PersonalName = entityTable.PersonalName; if (string.IsNullOrEmpty(schema.ConnectKey) && type == typeof(EntityHistory)) { schema.IsInternal = true; var dbPair = DbConnectionProvider.Find(DbLevel.Game); if (dbPair.Value == null) { dbPair = DbConnectionProvider.FindFirst(); } if (dbPair.Value != null) { schema.ConnectKey = dbPair.Key; schema.ConnectionProviderType = dbPair.Value.ProviderTypeName; schema.ConnectionString = dbPair.Value.ConnectionString; } //else //{ // TraceLog.WriteWarn("Not found Redis's history record of db connect config."); //} } } InitSchema(type, schema); } catch (Exception ex) { TraceLog.WriteError("InitSchema type:{0} error:\r\n{1}", type.FullName, ex); } //check cachetype if ((schema.CacheType == CacheType.Entity && !type.IsSubclassOf(typeof(ShareEntity))) || (schema.CacheType == CacheType.Dictionary && schema.AccessLevel == AccessLevel.ReadWrite && !type.IsSubclassOf(typeof(BaseEntity))) ) { throw new ArgumentException(string.Format("\"EntityTable.CacheType:{1}\" attribute of {0} class is error", type.FullName, schema.CacheType), "CacheType"); } return(schema); }
/// <summary> /// /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual int CompareTo(AbstractEntity other) { if (this == null && other == null) { return(0); } if (this == null && other != null) { return(-1); } if (this != null && other == null) { return(1); } int result = -1; SchemaTable schema = GetSchema(); if (schema != null) { //升序 foreach (var key in schema.Keys) { object x = this.GetPropertyValue(key); object y = other.GetPropertyValue(key); if (x is Enum || x is int || x is short || x is byte || x is bool || x is uint || x is ushort) { result = (x.ToInt()).CompareTo(y.ToInt()); } else if (x is string) { result = x.ToNotNullString().CompareTo(y.ToNotNullString()); } else if (x is decimal) { var diff = (decimal)x - (decimal)y; result = diff > 0 ? 1 : diff < 0 ? -1 : 0; } else if (x is double) { var diff = (double)x - (double)y; result = diff > 0 ? 1 : diff < 0 ? -1 : 0; } else if (x is long || x is ulong) { var diff = (long)x - (long)y; result = diff > 0 ? 1 : diff < 0 ? -1 : 0; } else if (x is float) { var diff = (float)x - (float)y; result = diff > 0 ? 1 : diff < 0 ? -1 : 0; } else if (x is DateTime) { result = DateTime.Compare((DateTime)x, (DateTime)y); } else { result = x.ToNotNullString().CompareTo(y.ToNotNullString()); } if (result != 0) { break; } } } return(result); }