PeopleWorks GPT's revolutionary multi-database support enables seamless natural language queries across SQL Server, MySQL, PostgreSQL, Oracle, and SQLite — all through a single, elegant API.
A clean abstraction layer that separates business logic from database-specific implementations
Every database provider implements this unified interface for consistent behavior
using System.Data.Common; namespace DatabaseGpt.Abstractions; public interface IDatabaseGptProvider : IDisposable { /// <summary>The display name of the database (e.g., "SQL Server", "MySQL")</summary> string Name { get; } /// <summary>The SQL dialect used (e.g., "T-SQL", "PL/pgSQL")</summary> string Language { get; } /// <summary>Returns provider-specific query optimization hints</summary> Task<string?> GetQueryHintsAsync(CancellationToken cancellationToken = default); /// <summary>Retrieves available tables from the database schema</summary> Task<IEnumerable<string>> GetTablesAsync( IEnumerable<string> includedTables, IEnumerable<string> excludedTables, CancellationToken cancellationToken = default); /// <summary>Generates CREATE TABLE scripts for AI context</summary> Task<string> GetCreateTablesScriptAsync( IEnumerable<string> tables, IEnumerable<string> excludedColumns, CancellationToken cancellationToken = default); /// <summary>Normalizes and validates the generated query</summary> Task<string> NormalizeQueryAsync( string query, CancellationToken cancellationToken = default); /// <summary>Executes the query and returns a data reader</summary> Task<DbDataReader> ExecuteQueryAsync( string query, CancellationToken cancellationToken = default); }
| Interface Method | Purpose | AI Integration |
|---|---|---|
Name |
Identifies the database engine for prompt construction | 🤖 Used in system prompts: "You are querying a {Name} database" |
Language |
Specifies the SQL dialect for code generation | 🤖 Instructs AI to generate {Language} syntax |
GetTablesAsync |
Retrieves schema metadata for table discovery | 🤖 Provides available tables for AI to reference |
GetCreateTablesScriptAsync |
Generates DDL scripts with columns and relationships | 🤖 Gives AI complete schema understanding |
GetQueryHintsAsync |
Provider-specific optimization guidance | 🤖 Teaches AI database-specific best practices |
NormalizeQueryAsync |
Validates and cleans AI-generated queries | ✅ Post-processing before execution |
ExecuteQueryAsync |
Runs the query against the actual database | 📊 Returns results to the application |
Each provider handles database-specific schema introspection and query execution
public class SqlServerDatabaseGptProvider : IDatabaseGptProvider { private readonly SqlConnection connection; // Database identification for AI prompts public string Name => "SQL Server"; public string Language => "T-SQL"; public async Task<IEnumerable<string>> GetTablesAsync(...) { // Uses INFORMATION_SCHEMA for cross-version compatibility var query = @" SELECT QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES"; return await connection.QueryAsync<string>(query); } public async Task<string> GetCreateTablesScriptAsync(...) { // Generates CREATE TABLE with columns, types, and constraints // Compatible with SQL Server 2008 R2+ (uses CASE instead of IIF) var query = @" SELECT COLUMN_NAME, UPPER(DATA_TYPE) + CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN '(MAX)' ELSE CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) END + CASE WHEN IS_NULLABLE = 'YES' THEN ' NULL' ELSE ' NOT NULL' END FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table"; // Also extracts foreign key relationships var relationships = await GetRelationshipsAsync(tables); return script + relationships; } }
public class MySqlDatabaseGptProvider : IDatabaseGptProvider { private readonly MySqlConnection connection; public string Name => "MySQL"; public string Language => "MySQL"; public async Task<IEnumerable<string>> GetTablesAsync(...) { // Excludes system schemas var query = @" SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS Tables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')"; return await connection.QueryAsync<string>(query); } public async Task<string> GetCreateTablesScriptAsync(...) { // MySQL-specific backtick quoting var columns = allColumns .Select(c => $"`{c.Column}` {c.Description}"); return $"CREATE TABLE `{schema}`.`{table}` ({string.Join(", ", columns)});"; } }
public class OracleDatabaseGptProvider : IDatabaseGptProvider { private readonly OracleConnection connection; public string Name => "Oracle"; public string Language => "PL/SQL"; public async Task<IEnumerable<string>> GetTablesAsync(...) { // Uses Oracle's ALL_TABLES catalog var query = @" SELECT owner || '.' || table_name AS TABLES FROM ALL_TABLES WHERE owner = USER"; return await connection.QueryAsync<string>(query); } public async Task<string> GetCreateTablesScriptAsync(...) { // Oracle-specific data types: VARCHAR2, NUMBER with precision/scale var query = @" SELECT DATA_TYPE || CASE WHEN DATA_TYPE IN ('VARCHAR2', 'CHAR') THEN '(' || CHAR_LENGTH || ')' WHEN DATA_TYPE = 'NUMBER' AND DATA_SCALE > 0 THEN '(' || DATA_PRECISION || ',' || DATA_SCALE || ')' ELSE '' END AS DESCRIPTION FROM ALL_TAB_COLUMNS WHERE OWNER = :schema AND TABLE_NAME = :table"; return await BuildScriptAsync(query); } }
Database-specific implementations and their capabilities
| Feature | SQL Server | MySQL | PostgreSQL | Oracle | SQLite |
|---|---|---|---|---|---|
| Schema Introspection | |||||
| Primary Key Detection | |||||
| Foreign Key Relationships | |||||
| Schema Filtering | N/A | ||||
| Column Exclusion | |||||
| Legacy Version Support | 2008 R2+ | 5.7+ | 9.6+ | 11g+ | 3.x+ |
| Identifier Quoting | [brackets] |
`backticks` |
"quotes" |
NONE |
[brackets] |
| System Catalog | INFORMATION_SCHEMA | INFORMATION_SCHEMA | INFORMATION_SCHEMA | ALL_TABLES | sqlite_schema |
PeopleWorks GPT supports SQL Server versions from 2008 R2 onwards. The provider automatically uses CASE statements instead of IIF for compatibility, and generates SQL optimized for each version's capabilities.
Fluent API design makes provider configuration intuitive and type-safe
Seamlessly integrates with ASP.NET Core's built-in dependency injection system. Configure once, use everywhere with proper lifecycle management.
Built-in retry policies handle transient failures automatically. Configurable retry attempts with Polly integration for robust operation.
Connection strings are handled securely through configuration. Only SELECT queries are allowed — INSERT, UPDATE, DELETE are blocked by design.
Fine-grained control over which tables and columns are exposed to AI. Protect sensitive data while enabling powerful natural language queries.
// Configure DatabaseGPT with SQL Server provider builder.Services.AddDatabaseGpt( databaseGpt => { // Use fluent extension method for SQL Server databaseGpt.UseSqlServer(connectionString); // Optional: Restrict tables visible to AI databaseGpt.IncludedTables = ["dbo.Customers", "dbo.Orders", "dbo.Products"]; // Optional: Hide sensitive columns databaseGpt.ExcludedColumns = ["SSN", "CreditCardNumber", "Password"]; // Optional: Add business context for AI databaseGpt.SystemMessage = @" This is an e-commerce database. Orders are linked to Customers via CustomerId. Products have a CategoryId foreign key."; // Configure retry attempts for failed queries databaseGpt.MaxRetries = 3; }, chatGpt => { chatGpt.UseOpenAI(apiKey); chatGpt.DefaultModel = "gpt-4"; } );
// MySQL Configuration databaseGpt.UseMySql("Server=localhost;Database=shop;User=root;Password=***;"); // PostgreSQL Configuration databaseGpt.UseNpgsql("Host=localhost;Database=shop;Username=postgres;Password=***;"); // Oracle Configuration databaseGpt.UseOracle("Data Source=//localhost:1521/XE;User Id=system;Password=***;"); // SQLite Configuration databaseGpt.UseSqlite("Data Source=shop.db"); // Dynamic provider selection at runtime switch (databaseType) { case "SqlServer": databaseGpt.UseSqlServer(conn); break; case "MySql": databaseGpt.UseMySql(conn); break; case "Postgres": databaseGpt.UseNpgsql(conn); break; case "Oracle": databaseGpt.UseOracle(conn); break; case "Sqlite": databaseGpt.UseSqlite(conn); break; }
The journey from natural language question to database results
Users ask questions in plain English. No SQL knowledge required. The system understands context from previous questions in the session.
AI analyzes the question and identifies which database tables contain relevant data. It considers all available tables from the provider.
The provider generates CREATE TABLE scripts including columns, data types, constraints, and foreign key relationships for AI context.
Using schema knowledge, AI generates optimized SQL in the provider's specific dialect (T-SQL, MySQL, PL/SQL, etc.).
The query is normalized, validated as a SELECT statement, and executed through the provider's database connection with built-in retry logic.
| Package | Provider | Dependencies | Framework |
|---|---|---|---|
DatabaseGpt.Abstractions |
Core interfaces and exceptions | None | .NET 8.0+ |
DatabaseGpt |
Main client and DI extensions | ChatGptNet, Polly | .NET 8.0+ |
DatabaseGpt.SqlServer |
SQL Server | Microsoft.Data.SqlClient, Dapper | .NET 8.0+ |
DatabaseGpt.MySql |
MySQL | MySql.Data, Dapper | .NET 8.0+ |
DatabaseGpt.Npgsql |
PostgreSQL | Npgsql, Dapper | .NET 8.0+ |
DatabaseGpt.Oracle |
Oracle | Oracle.ManagedDataAccess.Core, Dapper | .NET 8.0+ |
DatabaseGpt.Sqlite |
SQLite | Microsoft.Data.Sqlite, Dapper | .NET 8.0+ |
The same natural language query, optimized for each database
"Show me the top 5 customers who spent the most money last year"
SELECT TOP 5 c.[CustomerName], SUM(o.[TotalAmount]) AS TotalSpent FROM [dbo].[Customers] c INNER JOIN [dbo].[Orders] o ON c.[CustomerId] = o.[CustomerId] WHERE o.[OrderDate] >= DATEADD(YEAR, -1, GETDATE()) GROUP BY c.[CustomerName] ORDER BY TotalSpent DESC
SELECT c.`CustomerName`, SUM(o.`TotalAmount`) AS TotalSpent FROM `shop`.`Customers` c INNER JOIN `shop`.`Orders` o ON c.`CustomerId` = o.`CustomerId` WHERE o.`OrderDate` >= DATE_SUB(NOW(), INTERVAL 1 YEAR) GROUP BY c.`CustomerName` ORDER BY TotalSpent DESC LIMIT 5
SELECT c."CustomerName", SUM(o."TotalAmount") AS "TotalSpent" FROM public."Customers" c INNER JOIN public."Orders" o ON c."CustomerId" = o."CustomerId" WHERE o."OrderDate" >= CURRENT_DATE - INTERVAL '1 year' GROUP BY c."CustomerName" ORDER BY "TotalSpent" DESC LIMIT 5
SELECT CustomerName, TotalSpent FROM ( SELECT c.CustomerName, SUM(o.TotalAmount) AS TotalSpent FROM SHOP.Customers c INNER JOIN SHOP.Orders o ON c.CustomerId = o.CustomerId WHERE o.OrderDate >= ADD_MONTHS(SYSDATE, -12) GROUP BY c.CustomerName ORDER BY TotalSpent DESC ) WHERE ROWNUM <= 5
Connect any supported database and start asking questions in seconds
// 1. Register the service builder.Services.AddDatabaseGpt( db => db.UseSqlServer(connectionString), gpt => gpt.UseOpenAI(apiKey) ); // 2. Inject the client public class QueryController(IDatabaseGptClient client) { // 3. Ask questions in natural language! public async Task<IActionResult> Query(string question) { var result = await client.ExecuteNaturalLanguageQueryAsync( Guid.NewGuid(), // Session ID for conversation context question ); // result.Query = Generated SQL // result.Reader = Data results return Ok(result); } }