diff --git a/CHANGELOG.md b/CHANGELOG.md index b37a750..3b7935b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.0-alpha.6 (WIP) + +* Don't flatten objects when updating records, it causes too many issues + +## 1.4.0-alpha.5 (2024-08-16) + +* Pre-release with updated dependencies + ## 1.4.0-alpha.4 (2024-08-04) * Make `AQL` trail placeholders default to explicit `null` values diff --git a/lib/app/datasource/mongo_datasource.js b/lib/app/datasource/mongo_datasource.js index 1dd959b..ad1529e 100644 --- a/lib/app/datasource/mongo_datasource.js +++ b/lib/app/datasource/mongo_datasource.js @@ -131,7 +131,11 @@ Mongo.setMethod(function castToBigInt(value) { } if (typeof value == 'object') { - return value.toBigInt(); + if (value.toBigInt) { + return value.toBigInt(); + } + + return null; } return BigInt(value); @@ -541,110 +545,125 @@ Mongo.setMethod(function _create(context) { */ Mongo.setMethod(function _update(context) { - const model = context.getModel(), - options = context.getSaveOptions(); + const model = context.getModel(); return Swift.waterfall( this.collection(model.table), collection => { + return performUpdate(collection, model, context); + } + ); +}); - let key; +/** + * Perform the update + * + * @author Jelle De Loecker + * @since 1.4.0 + * @version 1.4.0 + * + * @return {Pledge} + */ +const performUpdate = (collection, model, context) => { - // Get the converted data - const data = context.getConvertedData(); + const options = context.getSaveOptions(); - // Get the id to update, it should always be inside the given data - let id = data._id; + let key; - // Clone the data object - let doc = {...data}; + // Get the converted data + const data = context.getConvertedData(); - // Values that will get flattened - let to_flatten = {}; + // Get the id to update, it should always be inside the given data + let id = data._id; - // Field names that won't get flattened - let no_flatten = {}; + // Clone the data object + let doc = {...data}; - // Remove the id - delete doc._id; + // Values that will get flattened + let to_flatten = {}; - if (!options.override_created) { - delete doc.created; - } + // Field names that won't get flattened + let no_flatten = {}; - // Iterate over the fields - for (key in doc) { - let field = model.getField(key); + // Remove the id + delete doc._id; - if (field && (field.is_self_contained || field.is_translatable)) { - no_flatten[key] = doc[key]; - } else { - to_flatten[key] = doc[key]; - } - } + if (!options.override_created) { + delete doc.created; + } - // Flatten the object, using periods & NOT flattening arrays - let flat = Object.flatten(to_flatten, '.', false); + // Iterate over the fields + for (key in doc) { + let field = model.getField(key); - // Assign the no-flatten values, too - Object.assign(flat, no_flatten); + if (field && (field.is_self_contained || field.is_translatable || typeof doc[key] == 'object')) { + no_flatten[key] = doc[key]; + } else { + to_flatten[key] = doc[key]; + } + } - let unset = {}; + // Flatten the object, using periods & NOT flattening arrays + let flat = Object.flatten(to_flatten, '.', false); - for (key in flat) { - // Undefined or null means we want to delete the value - // We can't set null, because that could interfere with dot notation updates - if (flat[key] == null) { + // Assign the no-flatten values, too + Object.assign(flat, no_flatten); - // Add the key to the unset object - unset[key] = ''; + let unset = {}; - // Remove it from the flat object - delete flat[key]; - } - } + for (key in flat) { + // Undefined or null means we want to delete the value + // We can't set null, because that could interfere with dot notation updates + if (flat[key] == null) { - let update_object = { - $set: flat - }; + // Add the key to the unset object + unset[key] = ''; - if (!Object.isEmpty(unset)) { - update_object.$unset = unset; - } + // Remove it from the flat object + delete flat[key]; + } + } - if (options.debug) { - console.log('Updating with obj', id, update_object); - } + let update_object = { + $set: flat + }; - let promise; + if (!Object.isEmpty(unset)) { + update_object.$unset = unset; + } - if (collection.findOneAndUpdate) { - promise = collection.findOneAndUpdate({_id: id}, update_object, {upsert: true}); - } else if (collection.findAndModify) { - promise = collection.findAndModify({_id: id}, [['_id', 1]], update_object, {upsert: true}); - } else { - // If it's not available (like nedb) - promise = collection.update({_id: ''+id}, update_object, {upsert: true}); - } + if (options.debug) { + console.log('Updating with obj', id, update_object); + } - let pledge = new Swift(); + let promise; - Pledge.done(promise, function afterUpdate(err, result) { + if (collection.findOneAndUpdate) { + promise = collection.findOneAndUpdate({_id: id}, update_object, {upsert: true}); + } else if (collection.findAndModify) { + promise = collection.findAndModify({_id: id}, [['_id', 1]], update_object, {upsert: true}); + } else { + // If it's not available (like nedb) + promise = collection.update({_id: ''+id}, update_object, {upsert: true}); + } - // Clear the cache - model.nukeCache(); + let pledge = new Swift(); - if (err != null) { - return pledge.reject(err); - } + Pledge.done(promise, function afterUpdate(err, result) { - pledge.resolve(Object.assign({}, data)); - }); + // Clear the cache + model.nukeCache(); - return pledge; + if (err != null) { + return pledge.reject(err); } - ); -}); + + pledge.resolve(Object.assign({}, data)); + }); + + return pledge; + +}; /** * Remove a record from the database diff --git a/package.json b/package.json index 96e50e6..02b8388 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "alchemymvc", "description": "MVC framework for Node.js", - "version": "1.4.0-alpha.5", + "version": "1.4.0-alpha.6", "author": "Jelle De Loecker ", "keywords": [ "alchemy",