Table of Contents

Data providers

A report names a data source and a query. ReportWright never trusts either: the host maps the name to a provider kind and a secret, the provider runs the query with the router's limits, and a client sees field names and rows, never a connection string.

The seam

  • DataSourceResolver answers "what is the data source called X in this report, for this caller?" with a ResolvedDataSource (provider kind, name, connection string, credentials). StaticDataSourceResolver holds a fixed map and a default; implement the abstract class to read a vault or a tenant table.
  • DataSourceRegistry holds the providers by kind.
  • DataSourceRouter is the ReportDataProvider the engine calls once per dataset: it resolves, picks the provider, applies DataSourceRouterOptions (MaxRows, DefaultTimeout) and the guard, and streams rows.
  • DataSourceMetadataService answers the designer's three design-time questions, test, schema and preview, through the same resolver, so the data pane works against real sources.
var resolver = new StaticDataSourceResolver()
    .Add("Files", new ResolvedDataSource(CsvDataSourceProvider.ProviderKind, "Files") { ConnectionString = dataDirectory })
    .Add("Sales", new ResolvedDataSource(SqlServerDataSourceProvider.ProviderKind, "Sales") { ConnectionString = sqlConnectionString });
var providers = new DataSourceRegistry()
    .Add(new CsvDataSourceProvider())
    .Add(new SqlServerDataSourceProvider());
var router = new DataSourceRouter(resolver, providers, new DataSourceRouterOptions { MaxRows = 100000, DefaultTimeout = TimeSpan.FromSeconds(30) });

The providers

Provider Package Connection string Query
CsvDataSourceProvider ReportWright.Data.Csv A directory A file name; the first row names the fields
JsonFileDataSourceProvider ReportWright.Data.Json A directory A file name and an optional path into the document
RestDataSourceProvider ReportWright.Data.Json A base URL A relative URL; same-origin and allow-list rules apply
XmlDataSourceProvider ReportWright.Data.Xml A directory or URL An element path
SqlServerDataSourceProvider ReportWright.Data.SqlServer A SQL Server or Azure SQL connection string SQL text with the report's parameters bound
SystemDataSourceProvider ReportWright.Data.SystemData — Your DataTable, DataSet, IDataReader or objects, registered by name

Every provider honours cancellation between rows, fails closed on anything it does not understand, and returns typed values the engine formats.

Shared data sources

A shared data source is one connection many reports reference by name (<DataSourceReference>), as in Reporting Services. Register it with StaticDataSourceResolver.AddShared("SalesDb", source), or load every .rsds/.rds file a team already has:

var resolver = new StaticDataSourceResolver().AddSharedFolder(Path.Combine(contentRoot, "shared-data-sources"));

The files' connection strings stay on the server; the designer lists the shared names and kinds.

What stays out

OLEDB and ODBC need native drivers and are refused by design; SSAS and MDX have cell-set semantics the engine does not model. PostgreSQL, MySQL, SQLite, OData and Excel files are planned for a later release.