/// <summary> /// Retrieves the columns for a given view. /// </summary> /// <param name="pragma">A schema-specific pragma accessor.</param> /// <param name="viewName">A view name.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>An ordered collection of columns.</returns> /// <exception cref="ArgumentNullException"><paramref name="viewName"/> is <c>null</c>.</exception> protected virtual Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsync(ISqliteDatabasePragma pragma, Identifier viewName, CancellationToken cancellationToken) { if (pragma == null) { throw new ArgumentNullException(nameof(pragma)); } if (viewName == null) { throw new ArgumentNullException(nameof(viewName)); } return(LoadColumnsAsyncCore(pragma, viewName, cancellationToken)); }
private async Task <IReadOnlyList <IDatabaseColumn> > LoadColumnsAsyncCore(ISqliteDatabasePragma pragma, Identifier viewName, CancellationToken cancellationToken) { IEnumerable <Pragma.Query.pragma_table_info> tableInfos; try { // When the view is invalid, this may throw an exception so we catch it. // This does mean that we are in a partial state, but if the definition is corrected // and the view is queried again then we'll end up with something correct. tableInfos = await pragma.TableInfoAsync(viewName, cancellationToken).ConfigureAwait(false); } catch (SqliteException ex) when(ex.SqliteErrorCode == SqliteError) { return(Array.Empty <IDatabaseColumn>()); } if (tableInfos.Empty()) { return(Array.Empty <IDatabaseColumn>()); } var result = new List <IDatabaseColumn>(); foreach (var tableInfo in tableInfos) { if (tableInfo.name == null) { continue; } var columnName = tableInfo.name; var columnTypeName = tableInfo.type; if (columnTypeName.IsNullOrWhiteSpace()) { columnTypeName = await GetTypeofColumnAsync(viewName, columnName, cancellationToken).ConfigureAwait(false); } var affinity = AffinityParser.ParseTypeName(columnTypeName); var columnType = new SqliteColumnType(affinity); var defaultValue = !tableInfo.dflt_value.IsNullOrWhiteSpace() ? Option <string> .Some(tableInfo.dflt_value) : Option <string> .None; var column = new DatabaseColumn(columnName, columnType, !tableInfo.notnull, defaultValue, Option <IAutoIncrement> .None); result.Add(column); } return(result); }