Skip to content
This repository was archived by the owner on Feb 15, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Automatic database type detection from connection string patterns
- Cross-database schema comparison capability (compare SQL Server and PostgreSQL schemas)
- Npgsql package dependency for PostgreSQL connectivity
- View extraction and export functionality for SQL Server
- View SQL definitions included in exports (using sys.sql_modules for complete definitions)
- View column structures with full metadata (data types, nullability, precision, etc.)
- Alphabetically sorted views in output for deterministic comparison
- Support for encrypted views (gracefully handles NULL definitions)
- `--exclude-view-definitions` CLI flag to optionally exclude SQL definitions from output

### Changed
- Updated `SchemaExportRequest` DTO to include `DatabaseType` property
- Refactored `SchemaExportService` to use factory pattern for extractor instantiation
- Updated CLI help text with PostgreSQL examples and database type parameter
- Updated `DatabaseSchema` domain entity to include `Views` collection
- Enhanced `CustomTextFormatter` to display view definitions and columns
- Improved logging to report both table and view counts
- Updated `SchemaExportResult` DTO with separate `TableCount` and `ViewCount` properties
- Made view definitions optional in export output via `IncludeViewDefinitions` formatter property

## [0.0.1] - 2025-12-16

Expand Down
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Current version: **0.0.1**
## Features

- Export database schemas to text format from SQL Server and PostgreSQL
- **Complete schema export including:**
- Tables with full column definitions
- Views with SQL definitions and column structures
- Deterministic, diff-friendly output format
- Alphabetically sorted tables and columns for easy comparison
- Cross-database schema comparison (compare SQL Server vs PostgreSQL schemas)
Expand Down Expand Up @@ -112,6 +115,7 @@ dbdiff --connection "Host=localhost;Database=mydb;Username=user;Password=pass" -
- `-d, --database-type <type>`: Database type: `sqlserver`, `postgresql` (auto-detected if not specified)
- `--config <path>`: Path to configuration file (default: appsettings.json)
- `--ignore-position`: Exclude column ordinal positions from output
- `--exclude-view-definitions`: Exclude view SQL definitions from output (column structure still included)
- `-h, --help`: Show help information

### Database Type Detection
Expand Down Expand Up @@ -174,12 +178,31 @@ TABLE: dbo.Users
Nullable: Yes
MaxLength: 100

TABLE: dbo.Orders
...
VIEW: dbo.ActiveUsers
DEFINITION:
CREATE VIEW dbo.ActiveUsers AS
SELECT Id, Name, Email
FROM dbo.Users
WHERE IsActive = 1
COLUMN: Email
OrdinalPosition: 3
Type: nvarchar
Nullable: Yes
MaxLength: 255
COLUMN: Id
OrdinalPosition: 1
Type: int
Nullable: No
COLUMN: Name
OrdinalPosition: 2
Type: nvarchar
Nullable: Yes
MaxLength: 100
```

Features:
- Tables and columns are alphabetically sorted
- Tables, views, and columns are alphabetically sorted
- Views include complete SQL definitions for comparison
- Consistent formatting and indentation
- One property per line
- Deterministic output for reliable diffing
Expand Down Expand Up @@ -320,7 +343,7 @@ See [CHANGELOG.md](CHANGELOG.md) for version history and planned features.
### Future Enhancements

- Schema comparison (diff) functionality
- Support for additional database objects (indexes, foreign keys, views, stored procedures, etc.)
- Support for additional database objects (indexes, foreign keys, stored procedures, functions, triggers, etc.)
- GUI application using AvaloniaUI
- Multiple output formats (JSON, YAML, SQL DDL)
- Support for additional databases (MySQL, Oracle, etc.)
Expand Down
15 changes: 9 additions & 6 deletions src/DbDiff.Application/DTOs/SchemaExportResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@ public class SchemaExportResult
{
public bool Success { get; init; }
public string ExportedFilePath { get; init; }
public int ObjectCount { get; init; }
public int TableCount { get; init; }
public int ViewCount { get; init; }
public int ObjectCount => TableCount + ViewCount;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Console message shows table+view count as table count

The ObjectCount property was changed to return TableCount + ViewCount, but the console output in Program.cs line 201 displays "Tables exported: {result.ObjectCount}". This causes the message to misleadingly report the combined table and view count while labeling it as just "Tables". The message text and the value displayed no longer match after this change.

Fix in Cursor Fix in Web

public string? ErrorMessage { get; init; }

private SchemaExportResult(bool success, string exportedFilePath, int objectCount, string? errorMessage)
private SchemaExportResult(bool success, string exportedFilePath, int tableCount, int viewCount, string? errorMessage)
{
Success = success;
ExportedFilePath = exportedFilePath;
ObjectCount = objectCount;
TableCount = tableCount;
ViewCount = viewCount;
ErrorMessage = errorMessage;
}

public static SchemaExportResult SuccessResult(string exportedFilePath, int objectCount)
public static SchemaExportResult SuccessResult(string exportedFilePath, int tableCount, int viewCount)
{
return new SchemaExportResult(true, exportedFilePath, objectCount, null);
return new SchemaExportResult(true, exportedFilePath, tableCount, viewCount, null);
}

public static SchemaExportResult FailureResult(string errorMessage)
{
return new SchemaExportResult(false, string.Empty, 0, errorMessage);
return new SchemaExportResult(false, string.Empty, 0, 0, errorMessage);
}
}

72 changes: 52 additions & 20 deletions src/DbDiff.Application/Formatters/CustomTextFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
public class CustomTextFormatter : ISchemaFormatter
{
public bool IncludeOrdinalPosition { get; set; } = true;
public bool IncludeViewDefinitions { get; set; } = true;

private static readonly string[] separator = new[] { "\r\n", "\r", "\n" };

public string Format(DatabaseSchema schema)
{
Expand All @@ -13,8 +16,8 @@
var sb = new StringBuilder();

// Header section
sb.AppendLine($"DATABASE: {schema.DatabaseName}");

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 19 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
sb.AppendLine($"EXTRACTED: {schema.ExtractedAt:yyyy-MM-ddTHH:mm:ss.fffZ}");

Check warning on line 20 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 20 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 20 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
sb.AppendLine();

// Sort tables alphabetically by full name for deterministic output
Expand All @@ -25,37 +28,66 @@

foreach (var table in sortedTables)
{
sb.AppendLine($"TABLE: {table.FullName}");

Check warning on line 31 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 31 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 31 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
FormatColumns(sb, table.Columns);
sb.AppendLine();
}

// Sort columns alphabetically by name
var sortedColumns = table.Columns
.OrderBy(c => c.Name)
.ToList();
// Sort views alphabetically by full name for deterministic output
var sortedViews = schema.Views
.OrderBy(v => v.SchemaName)
.ThenBy(v => v.ViewName)
.ToList();

foreach (var view in sortedViews)
{
sb.AppendLine($"VIEW: {view.FullName}");

Check warning on line 44 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 44 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 44 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

foreach (var column in sortedColumns)
// Include view definition if available and enabled
if (IncludeViewDefinitions && !string.IsNullOrWhiteSpace(view.Definition))
{
sb.AppendLine($" COLUMN: {column.Name}");
sb.AppendLine(" DEFINITION:");
// Indent each line of the definition
var definitionLines = view.Definition.Split(separator, StringSplitOptions.None);
foreach (var line in definitionLines)
{
sb.AppendLine($" {line}");

Check warning on line 54 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 54 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 54 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.Format(DatabaseSchema)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
}
}

if (IncludeOrdinalPosition)
sb.AppendLine($" OrdinalPosition: {column.OrdinalPosition}");
FormatColumns(sb, view.Columns);
sb.AppendLine();
}

sb.AppendLine($" Type: {column.DataType}");
sb.AppendLine($" Nullable: {(column.IsNullable ? "Yes" : "No")}");
return sb.ToString();
}

if (column.MaxLength.HasValue)
sb.AppendLine($" MaxLength: {column.MaxLength.Value}");
private void FormatColumns(StringBuilder sb, IReadOnlyList<Column> columns)
{
// Sort columns alphabetically by name
var sortedColumns = columns
.OrderBy(c => c.Name)
.ToList();

if (column.Precision.HasValue)
sb.AppendLine($" Precision: {column.Precision.Value}");
foreach (var column in sortedColumns)
{
sb.AppendLine($" COLUMN: {column.Name}");

Check warning on line 74 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 74 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

if (column.Scale.HasValue)
sb.AppendLine($" Scale: {column.Scale.Value}");
}
if (IncludeOrdinalPosition)
sb.AppendLine($" OrdinalPosition: {column.OrdinalPosition}");

Check warning on line 77 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 77 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

sb.AppendLine();
}
sb.AppendLine($" Type: {column.DataType}");

Check warning on line 79 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 79 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
sb.AppendLine($" Nullable: {(column.IsNullable ? "Yes" : "No")}");

Check warning on line 80 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 80 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

return sb.ToString();
if (column.MaxLength.HasValue)
sb.AppendLine($" MaxLength: {column.MaxLength.Value}");

Check warning on line 83 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / build-and-test

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 83 in src/DbDiff.Application/Formatters/CustomTextFormatter.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

The behavior of 'StringBuilder.AppendLine(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CustomTextFormatter.FormatColumns(StringBuilder, IReadOnlyList<Column>)' with a call to 'StringBuilder.AppendLine(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

if (column.Precision.HasValue)
sb.AppendLine($" Precision: {column.Precision.Value}");

if (column.Scale.HasValue)
sb.AppendLine($" Scale: {column.Scale.Value}");
}
}
}

7 changes: 4 additions & 3 deletions src/DbDiff.Application/Services/SchemaExportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

try
{
_logger.LogInformation("Starting schema extraction from {DatabaseType} database", request.DatabaseType);

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 32 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

// Get the appropriate extractor for the database type
var schemaExtractor = _extractorFactory(request.DatabaseType);
Expand All @@ -39,9 +39,10 @@
request.ConnectionString,
cancellationToken);

_logger.LogInformation("Successfully extracted schema from database {DatabaseName} with {TableCount} tables",
_logger.LogInformation("Successfully extracted schema from database {DatabaseName} with {TableCount} tables and {ViewCount} views",

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 42 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)
schema.DatabaseName,
schema.Tables.Count);
schema.Tables.Count,
schema.Views.Count);

// Format schema to text
var formattedSchema = _schemaFormatter.Format(schema);
Expand All @@ -51,19 +52,19 @@
if (!string.IsNullOrEmpty(outputDirectory) && !Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
_logger.LogDebug("Created output directory: {OutputDirectory}", outputDirectory);

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogDebug(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogDebug(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogDebug(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogDebug(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 55 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)
}

// Write to file
await File.WriteAllTextAsync(request.OutputPath, formattedSchema, cancellationToken);

_logger.LogInformation("Schema exported successfully to {OutputPath}", request.OutputPath);

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 61 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

Evaluation of this argument may be expensive and unnecessary if logging is disabled (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)

return SchemaExportResult.SuccessResult(request.OutputPath, schema.Tables.Count);
return SchemaExportResult.SuccessResult(request.OutputPath, schema.Tables.Count, schema.Views.Count);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to export schema");

Check warning on line 67 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogError(ILogger, Exception?, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 67 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (macos-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogError(ILogger, Exception?, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 67 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (ubuntu-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogError(ILogger, Exception?, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)

Check warning on line 67 in src/DbDiff.Application/Services/SchemaExportService.cs

View workflow job for this annotation

GitHub Actions / multi-platform-test (windows-latest)

For improved performance, use the LoggerMessage delegates instead of calling 'LoggerExtensions.LogError(ILogger, Exception?, string?, params object?[])' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848)
return SchemaExportResult.FailureResult(ex.Message);
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/DbDiff.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
string? databaseTypeArg = null;
bool showHelp = false;
bool ignorePosition = false;
bool excludeViewDefinitions = false;

for (int i = 0; i < args.Length; i++)
{
Expand All @@ -103,6 +104,9 @@
case "--ignore-position":
ignorePosition = true;
break;
case "--exclude-view-definitions":
excludeViewDefinitions = true;
break;
case "--help" or "-h" or "-?":
showHelp = true;
break;
Expand All @@ -122,6 +126,7 @@
Console.WriteLine(" -d, --database-type <type> Database type: sqlserver, postgresql (auto-detected if not specified)");
Console.WriteLine(" --config <path> Configuration file path");
Console.WriteLine(" --ignore-position Exclude column ordinal positions from output");
Console.WriteLine(" --exclude-view-definitions Exclude view SQL definitions from output");
Console.WriteLine(" -h, --help Show help information");
Console.WriteLine();
Console.WriteLine("Configuration:");
Expand Down Expand Up @@ -217,6 +222,7 @@
if (formatter is CustomTextFormatter customFormatter)
{
customFormatter.IncludeOrdinalPosition = !ignorePosition;
customFormatter.IncludeViewDefinitions = !excludeViewDefinitions;
}

var exportService = serviceProvider.GetRequiredService<SchemaExportService>();
Expand Down
4 changes: 3 additions & 1 deletion src/DbDiff.Domain/DatabaseSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ public class DatabaseSchema
public string DatabaseName { get; init; }
public DateTime ExtractedAt { get; init; }
public IReadOnlyList<Table> Tables { get; init; }
public IReadOnlyList<View> Views { get; init; }

public DatabaseSchema(string databaseName, DateTime extractedAt, IEnumerable<Table> tables)
public DatabaseSchema(string databaseName, DateTime extractedAt, IEnumerable<Table> tables, IEnumerable<View> views)
{
if (string.IsNullOrWhiteSpace(databaseName))
throw new ArgumentException("Database name cannot be null or empty.", nameof(databaseName));

DatabaseName = databaseName;
ExtractedAt = extractedAt;
Tables = tables?.ToList() ?? throw new ArgumentNullException(nameof(tables));
Views = views?.ToList() ?? throw new ArgumentNullException(nameof(views));
}
}

26 changes: 26 additions & 0 deletions src/DbDiff.Domain/View.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace DbDiff.Domain;

public class View
{
public string SchemaName { get; init; }
public string ViewName { get; init; }
public string? Definition { get; init; }
public IReadOnlyList<Column> Columns { get; init; }

public View(string schemaName, string viewName, IEnumerable<Column> columns, string? definition = null)
{
if (string.IsNullOrWhiteSpace(schemaName))
throw new ArgumentException("Schema name cannot be null or empty.", nameof(schemaName));

if (string.IsNullOrWhiteSpace(viewName))
throw new ArgumentException("View name cannot be null or empty.", nameof(viewName));

SchemaName = schemaName;
ViewName = viewName;
Definition = definition;
Columns = columns?.ToList() ?? throw new ArgumentNullException(nameof(columns));
}

public string FullName => $"{SchemaName}.{ViewName}";
}

46 changes: 45 additions & 1 deletion src/DbDiff.Infrastructure/MsSqlSchemaExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ public async Task<DatabaseSchema> ExtractSchemaAsync(
var extractedAt = DateTime.UtcNow;

var tables = await ExtractTablesAsync(connection, cancellationToken);
var views = await ExtractViewsAsync(connection, cancellationToken);

return new DatabaseSchema(databaseName, extractedAt, tables);
return new DatabaseSchema(databaseName, extractedAt, tables, views);
}

private static async Task<List<Table>> ExtractTablesAsync(
Expand Down Expand Up @@ -60,6 +61,49 @@ FROM INFORMATION_SCHEMA.TABLES
return tables;
}

private static async Task<List<View>> ExtractViewsAsync(
SqlConnection connection,
CancellationToken cancellationToken)
{
var views = new List<View>();

// Query to get all user views with their definitions (excluding system views)
// Using sys.views and sys.sql_modules to get the full definition (no 4000 char limit)
const string viewQuery = @"
SELECT
s.name AS SchemaName,
v.name AS ViewName,
m.definition AS Definition
FROM sys.views v
INNER JOIN sys.schemas s ON v.schema_id = s.schema_id
LEFT JOIN sys.sql_modules m ON v.object_id = m.object_id
WHERE s.name NOT IN ('sys', 'INFORMATION_SCHEMA')
ORDER BY s.name, v.name";

await using var viewCommand = new SqlCommand(viewQuery, connection);
await using var viewReader = await viewCommand.ExecuteReaderAsync(cancellationToken);

var viewInfoList = new List<(string Schema, string Name, string? Definition)>();
while (await viewReader.ReadAsync(cancellationToken))
{
var schemaName = viewReader.GetString(0);
var viewName = viewReader.GetString(1);
var definition = viewReader.IsDBNull(2) ? null : viewReader.GetString(2);
viewInfoList.Add((schemaName, viewName, definition));
}

await viewReader.CloseAsync();

// Extract columns for each view
foreach (var (schemaName, viewName, definition) in viewInfoList)
{
var columns = await ExtractColumnsAsync(connection, schemaName, viewName, cancellationToken);
views.Add(new View(schemaName, viewName, columns, definition));
}

return views;
}

private static async Task<List<Column>> ExtractColumnsAsync(
SqlConnection connection,
string schemaName,
Expand Down
Loading