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
@@ -1068,7 +1069,7 @@ def item(self, headers_, args, collection, item):
10681069 def manage_collection_item (self , headers_ , action = 'create' , collection = None ,
10691070 item = None , data = None ):
10701071 """
1071- :param action: action (create, update, delete)
1072+ :param action: action (create, replace, update, delete)
10721073 :param collection: collection identifier
10731074 :param item: record identifier
10741075 :param data: raw data / payload
@@ -1081,13 +1082,13 @@ def manage_collection_item(self, headers_, action='create', collection=None,
10811082 405 , headers_ , 'InvalidParameterValue' ,
10821083 'transactions not allowed' )
10831084
1084- if action in ['create' , 'update' ] and data is None :
1085+ if action in ['create' , 'replace' , ' update' ] and data is None :
10851086 msg = 'No data found'
10861087 LOGGER .error (msg )
10871088 return self .get_exception (
10881089 400 , headers_ , 'InvalidParameterValue' , msg )
10891090
1090- if action in ['create' , 'update ' ]:
1091+ if action in ['create' , 'replace ' ]:
10911092 try :
10921093 record = parse_record (self .context , data , self .repository )[0 ]
10931094 except Exception as err :
@@ -1121,7 +1122,7 @@ def manage_collection_item(self, headers_, action='create', collection=None,
11211122 code = 201
11221123 response = {}
11231124
1124- elif action == 'update ' :
1125+ elif action == 'replace ' :
11251126 LOGGER .debug (f'Querying repository for item { item } ' )
11261127 try :
11271128 _ = self .repository .query_ids ([record .identifier ])[0 ]
@@ -1135,6 +1136,40 @@ def manage_collection_item(self, headers_, action='create', collection=None,
11351136 code = 204
11361137 response = {}
11371138
1139+ elif action == 'update' :
1140+ LOGGER .debug (f'Querying repository for item { item } ' )
1141+ try :
1142+ content = self .repository .query_ids ([item ])[0 ]
1143+ except Exception :
1144+ msg = 'Identifier does not exist'
1145+ LOGGER .debug (msg )
1146+ return self .get_exception (404 , headers_ , 'InvalidParameterValue' , msg )
1147+
1148+ if 'id' in data :
1149+ msg = 'Update cannot alter id'
1150+ LOGGER .debug (msg )
1151+ return self .get_exception (400 , headers_ , 'InvalidParameterValue' , msg )
1152+
1153+ content = json .loads (content .metadata )
1154+ record = json_merge_patch .merge (content , data )
1155+
1156+ try :
1157+ record = parse_record (self .context , record , self .repository )[0 ]
1158+ except Exception as err :
1159+ msg = f'Failed to parse data: { err } '
1160+ LOGGER .exception (msg )
1161+ return self .get_exception (400 , headers_ , 'InvalidParameterValue' , msg )
1162+
1163+ if not hasattr (record , 'identifier' ):
1164+ msg = 'Record requires an identifier'
1165+ LOGGER .exception (msg )
1166+ return self .get_exception (400 , headers_ , 'InvalidParameterValue' , msg )
1167+
1168+ _ = self .repository .update (record )
1169+
1170+ code = 204
1171+ response = {}
1172+
11381173 elif action == 'delete' :
11391174 constraint = {
11401175 'where' : 'identifier = \' %s\' ' % item ,
0 commit comments