1
1
# inbuilt libraries
2
2
import os
3
- from typing import List , Optional , Set , Union
3
+ from typing import List , Optional , Set , Union , Dict , Iterable
4
4
from pathlib import Path
5
5
6
6
# third-party libraries
10
10
# custom functions
11
11
from .Calculation_gdal import raster_value
12
12
from .Style import catagorize_xml , classified_xml , coverage_style_xml , outline_only_xml
13
- from .supports import prepare_zip_file , is_valid_xml
13
+ from .supports import prepare_zip_file , is_valid_xml , is_surrounded_by_quotes
14
14
15
15
16
16
# Custom exceptions.
@@ -2025,25 +2025,48 @@ def publish_featurestore_sqlview(
2025
2025
name : str ,
2026
2026
store_name : str ,
2027
2027
sql : str ,
2028
+ parameters : Optional [Iterable [Dict ]] = None ,
2028
2029
key_column : Optional [str ] = None ,
2029
2030
geom_name : str = "geom" ,
2030
2031
geom_type : str = "Geometry" ,
2031
2032
srid : Optional [int ] = 4326 ,
2032
2033
workspace : Optional [str ] = None ,
2033
2034
):
2034
2035
"""
2036
+ Publishes an SQL query as a layer, optionally with parameters
2035
2037
2036
2038
Parameters
2037
2039
----------
2038
2040
name : str
2039
2041
store_name : str
2040
2042
sql : str
2043
+ parameters : iterable of dicts, optional
2041
2044
key_column : str, optional
2042
2045
geom_name : str, optional
2043
2046
geom_type : str, optional
2044
2047
workspace : str, optional
2045
2048
2049
+ Notes
2050
+ -----
2051
+ With regards to SQL view parameters, it is advised to read the relevant section from the geoserver docs:
2052
+ https://docs.geoserver.org/main/en/user/data/database/sqlview.html#parameterizing-sql-views
2053
+
2054
+ An integer-based parameter must have a default value
2055
+
2056
+ You should be VERY careful with the `regexp_validator`, as it can open you to SQL injection attacks. If you do
2057
+ not supply one for a parameter, it will use the geoserver default `^[\w\d\s]+$`.
2058
+
2059
+ The `parameters` iterable must contain dictionaries with this structure:
2060
+
2061
+ ```
2062
+ {
2063
+ "name": "<name of parameter (required)>"
2064
+ "rexegpValidator": "<string containing regex validator> (optional)"
2065
+ "defaultValue" : "<default value of parameter if not specified (required only for non-string parameters)>"
2066
+ }
2067
+ ```
2046
2068
"""
2069
+
2047
2070
if workspace is None :
2048
2071
workspace = "default"
2049
2072
@@ -2054,6 +2077,27 @@ def publish_featurestore_sqlview(
2054
2077
else :
2055
2078
key_column_xml = """"""
2056
2079
2080
+ parameters_xml = ""
2081
+ if parameters is not None :
2082
+ for parameter in parameters :
2083
+
2084
+ # non-string parameters MUST have a default value supplied
2085
+ if not is_surrounded_by_quotes (sql , parameter ["name" ]) and not "defaultValue" in parameter :
2086
+ raise ValueError (f"Parameter `{ parameter ['name' ]} ` appears to be a non-string in the supplied query"
2087
+ ", but does not have a default value specified. You must supply a default value "
2088
+ "for non-string parameters using the `defaultValue` key." )
2089
+
2090
+ param_name = parameter .get ("name" , "" )
2091
+ default_value = parameter .get ("defaultValue" , "" )
2092
+ regexp_validator = parameter .get ("regexpValidator" , r"^[\w\d\s]+$" )
2093
+ parameters_xml += (f"""
2094
+ <parameter>
2095
+ <name>{ param_name } </name>
2096
+ <defaultValue>{ default_value } </defaultValue>
2097
+ <regexpValidator>{ regexp_validator } </regexpValidator>
2098
+ </parameter>\n
2099
+ """ .strip ())
2100
+
2057
2101
layer_xml = """<featureType>
2058
2102
<name>{0}</name>
2059
2103
<enabled>true</enabled>
@@ -2073,11 +2117,12 @@ def publish_featurestore_sqlview(
2073
2117
<type>{3}</type>
2074
2118
<srid>{5}</srid>
2075
2119
</geometry>{6}
2120
+ {7}
2076
2121
</virtualTable>
2077
2122
</entry>
2078
2123
</metadata>
2079
2124
</featureType>""" .format (
2080
- name , sql , geom_name , geom_type , workspace , srid , key_column_xml
2125
+ name , sql , geom_name , geom_type , workspace , srid , key_column_xml , parameters_xml
2081
2126
)
2082
2127
2083
2128
# rest API url
0 commit comments