Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,8 @@
this.schemaLevelReadPreference = schemaRp;
const mongooseSchema = new Schema(cloneDeep(schema.fields as Indexable), {
...mo,
...(isView
? {
autoCreate: false,
autoIndex: false,
}
: {}),
autoCreate: false,
autoIndex: false,
});
this.model = mongoose.model(cloneDeep(schema.name), mongooseSchema);
}
Expand Down Expand Up @@ -427,75 +423,75 @@

public calculatePopulates(population: string[]) {
const populates: (string | PopulateOptions)[] = [];
population.forEach((r: string | string[], index: number) => {
const final = r.toString().trim();
if (final.indexOf('.') !== -1) {
let controlBool = true;
let processing = cloneDeep(final);
let validPath;
while (controlBool) {
if (this.model.schema.paths[processing]) {
validPath = this.model.schema.paths[processing];
controlBool = false;
} else if ((this.model.schema as any).subpaths[processing]) {
validPath = (this.model.schema as any).subpaths[processing];
controlBool = false;
} else if (
processing === undefined ||
processing.length === 0 ||
processing === ''
) {
throw new Error("Failed populating '" + final + "'");
} else {
const split = processing.split('.');
split.splice(split.length - 1, 1);
processing = split.join('.');
}
}
if (processing === final) {
populates.push(processing);
} else if (
validPath.options.ref === undefined &&
validPath.options.type[0].ref === undefined
) {
throw new Error(
`Failed populating '${final}', path exists for ${processing} but missing ${
final.split(processing)[1]
}`,
);
} else {
const ref = validPath.options.ref || validPath.options.type[0].ref;
const childPopulates = this.adapter.models[ref].calculatePopulates([
final.replace(processing + '.', ''),
]);
if (populates.indexOf(processing) !== -1) {
populates.splice(populates.indexOf(processing), 1);
populates.push({ path: processing, populate: childPopulates });
} else {
const found = populates.filter(r => {
if (
typeof r === 'object' &&
r.hasOwnProperty('path') &&
r['path'] === processing
) {
if (!r.hasOwnProperty('populate')) {
r['populate'] = childPopulates;
} else {
r['populate'] = (r['populate']! as UntypedArray).concat(childPopulates);
}
return true;
}
return false;
});
if (found.length === 0) {
populates.push({ path: processing, populate: childPopulates });
}
}
}
} else {
populates.push(final);
}
});

Check notice on line 494 in modules/database/src/adapters/mongoose-adapter/MongooseSchema.ts

View check run for this annotation

codefactor.io / CodeFactor

modules/database/src/adapters/mongoose-adapter/MongooseSchema.ts#L426-L494

Complex Method
return populates;
}

Expand Down
41 changes: 41 additions & 0 deletions modules/database/src/adapters/mongoose-adapter/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ConnectOptions, Mongoose, Types } from 'mongoose';
import type { IndexSpecification } from 'mongodb';
import { MongooseSchema } from './MongooseSchema.js';
import { schemaConverter } from './SchemaConverter.js';
import {
Expand Down Expand Up @@ -640,6 +641,43 @@ export class MongooseAdapter extends DatabaseAdapter<MongooseSchema> {
return 'Indexes created!';
}

private async createMongooseFieldIndexes(schemaName: string): Promise<void> {
const model = this.models[schemaName];
if (!model) throw new GrpcError(status.NOT_FOUND, 'Requested schema not found');
if (model.isView) return;

const declaredIndexes = model.model.schema.indexes();
if (!declaredIndexes.length) return;

const collection = this.mongoose.model(schemaName).collection;
for (const [keys, rawOptions] of declaredIndexes) {
const indexKeys = keys as IndexSpecification;
if (this.isDefaultIdIndex(indexKeys)) continue;

const options = this.sanitizeMongooseIndexOptions(
rawOptions as Record<string, unknown>,
);
await collection.createIndex(indexKeys, options).catch((e: Error) => {
throw new GrpcError(status.INTERNAL, e.message);
});
}
}

private isDefaultIdIndex(keys: IndexSpecification): boolean {
if (!keys || typeof keys !== 'object' || Array.isArray(keys)) return false;
const entries = Object.entries(keys as Record<string, unknown>);
return entries.length === 1 && entries[0][0] === '_id' && entries[0][1] === 1;
}

private sanitizeMongooseIndexOptions(
options?: Record<string, unknown>,
): Record<string, unknown> | undefined {
if (!options) return undefined;
const sanitized = { ...options };
delete sanitized._autoIndex;
return Object.keys(sanitized).length > 0 ? sanitized : undefined;
}

async getIndexes(schemaName: string): Promise<ModelOptionsIndexes[]> {
if (!this.models[schemaName])
throw new GrpcError(status.NOT_FOUND, 'Requested schema not found');
Expand Down Expand Up @@ -806,6 +844,9 @@ export class MongooseAdapter extends DatabaseAdapter<MongooseSchema> {
if (indexes && !isInstanceSync) {
await this.createIndexes(schema.name, indexes, schema.ownerModule);
}
if (!isInstanceSync) {
await this.createMongooseFieldIndexes(schema.name);
}
return this.models[schema.name];
}

Expand Down