public static PCache FromFile(string filename) { PCache data = new PCache(); List <string> header; long offset; using (var stream = File.OpenRead(filename)) { GetHeader(stream, out offset, out header); } if (header == null || header[0] != "pcache") { throw new Exception("Invalid header : missing magic number"); } Format format = (Format)int.MaxValue; data.elementCount = 0; data.properties = new List <PropertyDesc>(); foreach (string line in header) { var words = line.Split(' '); switch (words[0].ToLower()) { case "comment": //do nothing break; case "format": if (words.Length != 3) { throw new Exception("Invalid format description :" + line); } switch (words[1]) { case "ascii": format = Format.Ascii; break; case "binary": format = Format.Binary; break; default: throw new Exception("Invalid Format :" + words[1]); } break; case "elements": if (words.Length != 2) { throw new Exception("Invalid element description :" + line); } if (!int.TryParse(words[1], out data.elementCount)) { throw new Exception("Invalid element count :" + words[1]); } break; case "property": if (words.Length != 3) { throw new Exception("Invalid property description :" + line); } string property = words[2]; string component = GetComponentName(property); int idx = GetComponentIndex(property); string type = words[1]; int stride = GetPropertySize(type); if (stride == 0) { throw new Exception("Invalid Type for " + property + " property : " + type); } PropertyDesc prop = new PropertyDesc() { Name = property, Type = type, ComponentName = component, ComponentIndex = idx, Stride = stride }; data.properties.Add(prop); break; case "end_header": if (words.Length != 1) { throw new Exception("Invalid end_header description :" + line); } break; } } data.buckets = new List <List <object> >(); foreach (var property in data.properties) { data.buckets.Add(new List <object>(data.elementCount)); } if (format == Format.Binary) { using (var binaryReader = new BinaryReader(File.OpenRead(filename))) { binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin); for (int i = 0; i < data.elementCount; i++) { for (int j = 0; j < data.properties.Count; j++) { var prop = data.properties[j]; switch (prop.Type) { case "short": data.buckets[j].Add(binaryReader.ReadInt16()); break; case "ushort": data.buckets[j].Add(binaryReader.ReadUInt16()); break; case "int": data.buckets[j].Add(binaryReader.ReadInt32()); break; case "uint": data.buckets[j].Add(binaryReader.ReadUInt32()); break; case "char": data.buckets[j].Add(binaryReader.ReadSByte()); break; case "uchar": data.buckets[j].Add(binaryReader.ReadByte()); break; case "float": data.buckets[j].Add(binaryReader.ReadSingle()); break; case "double": data.buckets[j].Add(binaryReader.ReadDouble()); break; } } } } } else if (format == Format.Ascii) { string[] lines = null; using (var reader = new StreamReader(File.OpenRead(filename))) { reader.BaseStream.Seek(offset, SeekOrigin.Begin); lines = reader.ReadToEnd().Replace("\r", "").Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); } if (lines.Length != data.elementCount) { throw new InvalidOperationException(string.Format("Bad item amount, {0} expected in header, found {1}", data.elementCount, lines.Length)); } for (int i = 0; i < data.elementCount; i++) { string line = lines[i]; string[] elements = line.Split(' '); for (int j = 0; j < data.properties.Count; j++) { var prop = data.properties[j]; switch (prop.Type) { case "short": data.buckets[j].Add(short.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "ushort": data.buckets[j].Add(ushort.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "int": data.buckets[j].Add(int.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "uint": data.buckets[j].Add(uint.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "char": data.buckets[j].Add(sbyte.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "uchar": data.buckets[j].Add(byte.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "float": data.buckets[j].Add(float.Parse(elements[j], CultureInfo.InvariantCulture)); break; case "double": data.buckets[j].Add(double.Parse(elements[j], CultureInfo.InvariantCulture)); break; } } } } return(data); }
private static void CollectPropertyInfo(PropertyInfo[] piArr, ClassDesc clsDesc, DbClassLoader dbClsLoader) { for (int i = 0; i < piArr.Length; i++) { PropertyInfo pi = piArr[i]; object[] atbArr = pi.GetCustomAttributes(typeof(DbColumnAttribute), false); object[] splitAtbArr = pi.GetCustomAttributes(typeof(DbSplitColumnAttribute), false); object[] splitRangeAtbArr = pi.GetCustomAttributes(typeof(DbSplitRangeAttribute), false); object[] mergeAtbArr = pi.GetCustomAttributes(typeof(DbMergeColumnAttribute), false); if (atbArr.Length != 0) { // 检测和获取主键列信息 var atb = atbArr[0] as DbColumnAttribute; if (atb.KeyColumn) { // 主键一定不是外键 if (atb.IsForeignKey) { throw new Exception("Pk can't be foreign key."); } // 只有一个主键 if (clsDesc.keyAttribute != null) { Debug.LogError(string.Format("Key column already exist {0}", atb.ColumnName)); } else { clsDesc.keyAttribute = atb; } } if (atb.IsForeignKey) { // 保存外键信息 var foreignKeyPropertyDesc = new ForeignKeyPropertyDesc(); foreignKeyPropertyDesc.attribute = atb; foreignKeyPropertyDesc.propertyInfo = pi; var refClsDesc = dbClsLoader.GetClassDesc(atb.ReferencedClass); foreignKeyPropertyDesc.referencedPropertyInfo = refClsDesc.GetPropertyInfo(atb.ReferencedColumn).propertyInfo; clsDesc.rootKeyAttribute = atb; clsDesc.fkPropertyInfoList.Add(foreignKeyPropertyDesc); } if (clsDesc.propertyInfoDic.ContainsKey(atb.ColumnName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", atb.ColumnName)); } else { var propertyDesc = new PropertyDesc(); propertyDesc.attribute = atb; propertyDesc.propertyInfo = pi; clsDesc.propertyInfoDic.Add(atb.ColumnName, propertyDesc); } continue; } else if (splitAtbArr.Length != 0) { var splitAtb = splitAtbArr[0] as DbSplitColumnAttribute; if (clsDesc.splitPropertyInfoDic.ContainsKey(splitAtb.ColumnName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", splitAtb.ColumnName)); } else { var propertyDesc = new SplitPropertyDesc(); propertyDesc.splitAttribute = splitAtb; propertyDesc.propertyInfo = pi; clsDesc.splitPropertyInfoDic.Add(splitAtb.ColumnName, propertyDesc); } continue; } else if (mergeAtbArr.Length != 0) { var mergeAtb = mergeAtbArr[0] as DbMergeColumnAttribute; if (clsDesc.mergePropertyInfoDic.ContainsKey(mergeAtb.FieldTypeName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", mergeAtb.FieldTypeName)); } else { var propertyDesc = new MergePropertyDesc(); propertyDesc.mergeAttribute = mergeAtb; propertyDesc.propertyInfo = pi; clsDesc.mergePropertyInfoDic.Add(mergeAtb.FieldTypeName, propertyDesc); } continue; } else if (splitRangeAtbArr.Length != 0) { var splitRangeAtb = splitRangeAtbArr[0] as DbSplitRangeAttribute; if (clsDesc.splitRangePropertyInfoDic.ContainsKey(splitRangeAtb.ColumnName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", splitRangeAtb.ColumnName)); } else { var propertyDesc = new SplitRangePropertyDesc(); propertyDesc.rangeAttribute = splitRangeAtb; propertyDesc.propertyInfo = pi; clsDesc.splitRangePropertyInfoDic.Add(splitRangeAtb.ColumnName, propertyDesc); } } // 获取子表信息 atbArr = pi.GetCustomAttributes(typeof(DbColumnSubTableAttribute), false); if (atbArr.Length != 0) { var atb = atbArr[0] as DbColumnSubTableAttribute; var subTablePropertyDesc = new SubTablePropertyDesc(); subTablePropertyDesc.attribute = atb; subTablePropertyDesc.propertyInfo = pi; clsDesc.subTablePropertyDescList.Add(subTablePropertyDesc); continue; } } }
private static JsonElement GetValue(this IDictionary <string, JsonElement> obj, PropertyDesc property) { if (property.ParentPath.Length > 0) { if (!obj.TryGetValue(property.ParentPath[0], out var parent)) { return(JsonNull); } for (var i = 1; i < property.ParentPath.Length; i++) { if (!parent.TryGetProperty(property.ParentPath[1], out parent)) { return(JsonNull); } } if (parent.TryGetProperty(property.OriginalName, out var result)) { return(result); } } else if (obj.TryGetValue(property.OriginalName, out var result)) { return(result); } return(JsonNull); }
private List<PropertyDesc> GetPropertyDesc( List<PropertyInfo> Props ) { List<PropertyDesc> results = new List<PropertyDesc>(); foreach ( PropertyInfo prop in Props ) { PropertyDesc desc = new PropertyDesc { PropertyName = prop.Name, PropertyType = prop.PropertyType, ColumnName = this.GetColumnName( prop ), Length = this.GetColumnLength( prop ) }; desc.IsPrimaryKey = prop.GetCustomAttributes(typeof(KeyAttribute), inherit: true).FirstOrDefault() != null; desc.Nullable = !typeof(ValueType).IsAssignableFrom( prop.PropertyType ) || prop.PropertyType == typeof(char); if ( prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ) { Type[] genericArgs = prop.PropertyType.GetGenericArguments(); if ( genericArgs != null && genericArgs.Length == 1 ) { desc.PropertyType = genericArgs[0]; desc.Nullable = true; } } bool hasTimestamp = prop.GetCustomAttributes( typeof( TimestampAttribute ), inherit:true ).FirstOrDefault() != null; if ( hasTimestamp ) { desc.Nullable = false; // The entity is nullable, but the db isn't so "fake" like the entity isn't either } if ( this.HasRequiredAttribute( prop ) ) { desc.Nullable = false; } results.Add( desc ); } return results; }