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); }
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(); }
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)); }
/// <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; }
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); }
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); }
/// <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; }
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); }
/// <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); } }
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); }
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)); }
// 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"); }
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); }