Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ctk shell to also talk to CrateDB standalone databases #332

Merged
merged 1 commit into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Dependencies: Minimize dependencies of core installation,
defer `polars` to `cratedb-toolkit[io]`.
- Fixed `cratedb-wtf record` about too large values of `ulimit_hard`
- Improved `ctk shell` to also talk to CrateDB standalone databases

## 2024/10/13 v0.0.29
- MongoDB: Added Zyp transformations to the CDC subsystem,
Expand Down
22 changes: 18 additions & 4 deletions cratedb_toolkit/shell/cli.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import click

from cratedb_toolkit.cluster.util import get_cluster_info
from cratedb_toolkit.model import DatabaseAddress
from cratedb_toolkit.util.cli import boot_click
from cratedb_toolkit.util.crash import get_crash_output_formats, run_crash

output_formats = get_crash_output_formats()

cratedb_sqlalchemy_option = click.option(
"--cratedb-sqlalchemy-url", envvar="CRATEDB_SQLALCHEMY_URL", type=str, required=False, help="CrateDB SQLAlchemy URL"
)


@click.command()
@cratedb_sqlalchemy_option
@click.option(
"--cluster-id", envvar="CRATEDB_CLOUD_CLUSTER_ID", type=str, required=True, help="CrateDB Cloud cluster identifier"
"--cluster-id", envvar="CRATEDB_CLOUD_CLUSTER_ID", type=str, required=False, help="CrateDB Cloud cluster identifier"
)
@click.option("--username", envvar="CRATEDB_USERNAME", type=str, required=False, help="Username for CrateDB cluster")
@click.option("--password", envvar="CRATEDB_PASSWORD", type=str, required=False, help="Password for CrateDB cluster")
Expand All @@ -34,6 +40,7 @@
@click.pass_context
def cli(
ctx: click.Context,
cratedb_sqlalchemy_url: str,
cluster_id: str,
username: str,
password: str,
Expand All @@ -46,13 +53,20 @@
"""
Start an interactive database shell, or invoke SQL commands.

TODO: Only talks to CrateDB Cloud for now. Also implement for standalone CrateDB servers.
TODO: Learn/forward more options of `crash`.
"""
boot_click(ctx, verbose, debug)

cluster_info = get_cluster_info(cluster_id=cluster_id)
cratedb_http_url = cluster_info.cloud["url"]
if cratedb_sqlalchemy_url:
address = DatabaseAddress.from_string(cratedb_sqlalchemy_url)
cratedb_http_url = address.httpuri
elif cluster_id:
cluster_info = get_cluster_info(cluster_id=cluster_id)
cratedb_http_url = cluster_info.cloud["url"]

Check warning on line 65 in cratedb_toolkit/shell/cli.py

View check run for this annotation

Codecov / codecov/patch

cratedb_toolkit/shell/cli.py#L64-L65

Added lines #L64 - L65 were not covered by tests
else:
raise ValueError(
"Unknown database address, please specify either cluster id or database URI in SQLAlchemy format"
)

run_crash(
hosts=cratedb_http_url,
Expand Down
39 changes: 39 additions & 0 deletions tests/test_shell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import json

import pytest
from click.testing import CliRunner

from cratedb_toolkit.shell.cli import cli
from tests.conftest import TESTDRIVE_DATA_SCHEMA


def test_shell_success(cratedb):
"""
Verify successful incantation of `ctk shell`.
"""
runner = CliRunner()

database_url = cratedb.get_connection_url() + "?schema=" + TESTDRIVE_DATA_SCHEMA

result = runner.invoke(
cli,
args=f"--cratedb-sqlalchemy-url='{database_url}' --command 'SELECT 42 AS answer;' --format=json",
catch_exceptions=False,
)
assert result.exit_code == 0
assert json.loads(result.output) == [{"answer": 42}]


def test_shell_failure_no_address():
"""
Verify `ctk shell` fails when invoked without database address.
"""
runner = CliRunner()

with pytest.raises(ValueError) as ex:
runner.invoke(
cli,
args="--command 'SELECT 42 AS answer;' --format=json",
catch_exceptions=False,
)
assert ex.match("Unknown database address")
Loading