Feature: DatabaseResourceHandler CRUD and checkpoint methods
  As a CleverAgents developer
  I want DatabaseResourceHandler to implement full CRUD and checkpoint methods
  So that SQLite databases can be read, written, deleted, listed, diffed, and checkpointed

  Issue #1241: DatabaseResourceHandler CRUD and checkpoint methods

  # ============================================================
  # read() — SQLite schema query
  # ============================================================

  Scenario: read() returns schema for SQLite database with tables
    Given a SQLite database with tables "users" and "orders"
    When I read from the database handler
    Then the db read content should contain "users"
    And the db read content should contain "orders"
    And the db read content encoding should be "utf-8"
    And the db read content hash should not be empty

  Scenario: read() returns empty schema for empty SQLite database
    Given an empty SQLite database file
    When I read from the database handler
    Then the db read content encoding should be "utf-8"
    And the db read content data should be empty or whitespace

  Scenario: read() returns connection-info summary for remote database
    Given a remote postgres database resource with location "postgresql://localhost/mydb"
    When I read from the database handler
    Then the db read content should contain "postgres"
    And the db read content should contain "mydb"
    And the db read content encoding should be "utf-8"

  Scenario: read() returns empty content for resource with no location
    Given a database resource with no location
    When I read from the database handler
    Then the db read content data should be empty or whitespace

  Scenario: read() handles SQLite error gracefully
    Given a database resource pointing to a non-existent SQLite path
    When I read from the database handler
    Then no db exceptions should have been raised

  # ============================================================
  # write() — SQLite SQL execution
  # ============================================================

  Scenario: write() executes SQL on SQLite database
    Given a SQLite database with table "items"
    When I write SQL "INSERT INTO items (id, name) VALUES (1, 'apple')" to the database handler
    Then the db write result should be successful
    And the SQLite table "items" should contain 1 row

  Scenario: write() creates a new table via SQL
    Given an empty SQLite database file
    When I write SQL "CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT)" to the database handler
    Then the db write result should be successful
    And the SQLite database should have table "products"

  Scenario: write() returns not-supported for remote postgres database
    Given a remote postgres database resource with location "postgresql://localhost/mydb"
    When I write SQL "SELECT 1" to the database handler
    Then the db write result should not be successful
    And the db write result message should mention "not supported"

  Scenario: write() returns not-supported for remote mysql database
    Given a remote mysql database resource with location "mysql://localhost/mydb"
    When I write SQL "SELECT 1" to the database handler
    Then the db write result should not be successful
    And the db write result message should mention "not supported"

  Scenario: write() returns failure for resource with no location
    Given a database resource with no location
    When I write SQL "SELECT 1" to the database handler
    Then the db write result should not be successful

  Scenario: write() returns failure for invalid SQL
    Given an empty SQLite database file
    When I write SQL "THIS IS NOT SQL" to the database handler
    Then the db write result should not be successful
    And the db write result message should mention "error"

  # ============================================================
  # delete() — SQLite DROP TABLE
  # ============================================================

  Scenario: delete() drops a table from SQLite database
    Given a SQLite database with table "temp_data"
    When I delete table "temp_data" from the database handler
    Then the db delete result should be successful
    And the SQLite database should not have table "temp_data"

  Scenario: delete() with non-existent table succeeds (DROP TABLE IF EXISTS)
    Given an empty SQLite database file
    When I delete table "ghost_table" from the database handler
    Then the db delete result should be successful

  Scenario: delete() with empty path returns failure
    Given an empty SQLite database file
    When I delete with empty path from the database handler
    Then the db delete result should not be successful
    And the db delete result message should mention "table name"

  Scenario: delete() returns not-supported for remote postgres database
    Given a remote postgres database resource with location "postgresql://localhost/mydb"
    When I delete table "users" from the database handler
    Then the db delete result should not be successful
    And the db delete result message should mention "not supported"

  Scenario: delete() returns failure for resource with no location
    Given a database resource with no location
    When I delete table "users" from the database handler
    Then the db delete result should not be successful

  # ============================================================
  # list_children() — SQLite tables/views
  # ============================================================

  Scenario: list_children() returns table names for SQLite database
    Given a SQLite database with tables "alpha" and "beta"
    When I list children from the database handler
    Then the db children list should contain "alpha"
    And the db children list should contain "beta"
    And the db children list should be sorted

  Scenario: list_children() returns empty list for empty SQLite database
    Given an empty SQLite database file
    When I list children from the database handler
    Then the db children list should be empty

  Scenario: list_children() returns empty list for remote database
    Given a remote postgres database resource with location "postgresql://localhost/mydb"
    When I list children from the database handler
    Then the db children list should be empty

  Scenario: list_children() returns empty list for resource with no location
    Given a database resource with no location
    When I list children from the database handler
    Then the db children list should be empty

  # ============================================================
  # diff() — schema hash comparison
  # ============================================================

  Scenario: diff() detects no changes between identical SQLite databases
    Given a SQLite database with table "same_table"
    And a second SQLite database with the same schema
    When I diff the database handler against the second database
    Then the db diff result should have no changes

  Scenario: diff() detects changes between different SQLite databases
    Given a SQLite database with table "table_a"
    And a second SQLite database with table "table_b"
    When I diff the database handler against the second database
    Then the db diff result should have changes

  Scenario: diff() compares remote database by identity hash
    Given a remote postgres database resource with location "postgresql://localhost/db1"
    And a second remote database location "postgresql://localhost/db2"
    When I diff the database handler against the second remote location
    Then the db diff result should have changes

  # ============================================================
  # create_checkpoint() — SQLite SAVEPOINT
  # ============================================================

  Scenario: create_checkpoint() creates a SAVEPOINT on SQLite database
    Given a SQLite database with table "checkpoint_test"
    And a mock sandbox manager
    When I create a checkpoint with plan "PLAN-CKPT-001" on the database handler
    Then the db checkpoint result should have a checkpoint_id
    And the db checkpoint result plan_id should be "PLAN-CKPT-001"
    And the db checkpoint result message should mention "SAVEPOINT"

  Scenario: create_checkpoint() returns content-hash checkpoint for remote database
    Given a remote postgres database resource with location "postgresql://localhost/mydb"
    And a mock sandbox manager
    When I create a checkpoint with plan "PLAN-CKPT-002" on the database handler
    Then the db checkpoint result should have a checkpoint_id
    And the db checkpoint result message should mention "hash"

  # ============================================================
  # rollback_to() — SQLite ROLLBACK TO SAVEPOINT
  # ============================================================

  Scenario: rollback_to() rolls back SQLite changes to SAVEPOINT
    Given a SQLite database with table "rollback_test"
    And a mock sandbox manager
    When I create a checkpoint with plan "PLAN-RB-001" on the database handler
    And I insert a row into "rollback_test" via the database handler
    And I rollback to the last checkpoint on the database handler
    Then the db rollback result should be successful
    And the SQLite table "rollback_test" should contain 0 row

  Scenario: rollback_to() returns failure for unknown checkpoint_id
    Given a SQLite database with table "rollback_test2"
    And a mock sandbox manager
    When I rollback to checkpoint "nonexistent-ckpt" on the database handler
    Then the db rollback result should not be successful
    And the db rollback result message should mention "not found"

  Scenario: rollback_to() returns not-supported for remote database
    Given a remote postgres database resource with location "postgresql://localhost/mydb"
    And a mock sandbox manager
    When I rollback to checkpoint "some-ckpt" on the database handler
    Then the db rollback result should not be successful
    And the db rollback result message should mention "not supported"

  # ============================================================
  # Error handling
  # ============================================================

  Scenario: All methods handle missing location gracefully
    Given a database resource with no location
    And a mock sandbox manager
    When I read from the database handler
    And I write SQL "SELECT 1" to the database handler
    And I delete with empty path from the database handler
    And I list children from the database handler
    Then no db exceptions should have been raised
