Skip to content

Commit

Permalink
Added position option to push and pop
Browse files Browse the repository at this point in the history
  • Loading branch information
SReject committed Nov 11, 2021
1 parent 4c00abd commit d8a5dd8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
5 changes: 3 additions & 2 deletions lib/datastore.js
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ class Datastore extends EventEmitter {
const callback = cb || function () {};
const multi = options.multi !== undefined ? options.multi : false;
const upsert = options.upsert !== undefined ? options.upsert : false;
const position = options.position !== undefined ? options.position : false;

async.waterfall([
cb => {
Expand All @@ -602,7 +603,7 @@ class Datastore extends EventEmitter {
// updateQuery contains modifiers, use the find query as the base,
// strip it from all operators and update it according to updateQuery
try {
toBeInserted = model.modify(model.deepCopy(query, true), updateQuery);
toBeInserted = model.modify(model.deepCopy(query, true), updateQuery, position);
} catch (err) {
return callback(err);
}
Expand Down Expand Up @@ -638,7 +639,7 @@ class Datastore extends EventEmitter {
if (this.timestampData) {
createdAt = candidates[i].createdAt;
}
const modifiedDoc = model.modify(candidates[i], updateQuery);
const modifiedDoc = model.modify(candidates[i], updateQuery, position);
if (this.timestampData) {
modifiedDoc.createdAt = createdAt;
// modifiedDoc.updatedAt = new Date();
Expand Down
26 changes: 16 additions & 10 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ lastStepModifierFunctions.$unset = function (obj, field) {
* Optional modifier $slice to slice the resulting array, see https://docs.mongodb.org/manual/reference/operator/update/slice/
* Différeence with MongoDB: if $slice is specified and not $each, we act as if value is an empty array
*/
lastStepModifierFunctions.$push = function (obj, field, value) {
lastStepModifierFunctions.$push = function (obj, field, value, position) {
// Create the array if it doesn't exist
if (!has(obj, field)) {
obj[field] = [];
Expand All @@ -492,7 +492,7 @@ lastStepModifierFunctions.$push = function (obj, field, value) {
throw new Error("Can't $push an element on non-array values");
}

if (value !== null && typeof value === 'object' && value.$slice && value.$each === undefined) {
if (value !== null && typeof value === 'object' && value.$slice && value.$each === undefined && value.position === undefined) {
value.$each = [];
}

Expand Down Expand Up @@ -528,7 +528,11 @@ lastStepModifierFunctions.$push = function (obj, field, value) {
obj[field] = obj[field].slice(start, end);
}
} else {
obj[field].push(value);
if (position === undefined) {
obj[field].push(value);
} else {
obj[field].splice(position, 0, value);
}
}
};

Expand Down Expand Up @@ -572,7 +576,7 @@ lastStepModifierFunctions.$addToSet = function (obj, field, value) {
};

/** Remove the first or last element of an array */
lastStepModifierFunctions.$pop = function (obj, field, value) {
lastStepModifierFunctions.$pop = function (obj, field, value, position) {
if (!Array.isArray(obj[field])) {
throw new Error("Can't $pop an element from non-array values");
}
Expand All @@ -583,7 +587,9 @@ lastStepModifierFunctions.$pop = function (obj, field, value) {
return;
}

if (value > 0) {
if (position !== undefined) {
obj[field] = obj[field].splice(position, 1);
} else if (value > 0) {
obj[field] = obj[field].slice(0, obj[field].length - 1);
} else {
obj[field] = obj[field].slice(1);
Expand Down Expand Up @@ -641,11 +647,11 @@ lastStepModifierFunctions.$min = function (obj, field, value) {

// Given its name, create the complete modifier function
function createModifierFunction (modifier) {
return function (obj, field, value) {
return function (obj, field, value, position) {
let fieldParts = typeof field === 'string' ? field.split('.') : field;

if (fieldParts.length === 1) {
lastStepModifierFunctions[modifier](obj, field, value);
lastStepModifierFunctions[modifier](obj, field, value, position);
} else {
if (obj[fieldParts[0]] === undefined) {
// Bad looking specific fix, needs to be generalized modifiers that behave like $unset are implemented
Expand All @@ -654,7 +660,7 @@ function createModifierFunction (modifier) {
}
obj[fieldParts[0]] = {};
}
modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value);
modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value, position);
}
};
}
Expand All @@ -665,7 +671,7 @@ Object.keys(lastStepModifierFunctions).forEach(function (modifier) {
});

/** Modify a DB object according to an update query */
function modify (obj, updateQuery) {
function modify (obj, updateQuery, position) {
let keys = Object.keys(updateQuery),
firstChars = keys.map(item => item[0]),
dollarFirstChars = firstChars.filter(item => item === '$'),
Expand Down Expand Up @@ -701,7 +707,7 @@ function modify (obj, updateQuery) {

const keys = Object.keys(updateQuery[m]);
keys.forEach(function (k) {
modifierFunctions[m](newDoc, k, updateQuery[m][k]);
modifierFunctions[m](newDoc, k, updateQuery[m][k], position);
});
});
}
Expand Down

0 comments on commit d8a5dd8

Please sign in to comment.