Skip to content

Commit

Permalink
fix(model): make cleanIndexes() use diffIndexes() to get indexes …
Browse files Browse the repository at this point in the history
…to drop, make `diffIndexes()` handle discriminators

Fix #11430
Re: #11424
  • Loading branch information
vkarpov15 committed May 15, 2022
1 parent 9aa10a5 commit 735e0c6
Showing 1 changed file with 37 additions and 54 deletions.
91 changes: 37 additions & 54 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1488,61 +1488,68 @@ Model.syncIndexes = function syncIndexes(options, callback) {
* the result of this function would be the result of
* Model.syncIndexes().
*
* @param {Object} options not used at all.
* @param {Object} [options]
* @param {Function} callback optional callback
* @returns {Promise} which containts an object, {toDrop, toCreate}, which
* are indexes that would be dropped in mongodb and indexes that would be created in mongodb.
* @returns {Promise} which contains an object, {toDrop, toCreate}, which
* are indexes that would be dropped in MongoDB and indexes that would be created in MongoDB.
*/

Model.diffIndexes = function diffIndexes(options, callback) {
if (typeof options === 'function') {
callback = options;
options = null;
}
const toDrop = [];
const toCreate = [];
callback = this.$handleCallbackError(callback);
return this.db.base._promiseOrCallback(callback, cb => {
cb = this.$wrapCallback(cb);
this.listIndexes((err, indexes) => {
if (indexes === undefined) {
indexes = [];
this.listIndexes((err, dbIndexes) => {
if (dbIndexes === undefined) {
dbIndexes = [];
}
const schemaIndexes = this.schema.indexes();
// Iterate through the indexes created in mongodb and
// compare against the indexes in the schema.
for (const index of indexes) {
dbIndexes = getRelatedDBIndexes(this, dbIndexes);
const schemaIndexes = getRelatedSchemaIndexes(this, this.schema.indexes());

for (const dbIndex of dbIndexes) {
let found = false;
// Never try to drop `_id` index, MongoDB server doesn't allow it
if (isDefaultIdIndex(index)) {
if (isDefaultIdIndex(dbIndex)) {
continue;
}

for (const schemaIndex of schemaIndexes) {
const key = schemaIndex[0];
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndex[1]));
if (isIndexEqual(key, options, index)) {
for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndexOptions));
applySchemaCollation(schemaIndexKeysObject, options, this.schema.options);

if (isIndexEqual(schemaIndexKeysObject, options, dbIndex)) {
found = true;
}
}

if (!found) {
toDrop.push(index.name);
toDrop.push(dbIndex.name);
}
}
// Iterate through the indexes created on the schema and
// compare against the indexes in mongodb.
for (const schemaIndex of schemaIndexes) {
let found = false;
const key = schemaIndex[0];
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndex[1]));
for (const index of indexes) {
if (isDefaultIdIndex(index)) {
continue;
if (!options || options.toCreate !== false) {
for (const schemaIndex of schemaIndexes) {
let found = false;
const key = schemaIndex[0];
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndex[1]));
for (const index of dbIndexes) {
if (isDefaultIdIndex(index)) {
continue;
}
if (isIndexEqual(key, options, index)) {
found = true;
}
}
if (isIndexEqual(key, options, index)) {
found = true;
if (!found) {
toCreate.push(key);
}
}
if (!found) {
toCreate.push(key);
}
}
cb(null, { toDrop, toCreate });
});
Expand All @@ -1568,36 +1575,12 @@ Model.cleanIndexes = function cleanIndexes(callback) {
return this.db.base._promiseOrCallback(callback, cb => {
const collection = this.$__collection;

this.listIndexes((err, dbIndexes) => {
this.diffIndexes({ toCreate: false }, (err, res) => {
if (err != null) {
return cb(err);
}

dbIndexes = getRelatedDBIndexes(this, dbIndexes);
const schemaIndexes = getRelatedSchemaIndexes(this, this.schema.indexes());

const toDrop = [];

for (const dbIndex of dbIndexes) {
let found = false;
// Never try to drop `_id` index, MongoDB server doesn't allow it
if (isDefaultIdIndex(dbIndex)) {
continue;
}

for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndexOptions));
applySchemaCollation(schemaIndexKeysObject, options, this.schema.options);

if (isIndexEqual(schemaIndexKeysObject, options, dbIndex)) {
found = true;
}
}

if (!found) {
toDrop.push(dbIndex.name);
}
}
const toDrop = res.toDrop;

if (toDrop.length === 0) {
return cb(null, []);
Expand Down

0 comments on commit 735e0c6

Please sign in to comment.