@@ -950,6 +950,65 @@ local function process_tuple(state, tuple, opts)
950
950
return true
951
951
end
952
952
953
+ --- Get schema name by a collection name.
954
+ ---
955
+ --- @tparam table self data accessor instance
956
+ ---
957
+ --- @tparam string collection_name
958
+ ---
959
+ --- @treturn string `schema_name`
960
+ local function get_schema_name (self , collection_name )
961
+ local collection = self .collections [collection_name ]
962
+ assert (collection ~= nil ,
963
+ (' cannot find the collection "%s"' ):format (collection_name ))
964
+ local schema_name = collection .schema_name
965
+ assert (type (schema_name ) == ' string' ,
966
+ ' schema_name must be a string, got ' .. type (schema_name ))
967
+ return schema_name
968
+ end
969
+
970
+ --- Call one of accessor function: `update_tuple` or `delete_tuple` for each
971
+ --- selected object.
972
+ ---
973
+ --- @tparam table self data accessor instance
974
+ ---
975
+ --- @tparam string collection_name
976
+ ---
977
+ --- @tparam string schema_name
978
+ ---
979
+ --- @tparam table selected objects to perform the operation
980
+ ---
981
+ --- @tparam string operation 'update_tuple' or 'delete_tuple'
982
+ ---
983
+ --- @param [opt ] ... parameters to pass to the function
984
+ ---
985
+ --- @treturn table `new_objects` list of returned objects (in the order of the
986
+ --- `selected` parameter)
987
+ local function perform_primary_key_operation (self , collection_name , schema_name ,
988
+ selected , operation , ...)
989
+ check (operation , ' operation' , ' string' )
990
+
991
+ local _ , primary_index_meta = get_primary_index_meta (self , collection_name )
992
+
993
+ local new_objects = {}
994
+
995
+ for _ , object in ipairs (selected ) do
996
+ local key = {}
997
+ for _ , field_name in ipairs (primary_index_meta .fields ) do
998
+ table.insert (key , object [field_name ])
999
+ end
1000
+ -- XXX: we can pass a tuple corresponding the object to update_tuple /
1001
+ -- delete_tuple to save one get operation
1002
+ local new_tuple = self .funcs [operation ](collection_name , key , ... )
1003
+ local new_object = self .funcs .unflatten_tuple (collection_name ,
1004
+ new_tuple , {use_tomap = self .collection_use_tomap [collection_name ]},
1005
+ self .default_unflatten_tuple [schema_name ])
1006
+ table.insert (new_objects , new_object )
1007
+ end
1008
+
1009
+ return new_objects
1010
+ end
1011
+
953
1012
--- The function is core of this module and implements logic of fetching and
954
1013
--- filtering requested objects.
955
1014
---
@@ -1117,17 +1176,13 @@ local function insert_internal(self, collection_name, from, filter, args, extra)
1117
1176
local err_msg = ' "insert" must be the only argument when it is present'
1118
1177
assert (next (filter ) == nil , err_msg )
1119
1178
assert (next (args ) == nil , err_msg )
1179
+ assert (next (extra .extra_args , next (extra .extra_args )) == nil , err_msg )
1120
1180
check (from , ' from' , ' table' )
1121
1181
-- allow only top level collection
1122
1182
check (from .collection_name , ' from.collection_name' , ' nil' )
1123
1183
1124
1184
-- convert object -> tuple (set default values from a schema)
1125
- local collection = self .collections [collection_name ]
1126
- assert (collection ~= nil ,
1127
- (' cannot find the collection "%s"' ):format (collection_name ))
1128
- local schema_name = collection .schema_name
1129
- assert (type (schema_name ) == ' string' ,
1130
- ' schema_name must be a string, got ' .. type (schema_name ))
1185
+ local schema_name = get_schema_name (self , collection_name )
1131
1186
local default_flatten_object = self .default_flatten_object [schema_name ]
1132
1187
assert (default_flatten_object ~= nil ,
1133
1188
(' cannot find default_flatten_object ' ..
@@ -1164,42 +1219,44 @@ local function update_internal(self, collection_name, extra, selected)
1164
1219
local xobject = extra .extra_args .update
1165
1220
if xobject == nil then return nil end
1166
1221
1167
- -- convert xobject -> update statements
1168
- local collection = self .collections [collection_name ]
1169
- assert (collection ~= nil ,
1170
- (' cannot find the collection "%s"' ):format (collection_name ))
1171
- local schema_name = collection .schema_name
1172
- assert (type (schema_name ) == ' string' ,
1173
- ' schema_name must be a string, got ' .. type (schema_name ))
1222
+ local err_msg = ' "update" must not be passed with "insert" or "delete" ' ..
1223
+ ' arguments'
1224
+ assert (next (extra .extra_args , next (extra .extra_args )) == nil , err_msg )
1174
1225
1226
+ -- convert xobject -> update statements
1227
+ local schema_name = get_schema_name (self , collection_name )
1175
1228
local default_xflatten = self .default_xflatten [schema_name ]
1176
1229
assert (default_xflatten ~= nil ,
1177
1230
(' cannot find default_xflatten ' ..
1178
1231
' for collection "%s"' ):format (collection_name ))
1179
-
1180
1232
local statements = self .funcs .xflatten (collection_name , xobject , {
1181
1233
service_fields_defaults =
1182
1234
self .service_fields_defaults [schema_name ],
1183
1235
}, default_xflatten )
1184
1236
1185
- local _ , primary_index_meta = get_primary_index_meta (self , collection_name )
1186
- local new_objects = {}
1187
- for _ , object in ipairs (selected ) do
1188
- local key = {}
1189
- for _ , field_name in ipairs (primary_index_meta .fields ) do
1190
- table.insert (key , object [field_name ])
1191
- end
1192
- -- XXX: we can pass a tuple corresponding the object to update_tuple to
1193
- -- save one get operation
1194
- local new_tuple = self .funcs .update_tuple (collection_name , key ,
1195
- statements )
1196
- local new_object = self .funcs .unflatten_tuple (collection_name ,
1197
- new_tuple , {use_tomap = self .collection_use_tomap [collection_name ]},
1198
- self .default_unflatten_tuple [schema_name ])
1199
- table.insert (new_objects , new_object )
1200
- end
1237
+ return perform_primary_key_operation (self , collection_name , schema_name ,
1238
+ selected , ' update_tuple' , statements )
1239
+ end
1201
1240
1202
- return new_objects
1241
+ --- Delete an object.
1242
+ ---
1243
+ --- Parameters are the same as for @{select_update}.
1244
+ ---
1245
+ --- @tparam table extra `extra.extra_args.delete` is used
1246
+ ---
1247
+ --- @treturn table `new_objects` list of deleted objects (in the order of the
1248
+ --- `selected` parameter)
1249
+ local function delete_internal (self , collection_name , extra , selected )
1250
+ if not extra .extra_args .delete then return nil end
1251
+
1252
+ local err_msg = ' "delete" must not be passed with "insert" or "update" ' ..
1253
+ ' arguments'
1254
+ assert (next (extra .extra_args , next (extra .extra_args )) == nil , err_msg )
1255
+
1256
+ local schema_name = get_schema_name (self , collection_name )
1257
+
1258
+ return perform_primary_key_operation (self , collection_name , schema_name ,
1259
+ selected , ' delete_tuple' )
1203
1260
end
1204
1261
1205
1262
--- Set of asserts to check the `funcs` argument of the @{accessor_general.new}
@@ -1234,6 +1291,9 @@ local function validate_funcs(funcs)
1234
1291
assert (type (funcs .update_tuple ) == ' function' ,
1235
1292
' funcs.update_tuple must be a function, got ' ..
1236
1293
type (funcs .update_tuple ))
1294
+ assert (type (funcs .delete_tuple ) == ' function' ,
1295
+ ' funcs.delete_tuple must be a function, got ' ..
1296
+ type (funcs .delete_tuple ))
1237
1297
end
1238
1298
1239
1299
--- This function is called on first select related to a query. Its purpose is
@@ -1685,6 +1745,10 @@ function accessor_general.new(opts, funcs)
1685
1745
selected )
1686
1746
if updated ~= nil then return updated end
1687
1747
1748
+ local deleted = delete_internal (self , collection_name , extra ,
1749
+ selected )
1750
+ if deleted ~= nil then return deleted end
1751
+
1688
1752
return selected
1689
1753
end ,
1690
1754
list_args = list_args ,
0 commit comments