diff --git a/python/grass/temporal/core.py b/python/grass/temporal/core.py index 67d26a8b1d6..c992d9b5276 100644 --- a/python/grass/temporal/core.py +++ b/python/grass/temporal/core.py @@ -543,7 +543,11 @@ def get_available_temporal_mapsets(): ############################################################################### -def init(raise_fatal_error: bool = False, skip_db_version_check: bool = False): +def init( + raise_fatal_error: bool = False, + skip_db_version_check: bool = False, + skip_db_init: bool = False, +): """This function set the correct database backend from GRASS environmental variables and creates the grass temporal database structure for raster, vector and raster3d maps as well as for the space-time datasets strds, @@ -588,6 +592,14 @@ def init(raise_fatal_error: bool = False, skip_db_version_check: bool = False): database version check. Recommended to be used only for upgrade_temporal_database(). + :param skip_db_init: Set this True to allow init() to complete + without initializing, (version) checking or creating + a temporal database in the current mapset. + Use this when the calling process only needs the + global TGIS state (backend, mapset, interfaces) + but does not require a temporal database in the + current mapset for operations (like listing + datasets, getting metainformation, ...). """ # We need to set the correct database backend and several global variables # from the GRASS mapset specific environment variables of g.gisenv and t.connect @@ -600,9 +612,6 @@ def init(raise_fatal_error: bool = False, skip_db_version_check: bool = False): raise_on_error = raise_fatal_error - # We must run t.connect at first to create the temporal database and to - # get the environmental variables - gs.run_command("t.connect", flags="c") grassenv = gs.gisenv() new_mapset = grassenv["MAPSET"] @@ -647,14 +656,11 @@ def init(raise_fatal_error: bool = False, skip_db_version_check: bool = False): # Start the C-library interface server _init_tgis_c_library_interface() msgr = get_tgis_message_interface() - msgr.debug(1, "Initiate the temporal database") msgr.debug(1, ("Raise on error id: %s" % str(raise_on_error))) ciface = get_tgis_c_library_interface() current_mapset = decode(gs.gisenv().get("MAPSET")) - driver_string = ciface.get_driver_name(current_mapset) - database_string = ciface.get_database_name(current_mapset) # Set the mapset check and the timestamp write if "TGIS_DISABLE_MAPSET_CHECK" in grassenv: @@ -673,6 +679,15 @@ def init(raise_fatal_error: bool = False, skip_db_version_check: bool = False): enable_timestamp_write = False msgr.warning("TGIS_DISABLE_TIMESTAMP_WRITE is True") + if skip_db_init: + return + + # We must run t.connect at first to create the temporal database and to + # get the environmental variables + msgr.debug(1, "Initiate the temporal database") + gs.run_command("t.connect", flags="c") + driver_string = ciface.get_driver_name(current_mapset) + database_string = ciface.get_database_name(current_mapset) if driver_string is not None and driver_string != "": driver_string = decode(driver_string) if driver_string == "sqlite": diff --git a/temporal/t.info/t.info.py b/temporal/t.info/t.info.py index c04fe0c0a5f..6bc2197c933 100755 --- a/temporal/t.info/t.info.py +++ b/temporal/t.info/t.info.py @@ -54,6 +54,10 @@ # % suppress_required: yes # %end +# %rules +# % required: -d, input +# %end + import grass.script as gs ############################################################################ @@ -63,16 +67,59 @@ def main(): # lazy imports import grass.temporal as tgis - name = options["input"] - type_ = options["type"] + # Make sure the temporal database exists + tgis.init(skip_db_init=True) + + def get_stds( + name: str, + mapset: str | None, + stds_type: str, + dbif: tgis.SQLDatabaseInterfaceConnection, + ) -> tgis.STDSBase: + """Get a space time dataset from the temporal database connection. + + Returns None if the dataset is not found in the temporal database. + + :param name: Name of the space time dataset + :param mapset: Mapset of the space time dataset + :param stds_type: Type of the space time dataset + :param dbif: Database interface connection + :return: The space time dataset object or None if not found + """ + dataset = None + msg = _("Dataset <{n}> of type <{t}> not found in temporal database").format( + n=options["input"], t=stds_type + ) + if mapset: + dataset = tgis.dataset_factory(stds_type, f"{name}@{mapset}") + if not dataset.is_in_db(dbif): + gs.fatal(msg) + return dataset + # Try current mapset first + stds_id = f"{name}@{tgis.get_current_mapset()}" + dataset = tgis.dataset_factory(stds_type, stds_id) + if dataset.is_in_db(dbif): + return dataset + # Try all other available mapsets with a temporal database + for mapset in dbif.tgis_mapsets.keys(): + stds_id = f"{name}@{mapset}" + dataset = tgis.dataset_factory(stds_type, stds_id) + if dataset.is_in_db(dbif): + return dataset + gs.fatal(msg) + + mapset = None + if "@" in options["input"]: + name, mapset = options["input"].split("@", 1) + else: + name = options["input"] + + stds_type = options["type"] shellstyle = flags["g"] system = flags["d"] history = flags["h"] - # Make sure the temporal database exists - tgis.init() - - dbif, connection_state_changed = tgis.init_dbif(None) + dbif = tgis.SQLDatabaseInterfaceConnection(mapsets=mapset) rows = tgis.get_tgis_metadata(dbif) @@ -100,22 +147,11 @@ def main(): print("%s='%s'" % (row[0], row[1])) return - if not system and not name: - gs.fatal(_("Please specify %s=") % ("name")) - - id_ = name if name.find("@") >= 0 else name + "@" + gs.gisenv()["MAPSET"] - dataset = tgis.dataset_factory(type_, id_) - - if not dataset.is_in_db(dbif): - gs.fatal( - _("Dataset <{n}> of type <{t}> not found in temporal database").format( - n=id_, t=type_ - ) - ) + dataset = get_stds(name, mapset, stds_type, dbif) dataset.select(dbif) - if history and type_ in {"strds", "stvds", "str3ds"}: + if history and stds_type in {"strds", "stvds", "str3ds"}: dataset.print_history() return