From ce6ab45734b5b68eab7983fd01020e114a7c74b8 Mon Sep 17 00:00:00 2001 From: signedav Date: Thu, 7 Nov 2024 15:10:49 +0100 Subject: [PATCH] create display expression for domains with translation considerations - this fixes #115 and https://github.com/opengisch/QgisModelBaker/issues/982 --- modelbaker/dbconnector/db_connector.py | 6 +++++ modelbaker/dbconnector/gpkg_connector.py | 20 +++++++++++++++ modelbaker/dbconnector/pg_connector.py | 23 +++++++++++++++++ modelbaker/generator/generator.py | 24 ++++++++++++++++++ tests/test_translations.py | 32 ++++++++++++++++++++++-- 5 files changed, 103 insertions(+), 2 deletions(-) diff --git a/modelbaker/dbconnector/db_connector.py b/modelbaker/dbconnector/db_connector.py index b8e8847..3906928 100644 --- a/modelbaker/dbconnector/db_connector.py +++ b/modelbaker/dbconnector/db_connector.py @@ -433,6 +433,12 @@ def get_available_languages(self, irrelevant_models: list[str]) -> list[str]: """ return [] + def get_domain_dispnames(self, tablename): + """ + Get the domain display names with consideration of the translation + """ + return [] + class DBConnectorError(Exception): """This error is raised when DbConnector could not connect to database. diff --git a/modelbaker/dbconnector/gpkg_connector.py b/modelbaker/dbconnector/gpkg_connector.py index 95552bb..4878fed 100644 --- a/modelbaker/dbconnector/gpkg_connector.py +++ b/modelbaker/dbconnector/gpkg_connector.py @@ -1256,3 +1256,23 @@ def get_available_languages(self, irrelevant_models=[]): records = cursor.fetchall() cursor.close() return [record["lang"] for record in records] + + def get_domain_dispnames(self, tablename): + if not self._table_exists or not self._table_exists(GPKG_NLS_TABLE): + return [] + + cursor = self.conn.cursor() + cursor.execute( + """SELECT t.iliCode as code, nls.label as label + FROM "{tablename}" t + LEFT JOIN "{t_ili2db_nls}" nls + ON nls.ilielement = (t.thisClass||'.'||t.iliCode) and lang = '{lang}' + ; + """.format( + tablename=tablename, t_ili2db_nls=GPKG_NLS_TABLE, lang=self._lang + ) + ) + records = cursor.fetchall() + cursor.close() + + return records diff --git a/modelbaker/dbconnector/pg_connector.py b/modelbaker/dbconnector/pg_connector.py index e3df395..c10daf9 100644 --- a/modelbaker/dbconnector/pg_connector.py +++ b/modelbaker/dbconnector/pg_connector.py @@ -1393,3 +1393,26 @@ def get_available_languages(self, irrelevant_models=[]): ) return [row["lang"] for row in cur.fetchall()] return [] + + def get_domain_dispnames(self, tablename): + if self.schema and self._table_exists and self._table_exists(PG_NLS_TABLE): + cur = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) + cur.execute( + sql.SQL( + """SELECT t.iliCode as code, nls.label as label + FROM {schema}.{tablename} t + LEFT JOIN {schema}.{t_ili2db_nls} nls + ON nls.ilielement = (t.thisClass||'.'||t.iliCode) and lang = %s + ; + """ + ).format( + schema=sql.Identifier(self.schema), + tablename=sql.Identifier(tablename), + t_ili2db_nls=sql.Identifier(PG_NLS_TABLE), + ), + (self._lang,), + ) + records = cur.fetchall() + + return records + return [] diff --git a/modelbaker/generator/generator.py b/modelbaker/generator/generator.py index fe828ca..0e2b38e 100644 --- a/modelbaker/generator/generator.py +++ b/modelbaker/generator/generator.py @@ -251,6 +251,27 @@ def layers(self, filter_layer_list: list = []) -> list[Layer]: ]: display_expression = attr_record["attr_value"] + # for the domain we create a translated mapping expression in case there is not yet a displayexpression defined + if not display_expression and is_domain: + mapped_dispnames = self.get_domain_dispnames(record["tablename"]) + if mapped_dispnames: + case_expression = "CASE\n" + for entry in mapped_dispnames: + if entry["label"]: + case_expression += ( + "WHEN iliCode = '{code}' THEN '{label}'\n".format( + code=entry["code"], label=entry["label"] + ) + ) + else: + case_expression += ( + "WHEN iliCode = '{code}' THEN dispName\n".format( + code=entry["code"] + ) + ) + case_expression += "END" + display_expression = case_expression + coord_decimals = ( record["coord_decimals"] if "coord_decimals" in record else None ) @@ -954,3 +975,6 @@ def get_iliname_dbname_mapping(self): def get_basket_handling(self): return self._db_connector.get_basket_handling() + + def get_domain_dispnames(self, tablename): + return self._db_connector.get_domain_dispnames(tablename) diff --git a/tests/test_translations.py b/tests/test_translations.py index 6a04745..53d1de1 100644 --- a/tests/test_translations.py +++ b/tests/test_translations.py @@ -110,8 +110,22 @@ def test_translated_db_objects_gpkg(self): assert len(tab_list) == len(expected_tab_list) assert set(tab_list) == set(expected_tab_list) + # check domain table and translated domains + if layer.name == "rechtsstatus": + count += 1 + assert layer.alias == "StatutJuridique" + assert layer.layer.displayExpression() == "\n".join( + [ + "CASE", + "WHEN iliCode = 'AenderungOhneVorwirkung' THEN 'ModificationSansEffetAnticipe'", + "WHEN iliCode = 'inKraft' THEN 'enVigueur'", + "WHEN iliCode = 'AenderungMitVorwirkung' THEN 'ModificationAvecEffetAnticipe'", + "END", + ] + ) + # check if the layers have been considered - assert count == 1 + assert count == 2 assert fr_layer # Check translated relation @@ -189,8 +203,22 @@ def test_translated_db_objects_pg(self): assert len(tab_list) == len(expected_tab_list) assert set(tab_list) == set(expected_tab_list) + # check domain table and translated domains + if layer.name == "rechtsstatus": + count += 1 + assert layer.alias == "StatutJuridique" + assert layer.layer.displayExpression() == "\n".join( + [ + "CASE", + "WHEN iliCode = 'AenderungOhneVorwirkung' THEN 'ModificationSansEffetAnticipe'", + "WHEN iliCode = 'AenderungMitVorwirkung' THEN 'ModificationAvecEffetAnticipe'", + "WHEN iliCode = 'inKraft' THEN 'enVigueur'", + "END", + ] + ) + # check if the layers have been considered - assert count == 1 + assert count == 2 assert fr_layer # Check translated relation