@@ -1147,6 +1147,51 @@ 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
+ -- XXX: we can pass tuple to update_tuple to save one get operation
1184
+ local new_tuple = self .funcs .update_tuple (collection_name , key ,
1185
+ statements )
1186
+ local new_object = self .funcs .unflatten_tuple (collection_name ,
1187
+ new_tuple , {use_tomap = self .collection_use_tomap [collection_name ]},
1188
+ self .default_unflatten_tuple [schema_name ])
1189
+ table.insert (new_objects , new_object )
1190
+ end
1191
+
1192
+ return new_objects
1193
+ end
1194
+
1150
1195
--- Set of asserts to check the `funcs` argument of the @{accessor_general.new}
1151
1196
--- function.
1152
1197
--- @tparam table funcs set of function as defined in the
@@ -1170,9 +1215,15 @@ local function validate_funcs(funcs)
1170
1215
assert (type (funcs .flatten_object ) == ' function' ,
1171
1216
' funcs.flatten_object must be a function, got ' ..
1172
1217
type (funcs .flatten_object ))
1218
+ assert (type (funcs .xflatten ) == ' function' ,
1219
+ ' funcs.xflatten must be a function, got ' ..
1220
+ type (funcs .xflatten ))
1173
1221
assert (type (funcs .insert_tuple ) == ' function' ,
1174
1222
' funcs.insert_tuple must be a function, got ' ..
1175
1223
type (funcs .insert_tuple ))
1224
+ assert (type (funcs .update_tuple ) == ' function' ,
1225
+ ' funcs.update_tuple must be a function, got ' ..
1226
+ type (funcs .update_tuple ))
1176
1227
end
1177
1228
1178
1229
--- This function is called on first select related to a query. Its purpose is
@@ -1292,6 +1343,60 @@ local function get_pcre_argument_type(self, collection_name)
1292
1343
return pcre_type
1293
1344
end
1294
1345
1346
+ --- Create default unflatten/flatten/xflatten functions, that can be called
1347
+ --- from funcs.unflatten_tuple/funcs.flatten_object/funcs.xflatten when an
1348
+ --- additional pre/postprocessing is not needed.
1349
+ ---
1350
+ --- @tparam table models list of compiled schemas
1351
+ ---
1352
+ --- @treturn table table with default_* fields with maps from schema name to
1353
+ --- the corresponding default *flatten function
1354
+ local function gen_default_object_tuple_map_funcs (models )
1355
+ local default_unflatten_tuple = {}
1356
+ local default_flatten_object = {}
1357
+ local default_xflatten = {}
1358
+ for schema_name , model in pairs (models ) do
1359
+ default_unflatten_tuple [schema_name ] = function (_ , tuple , opts )
1360
+ local opts = opts or {}
1361
+ check (opts , ' opts' , ' table' )
1362
+
1363
+ local ok , obj = model .unflatten (tuple )
1364
+ assert (ok , (' cannot unflat tuple of schema "%s": %s' ):format (
1365
+ schema_name , tostring (obj )))
1366
+ return obj
1367
+ end
1368
+ default_flatten_object [schema_name ] = function (_ , obj , opts )
1369
+ local opts = opts or {}
1370
+ check (opts , ' opts' , ' table' )
1371
+ local sf_defaults = opts .service_fields_defaults or {}
1372
+ check (sf_defaults , ' service_fields_defaults' , ' table' )
1373
+
1374
+ local ok , tuple = model .flatten (obj , unpack (sf_defaults ))
1375
+ assert (ok , (' cannot flat object of schema "%s": %s' ):format (
1376
+ schema_name , tostring (tuple )))
1377
+ return tuple
1378
+ end
1379
+ default_xflatten [schema_name ] = function (_ , xobject , opts )
1380
+ local opts = opts or {}
1381
+ check (opts , ' opts' , ' table' )
1382
+
1383
+ -- it is not needed now, but maybe needed in custom xflatten
1384
+ local sf_defaults = opts .service_fields_defaults or {}
1385
+ check (sf_defaults , ' service_fields_defaults' , ' table' )
1386
+
1387
+ local ok , statements = model .xflatten (xobject )
1388
+ assert (ok , (' cannot xflat xobject of schema "%s": %s' ):format (
1389
+ schema_name , tostring (xobject )))
1390
+ return statements
1391
+ end
1392
+ end
1393
+ return {
1394
+ default_unflatten_tuple = default_unflatten_tuple ,
1395
+ default_flatten_object = default_flatten_object ,
1396
+ default_xflatten = default_xflatten ,
1397
+ }
1398
+ end
1399
+
1295
1400
--- Create a new data accessor.
1296
1401
---
1297
1402
--- Provided `funcs` argument determines certain functions for retrieving
@@ -1391,39 +1496,8 @@ function accessor_general.new(opts, funcs)
1391
1496
service_fields )
1392
1497
validate_collections (collections , schemas , indexes )
1393
1498
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
1499
+ local default_object_tuple_map_funcs =
1500
+ gen_default_object_tuple_map_funcs (models )
1427
1501
1428
1502
validate_funcs (funcs )
1429
1503
@@ -1433,8 +1507,12 @@ function accessor_general.new(opts, funcs)
1433
1507
service_fields = service_fields ,
1434
1508
indexes = indexes ,
1435
1509
models = models ,
1436
- default_unflatten_tuple = default_unflatten_tuple ,
1437
- default_flatten_object = default_flatten_object ,
1510
+ default_unflatten_tuple =
1511
+ default_object_tuple_map_funcs .default_unflatten_tuple ,
1512
+ default_flatten_object =
1513
+ default_object_tuple_map_funcs .default_flatten_object ,
1514
+ default_xflatten =
1515
+ default_object_tuple_map_funcs .default_xflatten ,
1438
1516
service_fields_defaults = service_fields_defaults ,
1439
1517
collection_use_tomap = opts .collection_use_tomap or {},
1440
1518
index_cache = index_cache ,
@@ -1461,8 +1539,14 @@ function accessor_general.new(opts, funcs)
1461
1539
filter , args , extra )
1462
1540
if inserted ~= nil then return inserted end
1463
1541
1464
- return select_internal (self , collection_name , from , filter ,
1542
+ local selected = select_internal (self , collection_name , from , filter ,
1465
1543
args , extra )
1544
+
1545
+ local updated = update_internal (self , collection_name , from ,
1546
+ filter , args , extra , selected )
1547
+ if updated ~= nil then return updated end
1548
+
1549
+ return selected
1466
1550
end ,
1467
1551
list_args = function (self , collection_name )
1468
1552
local offset_type = get_primary_key_type (self , collection_name )
0 commit comments