feat: add user-defined schema and migrations (#7418)

This commit is contained in:
Samuel Denis-D'Ortun
2021-11-01 09:28:49 -04:00
committed by GitHub
parent 653d25731f
commit 25d5c30be2
16 changed files with 1365 additions and 36 deletions

View File

@@ -212,7 +212,7 @@ class MongoSchemaCollection {
.then(
schema => {
// If a field with this name already exists, it will be handled elsewhere.
if (schema.fields[fieldName] != undefined) {
if (schema.fields[fieldName] !== undefined) {
return;
}
// The schema exists. Check for existing GeoPoints.
@@ -274,6 +274,22 @@ class MongoSchemaCollection {
}
});
}
async updateFieldOptions(className: string, fieldName: string, fieldType: any) {
const { ...fieldOptions } = fieldType;
delete fieldOptions.type;
delete fieldOptions.targetClass;
await this.upsertSchema(
className,
{ [fieldName]: { $exists: true } },
{
$set: {
[`_metadata.fields_options.${fieldName}`]: fieldOptions,
},
}
);
}
}
// Exported for testing reasons and because we haven't moved all mongo schema format

View File

@@ -362,6 +362,11 @@ export class MongoStorageAdapter implements StorageAdapter {
.catch(err => this.handleError(err));
}
async updateFieldOptions(className: string, fieldName: string, type: any) {
const schemaCollection = await this._schemaCollection();
await schemaCollection.updateFieldOptions(className, fieldName, type);
}
addFieldIfNotExists(className: string, fieldName: string, type: any): Promise<void> {
return this._schemaCollection()
.then(schemaCollection => schemaCollection.addFieldIfNotExists(className, fieldName, type))

View File

@@ -20,7 +20,7 @@ export function createClient(uri, databaseOptions) {
if (process.env.PARSE_SERVER_LOG_LEVEL === 'debug') {
const monitor = require('pg-monitor');
if(monitor.isAttached()) {
if (monitor.isAttached()) {
monitor.detach();
}
monitor.attach(initOptions);

View File

@@ -1119,6 +1119,16 @@ export class PostgresStorageAdapter implements StorageAdapter {
this._notifySchemaChange();
}
async updateFieldOptions(className: string, fieldName: string, type: any) {
await this._client.tx('update-schema-field-options', async t => {
const path = `{fields,${fieldName}}`;
await t.none(
'UPDATE "_SCHEMA" SET "schema"=jsonb_set("schema", $<path>, $<type>) WHERE "className"=$<className>',
{ path, type, className }
);
});
}
// Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.)
// and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible.
async deleteClass(className: string) {

View File

@@ -35,6 +35,7 @@ export interface StorageAdapter {
setClassLevelPermissions(className: string, clps: any): Promise<void>;
createClass(className: string, schema: SchemaType): Promise<void>;
addFieldIfNotExists(className: string, fieldName: string, type: any): Promise<void>;
updateFieldOptions(className: string, fieldName: string, type: any): Promise<void>;
deleteClass(className: string): Promise<void>;
deleteAllClasses(fast: boolean): Promise<void>;
deleteFields(className: string, schema: SchemaType, fieldNames: Array<string>): Promise<void>;