Skip to content
Draft
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
35 changes: 35 additions & 0 deletions .local_docker_test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
ARG QGIS_TEST_VERSION=latest
FROM qgis/qgis:${QGIS_TEST_VERSION}

RUN apt-get update && \
apt-get -y install openjdk-8-jre \
&& rm -rf /var/lib/apt/lists/*

# MSSQL: client side
RUN apt-get update
RUN apt-get install -y curl locales postgresql-client libpq-dev
RUN apt-get install -y unixodbc unixodbc-dev odbcinst unixodbc-common libodbcinst2 libodbccr2 libodbc2 libqt5sql5-odbc

RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install -y msodbcsql17 mssql-tools

# Useful only in 3.22 and 3.28: drop when not need anymore
RUN apt-get update && apt-get -y install python3-pip python3-venv python3-pytest python3-wheel
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv --system-site-packages $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

COPY ./requirements.txt /tmp/
RUN pip3 install -r /tmp/requirements.txt

# Avoid sqlcmd termination due to locale -- see https://github.com/Microsoft/mssql-docker/issues/163
RUN echo "nb_NO.UTF-8 UTF-8" > /etc/locale.gen
RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
RUN locale-gen
ENV PATH="/usr/local/bin:${PATH}"

ENV LANG=C.UTF-8

WORKDIR /
21 changes: 21 additions & 0 deletions .local_docker_test/docker-compose.gh.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: '3'
services:
mssql:
image: mcr.microsoft.com/mssql/server:2019-CU28-ubuntu-20.04
environment:
ACCEPT_EULA: Y
SA_PASSWORD: <YourStrong!Passw0rd>
ports:
- "1433:1433"

qgis:
build:
context: ..
dockerfile: ./.docker/Dockerfile
args:
QGIS_TEST_VERSION: ${QGIS_TEST_VERSION}
tty: true
volumes:
- ${GITHUB_WORKSPACE}:/usr/src
links:
- mssql
21 changes: 21 additions & 0 deletions .local_docker_test/run-docker-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
#***************************************************************************
# -------------------
# begin : 2017-08-24
# git sha : :%H$
# copyright : (C) 2017 by OPENGIS.ch
# email : info@opengis.ch
#***************************************************************************
#
#***************************************************************************
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU General Public License as published by *
#* the Free Software Foundation; either version 2 of the License, or *
#* (at your option) any later version. *
#* *
#***************************************************************************

set -e

/usr/src/tests/testdata/mssql/setup-mssql.sh
5 changes: 5 additions & 0 deletions modelbaker/dataobjects/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ def __init__(self, name: str) -> None:
self.default_value_expression = None
self.enum_domain = None
self.oid_domain = None
self.ili_name = None

def dump(self) -> dict:
definition = dict()
if self.alias:
definition["alias"] = self.alias
if self.ili_name:
definition["ili_name"] = self.ili_name

return definition

def load(self, definition: dict) -> None:
if "alias" in definition:
self.alias = definition["alias"]
if "ili_name" in definition:
self.ili_name = definition["ili_name"]

def create(self, layer: Layer) -> None:
field_idx = layer.layer.fields().indexOf(self.name)
Expand Down
81 changes: 81 additions & 0 deletions modelbaker/dataobjects/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,14 @@
)
from qgis.PyQt.QtCore import QObject, pyqtSignal
from qgis.PyQt.QtXml import QDomDocument
from QgisModelBaker.libs.modelbaker.libs.ili2py.interfaces.interlis.interlis_24.ilismeta.ilismeta16_2022_10_10.enum_type_type import (
EnumTypeType,
)
from QgisModelBaker.libs.modelbaker.libs.ili2py.writers.py.python_structure import (
Enumeration,
)

from ..pythonizer.pythonizer import Pythonizer
from ..utils.globals import LogLevel, OptimizeStrategy, default_log_function
from .layers import Layer
from .legend import LegendGroup
Expand All @@ -52,6 +59,9 @@ def __init__(
evaluate_default_values: bool = True,
context: dict[str, str] = {},
optimize_strategy: OptimizeStrategy = OptimizeStrategy.NONE,
pythonize_enums=None,
configuration=None,
models=[],
log_function=None,
) -> None:
QObject.__init__(self)
Expand All @@ -68,6 +78,9 @@ def __init__(
self.mapthemes = {}
self.context = context
self.optimize_strategy = optimize_strategy
self.pythonize_enums = pythonize_enums
self.configuration = configuration
self.models = models
self.log_function = log_function

if not log_function:
Expand Down Expand Up @@ -181,6 +194,9 @@ def create(
and referenced_layer.is_enum
and not referenced_layer.display_expression
):
if self.pythonize_enums:
continue

editor_widget_setup = QgsEditorWidgetSetup(
"ValueRelation",
{
Expand All @@ -206,6 +222,9 @@ def create(
},
)
elif referenced_layer and referenced_layer.is_domain:

if self.pythonize_enums:
continue
editor_widget_setup = QgsEditorWidgetSetup(
"RelationReference",
{
Expand Down Expand Up @@ -315,6 +334,68 @@ def create(
self.tr("The minimal selection is 1"),
)

if self.pythonize_enums:
self.log_function(
f"Let's get all the enums via ili2py and write them into Value Maps... Just for fun.",
LogLevel.INFO,
)
pythonizer = Pythonizer()
model_files = pythonizer.model_files_generated_from_db(
self.configuration, self.models
)
self.log_function(
f"Received modelfiles {model_files} for models {self.models}",
LogLevel.INFO,
)
if model_files:
result, imd_file = pythonizer.compile(
self.configuration.base_configuration, model_files[0]
)
if result:
self.log_function(
f"Having a nice imd {imd_file}",
LogLevel.INFO,
)
index, _ = pythonizer.pythonize(imd_file)
if index:
self.log_function(
"Having a proper index",
LogLevel.INFO,
)
for layer in self.layers:
for field in layer.fields:

# if field.enum_domain:
if not field.ili_name:
continue
imd_field_object = index.index.get(field.ili_name)
if not hasattr(imd_field_object, "type_value"):
continue
imd_field_type_oid = imd_field_object.type_value.ref
imd_field_type_object = index.index.get(imd_field_type_oid)

if isinstance(imd_field_type_object, EnumTypeType):
self.log_function(
f"Having a field with an enum {field.ili_name}",
LogLevel.INFO,
)

enum_object = Enumeration.from_imd(
imd_field_type_object, index
)
self.log_function(
f"Enum value: {enum_object.values}",
LogLevel.INFO,
)
widget = "ValueMap"
config = {"map": {}}
config["map"] = [
{val: val} for val in enum_object.values
]
setup = QgsEditorWidgetSetup(widget, config)

field_idx = layer.layer.fields().indexOf(field.name)
layer.layer.setEditorWidgetSetup(field_idx, setup)
for layer in self.layers:
if layer.layer.type() == QgsMapLayer.LayerType.VectorLayer:
# even when a style will be loaded we create the form because not sure if the style contains form settngs
Expand Down
6 changes: 6 additions & 0 deletions modelbaker/dbconnector/db_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ def get_models(self):
"""
return {}

def get_model_content(self, model):
"""
Returns content of the model
"""
return {}

def ili_version(self):
"""
Returns the version of the ili2db application that was used to create the schema.
Expand Down
24 changes: 10 additions & 14 deletions modelbaker/generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,11 @@ def layers(self, filter_layer_list: list = []) -> list[Layer]:
re_iliname = re.compile(r".*\.(.*)$")
for fielddef in fields_info:
column_name = fielddef["column_name"]

ili_name = fully_qualified_name = (
fielddef["fully_qualified_name"]
if "fully_qualified_name" in fielddef
else None
)
# If raw_naming is True, the fieldname should be the columnname
# Otherwise get field name in this order:
# - translation if exists,
Expand All @@ -345,22 +349,14 @@ def layers(self, filter_layer_list: list = []) -> list[Layer]:
alias = fielddef.get("column_tr", None)
if not alias:
alias = fielddef.get("column_alias", None)

if not alias:
fully_qualified_name = (
fielddef["fully_qualified_name"]
if "fully_qualified_name" in fielddef
else None
)
m = (
re_iliname.match(fully_qualified_name)
if fully_qualified_name
else None
)
if m:
alias = m.group(1)
if ili_name:
m = re_iliname.match(ili_name) if ili_name else None
if m:
alias = m.group(1)

field = Field(column_name)
field.ili_name = ili_name
field.alias = alias

# Should we hide the field?
Expand Down
30 changes: 30 additions & 0 deletions modelbaker/iliwrapper/ili2dbconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,3 +564,33 @@ def to_ili2db_args(self, extra_args=[], with_action=True):
self.append_args(args, Ili2DbCommandConfiguration.to_ili2db_args(self))

return args


class Ili2CCommandConfiguration:
def __init__(self, other=None):
if not isinstance(other, Ili2CCommandConfiguration):
self.base_configuration = BaseConfiguration()

self.oIMD16 = True
self.imdfile = ""
self.ilifile = ""
else:
# We got an 'other' object from which we'll get parameters
self.__dict__ = other.__dict__.copy()

def append_args(self, args, values):
args += values

def to_ili2c_args(self):

args = self.base_configuration.to_ili2db_args(False, False)

if self.oIMD16:
self.append_args(args, ["-oIMD16"])

if self.imdfile:
self.append_args(args, ["--out", self.imdfile])

if self.ilifile:
self.append_args(args, [self.ilifile])
return args
10 changes: 10 additions & 0 deletions modelbaker/iliwrapper/ili2dbtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,13 @@ def get_tool_url(tool, db_ili_version):
)

return ""


def get_ili2c_tool_version():
return "5.6.6"


def get_ili2c_tool_url():
return "https://downloads.interlis.ch/ili2c/ili2c-{version}.zip".format(
version=get_ili2c_tool_version()
)
Loading
Loading