private async Task <IReadOnlyCollection <IDatabaseIndex> > LoadIndexesAsyncCore(Identifier tableName, PostgreSqlTableQueryCache queryCache, CancellationToken cancellationToken) { var queryResult = await DbConnection.QueryAsync <IndexColumns>( IndexesQuery, new { SchemaName = tableName.Schema, TableName = tableName.LocalName }, cancellationToken ).ConfigureAwait(false); if (queryResult.Empty()) { return(Array.Empty <IDatabaseIndex>()); } var indexColumns = queryResult.GroupBy(row => new { row.IndexName, row.IsUnique, row.IsPrimary, row.KeyColumnCount }).ToList(); if (indexColumns.Empty()) { return(Array.Empty <IDatabaseIndex>()); } var columns = await queryCache.GetColumnsAsync(tableName, cancellationToken).ConfigureAwait(false); var columnLookup = GetColumnLookup(columns); var result = new List <IDatabaseIndex>(indexColumns.Count); foreach (var indexInfo in indexColumns) { var isUnique = indexInfo.Key.IsUnique; var indexName = Identifier.CreateQualifiedIdentifier(indexInfo.Key.IndexName); var indexCols = indexInfo .OrderBy(row => row.IndexColumnId) .Where(row => row.IndexColumnExpression != null) .Select(row => new { row.IsDescending, Expression = row.IndexColumnExpression, Column = row.IndexColumnExpression != null && columnLookup.ContainsKey(row.IndexColumnExpression) ? columnLookup[row.IndexColumnExpression] : null }) .Select(row => { var order = row.IsDescending ? IndexColumnOrder.Descending : IndexColumnOrder.Ascending; var expression = row.Column != null ? Dialect.QuoteName(row.Column.Name) : row.Expression !; return(row.Column != null ? new PostgreSqlDatabaseIndexColumn(expression, row.Column, order) : new PostgreSqlDatabaseIndexColumn(expression, order)); }) .Take(indexInfo.Key.KeyColumnCount) .ToList(); var includedCols = indexInfo .OrderBy(row => row.IndexColumnId) .Skip(indexInfo.Key.KeyColumnCount) .Where(row => row.IndexColumnExpression != null && columnLookup.ContainsKey(row.IndexColumnExpression)) .Select(row => columnLookup[row.IndexColumnExpression !])
/// <summary> /// Retrieves indexes that relate to the given table. /// </summary> /// <param name="tableName">A table name.</param> /// <param name="queryCache">A query cache for the given context.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A collection of indexes.</returns> /// <exception cref="ArgumentNullException"><paramref name="tableName"/> or <paramref name="queryCache"/> are <c>null</c>.</exception> protected override Task <IReadOnlyCollection <IDatabaseIndex> > LoadIndexesAsync(Identifier tableName, PostgreSqlTableQueryCache queryCache, CancellationToken cancellationToken) { if (tableName == null) { throw new ArgumentNullException(nameof(tableName)); } if (queryCache == null) { throw new ArgumentNullException(nameof(queryCache)); } return(LoadIndexesAsyncCore(tableName, queryCache, cancellationToken)); }