3737from typing import List , Union
3838from urllib .parse import urlencode , quote
3939
40+ import json_merge_patch
4041from owslib .ogcapi .records import Records
4142from pygeofilter .parsers .ecql import parse as parse_ecql
4243from pygeofilter .parsers .cql2_json import parse as parse_cql2_json
@@ -1015,7 +1016,7 @@ def item(self, headers_, args, collection, item):
10151016 def manage_collection_item (self , headers_ , action = 'create' , collection = None ,
10161017 item = None , data = None ):
10171018 """
1018- :param action: action (create, update, delete)
1019+ :param action: action (create, replace, update, delete)
10191020 :param collection: collection identifier
10201021 :param item: record identifier
10211022 :param data: raw data / payload
@@ -1028,13 +1029,13 @@ def manage_collection_item(self, headers_, action='create', collection=None,
10281029 405 , headers_ , 'InvalidParameterValue' ,
10291030 'transactions not allowed' )
10301031
1031- if action in ['create' , 'update' ] and data is None :
1032+ if action in ['create' , 'replace' , ' update' ] and data is None :
10321033 msg = 'No data found'
10331034 LOGGER .error (msg )
10341035 return self .get_exception (
10351036 400 , headers_ , 'InvalidParameterValue' , msg )
10361037
1037- if action in ['create' , 'update ' ]:
1038+ if action in ['create' , 'replace ' ]:
10381039 try :
10391040 record = parse_record (self .context , data , self .repository )[0 ]
10401041 except Exception as err :
@@ -1068,7 +1069,7 @@ def manage_collection_item(self, headers_, action='create', collection=None,
10681069 code = 201
10691070 response = {}
10701071
1071- elif action == 'update ' :
1072+ elif action == 'replace ' :
10721073 LOGGER .debug (f'Querying repository for item { item } ' )
10731074 try :
10741075 _ = self .repository .query_ids ([record .identifier ])[0 ]
@@ -1082,6 +1083,40 @@ def manage_collection_item(self, headers_, action='create', collection=None,
10821083 code = 204
10831084 response = {}
10841085
1086+ elif action == 'update' :
1087+ LOGGER .debug (f'Querying repository for item { item } ' )
1088+ try :
1089+ content = self .repository .query_ids ([item ])[0 ]
1090+ except Exception :
1091+ msg = 'Identifier does not exist'
1092+ LOGGER .debug (msg )
1093+ return self .get_exception (404 , headers_ , 'InvalidParameterValue' , msg )
1094+
1095+ if 'id' in data :
1096+ msg = 'Update cannot alter id'
1097+ LOGGER .debug (msg )
1098+ return self .get_exception (400 , headers_ , 'InvalidParameterValue' , msg )
1099+
1100+ content = json .loads (content .metadata )
1101+ record = json_merge_patch .merge (content , data )
1102+
1103+ try :
1104+ record = parse_record (self .context , record , self .repository )[0 ]
1105+ except Exception as err :
1106+ msg = f'Failed to parse data: { err } '
1107+ LOGGER .exception (msg )
1108+ return self .get_exception (400 , headers_ , 'InvalidParameterValue' , msg )
1109+
1110+ if not hasattr (record , 'identifier' ):
1111+ msg = 'Record requires an identifier'
1112+ LOGGER .exception (msg )
1113+ return self .get_exception (400 , headers_ , 'InvalidParameterValue' , msg )
1114+
1115+ _ = self .repository .update (record )
1116+
1117+ code = 204
1118+ response = {}
1119+
10851120 elif action == 'delete' :
10861121 constraint = {
10871122 'where' : 'identifier = \' %s\' ' % item ,
0 commit comments