Skip to content

Commit

Permalink
Merge branch '7.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed May 21, 2024
2 parents e661f5e + 32f1ee1 commit c7315fb
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 14 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ jobs:
matrix:
node: [16, 18, 20]
os: [ubuntu-20.04, ubuntu-22.04]
mongodb: [4.4.18, 5.0.14, 6.0.4]
mongodb: [4.4.28, 5.0.25, 6.0.14, 7.0.7]
include:
- os: ubuntu-20.04 # customize on which matrix the coverage will be collected on
mongodb: 5.0.14
mongodb: 5.0.25
node: 16
coverage: true
exclude:
- os: ubuntu-22.04 # exclude because there are no 4.x mongodb builds for 2204
mongodb: 4.4.18
mongodb: 4.4.28
- os: ubuntu-22.04 # exclude because there are no 5.x mongodb builds for 2204
mongodb: 5.0.14
mongodb: 5.0.25
name: Node ${{ matrix.node }} MongoDB ${{ matrix.mongodb }} OS ${{ matrix.os }}
env:
MONGOMS_VERSION: ${{ matrix.mongodb }}
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
runs-on: ubuntu-20.04
name: Deno tests
env:
MONGOMS_VERSION: 6.0.4
MONGOMS_VERSION: 6.0.14
MONGOMS_PREFER_GLOBAL_PATH: 1
FORCE_COLOR: true
steps:
Expand All @@ -108,7 +108,7 @@ jobs:
- name: Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: v1.36.x
deno-version: v1.37.x
- run: deno --version
- run: npm install
- name: Run Deno tests
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
7.6.12 / 2024-05-21
===================
* fix(array): avoid converting to $set when calling pull() on an element in the middle of the array #14531 #14502
* fix: bump mongodb driver to 5.9.2 #14561 [lorand-horvath](https://github.com/lorand-horvath)
* fix(update): cast array of strings underneath doc array with array filters #14605 #14595

8.4.0 / 2024-05-17
==================
* feat: upgrade mongodb -> 6.6.2 #14584
Expand Down
20 changes: 17 additions & 3 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -2380,15 +2380,29 @@ Document.prototype.isDirectModified = function(path) {
}

if (typeof path === 'string' && path.indexOf(' ') === -1) {
return this.$__.activePaths.getStatePaths('modify').hasOwnProperty(path);
const res = this.$__.activePaths.getStatePaths('modify').hasOwnProperty(path);
if (res || path.indexOf('.') === -1) {
return res;
}

const pieces = path.split('.');
for (let i = 0; i < pieces.length - 1; ++i) {
const subpath = pieces.slice(0, i + 1).join('.');
const subdoc = this.$get(subpath);
if (subdoc != null && subdoc.$__ != null && subdoc.isDirectModified(pieces.slice(i + 1).join('.'))) {
return true;
}
}

return false;
}

let paths = path;
if (!Array.isArray(paths)) {
if (typeof paths === 'string') {
paths = paths.split(' ');
}

return paths.some(path => this.$__.activePaths.getStatePaths('modify').hasOwnProperty(path));
return paths.some(path => this.isDirectModified(path));
};

/**
Expand Down
4 changes: 4 additions & 0 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -2636,6 +2636,10 @@ Schema.prototype._getSchema = function(path) {
// If there is no foundschema.schema we are dealing with
// a path like array.$
if (p !== parts.length) {
if (p + 1 === parts.length && foundschema.$embeddedSchemaType && (parts[p] === '$' || isArrayFilter(parts[p]))) {
return foundschema.$embeddedSchemaType;
}

if (foundschema.schema) {
let ret;
if (parts[p] === '$' || isArrayFilter(parts[p])) {
Expand Down
11 changes: 7 additions & 4 deletions lib/types/array/methods/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,10 @@ const methods = {

pull() {
const values = [].map.call(arguments, (v, i) => this._cast(v, i, { defaults: false }), this);
const cur = this[arrayParentSymbol].get(this[arrayPathSymbol]);
let cur = this[arrayParentSymbol].get(this[arrayPathSymbol]);
if (utils.isMongooseArray(cur)) {
cur = cur.__array;
}
let i = cur.length;
let mem;
this._markModified();
Expand All @@ -615,10 +618,10 @@ const methods = {
return mem.equals(v);
});
if (some) {
[].splice.call(cur, i, 1);
cur.splice(i, 1);
}
} else if (~cur.indexOf.call(values, mem)) {
[].splice.call(cur, i, 1);
} else if (~this.indexOf.call(values, mem)) {
cur.splice(i, 1);
}
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"mkdirp": "^3.0.1",
"mocha": "10.4.0",
"moment": "2.x",
"mongodb-memory-server": "8.15.1",
"mongodb-memory-server": "9.2.0",
"ncp": "^2.0.0",
"nyc": "15.1.0",
"pug": "3.0.2",
Expand Down
58 changes: 58 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13352,6 +13352,64 @@ describe('document', function() {
const obj = parent.toJSON({ getters: true });
assert.equal(obj.children[0].name, 'Stefan');
});

it('isDirectModified on paths underneath direct modified subdoc (gh-14502)', async function() {
const JsonFieldSchema = new Schema({
fieldA: String,
fieldB: String
});

const CommentSchema = new Schema({
title: String,
body: String,
jsonField: JsonFieldSchema
});

const BlogPostSchema = new Schema({
comment: CommentSchema
});

const Comments = db.model('Comments', CommentSchema);
const BlogPost = db.model('BlogPost', BlogPostSchema);

const comment1 = new Comments({});
comment1.init({
title: 'Test',
body: 'Test',
jsonField: {
fieldA: 'field A',
fieldB: 'field B'
}
});

const update = {
title: 'New test',
jsonField: {
fieldA: 'new Field A'
}
};
Object.assign(comment1, { ...update });

assert.ok(comment1.isDirectModified('jsonField.fieldA'));
assert.ok(comment1.jsonField.isDirectModified('fieldA'));

const blogPost = new BlogPost({});
blogPost.init({
comment: {
title: 'Test',
body: 'Test',
jsonField: {
fieldA: 'field A',
fieldB: 'field B'
}
}
});

Object.assign(blogPost.comment, { ...update });

assert.ok(blogPost.isDirectModified('comment.jsonField.fieldA'));
assert.ok(blogPost.comment.jsonField.isDirectModified('fieldA'));
});
});

describe('Check if instance function that is supplied in schema option is availabe', function() {
Expand Down
38 changes: 38 additions & 0 deletions test/helpers/update.castArrayFilters.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,42 @@ describe('castArrayFilters', function() {

assert.strictEqual(q.options.arrayFilters[0]['element.number'], 1);
});

it('correctly casts array of strings underneath doc array (gh-12565)', function() {
const userSchema = new Schema({
groups: [{
document: 'ObjectId',
tags: [String]
}]
});

const q = new Query();
q.schema = userSchema;

const groupId = new Types.ObjectId();
const filter = {
groups: {
$elemMatch: {
document: groupId,
tags: 'tag-to-update'
}
}
};
const update = {
$set: {
'groups.$[group].tags.$[tag]': 42
}
};
const opts = {
arrayFilters: [
{ 'group.document': groupId },
{ tag: { $eq: 'tag-to-update' } }
]
};
q.updateOne(filter, update, opts);
castArrayFilters(q);
q._update = q._castUpdate(q._update, false);

assert.strictEqual(q.getUpdate().$set['groups.$[group].tags.$[tag]'], '42');
});
});
3 changes: 3 additions & 0 deletions test/schema.select.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ describe('schema select option', function() {
afterEach(() => require('./util').stopRemainingOps(db));

it('excluding paths through schematype', async function() {
// data clearing is required for this test, because in deno some other test leaks a "_id: immutable" index
await db.dropDatabase();

const schema = new Schema({
thin: Boolean,
name: { type: String, select: false },
Expand Down
21 changes: 21 additions & 0 deletions test/types.array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,27 @@ describe('types array', function() {
doc.a.pull(cat.id);
assert.equal(doc.a.length, 0);

assert.ok(doc.getChanges().$pullAll.a);
});

it('registers $pull atomic if pulling from middle (gh-14502)', async function() {
const schema = new Schema({
a: [{ type: Schema.ObjectId, ref: 'Cat' }]
});
const A = db.model('Test', schema);

const oid1 = new mongoose.Types.ObjectId();
const oid2 = new mongoose.Types.ObjectId();
const oid3 = new mongoose.Types.ObjectId();
const a = new A({ a: [oid1, oid2, oid3] });
await a.save();

const doc = await A.findById(a);
assert.equal(doc.a.length, 3);
doc.a.pull(oid2);
assert.equal(doc.a.length, 2);

assert.ok(doc.getChanges().$pullAll.a);
});

it('handles pulling with no _id (gh-3341)', async function() {
Expand Down

0 comments on commit c7315fb

Please sign in to comment.