Пример #1
0
        internal KeyInfo(KeyAttribute attribute, IEnumerable <KeySegmentInfo> keySegments, RecordInfo record)
        {
            this.KeyNumber          = attribute.KeyNumber;
            this.DuplicateKeyOption = attribute.DuplicateKeyOption;
            this.IsModifiable       = attribute.IsModifiable;
            this.NullKeyOption      = attribute.NullKeyOption;
            this.Segments           = new KeySegmentCollection(keySegments);
            this.Length             = (ushort)this.Segments.Sum(s => s.Length);

            ushort position = 0;

            foreach (var keySegment in this.Segments)
            {
                keySegment.Position = position;
                keySegment.Key      = this;
                position           += keySegment.Length;
            }
            this.Record = record;
        }
Пример #2
0
        internal RecordInfo(Type recordType)
        {
            if (recordType.BaseType.GetGenericTypeDefinition() != typeof(Record <>))
            {
                throw new InvalidDefinitionException();
            }
            var classAttributes = recordType.GetCustomAttributes(false);
            var attribute       = classAttributes.SingleOrDefault(a => a is RecordAttribute) as RecordAttribute;

            if (attribute == null)
            {
                throw new InvalidDefinitionException();
            }

            this.Type                   = recordType;
            this.FixedLength            = attribute.FixedLength;
            this.PageSize               = attribute.PageSize;
            this.DuplicatedPointerCount = attribute.DuplicatedPointerCount;
            this.Allocation             = attribute.Allocation;
            this.VariableOption         = attribute.VariableOption;
            this.UsesIndexBalancing     = attribute.UsesIndexBalancing;
            this.IsCompressed           = attribute.IsCompressed;
            this.FreeSpaceThreshold     = attribute.FreeSpaceThreshold;
            this.SystemDataOption       = attribute.SystemDataOption;

            this.PrimaryKeyNumber = attribute.PrimaryKeyNumber;
            this.DefaultByte      = attribute.DefaultByte;
            this.DllPath          = attribute.DllPath;
            this.DependencyPaths  = attribute.DependencyPaths;

            this.PathType          = attribute.PathType;
            this.UriHost           = attribute.UriHost;
            this.UriUser           = attribute.UriUser;
            this.UriDbName         = attribute.UriDbName;
            this.UriTable          = attribute.UriTable;
            this.UriDbFile         = attribute.UriDbFile;
            this.UriFile           = attribute.UriFile;
            this.UriPassword       = attribute.UriPassword;
            this.UriPrompt         = attribute.UriPrompt;
            this.AbsolutePath      = attribute.AbsolutePath;
            this.RelativeDirectory = attribute.RelativeDirectory;
            this.RelativePath      = attribute.RelativePath;

            this.OwnerName       = attribute.OwnerName;
            this.OwnerNameOption = attribute.OwnerNameOption;
            this.OpenMode        = attribute.OpenMode;

            if (this.VariableOption == RecordVariableOption.NotVariable)
            {
                this.VariableFieldCapacity = 0;
            }
            else
            {
                this.VariableFieldCapacity = attribute.VariableFieldCapacity;
            }
            this.RejectCount = attribute.RejectCount;

            var properties = recordType
                             .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Where(p => p.CanRead || p.CanWrite);
            var fields = new List <FieldInfo>();

            foreach (var property in properties)
            {
                var propertyAttributes = property.GetCustomAttributes(false);
                var fieldAttribute     = propertyAttributes
                                         .SingleOrDefault(a => a is FieldAttribute) as FieldAttribute;
                if (fieldAttribute == null)
                {
                    continue;
                }
                if (fieldAttribute.Position + fieldAttribute.Length > attribute.FixedLength)
                {
                    throw new InvalidDefinitionException();
                }
                var field = new FieldInfo(fieldAttribute, this, propertyAttributes.Where(a => a is KeySegmentAttribute).Select(a => (KeySegmentAttribute)a), property);
                field.Name     = property.Name;
                field.FullName = recordType.FullName + "." + property.Name;
                fields.Add(field);
                Resource._fieldMemberInfoDictionary[property] = field;
                if (property.CanRead)
                {
                    Resource._fieldMemberInfoDictionary[property.GetGetMethod()] = field;
                }
                if (property.CanWrite)
                {
                    Resource._fieldMemberInfoDictionary[property.GetSetMethod()] = field;
                }
                Resource._fieldNameDictionary[field.FullName] = field;
            }
            foreach (var field in fields)
            {
                CheckKeyTypeLength(field);
            }
            this.Fields = fields.ToArray();

            var keyNumbers    = fields.SelectMany(f => f.KeySegments.Select(s => s.KeyNumber)).Distinct().OrderBy(n => n).ToArray();
            var keys          = new List <KeyInfo>();
            var keyAttributes = classAttributes
                                .Where(a => a is KeyAttribute)
                                .Select(a => (KeyAttribute)a);

            foreach (var keyNumber in keyNumbers)
            {
                var keyAttribute = keyAttributes
                                   .SingleOrDefault(a => a.KeyNumber == keyNumber);
                if (keyAttribute == null)
                {
                    keyAttribute = new KeyAttribute(keyNumber);
                }

                var keySegments = fields
                                  .Where(f => f.KeySegments.Any(s => s.KeyNumber == keyNumber))
                                  .Select(f => f.KeySegments.Single(s => s.KeyNumber == keyNumber))
                                  .OrderBy(s => s.Index);
                if (keySegments.Count() == 0 ||
                    keySegments
                    .Select((s, i) => s.Index != i)
                    .Any(r => r))
                {
                    throw new InvalidDefinitionException();
                }
                keySegments.Last().IsSegmentKey = false;
                var key = new KeyInfo(keyAttribute, keySegments, this);
                keys.Add(key);

                var matches = new bool[key.Length];
                foreach (var keySegment in keySegments)
                {
                    for (var i = 0; i < keySegment.Field.Length; i++)
                    {
                        if (matches[keySegment.Position + i])
                        {
                            throw new InvalidDefinitionException();
                        }
                        matches[keySegment.Position + i] = true;
                    }
                }
            }
            this.Keys = new KeyCollection(keys);

            foreach (var field in this.Fields)
            {
                var keyTypeAttribute = Resource.GetKeyTypeAttribute(field.KeyType);
                if (keyTypeAttribute != null)
                {
                    if (!keyTypeAttribute.ValidateLength(field.Length))
                    {
                        throw new InvalidDefinitionException();
                    }
                }
                if (field.NullType == NullType.Nullable)
                {
                    var nullFlagField = this.Fields.SingleOrDefault(f =>
                                                                    f.NullType == NullType.NullFlag &&
                                                                    f.Position == field.Position - 1);
                    if (nullFlagField == null ||
                        !field.KeySegments.All(s => nullFlagField.KeySegments.Any(ns => ns.Key == s.Key && ns.Index == s.Index - 1)))
                    {
                        throw new InvalidDefinitionException();
                    }
                    field.NullFlagField = nullFlagField;
                }
            }

            var isModArray = new bool[this.FixedLength];

            foreach (var keySegment in keys.Where(k => !k.IsModifiable).SelectMany(k => k.Segments))
            {
                for (var i = 0; i < keySegment.Field.Length; i++)
                {
                    isModArray[keySegment.Field.Position + i] = true;
                }
            }
            foreach (var field in this.Fields)
            {
                for (var i = 0; i < field.Length; i++)
                {
                    if (isModArray[field.Position + i])
                    {
                        field.IsModifiable = false;
                        break;
                    }
                }
            }
        }