From 2730398b92fa928cfca2f5d97440cf862b03dd09 Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Wed, 9 Mar 2016 15:20:59 -0800 Subject: [PATCH] Add new MongoSchemaCollection class that manages schemas for all collections. --- .../Storage/Mongo/MongoSchemaCollection.js | 58 +++++++++++++++++++ .../Storage/Mongo/MongoStorageAdapter.js | 9 +++ src/Controllers/DatabaseController.js | 4 ++ 3 files changed, 71 insertions(+) create mode 100644 src/Adapters/Storage/Mongo/MongoSchemaCollection.js diff --git a/src/Adapters/Storage/Mongo/MongoSchemaCollection.js b/src/Adapters/Storage/Mongo/MongoSchemaCollection.js new file mode 100644 index 00000000..992068b5 --- /dev/null +++ b/src/Adapters/Storage/Mongo/MongoSchemaCollection.js @@ -0,0 +1,58 @@ + +import MongoCollection from './MongoCollection'; + +function _mongoSchemaQueryFromNameQuery(name: string, query) { + return _mongoSchemaObjectFromNameFields(name, query); +} + +function _mongoSchemaObjectFromNameFields(name: string, fields) { + let object = { _id: name }; + if (fields) { + Object.keys(fields).forEach(key => { + object[key] = fields[key]; + }); + } + return object; +} + +export default class MongoSchemaCollection { + _collection: MongoCollection; + + constructor(collection: MongoCollection) { + this._collection = collection; + } + + getAllSchemas() { + return this._collection._rawFind({}); + } + + findSchema(name: string) { + return this._collection._rawFind(_mongoSchemaQueryFromNameQuery(name), { limit: 1 }).then(results => { + return results[0]; + }); + } + + // Atomically find and delete an object based on query. + // The result is the promise with an object that was in the database before deleting. + // Postgres Note: Translates directly to `DELETE * FROM ... RETURNING *`, which will return data after delete is done. + findAndDeleteSchema(name: string) { + // arguments: query, sort + return this._collection._mongoCollection.findAndRemove(_mongoSchemaQueryFromNameQuery(name), []).then(document => { + // Value is the object where mongo returns multiple fields. + return document.value; + }); + } + + addSchema(name: string, fields) { + let mongoObject = _mongoSchemaObjectFromNameFields(name, fields); + return this._collection.insertOne(mongoObject); + } + + updateSchema(name: string, update) { + return this._collection.updateOne(_mongoSchemaQueryFromNameQuery(name), update); + } + + upsertSchema(name: string, query: string, update) { + return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update); + } +} diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 201388b2..e3d59493 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -1,9 +1,12 @@ import MongoCollection from './MongoCollection'; +import MongoSchemaCollection from './MongoSchemaCollection'; let mongodb = require('mongodb'); let MongoClient = mongodb.MongoClient; +const MongoSchemaCollectionName = '_SCHEMA'; + export class MongoStorageAdapter { // Private _uri: string; @@ -38,6 +41,12 @@ export class MongoStorageAdapter { .then(rawCollection => new MongoCollection(rawCollection)); } + schemaCollection(collectionPrefix: string) { + return this.connect() + .then(() => this.adaptiveCollection(collectionPrefix + MongoSchemaCollectionName)) + .then(collection => new MongoSchemaCollection(collection)); + } + collectionExists(name: string) { return this.connect().then(() => { return this.database.listCollections({ name: name }).toArray(); diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 80eea63b..8d4fc4ff 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -33,6 +33,10 @@ DatabaseController.prototype.adaptiveCollection = function(className) { return this.adapter.adaptiveCollection(this.collectionPrefix + className); }; +DatabaseController.prototype.schemaCollection = function() { + return this.adapter.schemaCollection(this.collectionPrefix); +}; + DatabaseController.prototype.collectionExists = function(className) { return this.adapter.collectionExists(this.collectionPrefix + className); };