Skip to content

Commit dc0e8eb

Browse files
committed
Merge branch 'master' into patch-1
2 parents bb5cd08 + f08b0b3 commit dc0e8eb

File tree

9 files changed

+129
-33
lines changed

9 files changed

+129
-33
lines changed

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
11
## Parse Server Changelog
22

3+
### 2.1.5 (3/9/2016)
4+
5+
* New: FileAdapter for Google Cloud Storage [\#708](https://github.com/ParsePlatform/parse-server/pull/708) (mcdonamp)
6+
* Improvement: Minimize extra schema queries in some scenarios. [\#919](https://github.com/ParsePlatform/parse-server/pull/919) (Marco129)
7+
* Improvement: Move DatabaseController and Schema fully to adaptive mongo collection. [\#909](https://github.com/ParsePlatform/parse-server/pull/909) (nlutsenko)
8+
* Improvement: Cleanup PushController/PushRouter, remove raw mongo collection access. [\#903](https://github.com/ParsePlatform/parse-server/pull/903) (nlutsenko)
9+
* Improvement: Increment badge the right way [\#902](https://github.com/ParsePlatform/parse-server/pull/902) (flovilmart)
10+
* Improvement: Migrate ParseGlobalConfig to new database storage API. [\#901](https://github.com/ParsePlatform/parse-server/pull/901) (nlutsenko)
11+
* Improvement: Improve delete flow for non-existent \_Join collection [\#881](https://github.com/ParsePlatform/parse-server/pull/881) (Marco129)
12+
* Improvement: Adding a role scenario test for issue 827 [\#878](https://github.com/ParsePlatform/parse-server/pull/878) (gfosco)
13+
* Improvement: Test empty authData block on login for \#413 [\#863](https://github.com/ParsePlatform/parse-server/pull/863) (gfosco)
14+
* Improvement: Modified the npm dev script to support Windows [\#846](https://github.com/ParsePlatform/parse-server/pull/846) (aneeshd16)
15+
* Improvement: Move HooksController to use MongoCollection instead of direct Mongo access. [\#844](https://github.com/ParsePlatform/parse-server/pull/844) (nlutsenko)
16+
* Improvement: Adds public\_html and views for packaging [\#839](https://github.com/ParsePlatform/parse-server/pull/839) (flovilmart)
17+
* Improvement: Better support for windows builds [\#831](https://github.com/ParsePlatform/parse-server/pull/831) (flovilmart)
18+
* Improvement: Convert Schema.js to ES6 class. [\#826](https://github.com/ParsePlatform/parse-server/pull/826) (nlutsenko)
19+
* Improvement: Remove duplicated instructions [\#816](https://github.com/ParsePlatform/parse-server/pull/816) (hramos)
20+
* Improvement: Completely migrate SchemasRouter to new MongoCollection API. [\#794](https://github.com/ParsePlatform/parse-server/pull/794) (nlutsenko)
21+
* Fix: Do not require where clause in $dontSelect condition on queries. [\#925](https://github.com/ParsePlatform/parse-server/pull/925) (nlutsenko)
22+
* Fix: Make sure that ACLs propagate to before/after save hooks. [\#924](https://github.com/ParsePlatform/parse-server/pull/924) (nlutsenko)
23+
* Fix: Support params option in Parse.Cloud.httpRequest. [\#912](https://github.com/ParsePlatform/parse-server/pull/912) (carmenlau)
24+
* Fix: Fix flaky Parse.GeoPoint test. [\#908](https://github.com/ParsePlatform/parse-server/pull/908) (nlutsenko)
25+
* Fix: Handle legacy \_client\_permissions key in \_SCHEMA. [\#900](https://github.com/ParsePlatform/parse-server/pull/900) (drew-gross)
26+
* Fix: Fixes bug when querying equalTo on objectId and relation [\#887](https://github.com/ParsePlatform/parse-server/pull/887) (flovilmart)
27+
* Fix: Allow crossdomain on filesRouter [\#876](https://github.com/ParsePlatform/parse-server/pull/876) (flovilmart)
28+
* Fix: Remove limit when counting results. [\#867](https://github.com/ParsePlatform/parse-server/pull/867) (gfosco)
29+
* Fix: beforeSave changes should propagate to the response [\#865](https://github.com/ParsePlatform/parse-server/pull/865) (gfosco)
30+
* Fix: Delete relation field when \_Join collection not exist [\#864](https://github.com/ParsePlatform/parse-server/pull/864) (Marco129)
31+
* Fix: Related query on non-existing column [\#861](https://github.com/ParsePlatform/parse-server/pull/861) (gfosco)
32+
* Fix: Update markdown in .github/ISSUE\_TEMPLATE.md [\#859](https://github.com/ParsePlatform/parse-server/pull/859) (igorshubovych)
33+
* Fix: Issue with creating wrong \_Session for Facebook login [\#857](https://github.com/ParsePlatform/parse-server/pull/857) (tobernguyen)
34+
* Fix: Leak warnings in tests, use mongodb-runner from node\_modules [\#843](https://github.com/ParsePlatform/parse-server/pull/843) (drew-gross)
35+
* Fix: Reversed roles lookup [\#841](https://github.com/ParsePlatform/parse-server/pull/841) (flovilmart)
36+
* Fix: Improves loading of Push Adapter, fix loading of S3Adapter [\#833](https://github.com/ParsePlatform/parse-server/pull/833) (flovilmart)
37+
* Fix: Add field to system schema [\#828](https://github.com/ParsePlatform/parse-server/pull/828) (Marco129)
38+
339
### 2.1.4 (3/3/2016)
440

541
* New: serverInfo endpoint that returns server version and info about the server's features

bin/parse-server

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
#!/usr/bin/env node
2+
13
require("../lib/cli/parse-server");

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse-server",
3-
"version": "2.1.4",
3+
"version": "2.1.5",
44
"description": "An express module providing a Parse-compatible API server",
55
"main": "lib/index.js",
66
"repository": {

src/Adapters/Storage/Mongo/MongoCollection.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,6 @@ export default class MongoCollection {
7676
return this._mongoCollection.updateMany(query, update);
7777
}
7878

79-
// Atomically find and delete an object based on query.
80-
// The result is the promise with an object that was in the database before deleting.
81-
// Postgres Note: Translates directly to `DELETE * FROM ... RETURNING *`, which will return data after delete is done.
82-
findOneAndDelete(query) {
83-
// arguments: query, sort
84-
return this._mongoCollection.findAndRemove(query, []).then(document => {
85-
// Value is the object where mongo returns multiple fields.
86-
return document.value;
87-
});
88-
}
89-
9079
deleteOne(query) {
9180
return this._mongoCollection.deleteOne(query);
9281
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
import MongoCollection from './MongoCollection';
3+
4+
function _mongoSchemaQueryFromNameQuery(name: string, query) {
5+
return _mongoSchemaObjectFromNameFields(name, query);
6+
}
7+
8+
function _mongoSchemaObjectFromNameFields(name: string, fields) {
9+
let object = { _id: name };
10+
if (fields) {
11+
Object.keys(fields).forEach(key => {
12+
object[key] = fields[key];
13+
});
14+
}
15+
return object;
16+
}
17+
18+
export default class MongoSchemaCollection {
19+
_collection: MongoCollection;
20+
21+
constructor(collection: MongoCollection) {
22+
this._collection = collection;
23+
}
24+
25+
getAllSchemas() {
26+
return this._collection._rawFind({});
27+
}
28+
29+
findSchema(name: string) {
30+
return this._collection._rawFind(_mongoSchemaQueryFromNameQuery(name), { limit: 1 }).then(results => {
31+
return results[0];
32+
});
33+
}
34+
35+
// Atomically find and delete an object based on query.
36+
// The result is the promise with an object that was in the database before deleting.
37+
// Postgres Note: Translates directly to `DELETE * FROM ... RETURNING *`, which will return data after delete is done.
38+
findAndDeleteSchema(name: string) {
39+
// arguments: query, sort
40+
return this._collection._mongoCollection.findAndRemove(_mongoSchemaQueryFromNameQuery(name), []).then(document => {
41+
// Value is the object where mongo returns multiple fields.
42+
return document.value;
43+
});
44+
}
45+
46+
addSchema(name: string, fields) {
47+
let mongoObject = _mongoSchemaObjectFromNameFields(name, fields);
48+
return this._collection.insertOne(mongoObject);
49+
}
50+
51+
updateSchema(name: string, update) {
52+
return this._collection.updateOne(_mongoSchemaQueryFromNameQuery(name), update);
53+
}
54+
55+
upsertSchema(name: string, query: string, update) {
56+
return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update);
57+
}
58+
}

src/Adapters/Storage/Mongo/MongoStorageAdapter.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11

22
import MongoCollection from './MongoCollection';
3+
import MongoSchemaCollection from './MongoSchemaCollection';
34

45
let mongodb = require('mongodb');
56
let MongoClient = mongodb.MongoClient;
67

8+
const MongoSchemaCollectionName = '_SCHEMA';
9+
710
export class MongoStorageAdapter {
811
// Private
912
_uri: string;
@@ -38,6 +41,12 @@ export class MongoStorageAdapter {
3841
.then(rawCollection => new MongoCollection(rawCollection));
3942
}
4043

44+
schemaCollection(collectionPrefix: string) {
45+
return this.connect()
46+
.then(() => this.adaptiveCollection(collectionPrefix + MongoSchemaCollectionName))
47+
.then(collection => new MongoSchemaCollection(collection));
48+
}
49+
4150
collectionExists(name: string) {
4251
return this.connect().then(() => {
4352
return this.database.listCollections({ name: name }).toArray();

src/Controllers/DatabaseController.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ DatabaseController.prototype.adaptiveCollection = function(className) {
3333
return this.adapter.adaptiveCollection(this.collectionPrefix + className);
3434
};
3535

36+
DatabaseController.prototype.schemaCollection = function() {
37+
return this.adapter.schemaCollection(this.collectionPrefix);
38+
};
39+
3640
DatabaseController.prototype.collectionExists = function(className) {
3741
return this.adapter.collectionExists(this.collectionPrefix + className);
3842
};
@@ -59,7 +63,7 @@ DatabaseController.prototype.validateClassName = function(className) {
5963
DatabaseController.prototype.loadSchema = function(acceptor = returnsTrue) {
6064

6165
if (!this.schemaPromise) {
62-
this.schemaPromise = this.adaptiveCollection('_SCHEMA').then(collection => {
66+
this.schemaPromise = this.schemaCollection().then(collection => {
6367
delete this.schemaPromise;
6468
return Schema.load(collection);
6569
});
@@ -70,7 +74,7 @@ DatabaseController.prototype.loadSchema = function(acceptor = returnsTrue) {
7074
if (acceptor(schema)) {
7175
return schema;
7276
}
73-
this.schemaPromise = this.adaptiveCollection('_SCHEMA').then(collection => {
77+
this.schemaPromise = this.schemaCollection().then(collection => {
7478
delete this.schemaPromise;
7579
return Schema.load(collection);
7680
});

src/Routers/SchemasRouter.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,22 @@ function classNameMismatchResponse(bodyClass, pathClass) {
1515
}
1616

1717
function getAllSchemas(req) {
18-
return req.config.database.adaptiveCollection('_SCHEMA')
19-
.then(collection => collection.find({}))
18+
return req.config.database.schemaCollection()
19+
.then(collection => collection.getAllSchemas())
2020
.then(schemas => schemas.map(Schema.mongoSchemaToSchemaAPIResponse))
2121
.then(schemas => ({ response: { results: schemas } }));
2222
}
2323

2424
function getOneSchema(req) {
2525
const className = req.params.className;
26-
return req.config.database.adaptiveCollection('_SCHEMA')
27-
.then(collection => collection.find({ '_id': className }, { limit: 1 }))
28-
.then(results => {
29-
if (results.length != 1) {
26+
return req.config.database.schemaCollection()
27+
.then(collection => collection.findSchema(className))
28+
.then(mongoSchema => {
29+
if (!mongoSchema) {
3030
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`);
3131
}
32-
return results[0];
33-
})
34-
.then(schema => ({ response: Schema.mongoSchemaToSchemaAPIResponse(schema) }));
32+
return { response: Schema.mongoSchemaToSchemaAPIResponse(mongoSchema) };
33+
});
3534
}
3635

3736
function createSchema(req) {
@@ -142,8 +141,8 @@ function deleteSchema(req) {
142141
.then(() => {
143142
// We've dropped the collection now, so delete the item from _SCHEMA
144143
// and clear the _Join collections
145-
return req.config.database.adaptiveCollection('_SCHEMA')
146-
.then(coll => coll.findOneAndDelete({ _id: req.params.className }))
144+
return req.config.database.schemaCollection()
145+
.then(coll => coll.findAndDeleteSchema(req.params.className))
147146
.then(document => {
148147
if (document === null) {
149148
//tried to delete non-existent class

src/Schema.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class Schema {
184184
reloadData() {
185185
this.data = {};
186186
this.perms = {};
187-
return this._collection.find({}).then(results => {
187+
return this._collection.getAllSchemas().then(results => {
188188
for (let obj of results) {
189189
let className = null;
190190
let classData = {};
@@ -231,7 +231,7 @@ class Schema {
231231
return Promise.reject(mongoObject);
232232
}
233233

234-
return this._collection.insertOne(mongoObject.result)
234+
return this._collection.addSchema(className, mongoObject.result)
235235
.then(result => result.ops[0])
236236
.catch(error => {
237237
if (error.code === 11000) { //Mongo's duplicate key error
@@ -268,7 +268,7 @@ class Schema {
268268
'schema is frozen, cannot add: ' + className);
269269
}
270270
// We don't have this class. Update the schema
271-
return this._collection.insertOne({ _id: className }).then(() => {
271+
return this._collection.addSchema(className).then(() => {
272272
// The schema update succeeded. Reload the schema
273273
return this.reloadData();
274274
}, () => {
@@ -288,14 +288,13 @@ class Schema {
288288

289289
// Sets the Class-level permissions for a given className, which must exist.
290290
setPermissions(className, perms) {
291-
var query = {_id: className};
292291
var update = {
293292
_metadata: {
294293
class_permissions: perms
295294
}
296295
};
297296
update = {'$set': update};
298-
return this._collection.updateOne(query, update).then(() => {
297+
return this._collection.updateSchema(className, update).then(() => {
299298
// The update succeeded. Reload the schema
300299
return this.reloadData();
301300
});
@@ -353,12 +352,12 @@ class Schema {
353352
// We don't have this field. Update the schema.
354353
// Note that we use the $exists guard and $set to avoid race
355354
// conditions in the database. This is important!
356-
var query = { _id: className };
355+
let query = {};
357356
query[key] = { '$exists': false };
358357
var update = {};
359358
update[key] = type;
360359
update = {'$set': update};
361-
return this._collection.upsertOne(query, update).then(() => {
360+
return this._collection.upsertSchema(className, query, update).then(() => {
362361
// The update succeeded. Reload the schema
363362
return this.reloadData();
364363
}, () => {
@@ -428,7 +427,7 @@ class Schema {
428427
});
429428
})
430429
// Save the _SCHEMA object
431-
.then(() => this._collection.updateOne({ _id: className }, { $unset: { [fieldName]: null } }));
430+
.then(() => this._collection.updateSchema(className, { $unset: { [fieldName]: null } }));
432431
});
433432
}
434433

0 commit comments

Comments
 (0)