コード例 #1
0
        KeyInfo GetKey()
        {
            if (this.ApiFilter != null)
            {
                var keys = Resource.GetRecordInfo(typeof(TRecord)).Keys;
                var maxKeySegmentCount = keys.Max(k => k.Segments.Count);

                IEnumerable <KeyInfo> enabledKeys = keys, remainedKeys = new KeyInfo[0];
                var enabledKeyList = new List <KeyInfo>();
                var priorityList = new List <uint>();

                var fields = this.ApiFilter
                             .SelectMany(filter => filter.GetFields().Select(field => new {
                    State = filter.State,
                    Field = field
                }))
                             .GroupBy(f => f.Field)
                             .Select(g => new {
                    Field    = g.Key,
                    Priority = GetPriority(g.Select(f => f.State))
                });

                for (var i = 0; i < maxKeySegmentCount; i++)
                {
                    uint priority = 0;
                    foreach (var key in enabledKeys)
                    {
                        var field = fields.SingleOrDefault(f => f.Field == key.Segments[i].Field);
                        if (field != null)
                        {
                            if (field.Priority == priority)
                            {
                                enabledKeyList.Add(key);
                            }
                            else if (field.Priority > priority)
                            {
                                priority = field.Priority;
                                enabledKeyList.Clear();
                                enabledKeyList.Add(key);
                            }
                        }
                    }
                    if (enabledKeyList.Count == 0)
                    {
                        if (remainedKeys.Count() == 0)
                        {
                            remainedKeys = enabledKeys.Where(k => i == k.Segments.Count - 1).ToArray();
                        }
                        enabledKeys = enabledKeys.Where(k => i != k.Segments.Count - 1).ToArray();
                    }
                    else if (enabledKeyList.Count == 1)
                    {
                        return(enabledKeyList[0]);
                    }
                    else if (enabledKeyList.Count > 1)
                    {
                        enabledKeys  = enabledKeyList.Where(k => i != k.Segments.Count - 1).ToArray();
                        remainedKeys = enabledKeyList.Where(k => i == k.Segments.Count - 1).ToArray();
                    }
                    enabledKeyList.Clear();
                    priorityList.Add(priority);
                }
                if (priorityList.Any(p => p != 0))
                {
                    return(remainedKeys.FirstOrDefault() ?? enabledKeys.FirstOrDefault());
                }
                else
                {
                    return(null);
                }
            }
            return(null);
        }
コード例 #2
0
ファイル: RecordInfo.cs プロジェクト: DevSw/BtrieveWrapper
        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;
                    }
                }
            }
        }
コード例 #3
0
ファイル: KeyValue.cs プロジェクト: DevSw/BtrieveWrapper
 public static KeyValue MaximumComplement(KeyInfo key, params object[] segmentValues)
 {
     return(new KeyValue(key, segmentValues, false));
 }