Files
kami-parse-server/src/Routers/SchemasRouter.js

145 lines
5.0 KiB
JavaScript
Raw Normal View History

2016-02-02 17:38:47 -08:00
// schemas.js
var express = require('express'),
Parse = require('parse/node').Parse,
Schema = require('../Schema');
2016-02-02 17:38:47 -08:00
import PromiseRouter from '../PromiseRouter';
import * as middleware from "../middlewares";
2016-02-09 11:26:46 -08:00
function classNameMismatchResponse(bodyClass, pathClass) {
throw new Parse.Error(
Parse.Error.INVALID_CLASS_NAME,
`Class name mismatch between ${bodyClass} and ${pathClass}.`
);
2016-02-09 11:26:46 -08:00
}
2016-02-02 17:38:47 -08:00
function getAllSchemas(req) {
return req.config.database.schemaCollection()
.then(collection => collection.getAllSchemas())
.then(schemas => schemas.map(Schema.mongoSchemaToSchemaAPIResponse))
.then(schemas => ({ response: { results: schemas } }));
2016-02-02 17:38:47 -08:00
}
2016-02-03 16:10:00 -08:00
function getOneSchema(req) {
const className = req.params.className;
return req.config.database.schemaCollection()
.then(collection => collection.findSchema(className))
.then(mongoSchema => {
if (!mongoSchema) {
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`);
}
return { response: Schema.mongoSchemaToSchemaAPIResponse(mongoSchema) };
});
2016-02-03 16:10:00 -08:00
}
2016-02-05 14:56:11 -08:00
function createSchema(req) {
if (req.params.className && req.body.className) {
if (req.params.className != req.body.className) {
2016-02-09 11:26:46 -08:00
return classNameMismatchResponse(req.body.className, req.params.className);
2016-02-05 14:56:11 -08:00
}
}
const className = req.params.className || req.body.className;
2016-02-05 14:56:11 -08:00
if (!className) {
throw new Parse.Error(135, `POST ${req.path} needs a class name.`);
2016-02-05 14:56:11 -08:00
}
2016-02-05 18:36:23 -08:00
return req.config.database.loadSchema()
.then(schema => schema.addClassIfNotExists(className, req.body.fields, req.body.classLevelPermissions))
.then(result => ({ response: Schema.mongoSchemaToSchemaAPIResponse(result) }));
2016-02-05 14:56:11 -08:00
}
2016-02-09 11:26:46 -08:00
function modifySchema(req) {
if (req.body.className && req.body.className != req.params.className) {
return classNameMismatchResponse(req.body.className, req.params.className);
2016-02-09 11:26:46 -08:00
}
var submittedFields = req.body.fields || {};
var className = req.params.className;
2016-02-09 11:26:46 -08:00
return req.config.database.loadSchema()
.then(schema => {
return schema.updateClass(className, submittedFields, req.body.classLevelPermissions, req.config.database);
}).then((result) => {
return Promise.resolve({response: result});
});
2016-02-09 11:26:46 -08:00
}
2016-03-07 14:49:09 -05:00
function getSchemaPermissions(req) {
var className = req.params.className;
return req.config.database.loadSchema()
.then(schema => {
return Promise.resolve({response: schema.perms[className]});
});
}
2016-02-17 19:00:17 -08:00
// A helper function that removes all join tables for a schema. Returns a promise.
var removeJoinTables = (database, mongoSchema) => {
2016-02-17 19:00:17 -08:00
return Promise.all(Object.keys(mongoSchema)
.filter(field => mongoSchema[field].startsWith('relation<'))
.map(field => {
let collectionName = `_Join:${field}:${mongoSchema._id}`;
return database.dropCollection(collectionName);
2016-02-17 19:00:17 -08:00
})
);
};
function deleteSchema(req) {
if (!Schema.classNameIsValid(req.params.className)) {
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, Schema.invalidClassNameMessage(req.params.className));
2016-02-17 19:00:17 -08:00
}
return req.config.database.collectionExists(req.params.className)
.then(exist => {
if (!exist) {
return Promise.resolve();
}
return req.config.database.adaptiveCollection(req.params.className)
.then(collection => {
return collection.count()
.then(count => {
if (count > 0) {
throw new Parse.Error(255, `Class ${req.params.className} is not empty, contains ${count} objects, cannot drop schema.`);
}
return collection.drop();
})
})
})
.then(() => {
// We've dropped the collection now, so delete the item from _SCHEMA
// and clear the _Join collections
return req.config.database.schemaCollection()
.then(coll => coll.findAndDeleteSchema(req.params.className))
.then(document => {
if (document === null) {
//tried to delete non-existent class
return Promise.resolve();
}
return removeJoinTables(req.config.database, document);
});
})
.then(() => {
// Success
return { response: {} };
}, error => {
if (error.message == 'ns not found') {
// If they try to delete a non-existent class, that's fine, just let them.
return { response: {} };
2016-02-17 19:00:17 -08:00
}
return Promise.reject(error);
2016-02-17 19:00:17 -08:00
});
}
2016-02-19 23:47:44 -05:00
export class SchemasRouter extends PromiseRouter {
mountRoutes() {
this.route('GET', '/schemas', middleware.promiseEnforceMasterKeyAccess, getAllSchemas);
this.route('GET', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, getOneSchema);
this.route('POST', '/schemas', middleware.promiseEnforceMasterKeyAccess, createSchema);
this.route('POST', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, createSchema);
this.route('PUT', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, modifySchema);
this.route('DELETE', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, deleteSchema);
2016-02-19 23:47:44 -05:00
}
}