Skip to content

Commit

Permalink
Project checks - do not check tid only, but also ctid etc
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Aug 9, 2023
1 parent eb83942 commit ef0ca50
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 52 deletions.
92 changes: 51 additions & 41 deletions lizmap/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@
from lizmap.lizmap_api.config import LizmapConfig
from lizmap.ogc_project_validity import OgcProjectValidity
from lizmap.project_checker_tools import (
auto_generated_primary_key_field,
duplicated_layer_name_or_group,
duplicated_layer_with_filter,
invalid_int8_primary_key,
invalid_tid_field,
simplify_provider_side,
use_estimated_metadata,
)
Expand Down Expand Up @@ -2683,60 +2683,70 @@ def project_config_file(self, lwc_version: LwcVersions, with_gui: bool = True, c
message += "<br>"

message += tr(
"The process is continuing but expect some layers to not be visible in Lizmap Web Client.")
"The process is continuing but expect these layers to not be visible in Lizmap Web Client.")
ScrollMessageBox(self.dlg, QMessageBox.Warning, tr('Lizmap.com hosting'), message)

show_log = False
if check_server:
results = {
'tid': [],
'int8': [],
}
autogenerated_keys = {}
int8 = []
for layer in self.project.mapLayers().values():

if not isinstance(layer, QgsVectorLayer):
continue
if invalid_tid_field(layer):
results['tid'].append(layer.name())
if invalid_int8_primary_key(layer):
results['int8'].append(layer.name())

message = tr('Some fields are invalid for QGIS server.') + '<br>'
end = tr("We highly recommend you to set a proper integer field, but neither a bigint nor an integer8 :")

if results['tid']:
message += tr(
"The field 'tid' has been detected as primary key for your layer but it wasn't found in the layer "
"fields.") + " "
message += end
message += "<br><ul>"
for layer_name in results['tid']:
message += "<li>{}</li>".format(layer_name)
message += "</ul><br>"
result, field = auto_generated_primary_key_field(layer)
if result:
if field not in autogenerated_keys.keys():
autogenerated_keys[field] = []

if results['int8']:
message += tr("The primary key has been detected as a bigint (integer8) for your layer.") + " "
message += end
message += "<br><ul>"
for layer_name in results['int8']:
message += "<li>{}</li>".format(layer_name)
message += "</ul><br>"
autogenerated_keys[field].append(layer.name())

message += "<br>"
message += tr(
"The process is continuing but expect some layers to not be visible in Lizmap Web Client.")
if invalid_int8_primary_key(layer):
int8.append(layer.name())

if results['tid'] or results['int8']:
if autogenerated_keys or int8:
show_log = True
warnings.append(Warnings.InvalidFieldType.value)
ScrollMessageBox(self.dlg, QMessageBox.Warning, tr('QGIS server'), message)
self.dlg.log_panel.append(tr('Some fields are invalid for QGIS server'), Html.H2)

for field, layers in autogenerated_keys.items():
# field can be "tid", "ctid" etc
self.dlg.log_panel.append(tr(
"These layers don't have a proper primary key in the database. So QGIS Desktop tried to set a "
"temporary field called '{}' to be a unique identifier. On QGIS Server, this will bring issues."
).format(field))
self.dlg.log_panel.append("<br>")
for layer_name in layers:
self.dlg.log_panel.append('⚫ {}'.format(layer_name))
self.dlg.log_panel.append("<br>")

if int8:
self.dlg.log_panel.append(tr(
"The primary key has been detected as a bigint (integer8) for your layer :"))
self.dlg.log_panel.append("<br>")
for layer_name in int8:
self.dlg.log_panel.append("⚫ {}".format(layer_name))
self.dlg.log_panel.append("<br>")

self.dlg.log_panel.append("<br>")
self.dlg.log_panel.append(tr(
"We highly recommend you to set a proper integer field as a primary key, but neither a bigint nor an "
"integer8."))
self.dlg.log_panel.append("<br>")
self.dlg.log_panel.append(tr(
"The process is continuing but expect these layers to have some issues with some tools in "
"Lizmap Web Client: zoom to feature, filtering..."
))

if lwc_version >= LwcVersions.Lizmap_3_7:
text = duplicated_layer_with_filter(self.project)
if text:
message += tr(
text += tr(
"The process is continuing but the project might be slow in Lizmap Web Client.")
warnings.append(Warnings.DuplicatedLayersWithFilters.value)
ScrollMessageBox(self.dlg, QMessageBox.Warning, tr('Optimisation'), text)

show_log = False
results = simplify_provider_side(self.project)
if len(results):
self.dlg.log_panel.append(tr('Simplify on the provider side'), Html.H2)
Expand Down Expand Up @@ -3127,8 +3137,8 @@ def check_project_validity(self):
valid, results = validator.validate(self.project)
self.dlg.log_panel.append(tr("OGC validation"), style=Html.H2)
self.dlg.log_panel.append(tr("According to OGC standard : {}").format('VALID' if valid else 'NOT valid'))
if not valid:
self.dlg.log_panel.append(tr("According to OGC standard : {}").format('VALID' if valid else 'NOT valid'))
# if not valid:
# self.dlg.log_panel.append(tr("According to OGC standard : {}").format('VALID' if valid else 'NOT valid'))

LOGGER.info(f"Project has been detected : {'VALID' if valid else 'NOT valid'} according to OGC validation.")

Expand Down Expand Up @@ -3376,9 +3386,9 @@ def save_cfg_file(
self.dlg.cbIgnCadastral.isChecked(),
]

self.dlg.log_panel.separator()
self.dlg.log_panel.append(tr('Map - options'), Html.Strong)
self.dlg.log_panel.separator()
# self.dlg.log_panel.separator()
# self.dlg.log_panel.append(tr('Map - options'), Html.Strong)
# self.dlg.log_panel.separator()

# Checking configuration data
# Get the project data from api to check the "coordinate system restriction" of the WMS Server settings
Expand Down
22 changes: 11 additions & 11 deletions lizmap/project_checker_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'

from typing import List, Optional
from typing import List, Optional, Tuple

from qgis.core import (
QgsDataSourceUri,
Expand All @@ -20,26 +20,26 @@
# https://github.com/3liz/lizmap-web-client/issues/3692


def invalid_tid_field(layer: QgsVectorLayer) -> bool:
""" If the primary key has been detected as tid but the field does not exist. """
def auto_generated_primary_key_field(layer: QgsVectorLayer) -> Tuple[bool, Optional[str]]:
""" If the primary key has been detected as tid/ctid but the field does not exist. """
# Example
# CREATE TABLE IF NOT EXISTS public.test_tid
# (
# id bigint,
# label text
# )
# In QGIS source code, look for "Primary key is ctid"
uri = QgsDataSourceUri(layer.source())

# QgsVectorLayer.primaryKeyAttributes is returning a list.
# TODO check, but with QgsDataSourceUri, we have a single field
if uri.keyColumn() != 'tid':
return False
if len(layer.primaryKeyAttributes()) >= 2:
# We don't check for composite keys here
return False, None

if 'tid' in layer.fields().names():
return False
if layer.dataProvider().uri().keyColumn() in layer.fields().names():
return False, None

# The layer has "tid" as a primary key, but the field is not found.
return True
# The layer has "tid" or "ctid" as a primary key, but the field is not found.
return True, layer.dataProvider().uri().keyColumn()


def invalid_int8_primary_key(layer: QgsVectorLayer) -> bool:
Expand Down

0 comments on commit ef0ca50

Please sign in to comment.