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
11 changes: 9 additions & 2 deletions modelbaker/dbconnector/db_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,16 @@ def get_translation_handling(self) -> tuple[bool, str]:
"""
return False, ""

def get_available_languages(self, irrelevant_models: list[str]) -> list[str]:
def get_translation_models(self) -> list[str]:
"""
Returns a list of available languages in the t_ili2db_nls table and ignores the values for the irrelevant models
Returns a list of models that are a TRANSLATION OF another model.
"""
return []

def get_available_languages(self, irrelevant_models: list[str], relevant_models: list[str]) -> list[str]:
"""
Returns a list of available languages in the t_ili2db_nls table and ignores the values for the irrelevant models.
If a list for relevant models is passed, only those are considered (otherwise all the others)
"""
return []

Expand Down
64 changes: 52 additions & 12 deletions modelbaker/dbconnector/gpkg_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1260,30 +1260,70 @@ def set_ili2db_sequence_value(self, value):
def get_translation_handling(self) -> tuple[bool, str]:
return self._table_exists(GPKG_NLS_TABLE) and self._lang != "", self._lang

def get_available_languages(self, irrelevant_models=[]):
if not self._table_exists(GPKG_NLS_TABLE):
def get_translation_models(self):
if not self._table_exists(GPKG_METAATTRS_TABLE):
return []

cursor = self.conn.cursor()
cursor.execute(
"""SELECT DISTINCT
lang
FROM "{t_ili2db_nls}"
WHERE
lang IS NOT NULL
AND
substr(iliElement, 0, instr(iliElement, '.')) NOT IN ({model_list})
"""
SELECT DISTINCT
ilielement
FROM "{t_ili2db_meta_attrs}"
WHERE
attr_name = 'ili2db.ili.translationOf'
;
""".format(
t_ili2db_nls=GPKG_NLS_TABLE,
model_list=",".join(
t_ili2db_meta_attrs=GPKG_METAATTRS_TABLE,
)
)
records = cursor.fetchall()
cursor.close()
return [record["ilielement"] for record in records]

def get_available_languages(self, irrelevant_models=[], relevant_models=[]):
if not self._table_exists(GPKG_METAATTRS_TABLE):
return []

white_list_restriction = ''
if len(relevant_models) > 0:
white_list_restriction = """
AND
ilielement IN ({relevant_model_list})
""".format(
relevant_model_list=",".join(
[f"'{modelname}'" for modelname in relevant_models]
),
)
black_list_restriction = ''
if len(irrelevant_models) > 0:
black_list_restriction = """
AND
ilielement NOT IN ({irrelevant_model_list})
""".format(
irrelevant_model_list=",".join(
[f"'{modelname}'" for modelname in irrelevant_models]
),
)
cursor = self.conn.cursor()
cursor.execute(
"""SELECT DISTINCT
attr_value
FROM "{t_ili2db_meta_attrs}"
WHERE
attr_name = 'ili2db.ili.lang'
{black_list_restriction}
{white_list_restriction}
;
""".format(
t_ili2db_meta_attrs=GPKG_METAATTRS_TABLE,
black_list_restriction=black_list_restriction,
white_list_restriction=white_list_restriction,
)
)
records = cursor.fetchall()
cursor.close()
return [record["lang"] for record in records]
return [record["attr_value"] for record in records]

def get_domain_dispnames(self, tablename):
if (
Expand Down
60 changes: 48 additions & 12 deletions modelbaker/dbconnector/mssql_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1260,25 +1260,61 @@ def set_ili2db_sequence_value(self, value):
def get_translation_handling(self) -> tuple[bool, str]:
return self._table_exists(NLS_TABLE) and self._lang != "", self._lang

def get_available_languages(self, irrelevant_models=[]):
if self.schema and self._table_exists(NLS_TABLE):
def get_translation_models(self):
if self.schema and self._table_exists(METAATTRS_TABLE):
cur = self.conn.cursor()
cur.execute(
"""
SELECT DISTINCT
lang
FROM {schema}.t_ili2db_nls
WHERE
lang IS NOT NULL
AND
left(iliElement, charindex('.', iliElement)-1) NOT IN ({model_list})
ilielement
FROM {schema}.t_ili2db_meta_attrs
WHERE
attr_name = 'ili2db.ili.translationOf'
"""
).format(
schema=self.schema,
model_list=",".join(
[f"'{modelname}'" for modelname in irrelevant_models]
),
)
return [row.ilielement for row in cur.fetchall()]
return []

def get_available_languages(self, irrelevant_models=[], relevant_models=[]):
if self.schema and self._table_exists(METAATTRS_TABLE):

return [row.lang for row in cur.fetchall()]
white_list_restriction = ''
if len(relevant_models) > 0:
white_list_restriction = """
AND
ilielement IN ({relevant_model_list})
""".format(
relevant_model_list=",".join(
[f"'{modelname}'" for modelname in relevant_models]
),
)
black_list_restriction = ''
if len(irrelevant_models) > 0:
black_list_restriction = """
AND
ilielement NOT IN ({irrelevant_model_list})
""".format(
irrelevant_model_list=",".join(
[f"'{modelname}'" for modelname in irrelevant_models]
),
)
cur = self.conn.cursor()
cur.execute(
"""
SELECT DISTINCT
attr_value
FROM {schema}.t_ili2db_meta_attrs
WHERE
attr_name = 'ili2db.ili.lang'
{black_list_restriction}
{white_list_restriction}
"""
).format(
schema=self.schema,
black_list_restriction=black_list_restriction,
white_list_restriction=white_list_restriction,
)
return [row.attr_value for row in cur.fetchall()]
return []
67 changes: 55 additions & 12 deletions modelbaker/dbconnector/pg_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1396,29 +1396,72 @@ def get_all_schemas(self):
def get_translation_handling(self) -> tuple[bool, str]:
return self._table_exists(PG_NLS_TABLE) and self._lang != "", self._lang

def get_available_languages(self, irrelevant_models=[]):
if self.schema and self._table_exists(PG_NLS_TABLE):
def get_translation_models(self):
if self.schema and self._table_exists(PG_METAATTRS_TABLE):
cur = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute(
sql.SQL(
"""
SELECT DISTINCT
lang
FROM {schema}.t_ili2db_nls
WHERE
lang IS NOT NULL
AND
split_part(iliElement,'.',1) NOT IN ({model_list})
ilielement
FROM {schema}.t_ili2db_meta_attrs
WHERE
attr_name = 'ili2db.ili.translationOf'
"""
).format(
schema=sql.Identifier(self.schema),
model_list=sql.SQL(", ").join(
sql.Placeholder() * len(irrelevant_models)
)
)
return [row["ilielement"] for row in cur.fetchall()]
return []


def get_available_languages(self, irrelevant_models=[], relevant_models=[]):
if self.schema and self._table_exists(PG_METAATTRS_TABLE):

white_list_placeholders = sql.SQL('')
if len(relevant_models) > 0:
white_list_placeholders = sql.SQL("""
AND
ilielement IN ({relevant_model_list})
"""
).format(
relevant_model_list=sql.SQL(", ").join(
sql.Placeholder() * len(relevant_models)
),
)
black_list_placeholders = sql.SQL('')
if len(irrelevant_models) > 0:
black_list_placeholders = sql.SQL("""
AND
ilielement NOT IN ({irrelevant_model_list})
"""
).format(
irrelevant_model_list=sql.SQL(", ").join(
sql.Placeholder() * len(irrelevant_models)
)
)

cur = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute(
sql.SQL(
"""
SELECT DISTINCT
attr_value
FROM {schema}.t_ili2db_meta_attrs
WHERE
attr_name = 'ili2db.ili.lang'
{white_list_placeholders}
{black_list_placeholders}
"""
).format(
schema=sql.Identifier(self.schema),
white_list_placeholders=white_list_placeholders,
black_list_placeholders=black_list_placeholders,
),
irrelevant_models,
relevant_models+irrelevant_models
)
return [row["lang"] for row in cur.fetchall()]
return [row["attr_value"] for row in cur.fetchall()]
return []

def get_domain_dispnames(self, tablename):
Expand Down
77 changes: 77 additions & 0 deletions tests/test_translations.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from qgis.core import QgsProject
from qgis.testing import start_app, unittest

import modelbaker.utils.db_utils as db_utils
from modelbaker.dataobjects.project import Project
from modelbaker.db_factory.gpkg_command_config_manager import GpkgCommandConfigManager
from modelbaker.generator.generator import Generator
Expand Down Expand Up @@ -230,6 +231,82 @@ def test_translated_db_objects_pg(self):
== "Geometrie_Document_(Geometrie)_AffectationPrimaire_SurfaceDeZones_(t_id)"
)

def test_available_langs_gpkg(self):
importer = iliimporter.Importer()
importer.tool = DbIliMode.ili2gpkg
importer.configuration = iliimporter_config(importer.tool)
importer.configuration.ilimodels = "PlansDAffectation_V1_2"
importer.configuration.dbfile = os.path.join(
self.basetestpath, "tmp_translated_gpkg.gpkg"
)
importer.configuration.inheritance = "smart2"
importer.configuration.create_basket_col = True
importer.stdout.connect(self.print_info)
importer.stderr.connect(self.print_error)
assert importer.run() == iliimporter.Importer.SUCCESS

db_connector = db_utils.get_db_connector(importer.configuration)

# Translation handling is active
assert db_connector.get_translation_handling()

# Get the translated models
assert {"PlansDAffectation_V1_2"} == set(db_connector.get_translation_models())

# Get all languages
assert {'en','de','fr'} == set(db_connector.get_available_languages())

# ... without irrelevant models
irrelevants = ["AdministrativeUnits_V1","AdministrativeUnitsCH_V1","Dictionaries_V1","DictionariesCH_V1"]
assert {'de','fr'} == set(db_connector.get_available_languages(irrelevants))

# ... and the language of the translated model only
assert {'fr'} == set(db_connector.get_available_languages([],["PlansDAffectation_V1_2"]))

# --- and nonsense use case for the validation, get only of an english model
assert {'en'} == set(db_connector.get_available_languages([],["AdministrativeUnits_V1"]))

# ... as well as ignoring the translated models and alowing it again and the english one
assert {'de','en'} == set(db_connector.get_available_languages(["PlansDAffectation_V1_2"]))

def test_translated_db_objects_pg(self):
importer = iliimporter.Importer()
importer.tool = DbIliMode.ili2pg
importer.configuration = iliimporter_config(importer.tool)
importer.configuration.ilimodels = "PlansDAffectation_V1_2"
importer.configuration.dbschema = "tid_{:%Y%m%d%H%M%S%f}".format(
datetime.datetime.now()
)
importer.configuration.inheritance = "smart2"
importer.configuration.create_basket_col = True
importer.stdout.connect(self.print_info)
importer.stderr.connect(self.print_error)
assert importer.run() == iliimporter.Importer.SUCCESS

db_connector = db_utils.get_db_connector(importer.configuration)

# Translation handling is active
assert db_connector.get_translation_handling()

# Get the translated models
assert {"PlansDAffectation_V1_2"} == set(db_connector.get_translation_models())

# Get all languages
assert {'en','de','fr'} == set(db_connector.get_available_languages())

# ... without irrelevant models
irrelevants = ["AdministrativeUnits_V1","AdministrativeUnitsCH_V1","Dictionaries_V1","DictionariesCH_V1"]
assert {'de','fr'} == set(db_connector.get_available_languages(irrelevants))

# ... and the language of the translated model only
assert {'fr'} == set(db_connector.get_available_languages([],["PlansDAffectation_V1_2"]))

# --- and nonsense use case for the validation, get only of an english model
assert {'en'} == set(db_connector.get_available_languages([],["AdministrativeUnits_V1"]))

# ... as well as ignoring the translated models and alowing it again and the english one
assert {'de','en'} == set(db_connector.get_available_languages(["PlansDAffectation_V1_2"]))

def print_info(self, text):
logging.info(text)

Expand Down