public static void FindAddIndexes(SqoTypeInfo ti, FieldSqoInfo fi) { bool found = false; if (fi.FInfo != null) { if (typeof(IList).IsAssignableFrom(fi.FInfo.FieldType))//ignore { return; } object[] customAttStr = fi.FInfo.GetCustomAttributes(typeof(IndexAttribute), false); if (customAttStr.Length > 0) { ti.IndexedFields.Add(fi); found = true; } else { PropertyInfo pi = MetaHelper.GetAutomaticProperty(fi.FInfo); if (pi != null) { customAttStr = pi.GetCustomAttributes(typeof(IndexAttribute), false); if (customAttStr.Length > 0) { ti.IndexedFields.Add(fi); found = true; } } } if (!found)//look in configuration { if (SiaqodbConfigurator.Indexes != null) { if (SiaqodbConfigurator.Indexes.ContainsKey(ti.Type)) { if (SiaqodbConfigurator.Indexes[ti.Type].Contains(fi.Name)) { ti.IndexedFields.Add(fi); } } } } } }
public static void FindAddConstraints(SqoTypeInfo ti, FieldSqoInfo fi) { bool found = false; if (fi.FInfo != null)//if is null can be from OLD schema version and now field is missing { object[] customAttStr = fi.FInfo.GetCustomAttributes(typeof(UniqueConstraint), false); if (customAttStr.Length > 0) { ti.UniqueFields.Add(fi); found = true; } else { PropertyInfo pi = MetaHelper.GetAutomaticProperty(fi.FInfo); if (pi != null) { customAttStr = pi.GetCustomAttributes(typeof(UniqueConstraint), false); if (customAttStr.Length > 0) { ti.UniqueFields.Add(fi); found = true; } } } if (!found)//look in configuration { if (SiaqodbConfigurator.Constraints != null) { if (SiaqodbConfigurator.Constraints.ContainsKey(ti.Type)) { if (SiaqodbConfigurator.Constraints[ti.Type].Contains(fi.Name)) { ti.UniqueFields.Add(fi); } } } } } }
/// <summary> /// Return true if is same /// </summary> /// <param name="actual"></param> /// <param name="fromDB"></param> /// <returns></returns> public static bool CompareSqoTypeInfos(SqoTypeInfo actual, SqoTypeInfo fromDB) { if (fromDB.Header.version > -30)//version < 3.0 { return(false); } if (actual.Header.NrFields != fromDB.Header.NrFields) { return(false); } else { foreach (FieldSqoInfo fi in actual.Fields) { FieldSqoInfo fiDB = FindSqoField(fromDB.Fields, fi.Name); if (fiDB == null) { return(false); } else { if (fi.AttributeTypeId != fiDB.AttributeTypeId) { return(false); } else if (fi.Header.Length != fiDB.Header.Length) { return(false); } } } } return(true); }
public static SqoTypeInfo GetSqoTypeInfo(Type t) { List <FieldInfo> fi = new List <FieldInfo>(); Dictionary <FieldInfo, PropertyInfo> automaticProperties = new Dictionary <FieldInfo, PropertyInfo>(); FindFields(fi, automaticProperties, t); SqoTypeInfo ti = new SqoTypeInfo(t); int lengthOfRecord = sizeof(int); //=> +OID size; int i = 0; int nrOrder = 1; for (i = 0; i < fi.Count; i++) { int maxLength = -1; Type fType = fi[i].FieldType; bool isText = false; if (IsSpecialType(fType) || fi[i].IsLiteral || fi[i].IsInitOnly) { continue; } //TODO:check ignore for properties(automatic properties) #region Ignore field object[] customAtt = fi[i].GetCustomAttributes(typeof(IgnoreAttribute), false); if (customAtt.Length > 0) { continue; } if (automaticProperties.ContainsKey(fi[i])) { customAtt = automaticProperties[fi[i]].GetCustomAttributes(typeof(IgnoreAttribute), false); if (customAtt.Length > 0) { continue; } } //check config if (SiaqodbConfigurator.Ignored != null) { if (SiaqodbConfigurator.Ignored.ContainsKey(ti.Type)) { if (SiaqodbConfigurator.Ignored[ti.Type].Contains(fi[i].Name)) { continue; } } } #endregion #region MaxLength for String Type elementType = fType.GetElementType(); if (typeof(IList).IsAssignableFrom(fType)) { if (elementType == null) { elementType = fType.GetProperty("Item").PropertyType; } } if (fType == typeof(string) || elementType == typeof(string)) { //throw new SiaqodbException("String Type must have MaxLengthAttribute set"); //TODO: set default 100 MaxLength for a string??? activate when automatically schema supported maxLength = 100; bool maxLengthFound = false; object[] customAttStr = fi[i].GetCustomAttributes(typeof(MaxLengthAttribute), false); if (customAttStr.Length > 0) { MaxLengthAttribute m = customAttStr[0] as MaxLengthAttribute; maxLength = m.maxLength; maxLengthFound = true; } else if (automaticProperties.ContainsKey(fi[i])) { customAttStr = automaticProperties[fi[i]].GetCustomAttributes(typeof(MaxLengthAttribute), false); if (customAttStr.Length > 0) { MaxLengthAttribute m = customAttStr[0] as MaxLengthAttribute; maxLength = m.maxLength; maxLengthFound = true; } } if (!maxLengthFound) { //check config if (SiaqodbConfigurator.MaxLengths != null) { if (SiaqodbConfigurator.MaxLengths.ContainsKey(ti.Type)) { if (SiaqodbConfigurator.MaxLengths[ti.Type].ContainsKey(fi[i].Name)) { maxLength = SiaqodbConfigurator.MaxLengths[ti.Type][fi[i].Name]; } } } } //isText for saving dynamic length type object[] customAttStrText = fi[i].GetCustomAttributes(typeof(TextAttribute), false); if (customAttStrText.Length > 0) { isText = true; maxLength = GetSizeOfField(MetaExtractor.byteID);//get byte type size(simulate array byte[]) } else if (automaticProperties.ContainsKey(fi[i])) { customAttStrText = automaticProperties[fi[i]].GetCustomAttributes(typeof(TextAttribute), false); if (customAttStrText.Length > 0) { isText = true; maxLength = GetSizeOfField(MetaExtractor.byteID);//get byte type size(simulate array byte[]) } } if (!isText) { //check config if (SiaqodbConfigurator.Texts != null) { if (SiaqodbConfigurator.Texts.ContainsKey(ti.Type)) { if (SiaqodbConfigurator.Texts[ti.Type].Contains(fi[i].Name)) { isText = true; } } } } } #endregion int fTypeId = -1; if (FieldIsDocument(ti, fi[i], automaticProperties)) { fTypeId = documentID; } else { fTypeId = GetAttributeType(fType); } if (fTypeId == -1) { throw new NotSupportedTypeException(@"Field:" + fi[i].Name + " of class:" + t.Name + " has type:" + fType.Name + @" which is not supported , check documentation about types supported: http://siaqodb.com/?page_id=620 "); } if (isText) { fTypeId = MetaExtractor.textID; } FieldSqoInfo ai = new FieldSqoInfo(fTypeId, fType); ai.Name = fi[i].Name; ai.FInfo = fi[i]; ai.IsText = isText; ai.Header.Length = maxLength == -1 ? GetSizeOfField(fTypeId) : MetaHelper.PaddingSize(maxLength); if (fType.IsGenericType() && fTypeId != documentID) { Type genericTypeDef = fType.GetGenericTypeDefinition(); if (genericTypeDef == typeof(Nullable <>)) { ai.Header.Length++;//increase Length to be able to store IsNull byte } else if (typeof(IList).IsAssignableFrom(fType)) { ai.Header.Length += ExtraSizeForArray;//store OID from rawdata + number of elements ai.AttributeTypeId += MetaExtractor.ArrayTypeIDExtra; } } else if (fType.IsArray && fTypeId != documentID) { if (ti.Type.IsGenericType() && ti.Type.GetGenericTypeDefinition() == typeof(Indexes.BTreeNode <>) && (ai.Name == "Keys" || ai.Name == "_childrenOIDs")) { ai.AttributeTypeId += MetaExtractor.FixedArrayTypeId; if (ai.Name == "Keys") { ai.Header.Length = ai.Header.Length * Indexes.BTreeNode <int> .KEYS_PER_NODE; } else { ai.Header.Length = ai.Header.Length * Indexes.BTreeNode <int> .CHILDREN_PER_NODE; } } else { ai.Header.Length += ExtraSizeForArray;//store OID from rawdata + number of elements ai.AttributeTypeId += MetaExtractor.ArrayTypeIDExtra; } } else if (ai.IsText) { ai.Header.Length += ExtraSizeForArray; } ai.Header.RealLength = maxLength == -1 ? GetAbsoluteSizeOfField(fTypeId) : maxLength; ai.Header.PositionInRecord = lengthOfRecord; ai.Header.SizeOfName = ByteConverter.SerializeValueType(ai.Name, typeof(string), ti.Header.version).Length; ti.Fields.Add(ai); lengthOfRecord += ai.Header.Length; nrOrder++; FindAddConstraints(ti, ai); FindAddIndexes(ti, ai); } ti.Header.lengthOfRecord = lengthOfRecord; ti.Header.typeNameSize = ByteConverter.SerializeValueType(ti.TypeName, typeof(string), ti.Header.version).Length; ti.Header.NrFields = nrOrder - 1; ti.Header.headerSize = sizeof(int) + sizeof(int) + sizeof(long) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + (ti.Header.NrFields * FieldSize) + ti.Header.typeNameSize; ti.Header.positionFirstRecord = ti.Header.headerSize; //cacheOfTypes[t] = ti; return(ti); }
public static SqoTypeInfo GetIndexSqoTypeInfo(Type t, FieldSqoInfo indexItemField) { List <FieldInfo> fi = new List <FieldInfo>(); Dictionary <FieldInfo, PropertyInfo> automaticProperties = new Dictionary <FieldInfo, PropertyInfo>(); FindFields(fi, automaticProperties, t); SqoTypeInfo ti = new SqoTypeInfo(t); int lengthOfRecord = sizeof(int); //=> +OID size; int i = 0; int nrOrder = 1; for (i = 0; i < fi.Count; i++) { int maxLength = -1; Type fType = fi[i].FieldType; bool isText = false; int fTypeId = -1; if (fType == typeof(object))//Item field { fTypeId = indexItemField.AttributeTypeId; fType = indexItemField.AttributeType; if (indexItemField.AttributeType == typeof(string)) { isText = true; maxLength = GetSizeOfField(MetaExtractor.byteID);//get byte type size(simulate array byte[]) } } else { fTypeId = GetAttributeType(fType); } if (isText) { fTypeId = MetaExtractor.textID; } FieldSqoInfo ai = new FieldSqoInfo(fTypeId, fType); ai.Name = fi[i].Name; ai.FInfo = fi[i]; ai.IsText = isText; ai.Header.Length = maxLength == -1 ? GetSizeOfField(fTypeId) : MetaHelper.PaddingSize(maxLength); if (fType.IsGenericType()) { Type genericTypeDef = fType.GetGenericTypeDefinition(); if (genericTypeDef == typeof(Nullable <>)) { ai.Header.Length++;//increase Length to be able to store IsNull byte } else { ai.Header.Length += ExtraSizeForArray;//store OID from rawdata + number of elements ai.AttributeTypeId += MetaExtractor.ArrayTypeIDExtra; } } else if (fType.IsArray) { ai.Header.Length += ExtraSizeForArray;//store OID from rawdata + number of elements ai.AttributeTypeId += MetaExtractor.ArrayTypeIDExtra; } else if (ai.IsText) { ai.Header.Length += ExtraSizeForArray; } ai.Header.RealLength = maxLength == -1 ? GetAbsoluteSizeOfField(fTypeId) : maxLength; ai.Header.PositionInRecord = lengthOfRecord; ai.Header.SizeOfName = ByteConverter.SerializeValueType(ai.Name, typeof(string), ti.Header.version).Length; ti.Fields.Add(ai); lengthOfRecord += ai.Header.Length; nrOrder++; } ti.Header.lengthOfRecord = lengthOfRecord; ti.Header.typeNameSize = ByteConverter.SerializeValueType(ti.TypeName, typeof(string), ti.Header.version).Length; ti.Header.NrFields = nrOrder - 1; ti.Header.headerSize = sizeof(int) + sizeof(int) + sizeof(long) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int) + (ti.Header.NrFields * FieldSize) + ti.Header.typeNameSize; ti.Header.positionFirstRecord = ti.Header.headerSize; //cacheOfTypes[t] = ti; return(ti); }