Skip to content

Commit 9963347

Browse files
fix: address CI findings — psycopg2.sql composition in migrations, regenerate spp_gis README
Semgrep flagged f-string SQL in the tag migration scripts; identifiers were constants but composed SQL via psycopg2.sql removes the pattern entirely. README.rst regenerated from the updated HISTORY fragment (in-scope module only).
1 parent f1793cb commit 9963347

4 files changed

Lines changed: 67 additions & 27 deletions

File tree

spp_gis/README.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,20 @@ External Python libraries: ``shapely``, ``pyproj``, ``geojson``
131131
Changelog
132132
=========
133133

134+
19.0.2.1.0
135+
~~~~~~~~~~
136+
137+
- feat: spatial operators support MultiPolygon and GeometryCollection,
138+
including distance buffering (re-land from #76).
139+
- feat: OSM style fallback in map renderer/edit widgets when no MapTiler
140+
API key is configured; placeholder key treated as unconfigured
141+
(re-land from #76).
142+
- feat: geofence GeoJSON output includes the record uuid as feature id;
143+
new ``spp.gis.geofence.tag`` model replaces vocabulary-based geofence
144+
tags (re-land from #76).
145+
- feat: migration remaps existing vocabulary-based geofence tag links
146+
onto ``spp.gis.geofence.tag`` records when upgrading from 19.0.2.0.x.
147+
134148
19.0.2.0.0
135149
~~~~~~~~~~
136150

spp_gis/migrations/19.0.2.1.0/post-migration.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import logging
1010

11+
from psycopg2 import sql
12+
1113
from odoo import SUPERUSER_ID, api
1214

1315
_logger = logging.getLogger("odoo.addons.spp_gis.migrations.geofence_tags")
@@ -26,8 +28,9 @@ def migrate(cr, version):
2628

2729
env = api.Environment(cr, SUPERUSER_ID, {})
2830
Tag = env["spp.gis.geofence.tag"]
31+
aux = sql.Identifier(AUX_TABLE)
2932

30-
cr.execute(f"SELECT DISTINCT vocab_name FROM {AUX_TABLE}")
33+
cr.execute(sql.SQL("SELECT DISTINCT vocab_name FROM {aux}").format(aux=aux))
3134
tag_ids_by_name = {}
3235
for (name,) in cr.fetchall():
3336
tag = Tag.search([("name", "=", name)], limit=1)
@@ -36,7 +39,7 @@ def migrate(cr, version):
3639
tag_ids_by_name[name] = tag.id
3740

3841
restored = 0
39-
cr.execute(f"SELECT geofence_id, vocab_name FROM {AUX_TABLE}")
42+
cr.execute(sql.SQL("SELECT geofence_id, vocab_name FROM {aux}").format(aux=aux))
4043
for geofence_id, name in cr.fetchall():
4144
cr.execute(
4245
"""
@@ -48,7 +51,7 @@ def migrate(cr, version):
4851
)
4952
restored += cr.rowcount
5053

51-
cr.execute(f"DROP TABLE {AUX_TABLE}")
54+
cr.execute(sql.SQL("DROP TABLE {aux}").format(aux=aux))
5255
_logger.info(
5356
"spp_gis geofence tag migration: created %s tags, restored %s links",
5457
len(tag_ids_by_name),

spp_gis/migrations/19.0.2.1.0/pre-migration.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import logging
1616

17+
from psycopg2 import sql
18+
1719
_logger = logging.getLogger("odoo.addons.spp_gis.migrations.geofence_tags")
1820

1921
AUX_TABLE = "spp_gis_geofence_tag_legacy_migration"
@@ -32,37 +34,43 @@ def migrate(cr, version):
3234
# table (only possible when this migration reruns or in tests); it is
3335
# legacy if it references a vocabulary instead. Checking the new table
3436
# first resolves numeric id collisions in favor of valid links.
35-
new_table_exists = _table_exists(cr, "spp_gis_geofence_tag")
36-
valid_clause = (
37-
"AND rel.tag_id NOT IN (SELECT id FROM spp_gis_geofence_tag)" if new_table_exists else ""
38-
)
37+
if _table_exists(cr, "spp_gis_geofence_tag"):
38+
valid_clause = sql.SQL("AND rel.tag_id NOT IN (SELECT id FROM spp_gis_geofence_tag)")
39+
else:
40+
valid_clause = sql.SQL("")
3941

42+
aux = sql.Identifier(AUX_TABLE)
4043
cr.execute(
41-
f"""
42-
CREATE TABLE IF NOT EXISTS {AUX_TABLE} (
43-
geofence_id integer NOT NULL,
44-
vocab_name varchar NOT NULL
45-
)
46-
"""
44+
sql.SQL(
45+
"""
46+
CREATE TABLE IF NOT EXISTS {aux} (
47+
geofence_id integer NOT NULL,
48+
vocab_name varchar NOT NULL
49+
)
50+
"""
51+
).format(aux=aux)
4752
)
4853
cr.execute(
49-
f"""
50-
INSERT INTO {AUX_TABLE} (geofence_id, vocab_name)
51-
SELECT rel.geofence_id,
52-
-- name is a translated (jsonb) field: prefer en_US, else any value
53-
COALESCE(v.name->>'en_US', (SELECT t.value FROM jsonb_each_text(v.name) t LIMIT 1))
54-
FROM spp_gis_geofence_tag_rel rel
55-
JOIN spp_vocabulary v ON v.id = rel.tag_id
56-
WHERE true {valid_clause}
57-
"""
54+
sql.SQL(
55+
"""
56+
INSERT INTO {aux} (geofence_id, vocab_name)
57+
SELECT rel.geofence_id,
58+
COALESCE(v.name->>'en_US', (SELECT t.value FROM jsonb_each_text(v.name) t LIMIT 1))
59+
FROM spp_gis_geofence_tag_rel rel
60+
JOIN spp_vocabulary v ON v.id = rel.tag_id
61+
WHERE true {valid_clause}
62+
"""
63+
).format(aux=aux, valid_clause=valid_clause)
5864
)
5965
parked = cr.rowcount
6066
cr.execute(
61-
f"""
62-
DELETE FROM spp_gis_geofence_tag_rel rel
63-
USING spp_vocabulary v
64-
WHERE v.id = rel.tag_id {valid_clause}
65-
"""
67+
sql.SQL(
68+
"""
69+
DELETE FROM spp_gis_geofence_tag_rel rel
70+
USING spp_vocabulary v
71+
WHERE v.id = rel.tag_id {valid_clause}
72+
"""
73+
).format(valid_clause=valid_clause)
6674
)
6775
_logger.info(
6876
"spp_gis geofence tag migration: parked %s legacy vocabulary tag links (%s rows removed)",

spp_gis/static/description/index.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,21 @@ <h2><a class="toc-backref" href="#toc-entry-1">Changelog</a></h2>
507507
</div>
508508
</div>
509509
<div class="section" id="section-1">
510+
<h1>19.0.2.1.0</h1>
511+
<ul class="simple">
512+
<li>feat: spatial operators support MultiPolygon and GeometryCollection,
513+
including distance buffering (re-land from #76).</li>
514+
<li>feat: OSM style fallback in map renderer/edit widgets when no MapTiler
515+
API key is configured; placeholder key treated as unconfigured
516+
(re-land from #76).</li>
517+
<li>feat: geofence GeoJSON output includes the record uuid as feature id;
518+
new <tt class="docutils literal">spp.gis.geofence.tag</tt> model replaces vocabulary-based geofence
519+
tags (re-land from #76).</li>
520+
<li>feat: migration remaps existing vocabulary-based geofence tag links
521+
onto <tt class="docutils literal">spp.gis.geofence.tag</tt> records when upgrading from 19.0.2.0.x.</li>
522+
</ul>
523+
</div>
524+
<div class="section" id="section-2">
510525
<h1>19.0.2.0.0</h1>
511526
<ul class="simple">
512527
<li>Initial migration to OpenSPP2</li>

0 commit comments

Comments
 (0)