Interface DatabaseProvider

All Superinterfaces:
Serializable

public interface DatabaseProvider extends Serializable
Provider for database schema information and SQL query execution on behalf of an LLM. This interface enables AI-powered components to interact with application databases for features.

Applications implement this interface with their own database connection. The provider exposes the schema so the LLM can generate valid SQL, and executes the resulting queries.

Note: For security, the implementation should use a database account with read-only access limited to the relevant tables or views. This prevents the LLM from inadvertently modifying or deleting data.

 public class MyDatabaseProvider implements DatabaseProvider {

     private final DataSource readOnlyDataSource;

     public MyDatabaseProvider(DataSource readOnlyDataSource) {
         this.readOnlyDataSource = readOnlyDataSource;
     }

     @Override
     public String getSchema() {
         return "Tables: employees(id INT, name VARCHAR, dept VARCHAR), "
                 + "departments(id INT, name VARCHAR). Dialect: PostgreSQL.";
     }

     @Override
     public List<Map<String, Object>> executeQuery(String sql) {
         try (var connection = readOnlyDataSource.getConnection();
                 var statement = connection.prepareStatement(sql);
                 var resultSet = statement.executeQuery()) {
             // Convert to List<Map<String, Object>>
         }
     }
 }
 

Dynamic schema retrieval: Hand-writing the schema string works for small fixed schemas, but for larger schemas DatabaseMetaData builds the description at runtime from a truly read-only connection and works consistently across H2, MySQL, and PostgreSQL. Including primary and foreign keys helps the LLM pick correct joins rather than guessing them from column names:

 @Override
 public String getSchema() {
     try (var connection = readOnlyDataSource.getConnection()) {
         var meta = connection.getMetaData();
         var catalog = connection.getCatalog();
         var schemaName = connection.getSchema();
         var schema = new StringBuilder();
         try (var tables = meta.getTables(catalog, schemaName, "%",
                 new String[] { "TABLE" })) {
             while (tables.next()) {
                 var table = tables.getString("TABLE_NAME");
                 // Append columns via meta.getColumns(catalog, schemaName,
                 // table, "%")
                 // Append primary keys via meta.getPrimaryKeys(catalog,
                 // schemaName, table)
                 // Append foreign keys via meta.getImportedKeys(catalog,
                 // schemaName, table)
             }
         }
         return schema.toString();
     } catch (SQLException e) {
         throw new RuntimeException(e);
     }
 }
 
Author:
Vaadin Ltd
  • Method Summary

    Modifier and Type
    Method
    Description
    Executes the given SQL query and returns the results.
    Returns a text description of the database schema available to the LLM.
  • Method Details

    • getSchema

      String getSchema()
      Returns a text description of the database schema available to the LLM. The description should include table names, column names with their types, and optionally the SQL dialect (e.g., PostgreSQL, MySQL). The LLM uses this information to generate valid SQL queries.

      See the class-level "Dynamic schema retrieval" section for a DatabaseMetaData-based example that builds this description at runtime.

      Returns:
      a text description of the database schema, never null
    • executeQuery

      List<Map<String,Object>> executeQuery(String sql)
      Executes the given SQL query and returns the results. Each row is represented as a map from column name to column value.

      Implementations should ensure that only read-only queries are executed.

      Parameters:
      sql - the SQL query to execute, not null
      Returns:
      the query results as a list of column-name-to-value maps, never null but may be empty
      Throws:
      NullPointerException - if the query is null
      IllegalArgumentException - if the query is invalid