Skip to content
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
2 changes: 1 addition & 1 deletion temporal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ if(WITH_DOCS)
generate_docs(temporalintro TARGET ALL_TEMPORAL_MODULES)
endif()

build_program_in_subdir(t.connect DEPENDS grass_gis grass_temporal)
build_program_in_subdir(t.connect DEPENDS grass_gis grass_temporal grass_parson)

foreach(temporal_DIR ${temporal_script_modules_list})
build_script_in_subdir(${temporal_DIR})
Expand Down
2 changes: 1 addition & 1 deletion temporal/t.connect/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MODULE_TOPDIR = ../..

LIBES = $(TEMPORALLIB) $(GISLIB)
LIBES = $(TEMPORALLIB) $(GISLIB) $(PARSONLIB)
DEPENDENCIES = $(TEMPORALDEP) $(GISDEP)

PGM = t.connect
Expand Down
122 changes: 106 additions & 16 deletions temporal/t.connect/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@
#include <grass/gis.h>
#include <grass/temporal.h>
#include <grass/glocale.h>
#include <grass/gjson.h>

enum OutputFormat { PLAIN, SHELL, JSON };

int main(int argc, char *argv[])
{
dbConnection conn;
struct Flag *print, *check_set_default, *def, *sh;
struct Option *driver, *database;
struct Option *driver, *database, *format_opt;
struct GModule *module;

enum OutputFormat format;
G_JSON_Value *root_value = NULL;
G_JSON_Object *root_object = NULL;

/* Initialize the GIS calls */
G_gisinit(argv[0]);

Expand All @@ -42,6 +49,15 @@ int main(int argc, char *argv[])
print->description = _("Print current connection parameters and exit");
print->guisection = _("Print");

format_opt = G_define_standard_option(G_OPT_F_FORMAT);
format_opt->options = "plain,shell,json";
format_opt->required = NO;
format_opt->answer = "plain";
format_opt->descriptions = _("plain;Plain text output;"
"shell;Shell script style output;"
"json;JSON (JavaScript Object Notation)");
format_opt->guisection = _("Print");

check_set_default = G_define_flag();
check_set_default->key = 'c';
check_set_default->description =
Expand All @@ -56,9 +72,12 @@ int main(int argc, char *argv[])

sh = G_define_flag();
sh->key = 'g';
sh->label = _("Print current connection parameters using shell style "
"and exit [deprecated]");
sh->description =
_("Print current connection parameter in shell style and exit");
sh->guisection = _("Set");
_("This flag is deprecated and will be removed in a future "
"release. Use format=shell instead.");
sh->guisection = _("Print");

driver = G_define_standard_option(G_OPT_DB_DRIVER);
driver->options = "sqlite,pg";
Expand All @@ -72,31 +91,102 @@ int main(int argc, char *argv[])
if (G_parser(argc, argv))
exit(EXIT_FAILURE);

if (format_opt->answer != NULL) {
if (strcmp(format_opt->answer, "json") == 0) {
format = JSON;
root_value = G_json_value_init_object();
if (root_value == NULL) {
G_fatal_error(
_("Failed to initialize JSON object. Out of memory?"));
}
root_object = G_json_object(root_value);
}
else if (strcmp(format_opt->answer, "shell") == 0) {
format = SHELL;
}
else {
format = PLAIN;
}
}
else {
format = PLAIN;
}

if (sh->answer) {
G_verbose_message(
_("Flag 'g' is deprecated and will be removed in a future "
Comment thread
saket0187 marked this conversation as resolved.
Resolved
"release. Please use format=shell instead."));
if (format == JSON) {
/* Free memory before failing to prevent memory leaks */
if (root_value)
G_json_value_free(root_value);
G_fatal_error(_("The -g flag cannot be used with format=json. "
"Please select only one output format."));
}
format = SHELL;
print->answer = 1;
}

if (format != PLAIN && !print->answer) {
G_fatal_error(
_("The -p flag is required when using the format option."));
}

if (print->answer) {
if (sh->answer) {
if (tgis_get_connection(&conn) == DB_OK) {
if (tgis_get_connection(&conn) == DB_OK) {
switch (format) {
case SHELL:
fprintf(stdout, "driver=%s\n",
conn.driverName ? conn.driverName : "");
fprintf(stdout, "database=%s\n",
conn.databaseName ? conn.databaseName : "");
}
else
G_fatal_error(_("Temporal GIS database connection not defined. "
"Run t.connect."));
}
else {
/* get and print connection */
if (tgis_get_connection(&conn) == DB_OK) {
break;

case PLAIN:
fprintf(stdout, "driver:%s\n",
conn.driverName ? conn.driverName : "");
fprintf(stdout, "database:%s\n",
conn.databaseName ? conn.databaseName : "");
break;

case JSON:
if (conn.driverName)
G_json_object_set_string(root_object, "driver",
conn.driverName);
else
G_json_object_set_null(root_object, "driver");

if (conn.databaseName)
G_json_object_set_string(root_object, "database",
conn.databaseName);
else
G_json_object_set_null(root_object, "database");
break;
}
}
else {
if (root_value)
G_json_value_free(root_value);
G_fatal_error(_("Temporal GIS database connection not defined. "
"Run t.connect."));
}

if (format == JSON) {
char *json_string = G_json_serialize_to_string_pretty(root_value);
if (!json_string) {
G_json_value_free(root_value);
G_fatal_error(_("Failed to serialize JSON to pretty format."));
}
else
G_fatal_error(_("Temporal GIS database connection not defined. "
"Run t.connect."));

fputs(json_string, stdout);
fputc('\n', stdout);

G_json_free_serialized_string(json_string);
G_json_value_free(root_value);
}

fflush(stdout);

exit(EXIT_SUCCESS);
}

Expand Down
7 changes: 4 additions & 3 deletions temporal/t.connect/t.connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ default setting is that the temporal database of type *sqlite3* is
located in the current mapset directory.

The **-p** flag will display the current temporal database connection
parameters.
parameters. Use the **format** option to specify the output format: `plain`,
`shell`, or `json` — with `plain` being the default.

The **-pg** flag will display the current temporal database connection
parameters using shell style.
The **-g** flag is deprecated and will be removed in a future release. Please
use **format=shell** option with the **-p** flag instead.

The **-c** flag will silently check if the temporal database connection
parameters have been set, and if not will set them to use GRASS's
Expand Down
33 changes: 31 additions & 2 deletions temporal/t.connect/tests/test_t_connect.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Test current baseline functionality of t.connect"""

from grass.tools import Tools
import pytest

from grass.tools import ToolError, Tools


def test_no_connection(empty_session):
Expand Down Expand Up @@ -28,8 +30,35 @@ def test_print_shell(t_connect_session):
"""Check that the shell format prints correctly."""
tools = Tools(session=t_connect_session.session)

result = tools.t_connect(flags="pg")
result = tools.t_connect(flags="p", format="shell")
lines = result.text_split("\n")

assert "driver=sqlite" in lines
assert "database=$GISDBASE/$LOCATION_NAME/$MAPSET/tgis/sqlite.db" in lines


def test_print_json(t_connect_session):
"""Check that the JSON format parses correctly and matches connection values."""
tools = Tools(session=t_connect_session.session)

result = tools.t_connect(flags="p", format="json")

assert result["driver"] == "sqlite"
assert result["database"] == "$GISDBASE/$LOCATION_NAME/$MAPSET/tgis/sqlite.db"


@pytest.mark.parametrize("output_format", ["shell", "json"])
def test_missing_print_flag(t_connect_session, output_format):
"""Ensure omitting the -p flag when requesting a format triggers a fatal error."""
tools = Tools(session=t_connect_session.session)

with pytest.raises(ToolError):
tools.t_connect(format=output_format)


def test_incompatible_flags(t_connect_session):
"""Ensure combining the deprecated -g flag with format=json triggers a fatal error."""
tools = Tools(session=t_connect_session.session)

with pytest.raises(ToolError):
tools.t_connect(flags="g", format="json")
Loading