Skip to content

feat: scope all commands to active database; remove connections command#221

Merged
eddietejeda merged 13 commits into
mainfrom
feat/tables-list-active-db
Jul 10, 2026
Merged

feat: scope all commands to active database; remove connections command#221
eddietejeda merged 13 commits into
mainfrom
feat/tables-list-active-db

Conversation

@eddietejeda

@eddietejeda eddietejeda commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Remove connections commandhotdata connections is gone entirely; the internal resolver is kept as a private helper used by indexes and databases attach/detach
  • tables list — scopes to the active database when one is set (hotdata databases set <id>); --table, --schema, --limit, and --cursor all work within that scope; falls back to workspace-wide listing when no database is active
  • tables show <schema.table> — new subcommand; accepts schema.table (resolves catalog from active database) or catalog.schema.table; displays columns with data types
  • results show <id> — new subcommand; downloads and prints a stored result by ID
  • indexes list — scopes to the active database's connection when one is set; workspace-wide otherwise; --connection-id flag removed
  • indexes delete--connection-id removed; --catalog is now the only scope flag (resolves via the same catalog to connection resolver used by indexes create)
  • search --table — changed from connection.table / connection.schema.table to schema.table (active database) or catalog.schema.table; 2-part form resolves the catalog from the active database automatically
  • Error messages — "no connection named or with id" replaced with "no catalog with id"; all user-facing connection terminology removed

Behavior

With an active database set (hotdata databases set <id>):

  • hotdata tables list — shows only that database's tables, catalog-prefixed (default.public.cpi)
  • hotdata tables list --table foo --limit 10 — filter and pagination work within the active database
  • hotdata tables show public.orders — resolves catalog from active DB
  • hotdata search "query" --table public.orders — resolves catalog from active DB
  • hotdata indexes list — scoped to active DB's connection

Without an active database: all commands fall back to workspace-wide behavior (same as before).

Test plan

  • tables list with no filter, --table, --schema, --limit, --cursor — all scoped to active DB
  • tables show schema.table and catalog.schema.table — both resolve correctly
  • results show <id> — downloads and prints stored result
  • indexes create --catalog / list / delete --catalog — full lifecycle, no --connection-id
  • search --table schema.table and catalog.schema.table — resolves active DB catalog
  • All commands tested with no active database set — correct fallback or clear error
  • Fuzz tested: bad table formats, empty strings, SQL injection, unicode, garbage cursors — all exit cleanly with appropriate error messages

Comment thread src/main.rs Outdated
Comment on lines +493 to +502
if connection_id.is_none()
&& crate::config::load_current_database("default", &workspace_id)
.is_some()
{
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When an active database is set (and no --connection-id), this branch routes to databases::tables_list(workspace_id, None, schema, output), which silently drops the --table, --limit, and --cursor flags the user may have passed. tables list --table users (or --limit 5, or --cursor <c>) will now return all tables in the active database with no error or warning — a misleading result, since the user explicitly asked to filter/paginate.

Two reasonable fixes:

  • Fall through to tables::list whenever any of table, limit, or cursor is provided, e.g. gate the new branch on connection_id.is_none() && table.is_none() && limit.is_none() && cursor.is_none() && <active db set>; or
  • Emit a warning to stderr that these flags are ignored in active-database mode.

Silently ignoring explicit user input here is a correctness concern.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

Blocking Issues

  • src/main.rs (lines 493-502): The new active-database branch calls databases::tables_list, which does not accept the --table, --limit, or --cursor flags. When an active database is set and none of these are consumed, the flags are silently ignored, so tables list --table users returns all tables instead of the filtered subset - a misleading result with no error or warning.

Action Required

  • Either gate the new branch so it is only taken when table, limit, and cursor are all None (falling through to tables::list otherwise), or warn on stderr that these flags are ignored in active-database mode.

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 37.93103% with 198 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/commands/tables.rs 0.00% 117 Missing ⚠️
src/main.rs 14.51% 53 Missing ⚠️
src/commands/databases.rs 74.50% 26 Missing ⚠️
src/commands/connections.rs 0.00% 1 Missing ⚠️
src/commands/results.rs 94.44% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Comment thread src/main.rs
Comment on lines +416 to +421
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking (from cycle 1, still unaddressed): this active-database branch calls databases::tables_list(workspace_id, None, schema, output), whose signature only accepts (workspace_id, database, schema, format). The user's --table, --limit, and --cursor flags are structurally dropped, so tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database with no error or warning — a misleading result when the user explicitly asked to filter/paginate.

The branch condition still only checks connection_id.is_none() && <active db set>; it does not account for these flags.

Suggested fix — gate the branch so it only fires when none of these flags are set, otherwise fall through to tables::list:

Suggested change
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)
if connection_id.is_none()
&& table.is_none()
&& limit.is_none()
&& cursor.is_none()
&& crate::config::load_current_database("default", &workspace_id)
.is_some()
{
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

(Alternatively, emit a stderr warning that these flags are ignored in active-database mode.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review — Blocking

src/main.rs (lines 416-421): The active-database branch calls databases::tables_list, which only accepts (workspace_id, database, schema, format). The user's --table, --limit, and --cursor flags are silently dropped, so 'tables list --table users' returns all tables in the active database with no error or warning. This is the same blocking issue raised in the prior review; the code has not changed.

Action required: Gate the new branch on connection_id.is_none() together with table.is_none(), limit.is_none(), and cursor.is_none() (falling through to tables::list otherwise), or emit a stderr warning that these flags are ignored in active-database mode.

Comment thread src/main.rs
Comment on lines +411 to +417
if crate::config::load_current_database("default", &workspace_id).is_some() {
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking (from cycles 1 and 2, still unaddressed): this active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), whose signature is only (workspace_id, database, schema, format). The destructured table, limit, and cursor flags are structurally dropped here — they're only used in the else branch. So with an active database set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database, ignoring the filter/pagination the user explicitly requested.

The branch condition is still just load_current_database(...).is_some(); it doesn't account for these flags.

Suggested fix — only take this branch when none of those flags are set, otherwise fall through to tables::list:

Suggested change
if crate::config::load_current_database("default", &workspace_id).is_some() {
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)
if table.is_none()
&& limit.is_none()
&& cursor.is_none()
&& crate::config::load_current_database("default", &workspace_id)
.is_some()
{
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

(Alternatively, emit a stderr warning that these flags are ignored in active-database mode.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review — Blocking

src/main.rs:411-417 — The active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), which accepts only (workspace_id, database, schema, format). The --table, --limit, and --cursor flags are silently dropped, so with an active database set tables list --table users (or --limit 5 / --cursor <c>) returns all tables in the active database, ignoring the filter/pagination the user requested. Flagged in cycles 1 and 2, still unaddressed.

Action required: Gate the active-database branch so it only fires when table, limit, and cursor are all unset, otherwise fall through to tables::list (or emit a stderr warning that these flags are ignored). See inline comment for a suggested diff.

Comment thread src/main.rs
Comment on lines +411 to +417
if crate::config::load_current_database("default", &workspace_id).is_some() {
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking (from cycles 1, 2, and 3, still unaddressed): this active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), whose signature is only (workspace_id, database, schema, format). The destructured table, limit, and cursor flags are structurally dropped here — they are only used in the else branch. So with an active database set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database, ignoring the filter/pagination the user explicitly requested.

The branch condition is still just load_current_database(...).is_some(); it does not account for these flags.

Only take this branch when none of those flags are set, otherwise fall through to tables::list:

Suggested change
if crate::config::load_current_database("default", &workspace_id).is_some() {
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)
if table.is_none()
&& limit.is_none()
&& cursor.is_none()
&& crate::config::load_current_database("default", &workspace_id)
.is_some()
{
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

(Alternatively, emit a stderr warning that these flags are ignored in active-database mode.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

Blocking Issues

  • src/main.rs:411-417 — The active-database branch in TablesCommands::List calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), which structurally drops the destructured table, limit, and cursor flags. When an active database is set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables, ignoring the filter/pagination the user requested. Flagged in cycles 1-3, still unaddressed.

Action Required

Gate the active-database branch so it only fires when table, limit, and cursor are all None, falling through to tables::list otherwise (or emit a stderr warning that these flags are ignored in active-database mode). See inline comment for a suggested diff.

Comment thread src/main.rs
Comment on lines +411 to +417
if crate::config::load_current_database("default", &workspace_id).is_some() {
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking (from cycles 1–4, still unaddressed): this active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), whose signature is only (workspace_id, database, schema, format). The destructured table, limit, and cursor flags are structurally dropped here — they are only used in the else branch. So with an active database set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database, ignoring the filter/pagination the user explicitly requested.

The branch condition is still just load_current_database(...).is_some(); it does not account for these flags.

Only take this branch when none of those flags are set, otherwise fall through to tables::list:

Suggested change
if crate::config::load_current_database("default", &workspace_id).is_some() {
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)
if table.is_none()
&& limit.is_none()
&& cursor.is_none()
&& crate::config::load_current_database("default", &workspace_id)
.is_some()
{
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

(Alternatively, emit a stderr warning that these flags are ignored in active-database mode.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

Blocking Issues

  • src/main.rs:411-417tables list active-database branch drops the --table, --limit, and --cursor flags. When an active database is set, databases::tables_list(&workspace_id, None, schema.as_deref(), &output) is called, and that signature has no place for those flags. As a result tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database, ignoring the filter/pagination the user explicitly requested. Flagged in cycles 1–4 and still unaddressed.

Action Required

Gate the active-database branch on table.is_none() && limit.is_none() && cursor.is_none() && load_current_database(...).is_some() so it falls through to tables::list when any of those flags are set, or emit a stderr warning that they are ignored in active-database mode.

Comment thread src/main.rs
cursor.as_deref(),
&output,
)
if crate::config::load_current_database("default", &workspace_id).is_some() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking (from cycles 1–5, still unaddressed): this active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), whose signature is only (workspace_id, database, schema, format). The destructured table, limit, and cursor flags are structurally dropped here — they are only used in the else branch. So with an active database set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database, ignoring the filter/pagination the user explicitly requested.

The branch condition is still just load_current_database(...).is_some(); it does not account for these flags.

Only take this branch when none of those flags are set, otherwise fall through to tables::list:

Suggested change
if crate::config::load_current_database("default", &workspace_id).is_some() {
if table.is_none()
&& limit.is_none()
&& cursor.is_none()
&& crate::config::load_current_database("default", &workspace_id)
.is_some()
{
databases::tables_list(
&workspace_id,
None,
schema.as_deref(),
&output,
)

(Alternatively, emit a stderr warning that these flags are ignored in active-database mode.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

Blocking Issues

  • src/main.rs:411 — The active-database branch of tables list gates only on load_current_database(...).is_some() and calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), structurally dropping the destructured --table, --limit, and --cursor flags. With an active database set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables, ignoring the filter/pagination the user explicitly requested. Flagged in cycles 1–5, still unaddressed.

Action Required

Gate the active-database branch on table.is_none() && limit.is_none() && cursor.is_none() so it only fires when none of those flags are set, otherwise fall through to tables::list (which honors them). Alternatively, emit a stderr warning that these flags are ignored in active-database mode.

Comment thread src/main.rs
cursor.as_deref(),
&output,
)
if crate::config::load_current_database("default", &workspace_id).is_some() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking (from cycles 1–6, still unaddressed): this active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), whose signature is only (workspace_id, database, schema, format) (src/commands/databases.rs:1336). The destructured table, limit, and cursor flags are structurally dropped here — they are only used in the else branch. So with an active database set, tables list --table users (or --limit 5 / --cursor <c>) silently returns all tables in the active database, ignoring the filter/pagination the user explicitly requested.

The branch condition is still just load_current_database(...).is_some(); it does not account for these flags.

Only take this branch when none of those flags are set, otherwise fall through to tables::list:

Suggested change
if crate::config::load_current_database("default", &workspace_id).is_some() {
if table.is_none()
&& limit.is_none()
&& cursor.is_none()
&& crate::config::load_current_database("default", &workspace_id).is_some()
{

(Alternatively, emit a stderr warning that these flags are ignored in active-database mode.)

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

Blocking Issues

  • src/main.rs:411 — the tables list active-database branch calls databases::tables_list(&workspace_id, None, schema.as_deref(), &output), which has no parameters for table, limit, or cursor. These flags are structurally dropped, so with an active database set, "tables list --table users" (or --limit 5 / --cursor) silently returns all tables, ignoring the filter/pagination the user requested. Unaddressed since cycle 1.

Action Required
Gate the active-database branch on table.is_none() && limit.is_none() && cursor.is_none() && load_current_database(...).is_some() so these flags fall through to tables::list, or emit a stderr warning that they are ignored in active-database mode.

claude[bot]
claude Bot previously approved these changes Jul 10, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cycle 8: The prior blocking issue (tables list silently dropping --table/--limit/--cursor in active-database mode) is resolved. use_db_path now gates on limit.is_none() && cursor.is_none() (src/main.rs:413-414), and --table is forwarded to databases::tables_list (src/main.rs:422), whose signature was updated to filter accordingly (src/commands/databases.rs:1345,1356). No new blocking issues.

claude[bot]
claude Bot previously approved these changes Jul 10, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Blocking issue from cycles 1–7 (tables list dropping --table/--limit/--cursor in active-database mode) is resolved: databases::tables_list now accepts and forwards those flags to collect_tables, and main.rs:418-426 passes them through. No new issues.

claude[bot]
claude Bot previously approved these changes Jul 10, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The blocking issue from prior cycles is resolved: databases::tables_list now accepts table, limit, and cursor, and the active-database branch in src/main.rs passes all three through — so tables list --table/--limit/--cursor are no longer silently dropped. This is a cleaner fix than the fall-through I suggested. No remaining blocking issues.

@eddietejeda eddietejeda changed the title feat: scope tables list to active database when set feat: scope all commands to active database; remove connections command Jul 10, 2026
claude[bot]
claude Bot previously approved these changes Jul 10, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cycle 8: The blocking issue tracked since cycle 1 — the active-database tables list branch dropping --table/--limit/--cursor — is resolved. databases::tables_list now accepts and forwards all three flags to collect_tables, and main.rs passes them through. Test coverage is present. No remaining blocking issues.

When a database is active, indexes list automatically narrows to that
database connection ID. Falls back to workspace-wide when none is set.
…active DB

--table now accepts schema.table (resolves catalog from active database)
or the full catalog.schema.table form. Removes the old connection.table
syntax. Also updates hotdata-search SKILL.md to match.
…ursor

When an active database is set, --table now passes through to the API
instead of being silently dropped. --limit and --cursor fall through to
tables::list (which supports pagination) rather than the active-db path.
…imit/--cursor

P1: Remove stale tests that pattern-matched IndexesCommands::Delete with
the old connection_id field; update to match the new catalog-only shape.

P2: tables list now always uses the active-database path when a DB is set,
even with --limit/--cursor. collect_tables does a single paged fetch when
limit/cursor are provided, so pagination works and the TABLE column stays
catalog-prefixed.
…w args

Fixes failing table-filter test: mockito matcher used 'table_name' but the SDK
sends 'table' as the query parameter.
@eddietejeda
eddietejeda dismissed claude[bot]’s stale review July 10, 2026 05:26

The merge-base changed after approval.

@eddietejeda
eddietejeda force-pushed the feat/tables-list-active-db branch from ce14185 to 5707cbc Compare July 10, 2026 05:26

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prior blocking issue (cycles 1–7) is resolved: databases::tables_list now accepts and forwards table/limit/cursor (main.rs:417) to collect_tables, which honors them, with test coverage. No flags are dropped in active-database mode. No new blocking issues.

@eddietejeda
eddietejeda merged commit 2c136bf into main Jul 10, 2026
13 checks passed
@eddietejeda
eddietejeda deleted the feat/tables-list-active-db branch July 10, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant