Beispiel #1
0
        private SqlSelect BuildTableQuery(IndexInfo index)
        {
            var domainHandler = Handlers.DomainHandler;
            var table         = Mapping[index.ReflectedType];

            var atRootPolicy = false;

            if (table == null)
            {
                table        = Mapping[index.ReflectedType.GetRoot()];
                atRootPolicy = true;
            }

            SqlSelect query;

            if (!atRootPolicy)
            {
                var tableRef = SqlDml.TableRef(table);
                query = SqlDml.Select(tableRef);
                query.Columns.AddRange(index.Columns.Select(c => tableRef[c.Name]));
            }
            else
            {
                var root     = index.ReflectedType.GetRoot().AffectedIndexes.First(i => i.IsPrimary);
                var lookup   = root.Columns.ToDictionary(c => c.Field, c => c.Name);
                var tableRef = SqlDml.TableRef(table);
                query = SqlDml.Select(tableRef);
                query.Columns.AddRange(index.Columns.Select(c => tableRef[lookup[c.Field]]));
            }
            return(query);
        }
Beispiel #2
0
 protected SqlSelect BuildProviderQuery(IndexInfo index)
 {
     if (index.IsVirtual)
     {
         if ((index.Attributes & IndexAttributes.Union) > 0)
         {
             return(BuildUnionQuery(index));
         }
         if ((index.Attributes & IndexAttributes.Join) > 0)
         {
             return(BuildJoinQuery(index));
         }
         if ((index.Attributes & IndexAttributes.Filtered) > 0)
         {
             return(BuildFilteredQuery(index));
         }
         if ((index.Attributes & IndexAttributes.View) > 0)
         {
             return(BuildViewQuery(index));
         }
         if ((index.Attributes & IndexAttributes.Typed) > 0)
         {
             return(BuildTypedQuery(index));
         }
         throw new NotSupportedException(String.Format(Strings.ExUnsupportedIndex, index.Name, index.Attributes));
     }
     return(BuildTableQuery(index));
 }
 /// <inheritdoc/>
 public override void UpdateState()
 {
     base.UpdateState();
     primaryIndex             = FindPrimaryIndex();
     realPrimaryIndexes       = new ReadOnlyList <IndexInfo>(FindRealPrimaryIndexes(primaryIndex));
     indexesContainingAllData = new ReadOnlyList <IndexInfo>(FindIndexesContainingAllData());
 }
        private List <IndexInfo> FindRealPrimaryIndexes(IndexInfo index)
        {
            if (index == null)
            {
                return(new List <IndexInfo>());
            }
            if (index.IsPrimary && !index.IsVirtual)
            {
                return(new List <IndexInfo>(new[] { index }));
            }
            var result = new List <IndexInfo>();

            foreach (IndexInfo underlyingIndex in index.UnderlyingIndexes)
            {
                if (underlyingIndex.IsPrimary && !underlyingIndex.IsVirtual)
                {
                    result.Add(underlyingIndex);
                }
                else
                {
                    result.AddRange(FindRealPrimaryIndexes(underlyingIndex));
                }
            }
            return(result);
        }
        // Constructors

        public IndexProvider(IndexInfo index)
            : base(ProviderType.Index)
        {
            indexHeader = index.GetRecordSetHeader();
            Index       = new IndexInfoRef(index);
            Initialize();
        }
Beispiel #6
0
        private static RecordSetHeader CreateHeader(IndexInfo indexInfo)
        {
            TupleDescriptor resultTupleDescriptor = TupleDescriptor.Create(
                indexInfo.Columns.Select(columnInfo => columnInfo.ValueType));

            var keyOrder = new List <KeyValuePair <int, Direction> >(
                indexInfo.KeyColumns.Select((p, i) => new KeyValuePair <int, Direction>(i, p.Value)));

            if (!indexInfo.IsPrimary)
            {
                var pkKeys = indexInfo.ReflectedType.Indexes.PrimaryIndex.KeyColumns;
                keyOrder.AddRange(
                    indexInfo.ValueColumns
                    .Select((c, i) => new Pair <Orm.Model.ColumnInfo, int>(c, i + indexInfo.KeyColumns.Count))
                    .Where(pair => pair.First.IsPrimaryKey)
                    .Select(pair => new KeyValuePair <int, Direction>(pair.Second, pkKeys[pair.First])));
            }

            var order         = new DirectionCollection <int>(keyOrder);
            var keyDescriptor = TupleDescriptor.Create(indexInfo.KeyColumns.Select(columnInfo => columnInfo.Key.ValueType));
            var resultColumns = indexInfo.Columns.Select((c, i) => (Column) new MappedColumn(c, i, c.ValueType));
            var resultGroups  = new[] { indexInfo.Group };

            return(new RecordSetHeader(
                       resultTupleDescriptor,
                       resultColumns,
                       resultGroups,
                       keyDescriptor,
                       order));
        }
Beispiel #7
0
 /// <summary>
 /// Initializes a new instance of this class.
 /// </summary>
 /// <param name="declaringType">The <see cref="TypeInfo"/> that declares this instance.</param>
 /// <param name="indexAttributes"><see cref="IndexAttributes"/> attributes for this instance.</param>
 public IndexInfo(TypeInfo declaringType, IndexAttributes indexAttributes)
     : this()
 {
     this.declaringType = declaringType;
     attributes         = indexAttributes;
     reflectedType      = declaringType;
     declaringIndex     = this;
 }
Beispiel #8
0
        private SqlSelect BuildViewQuery(IndexInfo index)
        {
            var underlyingIndex = index.UnderlyingIndexes[0];
            var baseQuery       = BuildProviderQuery(underlyingIndex);
            var query           = SqlDml.Select(baseQuery.From);

            query.Where = baseQuery.Where;
            query.Columns.AddRange(index.SelectColumns.Select(i => baseQuery.Columns[i]));
            return(query);
        }
Beispiel #9
0
        public IndexInfo Clone()
        {
            var result = new IndexInfo(reflectedType, attributes, declaringIndex);

            result.shortName       = shortName;
            result.Name            = Name;
            result.keyColumns      = keyColumns;
            result.valueColumns    = valueColumns;
            result.includedColumns = includedColumns;
            return(result);
        }
Beispiel #10
0
        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        /// <param name="reflectedType">Reflected type.</param>
        /// <param name="ancestorIndex">The ancestors index.</param>
        /// <param name="indexAttributes"><see cref="IndexAttributes"/> attributes for this instance.</param>
        public IndexInfo(TypeInfo reflectedType, IndexAttributes indexAttributes, IndexInfo ancestorIndex)
            : this()
        {
            declaringType      = ancestorIndex.DeclaringType;
            this.reflectedType = reflectedType;
            attributes         = indexAttributes;

            fillFactor       = ancestorIndex.FillFactor;
            filterExpression = ancestorIndex.FilterExpression;
            declaringIndex   = ancestorIndex.DeclaringIndex;
            shortName        = ancestorIndex.ShortName;
        }
Beispiel #11
0
        private SqlSelect BuildFilteredQuery(IndexInfo index)
        {
            var underlyingIndex = index.UnderlyingIndexes[0];
            var baseQuery       = BuildProviderQuery(underlyingIndex);

            SqlExpression filter           = null;
            var           type             = index.ReflectedType;
            var           discriminatorMap = type.Hierarchy.TypeDiscriminatorMap;
            var           filterByTypes    = index.FilterByTypes.ToList();

            if (underlyingIndex.IsTyped && discriminatorMap != null)
            {
                var columnType = discriminatorMap.Column.ValueType;
                var discriminatorColumnIndex = underlyingIndex.Columns
                                               .Where(c => !c.Field.IsTypeId)
                                               .Select((c, i) => new { c, i })
                                               .Where(p => p.c == discriminatorMap.Column)
                                               .Single().i;
                var discriminatorColumn = baseQuery.From.Columns[discriminatorColumnIndex];
                var containsDefault     = filterByTypes.Contains(discriminatorMap.Default);
                var values = filterByTypes
                             .Select(t => GetDiscriminatorValue(discriminatorMap, t.TypeDiscriminatorValue));
                if (filterByTypes.Count == 1)
                {
                    var discriminatorValue = GetDiscriminatorValue(discriminatorMap, filterByTypes.First().TypeDiscriminatorValue);
                    filter = discriminatorColumn == SqlDml.Literal(discriminatorValue);
                }
                else
                {
                    filter = SqlDml.In(discriminatorColumn, SqlDml.Array(values));
                    if (containsDefault)
                    {
                        var allValues = discriminatorMap
                                        .Select(p => GetDiscriminatorValue(discriminatorMap, p.First));
                        filter |= SqlDml.NotIn(discriminatorColumn, SqlDml.Array(allValues));
                    }
                }
            }
            else
            {
                var typeIdColumn = baseQuery.Columns[Handlers.Domain.Handlers.NameBuilder.TypeIdColumnName];
                var typeIds      = filterByTypes.Select(t => TypeIdRegistry[t]).ToArray();
                filter = filterByTypes.Count == 1
          ? typeIdColumn == TypeIdRegistry[filterByTypes.First()]
          : SqlDml.In(typeIdColumn, SqlDml.Array(typeIds));
            }
            var query = SqlDml.Select(baseQuery.From);

            query.Columns.AddRange(baseQuery.Columns);
            query.Where = filter;
            return(query);
        }
Beispiel #12
0
        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        /// <param name="reflectedType">Reflected type.</param>
        /// <param name="indexAttributes">The index attributes.</param>
        /// <param name="baseIndex">Base index.</param>
        /// <param name="baseIndexes">The base indexes.</param>
        public IndexInfo(TypeInfo reflectedType, IndexAttributes indexAttributes, IndexInfo baseIndex, params IndexInfo[] baseIndexes)
            : this()
        {
            declaringType      = baseIndex.DeclaringType;
            this.reflectedType = reflectedType;
            attributes         = indexAttributes;

            fillFactor       = baseIndex.FillFactor;
            filterExpression = baseIndex.FilterExpression;
            declaringIndex   = baseIndex.DeclaringIndex;
            shortName        = baseIndex.ShortName;

            UnderlyingIndexes.Add(baseIndex);

            foreach (IndexInfo info in baseIndexes)
            {
                UnderlyingIndexes.Add(info);
            }
        }
Beispiel #13
0
        private SqlSelect BuildUnionQuery(IndexInfo index)
        {
            ISqlQueryExpression result = null;

            var baseQueries = index.UnderlyingIndexes.Select(BuildProviderQuery).ToList();

            foreach (var select in baseQueries)
            {
                result = result == null
          ? (ISqlQueryExpression)select
          : result.Union(select);
            }

            var unionRef = SqlDml.QueryRef(result);
            var query    = SqlDml.Select(unionRef);

            query.Columns.AddRange(unionRef.Columns);
            return(query);
        }
Beispiel #14
0
        private SqlSelect BuildTypedQuery(IndexInfo index)
        {
            var underlyingIndex = index.UnderlyingIndexes[0];
            var baseQuery       = BuildProviderQuery(underlyingIndex);
            var query           = SqlDml.Select(baseQuery.From);

            query.Where = baseQuery.Where;

            var baseColumns       = baseQuery.Columns.ToList();
            var typeIdColumnIndex = index.Columns
                                    .Select((c, i) => new { c, i })
                                    .Single(p => p.c.Field.IsTypeId).i;
            var type         = index.ReflectedType;
            var typeIdColumn = SqlDml.ColumnRef(
                SqlDml.Column(SqlDml.Literal(TypeIdRegistry[type])),
                WellKnown.TypeIdFieldName);
            var discriminatorMap = type.Hierarchy.TypeDiscriminatorMap;

            if (discriminatorMap != null)
            {
                var discriminatorColumnIndex = underlyingIndex.Columns.IndexOf(discriminatorMap.Column);
                var discriminatorColumn      = baseQuery.From.Columns[discriminatorColumnIndex];
                var sqlCase = SqlDml.Case(discriminatorColumn);
                foreach (var pair in discriminatorMap)
                {
                    var discriminatorValue = GetDiscriminatorValue(discriminatorMap, pair.First);
                    var typeId             = TypeIdRegistry[pair.Second];
                    sqlCase.Add(SqlDml.Literal(discriminatorValue), SqlDml.Literal(typeId));
                }
                if (discriminatorMap.Default != null)
                {
                    sqlCase.Else = SqlDml.Literal(TypeIdRegistry[discriminatorMap.Default]);
                }
                typeIdColumn = SqlDml.ColumnRef(
                    SqlDml.Column(sqlCase),
                    WellKnown.TypeIdFieldName);
            }
            baseColumns.Insert(typeIdColumnIndex, typeIdColumn);
            query.Columns.AddRange(baseColumns);
            return(query);
        }
        private SqlSelect BuildTableQuery(IndexInfo index)
        {
            var domainHandler = Handlers.DomainHandler;
            var table         = Mapping[index.ReflectedType];

            var atRootPolicy = false;

            if (table == null)
            {
                table        = Mapping[index.ReflectedType.GetRoot()];
                atRootPolicy = true;
            }

            var indexColumns = index.Columns;
            var tableRef     = SqlDml.TableRef(table);
            var query        = SqlDml.Select(tableRef);
            var queryColumns = query.Columns;

            queryColumns.Capacity = queryColumns.Count + indexColumns.Count;
            if (!atRootPolicy)
            {
                foreach (var c in indexColumns)
                {
                    queryColumns.Add(tableRef[c.Name]);
                }
            }
            else
            {
                var root   = index.ReflectedType.GetRoot().AffectedIndexes.First(i => i.IsPrimary);
                var lookup = root.Columns.ToDictionary(c => c.Field, c => c.Name);
                foreach (var c in indexColumns)
                {
                    queryColumns.Add(tableRef[lookup[c.Field]]);
                }
            }
            return(query);
        }
 /// <summary>
 /// Visits an index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <returns>Visit result.</returns>
 protected abstract TResult VisitIndexInfo(IndexInfo index);
        // Constructors

        /// <summary>
        ///   Initializes a new instance of this class.
        /// </summary>
        /// <param name="indexInfo"><see cref="IndexInfo"/> object to make reference for.</param>
        public IndexInfoRef(IndexInfo indexInfo)
        {
            IndexName          = indexInfo.Name;
            TypeName           = indexInfo.ReflectedType.Name;
            KeyTupleDescriptor = indexInfo.KeyTupleDescriptor;
        }
 /// <summary>
 /// Gets the <see cref="RecordSetHeader"/> object for the specified <paramref name="indexInfo"/>.
 /// </summary>
 /// <param name="indexInfo">The index info to get the header for.</param>
 /// <returns>The <see cref="RecordSetHeader"/> object.</returns>
 public static RecordSetHeader GetHeader(IndexInfo indexInfo)
 {
     return(CreateHeader(indexInfo));
 }
Beispiel #19
0
        // Constructors

        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        public FullTextIndexInfo(IndexInfo primaryIndex, string name)
            : base(name)
        {
            this.primaryIndex = primaryIndex;
            columns           = new FullTextColumnInfoCollection(this, "Columns");
        }
Beispiel #20
0
        private SqlSelect BuildJoinQuery(IndexInfo index)
        {
            SqlTable resultTable = null;
            SqlTable rootTable   = null;

            int keyColumnCount    = index.KeyColumns.Count;
            var underlyingQueries = index.UnderlyingIndexes.Select(BuildProviderQuery);

            var sourceTables = index.UnderlyingIndexes.Any(i => i.IsVirtual)
        ? underlyingQueries.Select(SqlDml.QueryRef).Cast <SqlTable>().ToList()
        : underlyingQueries.Select(q => {
                var tableRef = (SqlTableRef)q.From;
                return((SqlTable)SqlDml.TableRef(tableRef.DataTable, tableRef.Name, q.Columns.Select(c => c.Name)));
            }).ToList();

            foreach (var table in sourceTables)
            {
                if (resultTable == null)
                {
                    resultTable = rootTable = table;
                }
                else
                {
                    SqlExpression joinExpression = null;
                    for (int i = 0; i < keyColumnCount; i++)
                    {
                        var binary = (table.Columns[i] == rootTable.Columns[i]);
                        if (joinExpression.IsNullReference())
                        {
                            joinExpression = binary;
                        }
                        else
                        {
                            joinExpression &= binary;
                        }
                    }
                    resultTable = resultTable.InnerJoin(table, joinExpression);
                }
            }

            var columns = new List <SqlColumn>();

            foreach (var map in index.ValueColumnsMap)
            {
                var table = sourceTables[map.First];
                if (columns.Count == 0)
                {
                    var keyColumns = Enumerable
                                     .Range(0, keyColumnCount)
                                     .Select(i => table.Columns[i])
                                     .Cast <SqlColumn>();
                    columns.AddRange(keyColumns);
                }
                var valueColumns = map.Second
                                   .Select(columnIndex => table.Columns[columnIndex + keyColumnCount])
                                   .Cast <SqlColumn>();
                columns.AddRange(valueColumns);
            }

            var query = SqlDml.Select(resultTable);

            query.Columns.AddRange(columns);

            return(query);
        }