@@ -1147,6 +1147,50 @@ local function insert_internal(self, collection_name, from, filter, args, extra)
1147
1147
return {new_object }
1148
1148
end
1149
1149
1150
+ --- XXX
1151
+ local function update_internal (self , collection_name , from , filter , args ,
1152
+ extra , selected )
1153
+ local xobject = extra .extra_args .update
1154
+ if xobject == nil then return nil end
1155
+
1156
+ -- convert xobject -> update statements
1157
+ local collection = self .collections [collection_name ]
1158
+ assert (collection ~= nil ,
1159
+ (' cannot find the collection "%s"' ):format (collection_name ))
1160
+ local schema_name = collection .schema_name
1161
+ assert (type (schema_name ) == ' string' ,
1162
+ ' schema_name must be a string, got ' .. type (schema_name ))
1163
+
1164
+ local default_xflatten = self .default_xflatten [schema_name ]
1165
+ assert (default_xflatten ~= nil ,
1166
+ (' cannot find default_xflatten ' ..
1167
+ ' for collection "%s"' ):format (collection_name ))
1168
+
1169
+ local statements = self .funcs .xflatten (collection_name , xobject , {
1170
+ service_fields_defaults =
1171
+ self .service_fields_defaults [schema_name ],
1172
+ }, default_xflatten )
1173
+
1174
+ -- XXX: remove connection fields from the selected objects in process_tuple
1175
+ -- apply update statements & tuples -> objects
1176
+ local _ , primary_index_meta = get_primary_index_meta (self , collection_name )
1177
+ local new_objects = {}
1178
+ for _ , object in ipairs (selected ) do
1179
+ local key = {}
1180
+ for _ , field_name in ipairs (primary_index_meta .fields ) do
1181
+ table.insert (key , object [field_name ])
1182
+ end
1183
+ local new_tuple = self .funcs .update_tuple (collection_name , key ,
1184
+ statements )
1185
+ local new_object = self .funcs .unflatten_tuple (collection_name ,
1186
+ new_tuple , {use_tomap = self .collection_use_tomap [collection_name ]},
1187
+ self .default_unflatten_tuple [schema_name ])
1188
+ table.insert (new_objects , new_object )
1189
+ end
1190
+
1191
+ return new_objects
1192
+ end
1193
+
1150
1194
--- Set of asserts to check the `funcs` argument of the @{accessor_general.new}
1151
1195
--- function.
1152
1196
--- @tparam table funcs set of function as defined in the
@@ -1170,9 +1214,15 @@ local function validate_funcs(funcs)
1170
1214
assert (type (funcs .flatten_object ) == ' function' ,
1171
1215
' funcs.flatten_object must be a function, got ' ..
1172
1216
type (funcs .flatten_object ))
1217
+ assert (type (funcs .xflatten ) == ' function' ,
1218
+ ' funcs.xflatten must be a function, got ' ..
1219
+ type (funcs .xflatten ))
1173
1220
assert (type (funcs .insert_tuple ) == ' function' ,
1174
1221
' funcs.insert_tuple must be a function, got ' ..
1175
1222
type (funcs .insert_tuple ))
1223
+ assert (type (funcs .update_tuple ) == ' function' ,
1224
+ ' funcs.update_tuple must be a function, got ' ..
1225
+ type (funcs .update_tuple ))
1176
1226
end
1177
1227
1178
1228
--- This function is called on first select related to a query. Its purpose is
@@ -1292,6 +1342,60 @@ local function get_pcre_argument_type(self, collection_name)
1292
1342
return pcre_type
1293
1343
end
1294
1344
1345
+ --- Create default unflatten/flatten/xflatten functions, that can be called
1346
+ --- from funcs.unflatten_tuple/funcs.flatten_object/funcs.xflatten when an
1347
+ --- additional pre/postprocessing is not needed.
1348
+ ---
1349
+ --- @tparam table models list of compiled schemas
1350
+ ---
1351
+ --- @treturn table table with default_* fields with maps from schema name to
1352
+ --- the corresponding default *flatten function
1353
+ local function gen_default_object_tuple_map_funcs (models )
1354
+ local default_unflatten_tuple = {}
1355
+ local default_flatten_object = {}
1356
+ local default_xflatten = {}
1357
+ for schema_name , model in pairs (models ) do
1358
+ default_unflatten_tuple [schema_name ] = function (_ , tuple , opts )
1359
+ local opts = opts or {}
1360
+ check (opts , ' opts' , ' table' )
1361
+
1362
+ local ok , obj = model .unflatten (tuple )
1363
+ assert (ok , (' cannot unflat tuple of schema "%s": %s' ):format (
1364
+ schema_name , tostring (obj )))
1365
+ return obj
1366
+ end
1367
+ default_flatten_object [schema_name ] = function (_ , obj , opts )
1368
+ local opts = opts or {}
1369
+ check (opts , ' opts' , ' table' )
1370
+ local sf_defaults = opts .service_fields_defaults or {}
1371
+ check (sf_defaults , ' service_fields_defaults' , ' table' )
1372
+
1373
+ local ok , tuple = model .flatten (obj , unpack (sf_defaults ))
1374
+ assert (ok , (' cannot flat object of schema "%s": %s' ):format (
1375
+ schema_name , tostring (tuple )))
1376
+ return tuple
1377
+ end
1378
+ default_xflatten [schema_name ] = function (_ , xobject , opts )
1379
+ local opts = opts or {}
1380
+ check (opts , ' opts' , ' table' )
1381
+
1382
+ -- it is not needed now, but maybe needed in custom xflatten
1383
+ local sf_defaults = opts .service_fields_defaults or {}
1384
+ check (sf_defaults , ' service_fields_defaults' , ' table' )
1385
+
1386
+ local ok , statements = model .xflatten (xobject )
1387
+ assert (ok , (' cannot xflat xobject of schema "%s": %s' ):format (
1388
+ schema_name , tostring (xobject )))
1389
+ return statements
1390
+ end
1391
+ end
1392
+ return {
1393
+ default_unflatten_tuple = default_unflatten_tuple ,
1394
+ default_flatten_object = default_flatten_object ,
1395
+ default_xflatten = default_xflatten ,
1396
+ }
1397
+ end
1398
+
1295
1399
--- Create a new data accessor.
1296
1400
---
1297
1401
--- Provided `funcs` argument determines certain functions for retrieving
@@ -1391,39 +1495,8 @@ function accessor_general.new(opts, funcs)
1391
1495
service_fields )
1392
1496
validate_collections (collections , schemas , indexes )
1393
1497
local index_cache = build_index_cache (indexes , collections )
1394
-
1395
- -- create default unflatten/flatten functions, that can be called from
1396
- -- funcs.unflatten_tuple/funcs.flatten_object when an additional
1397
- -- pre/postprocessing is not needed
1398
- local default_unflatten_tuple = {}
1399
- local default_flatten_object = {}
1400
- for schema_name , model in pairs (models ) do
1401
- default_unflatten_tuple [schema_name ] =
1402
- function (_ , tuple , opts )
1403
- local opts = opts or {}
1404
- check (opts , ' opts' , ' table' )
1405
-
1406
- local ok , obj = model .unflatten (tuple )
1407
- assert (ok , (' cannot unflat tuple of schema "%s": %s' ):format (
1408
- schema_name , tostring (obj )))
1409
- return obj
1410
- end
1411
- default_flatten_object [schema_name ] =
1412
- function (_ , obj , opts )
1413
- local opts = opts or {}
1414
- check (opts , ' opts' , ' table' )
1415
- local service_fields_defaults = opts .service_fields_defaults or
1416
- {}
1417
- check (service_fields_defaults , ' service_fields_defaults' ,
1418
- ' table' )
1419
-
1420
- local ok , tuple = model .flatten (obj ,
1421
- unpack (service_fields_defaults ))
1422
- assert (ok , (' cannot flat object of schema "%s": %s' ):format (
1423
- schema_name , tostring (tuple )))
1424
- return tuple
1425
- end
1426
- end
1498
+ local default_object_tuple_map_funcs =
1499
+ gen_default_object_tuple_map_funcs (models )
1427
1500
1428
1501
validate_funcs (funcs )
1429
1502
@@ -1433,8 +1506,12 @@ function accessor_general.new(opts, funcs)
1433
1506
service_fields = service_fields ,
1434
1507
indexes = indexes ,
1435
1508
models = models ,
1436
- default_unflatten_tuple = default_unflatten_tuple ,
1437
- default_flatten_object = default_flatten_object ,
1509
+ default_unflatten_tuple =
1510
+ default_object_tuple_map_funcs .default_unflatten_tuple ,
1511
+ default_flatten_object =
1512
+ default_object_tuple_map_funcs .default_flatten_object ,
1513
+ default_xflatten =
1514
+ default_object_tuple_map_funcs .default_xflatten ,
1438
1515
service_fields_defaults = service_fields_defaults ,
1439
1516
collection_use_tomap = opts .collection_use_tomap or {},
1440
1517
index_cache = index_cache ,
@@ -1461,8 +1538,14 @@ function accessor_general.new(opts, funcs)
1461
1538
filter , args , extra )
1462
1539
if inserted ~= nil then return inserted end
1463
1540
1464
- return select_internal (self , collection_name , from , filter ,
1541
+ local selected = select_internal (self , collection_name , from , filter ,
1465
1542
args , extra )
1543
+
1544
+ local updated = update_internal (self , collection_name , from ,
1545
+ filter , args , extra , selected )
1546
+ if updated ~= nil then return updated end
1547
+
1548
+ return selected
1466
1549
end ,
1467
1550
list_args = function (self , collection_name )
1468
1551
local offset_type = get_primary_key_type (self , collection_name )
0 commit comments