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); }
/// <summary> /// Gets the type affinity of a given type name. /// </summary> /// <param name="typeName">A type name.</param> /// <returns>A type affinity.</returns> protected static SqliteTypeAffinity GetAffinity(string typeName) => AffinityParser.ParseTypeName(typeName);