Skip to content

Commit

Permalink
Merged in the changes to DatabaseProvider and FilesProvider. Updated …
Browse files Browse the repository at this point in the history
…implementation of the said providers and added a ParseApp class. Needs to be documented.

Signed-off-by: Alexander Mays <maysale01@gmail.com>
  • Loading branch information
Alexander Mays committed Feb 9, 2016
1 parent df63ba1 commit ffeeb4f
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 121 deletions.
4 changes: 2 additions & 2 deletions Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// mount is the URL for the root of the API; includes http, domain, etc.
function Config(applicationId, mount) {
var cache = require('./classes/CacheProvider').getAdapter();
var DatabaseAdapter = require('./DatabaseAdapter');
var DatabaseProvider = require('./classes/DatabaseProvider');

var cacheInfo = cache.get(applicationId);
this.valid = !!cacheInfo;
Expand All @@ -13,7 +13,7 @@ function Config(applicationId, mount) {

this.applicationId = applicationId;
this.collectionPrefix = cacheInfo.collectionPrefix || '';
this.database = DatabaseAdapter.getDatabaseConnection(applicationId);
this.database = DatabaseProvider.getDatabaseConnection(applicationId);
this.masterKey = cacheInfo.masterKey;
this.clientKey = cacheInfo.clientKey;
this.javascriptKey = cacheInfo.javascriptKey;
Expand Down
56 changes: 0 additions & 56 deletions DatabaseAdapter.js

This file was deleted.

10 changes: 10 additions & 0 deletions classes/BaseProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,18 @@ function resolveAdapter(adapter, options) {
return adapter;
}

function setup (config) {
config = config || {};
config.adapter = config.adapter || DefaultFilesAdapter;

var adapter = this.resolveAdapter(config.adapter, config.options);
this.setAdapter(adapter);
}


BaseProvider.prototype.getAdapter = getAdapter;
BaseProvider.prototype.setAdapter = setAdapter;
BaseProvider.prototype.resolveAdapter = resolveAdapter;
BaseProvider.prototype.setup = setup;

exports = module.exports = BaseProvider;
72 changes: 72 additions & 0 deletions classes/DatabaseProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
var BaseProvider = require('./BaseProvider');
var CacheProvider = require('./CacheProvider');
var util = require('util');

var DefaultDatabaseAdapter = require('../ExportAdapter');
var defaultURI = "mongodb://localhost:27017/parse";

function DatabaseProvider(adapter) {
DatabaseProvider.super_.call(this)
};

function setup(config) {
config = config || {};
config.adapter = config.adapter || DefaultDatabaseAdapter;
this.dbConnections = config.dbConnections || this.dbConnections || {};
this.databaseURI = config.defaultURI || defaultURI;
this.appDatabaseURIs = config.appDatabaseURIs || {};

var adapter = this.resolveAdapter(config.adapter, config.options);
this.setAdapter(adapter);
}

// TODO: Reimplement this whenever @Flovilmart finishes running CloudCode in subprocesses
function registerAppDatabaseURI(appId, uri) {
this.appDatabaseURIs[appId] = uri;
}

function getDatabaseConnections() {
return this.dbConnections;
}

function getDatabaseConnection(appId) {
if (this.dbConnections[appId]) {
return this.dbConnections[appId];
}

var cache = CacheProvider.getAdapter();
var app = cache.get(appId);

if (!app) {
throw new Error('Application ID provided is not a registered application.');
}

var adapterFn = this.getAdapter();
var dbURI = this.appDatabaseURIs[appId] || this.databaseURI;
var options = { collectionPrefix: app.collectionPrefix };

this.dbConnections[appId] = new adapterFn(dbURI, options);
this.dbConnections[appId].connect();
return this.dbConnections[appId];
}

// Overriding resolveAdapter to return the class, rather than an instance
function resolveAdapter(adapter, options) {
// Support passing in adapter paths
if (typeof adapter === 'string') {
adapter = require(adapter);
}

return adapter;
}

util.inherits(DatabaseProvider, BaseProvider);

DatabaseProvider.prototype.setup = setup;
DatabaseProvider.prototype.registerAppDatabaseURI = registerAppDatabaseURI;
DatabaseProvider.prototype.getDatabaseConnections = getDatabaseConnections;
DatabaseProvider.prototype.getDatabaseConnection = getDatabaseConnection;
DatabaseProvider.prototype.resolveAdapter = resolveAdapter;
DatabaseProvider.prototype.DatabaseProvider = DatabaseProvider;

exports = module.exports = new DatabaseProvider();
23 changes: 23 additions & 0 deletions classes/FilesProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var BaseProvider = require('./BaseProvider');
var util = require('util');

var DefaultFilesAdapter = require('../GridStoreAdapter');

function FilesProvider(adapter) {
FilesProvider.super_.call(this)
};

function setup (config) {
config = config || {};
config.adapter = config.adapter || DefaultFilesAdapter;

var adapter = this.resolveAdapter(config.adapter, config.options);
this.setAdapter(adapter);
}

util.inherits(FilesProvider, BaseProvider);

FilesProvider.prototype.setup = setup;
FilesProvider.prototype.FilesProvider = FilesProvider;

exports = module.exports = new FilesProvider();
30 changes: 30 additions & 0 deletions classes/ParseApp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var DatabaseProvider = require('./DatabaseProvider');

function ParseApp(args) {
if (!args.appId || !args.masterKey) {
throw 'You must provide an appId and masterKey!';
}

this.appId = args.appId;
this.masterKey = args.masterKey;
this.collectionPrefix = args.collectionPrefix || '';
this.clientKey = args.clientKey || '';
this.javascriptKey = args.javascriptKey || '';
this.dotNetKey = args.dotNetKey || '';
this.restAPIKey = args.restAPIKey || '';
this.fileKey = args.fileKey || 'invalid-file-key';
this.facebookAppIds = args.facebookAppIds || [];
this.databaseURI = args.databaseURI;

// To maintain compatibility. TODO: Remove in v2.1
if (process.env.FACEBOOK_APP_ID) {
this['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
}

// Register with the database provider if we have an app specific database URI
if (this.databaseURI) {
DatabaseProvider.registerAppDatabaseURI(this.appId, this.databaseURI);
}
}

exports = module.exports = ParseApp;
16 changes: 12 additions & 4 deletions files.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
var bodyParser = require('body-parser'),
Config = require('./Config'),
express = require('express'),
FilesAdapter = require('./FilesAdapter'),
middlewares = require('./middlewares.js'),
mime = require('mime'),
Parse = require('parse/node').Parse,
rack = require('hat').rack();

var FilesProvider = require('./classes/FilesProvider');
var router = express.Router();

var processCreate = function(req, res, next) {
var FilesAdapter = FilesProvider.getAdapter();

if (!FilesAdapter) {
throw new Error('Unable to get an instance of the FilesAdapter');
}

if (!req.body || !req.body.length) {
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
'Invalid file upload.'));
Expand Down Expand Up @@ -40,10 +46,10 @@ var processCreate = function(req, res, next) {
}

var filename = rack() + '_' + req.params.filename + extension;
FilesAdapter.getAdapter().create(req.config, filename, req.body)
FilesAdapter.create(req.config, filename, req.body)
.then(() => {
res.status(201);
var location = FilesAdapter.getAdapter().location(req.config, req, filename);
var location = FilesAdapter.location(req.config, req, filename);
res.set('Location', location);
res.json({ url: location, name: filename });
}).catch((error) => {
Expand All @@ -53,8 +59,10 @@ var processCreate = function(req, res, next) {
};

var processGet = function(req, res) {
var FilesAdapter = FilesProvider.getAdapter();
var config = new Config(req.params.appId);
FilesAdapter.getAdapter().get(config, req.params.filename)

FilesAdapter.get(config, req.params.filename)
.then((data) => {
res.status(200);
var contentType = mime.lookup(req.params.filename);
Expand Down
56 changes: 18 additions & 38 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

var batch = require('./batch'),
bodyParser = require('body-parser'),
CacheProvider = require('./classes/CacheProvider'),
DatabaseAdapter = require('./DatabaseAdapter'),
express = require('express'),
FilesAdapter = require('./FilesAdapter'),
S3Adapter = require('./S3Adapter'),
middlewares = require('./middlewares'),
multer = require('multer'),
Parse = require('parse/node').Parse,
PromiseRouter = require('./PromiseRouter'),
httpRequest = require('./httpRequest');

var ParseApp = require('./classes/ParseApp');
var CacheProvider = require('./classes/CacheProvider');
var FilesProvider = require('./classes/FilesProvider');
var DatabaseProvider = require('./classes/DatabaseProvider');

// Mutate the Parse object to add the Cloud Code handlers
addParseCloud();

Expand Down Expand Up @@ -40,53 +42,31 @@ addParseCloud();
// "javascriptKey": optional key from Parse dashboard

function ParseServer(args) {
if (!args.appId || !args.masterKey) {
throw 'You must provide an appId and masterKey!';
}

// Setup providers
CacheProvider.setup(args.cache);
FilesProvider.setup(args.files);
DatabaseProvider.setup(args.database);

// Instantiate the app
var app = new ParseApp(args.app);

if (args.databaseAdapter) {
DatabaseAdapter.setAdapter(args.databaseAdapter);
}
if (args.filesAdapter) {
FilesAdapter.setAdapter(args.filesAdapter);
}
if (args.databaseURI) {
DatabaseAdapter.setAppDatabaseURI(args.appId, args.databaseURI);
}
if (args.cloud) {
// Add the Parse.Cloud global function definitions
addParseCloud();
if (typeof args.cloud === 'function') {
args.cloud(Parse)
} else if (typeof args.cloud === 'string') {
require(args.cloud);

// Load the cloud code entry point
if (typeof args.cloud.entry === 'function') {
args.cloud.entry(Parse)
} else if (typeof args.cloud.entry === 'string') {
require(args.cloud.entry);
} else {
throw new Error("argument 'cloud' must either be a string or a function");
}

}

var appInfo = {
masterKey: args.masterKey,
collectionPrefix: args.collectionPrefix || '',
clientKey: args.clientKey || '',
javascriptKey: args.javascriptKey || '',
dotNetKey: args.dotNetKey || '',
restAPIKey: args.restAPIKey || '',
fileKey: args.fileKey || 'invalid-file-key',
facebookAppIds: args.facebookAppIds || []
};

// To maintain compatibility. TODO: Remove in v2.1
if (process.env.FACEBOOK_APP_ID) {
appInfo['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
}

// Cache the application information indefinitely
var cache = CacheProvider.getAdapter();
cache.put(args.appId, appInfo, Infinity);
cache.put(app.appId, app, Infinity);

// Initialize the node client SDK automatically
Parse.initialize(args.appId, args.javascriptKey || '', args.masterKey);
Expand Down
4 changes: 4 additions & 0 deletions interfaces/ServiceProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ ServiceProvider.prototype.resolveAdapter = function() {
throw new Error('A service provider must implement resolveAdapter!');
}

ServiceProvider.prototype.setup = function() {
throw new Error('A service provider must implement setup!');
}

exports = module.exports = ServiceProvider;
4 changes: 2 additions & 2 deletions spec/ParseAPI.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// A bunch of different tests are in here - it isn't very thematic.
// It would probably be better to refactor them into different files.

var DatabaseAdapter = require('../DatabaseAdapter');
var DatabaseProvider = require('../classes/DatabaseProvider');
var request = require('request');

describe('miscellaneous', function() {
Expand Down Expand Up @@ -358,7 +358,7 @@ describe('miscellaneous', function() {
obj.set('foo', 'bar');
return obj.save();
}).then(() => {
var db = DatabaseAdapter.getDatabaseConnection(appId);
var db = DatabaseProvider.getDatabaseConnection(appId);
return db.mongoFind('TestObject', {}, {});
}).then((results) => {
expect(results.length).toEqual(1);
Expand Down
Loading

0 comments on commit ffeeb4f

Please sign in to comment.