Skip to content

Commit 77a9920

Browse files
author
Alexander Mays
committed
Merged in the changes to DatabaseProvider and FilesProvider. Updated implementation of the said providers and added a ParseApp class. Needs to be documented.
Signed-off-by: Alexander Mays <maysale01@gmail.com>
1 parent e47331b commit 77a9920

12 files changed

+206
-65
lines changed

classes/BaseProvider.js

+10
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,18 @@ function resolveAdapter(adapter, options) {
5555
return adapter;
5656
}
5757

58+
function setup (config) {
59+
config = config || {};
60+
config.adapter = config.adapter || DefaultFilesAdapter;
61+
62+
var adapter = this.resolveAdapter(config.adapter, config.options);
63+
this.setAdapter(adapter);
64+
}
65+
66+
5867
BaseProvider.prototype.getAdapter = getAdapter;
5968
BaseProvider.prototype.setAdapter = setAdapter;
6069
BaseProvider.prototype.resolveAdapter = resolveAdapter;
70+
BaseProvider.prototype.setup = setup;
6171

6272
exports = module.exports = BaseProvider;

classes/DatabaseProvider.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
var BaseProvider = require('./BaseProvider');
2+
var CacheProvider = require('./CacheProvider');
3+
var util = require('util');
4+
5+
var DefaultDatabaseAdapter = require('../ExportAdapter');
6+
var defaultURI = "mongodb://localhost:27017/parse";
7+
8+
function DatabaseProvider(adapter) {
9+
DatabaseProvider.super_.call(this)
10+
};
11+
12+
function setup(config) {
13+
config = config || {};
14+
config.adapter = config.adapter || DefaultDatabaseAdapter;
15+
this.dbConnections = config.dbConnections || this.dbConnections || {};
16+
this.databaseURI = config.defaultURI || defaultURI;
17+
this.appDatabaseURIs = config.appDatabaseURIs || {};
18+
19+
var adapter = this.resolveAdapter(config.adapter, config.options);
20+
this.setAdapter(adapter);
21+
}
22+
23+
// TODO: Reimplement this whenever @Flovilmart finishes running CloudCode in subprocesses
24+
function registerAppDatabaseURI(appId, uri) {
25+
this.appDatabaseURIs[appId] = uri;
26+
}
27+
28+
function getDatabaseConnections() {
29+
return this.dbConnections;
30+
}
31+
32+
function getDatabaseConnection(appId) {
33+
if (this.dbConnections[appId]) {
34+
return this.dbConnections[appId];
35+
}
36+
37+
var cache = CacheProvider.getAdapter();
38+
var app = cache.get(appId);
39+
40+
if (!app) {
41+
throw new Error('Application ID provided is not a registered application.');
42+
}
43+
44+
var adapterFn = this.getAdapter();
45+
var dbURI = this.appDatabaseURIs[appId] || this.databaseURI;
46+
var options = { collectionPrefix: app.collectionPrefix };
47+
48+
this.dbConnections[appId] = new adapterFn(dbURI, options);
49+
this.dbConnections[appId].connect();
50+
return this.dbConnections[appId];
51+
}
52+
53+
// Overriding resolveAdapter to return the class, rather than an instance
54+
function resolveAdapter(adapter, options) {
55+
// Support passing in adapter paths
56+
if (typeof adapter === 'string') {
57+
adapter = require(adapter);
58+
}
59+
60+
return adapter;
61+
}
62+
63+
util.inherits(DatabaseProvider, BaseProvider);
64+
65+
DatabaseProvider.prototype.setup = setup;
66+
DatabaseProvider.prototype.registerAppDatabaseURI = registerAppDatabaseURI;
67+
DatabaseProvider.prototype.getDatabaseConnections = getDatabaseConnections;
68+
DatabaseProvider.prototype.getDatabaseConnection = getDatabaseConnection;
69+
DatabaseProvider.prototype.resolveAdapter = resolveAdapter;
70+
DatabaseProvider.prototype.DatabaseProvider = DatabaseProvider;
71+
72+
exports = module.exports = new DatabaseProvider();

classes/FilesProvider.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var BaseProvider = require('./BaseProvider');
2+
var util = require('util');
3+
4+
var DefaultFilesAdapter = require('../GridStoreAdapter');
5+
6+
function FilesProvider(adapter) {
7+
FilesProvider.super_.call(this)
8+
};
9+
10+
function setup (config) {
11+
config = config || {};
12+
config.adapter = config.adapter || DefaultFilesAdapter;
13+
14+
var adapter = this.resolveAdapter(config.adapter, config.options);
15+
this.setAdapter(adapter);
16+
}
17+
18+
util.inherits(FilesProvider, BaseProvider);
19+
20+
FilesProvider.prototype.setup = setup;
21+
FilesProvider.prototype.FilesProvider = FilesProvider;
22+
23+
exports = module.exports = new FilesProvider();

classes/ParseApp.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
var DatabaseProvider = require('./DatabaseProvider');
2+
3+
function ParseApp(args) {
4+
if (!args.appId || !args.masterKey) {
5+
throw 'You must provide an appId and masterKey!';
6+
}
7+
8+
this.appId = args.appId;
9+
this.masterKey = args.masterKey;
10+
this.collectionPrefix = args.collectionPrefix || '';
11+
this.clientKey = args.clientKey || '';
12+
this.javascriptKey = args.javascriptKey || '';
13+
this.dotNetKey = args.dotNetKey || '';
14+
this.restAPIKey = args.restAPIKey || '';
15+
this.fileKey = args.fileKey || 'invalid-file-key';
16+
this.facebookAppIds = args.facebookAppIds || [];
17+
this.databaseURI = args.databaseURI;
18+
19+
// To maintain compatibility. TODO: Remove in v2.1
20+
if (process.env.FACEBOOK_APP_ID) {
21+
this['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
22+
}
23+
24+
// Register with the database provider if we have an app specific database URI
25+
if (this.databaseURI) {
26+
DatabaseProvider.registerAppDatabaseURI(this.appId, this.databaseURI);
27+
}
28+
}
29+
30+
exports = module.exports = ParseApp;

interfaces/ServiceProvider.js

+4
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,8 @@ ServiceProvider.prototype.resolveAdapter = function() {
3333
throw new Error('A service provider must implement resolveAdapter!');
3434
}
3535

36+
ServiceProvider.prototype.setup = function() {
37+
throw new Error('A service provider must implement setup!');
38+
}
39+
3640
exports = module.exports = ServiceProvider;

spec/ParseAPI.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// A bunch of different tests are in here - it isn't very thematic.
22
// It would probably be better to refactor them into different files.
33

4-
var DatabaseAdapter = require('../src/DatabaseAdapter');
4+
var DatabaseProvider = require('../classes/DatabaseProvider');
55
var request = require('request');
66

77
describe('miscellaneous', function() {
@@ -358,7 +358,7 @@ describe('miscellaneous', function() {
358358
obj.set('foo', 'bar');
359359
return obj.save();
360360
}).then(() => {
361-
var db = DatabaseAdapter.getDatabaseConnection(appId);
361+
var db = DatabaseProvider.getDatabaseConnection(appId);
362362
return db.mongoFind('TestObject', {}, {});
363363
}).then((results) => {
364364
expect(results.length).toEqual(1);

spec/ParseInstallation.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
var auth = require('../Auth');
55
var Config = require('../Config');
6-
var DatabaseAdapter = require('../DatabaseAdapter');
6+
var DatabaseProvider = require('../classes/DatabaseProvider');
77
var Parse = require('parse/node').Parse;
88
var rest = require('../src/rest');
99

1010
var config = new Config('test');
11-
var database = DatabaseAdapter.getDatabaseConnection('test');
11+
var database = DatabaseProvider.getDatabaseConnection('test');
1212

1313
describe('Installations', () => {
1414

spec/RestCreate.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// These tests check the "create" functionality of the REST API.
22
var auth = require('../Auth');
33
var Config = require('../Config');
4-
var DatabaseAdapter = require('../DatabaseAdapter');
4+
var DatabaseProvider = require('../classes/DatabaseProvider');
55
var Parse = require('parse/node').Parse;
66
var rest = require('../src/rest');
77
var request = require('request');
88

99
var config = new Config('test');
10-
var database = DatabaseAdapter.getDatabaseConnection('test');
10+
var database = DatabaseProvider.getDatabaseConnection('test');
1111

1212
describe('rest create', () => {
1313
it('handles _id', (done) => {

spec/helper.js

+29-15
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,40 @@
22

33
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000;
44

5-
var DatabaseAdapter = require('../DatabaseAdapter');
5+
var DatabaseProvider = require('../classes/DatabaseProvider');
66
var express = require('express');
77
var facebook = require('../src/facebook');
88
var ParseServer = require('../src/index').ParseServer;
99

1010
var databaseURI = process.env.DATABASE_URI;
1111
var cloudMain = process.env.CLOUD_CODE_MAIN || './cloud/main.js';
1212

13+
var config = {
14+
database: {
15+
databaseURI: databaseURI,
16+
/** adapter: "../ExportAdapter" */
17+
},
18+
cache: {
19+
},
20+
files: {
21+
},
22+
cloud: {
23+
entry: cloudMain
24+
},
25+
app: {
26+
appId: 'test',
27+
javascriptKey: 'test',
28+
dotNetKey: 'windows',
29+
clientKey: 'client',
30+
restAPIKey: 'rest',
31+
masterKey: 'test',
32+
collectionPrefix: 'test_',
33+
fileKey: 'test'
34+
}
35+
};
36+
1337
// Set up an API server for testing
14-
var api = new ParseServer({
15-
databaseURI: databaseURI,
16-
cloud: cloudMain,
17-
appId: 'test',
18-
javascriptKey: 'test',
19-
dotNetKey: 'windows',
20-
clientKey: 'client',
21-
restAPIKey: 'rest',
22-
masterKey: 'test',
23-
collectionPrefix: 'test_',
24-
fileKey: 'test'
25-
});
38+
var api = new ParseServer(config);
2639

2740
var app = express();
2841
app.use('/1', api);
@@ -190,8 +203,9 @@ function mockFacebook() {
190203

191204
function clearData() {
192205
var promises = [];
193-
for (var conn in DatabaseAdapter.dbConnections) {
194-
promises.push(DatabaseAdapter.dbConnections[conn].deleteEverything());
206+
var connections = DatabaseProvider.getDatabaseConnections();
207+
for (var conn in connections) {
208+
promises.push(connections[conn].deleteEverything());
195209
}
196210
return Promise.all(promises);
197211
}

src/Config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// mount is the URL for the root of the API; includes http, domain, etc.
44
function Config(applicationId, mount) {
55
var cache = require('./classes/CacheProvider').getAdapter();
6-
var DatabaseAdapter = require('./DatabaseAdapter');
6+
var DatabaseProvider = require('./classes/DatabaseProvider');
77

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

1414
this.applicationId = applicationId;
1515
this.collectionPrefix = cacheInfo.collectionPrefix || '';
16-
this.database = DatabaseAdapter.getDatabaseConnection(applicationId);
16+
this.database = DatabaseProvider.getDatabaseConnection(applicationId);
1717
this.masterKey = cacheInfo.masterKey;
1818
this.clientKey = cacheInfo.clientKey;
1919
this.javascriptKey = cacheInfo.javascriptKey;

src/files.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33
var bodyParser = require('body-parser'),
44
Config = require('./Config'),
55
express = require('express'),
6-
FilesAdapter = require('./FilesAdapter'),
76
middlewares = require('./middlewares.js'),
87
mime = require('mime'),
98
Parse = require('parse/node').Parse,
109
rack = require('hat').rack();
1110

11+
var FilesProvider = require('./classes/FilesProvider');
1212
var router = express.Router();
1313

1414
var processCreate = function(req, res, next) {
15+
var FilesAdapter = FilesProvider.getAdapter();
16+
17+
if (!FilesAdapter) {
18+
throw new Error('Unable to get an instance of the FilesAdapter');
19+
}
20+
1521
if (!req.body || !req.body.length) {
1622
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
1723
'Invalid file upload.'));
@@ -40,10 +46,10 @@ var processCreate = function(req, res, next) {
4046
}
4147

4248
var filename = rack() + '_' + req.params.filename + extension;
43-
FilesAdapter.getAdapter().create(req.config, filename, req.body)
49+
FilesAdapter.create(req.config, filename, req.body)
4450
.then(() => {
4551
res.status(201);
46-
var location = FilesAdapter.getAdapter().location(req.config, req, filename);
52+
var location = FilesAdapter.location(req.config, req, filename);
4753
res.set('Location', location);
4854
res.json({ url: location, name: filename });
4955
}).catch((error) => {
@@ -53,8 +59,10 @@ var processCreate = function(req, res, next) {
5359
};
5460

5561
var processGet = function(req, res) {
62+
var FilesAdapter = FilesProvider.getAdapter();
5663
var config = new Config(req.params.appId);
57-
FilesAdapter.getAdapter().get(config, req.params.filename)
64+
65+
FilesAdapter.get(config, req.params.filename)
5866
.then((data) => {
5967
res.status(200);
6068
var contentType = mime.lookup(req.params.filename);

0 commit comments

Comments
 (0)