feat: Add option keepUnknownIndexes to retain indexes which are not specified in schema (#9857)

This commit is contained in:
Rahul Lanjewar
2025-10-03 18:05:34 +05:30
committed by GitHub
parent b7faabb569
commit 89fad468c3
6 changed files with 64 additions and 2 deletions

View File

@@ -371,7 +371,7 @@ describe('DefinedSchemas', () => {
expect(schema.indexes).toEqual(indexes);
});
it('should delete removed indexes', async () => {
it('should delete unknown indexes when keepUnknownIndexes is not set', async () => {
const server = await reconfigureServer();
let indexes = { complex: { createdAt: 1, updatedAt: 1 } };
@@ -393,6 +393,53 @@ describe('DefinedSchemas', () => {
cleanUpIndexes(schema);
expect(schema.indexes).toBeUndefined();
});
it('should delete unknown indexes when keepUnknownIndexes is set to false', async () => {
const server = await reconfigureServer();
let indexes = { complex: { createdAt: 1, updatedAt: 1 } };
let schemas = { definitions: [{ className: 'Test', indexes }], keepUnknownIndexes: false };
await new DefinedSchemas(schemas, server.config).execute();
indexes = {};
schemas = { definitions: [{ className: 'Test', indexes }], keepUnknownIndexes: false };
// Change indexes
await new DefinedSchemas(schemas, server.config).execute();
let schema = await new Parse.Schema('Test').get();
cleanUpIndexes(schema);
expect(schema.indexes).toBeUndefined();
// Update
await new DefinedSchemas(schemas, server.config).execute();
schema = await new Parse.Schema('Test').get();
cleanUpIndexes(schema);
expect(schema.indexes).toBeUndefined();
});
it('should not delete unknown indexes when keepUnknownIndexes is set to true', async () => {
const server = await reconfigureServer();
const indexes = { complex: { createdAt: 1, updatedAt: 1 } };
let schemas = { definitions: [{ className: 'Test', indexes }], keepUnknownIndexes: true };
await new DefinedSchemas(schemas, server.config).execute();
schemas = { definitions: [{ className: 'Test', indexes: {} }], keepUnknownIndexes: true };
// Change indexes
await new DefinedSchemas(schemas, server.config).execute();
let schema = await new Parse.Schema('Test').get();
cleanUpIndexes(schema);
expect(schema.indexes).toEqual({ complex: { createdAt: 1, updatedAt: 1 } });
// Update
await new DefinedSchemas(schemas, server.config).execute();
schema = await new Parse.Schema('Test').get();
cleanUpIndexes(schema);
expect(schema.indexes).toEqual(indexes);
});
xit('should keep protected indexes', async () => {
const server = await reconfigureServer();

View File

@@ -28,6 +28,13 @@ module.exports.SchemaOptions = {
action: parsers.booleanParser,
default: false,
},
keepUnknownIndexes: {
env: 'PARSE_SERVER_SCHEMA_KEEP_UNKNOWN_INDEXES',
help:
"(Optional) Keep indexes that are present in the database but not defined in the schema. Set this to `true` if you are adding indexes manually, so that they won't be removed when running schema migration. Default is `false`.",
action: parsers.booleanParser,
default: false,
},
lockSchemas: {
env: 'PARSE_SERVER_SCHEMA_LOCK_SCHEMAS',
help:

View File

@@ -4,6 +4,7 @@
* @property {Function} beforeMigration Execute a callback before running schema migrations.
* @property {Any} definitions Rest representation on Parse.Schema https://docs.parseplatform.org/rest/guide/#adding-a-schema
* @property {Boolean} deleteExtraFields Is true if Parse Server should delete any fields not defined in a schema definition. This should only be used during development.
* @property {Boolean} keepUnknownIndexes (Optional) Keep indexes that are present in the database but not defined in the schema. Set this to `true` if you are adding indexes manually, so that they won't be removed when running schema migration. Default is `false`.
* @property {Boolean} lockSchemas Is true if Parse Server will reject any attempts to modify the schema while the server is running.
* @property {Boolean} recreateModifiedFields Is true if Parse Server should recreate any fields that are different between the current database schema and theschema definition. This should only be used during development.
* @property {Boolean} strict Is true if Parse Server should exit if schema update fail.

View File

@@ -25,6 +25,9 @@ export interface SchemaOptions {
/* Is true if Parse Server will reject any attempts to modify the schema while the server is running.
:DEFAULT: false */
lockSchemas: ?boolean;
/* (Optional) Keep indexes that are present in the database but not defined in the schema. Set this to `true` if you are adding indexes manually, so that they won't be removed when running schema migration. Default is `false`.
:DEFAULT: false */
keepUnknownIndexes: ?boolean;
/* Execute a callback before running schema migrations. */
beforeMigration: ?() => void | Promise<void>;
/* Execute a callback after running schema migrations. */

View File

@@ -349,7 +349,10 @@ export class DefinedSchemas {
Object.keys(cloudSchema.indexes).forEach(indexName => {
if (!this.isProtectedIndex(localSchema.className, indexName)) {
if (!localSchema.indexes || !localSchema.indexes[indexName]) {
newLocalSchema.deleteIndex(indexName);
// If keepUnknownIndex is falsy, then delete all unknown indexes from the db.
if(!this.schemaOptions.keepUnknownIndexes){
newLocalSchema.deleteIndex(indexName);
}
} else if (
!this.paramsAreEquals(localSchema.indexes[indexName], cloudSchema.indexes[indexName])
) {

View File

@@ -6,6 +6,7 @@ export interface SchemaOptions {
deleteExtraFields: ?boolean;
recreateModifiedFields: ?boolean;
lockSchemas: ?boolean;
keepUnknownIndexes: ?boolean;
beforeMigration: ?() => void | Promise<void>;
afterMigration: ?() => void | Promise<void>;
}