Skip to content

Commit a6c692d

Browse files
committed
Create Singleton Object
1 parent d49e4d4 commit a6c692d

13 files changed

+177
-172
lines changed

spec/MongoStorageAdapter.spec.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ const fakeClient = {
1818
describe_only_db('mongo')('MongoStorageAdapter', () => {
1919
beforeEach(done => {
2020
new MongoStorageAdapter({ uri: databaseURI }).deleteAllClasses().then(done, fail);
21-
const { database } = Config.get(Parse.applicationId);
22-
database.schemaCache.clear();
21+
Config.get(Parse.applicationId).schemaCache.clear();
2322
});
2423

2524
it('auto-escapes symbols in auth information', () => {

spec/ParseGraphQLServer.spec.js

+120-121
Large diffs are not rendered by default.

spec/ParseUser.spec.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,7 @@ describe('Parse.User testing', () => {
246246
await adapter.connect();
247247
await adapter.database.dropDatabase();
248248
delete adapter.connectionPromise;
249-
const { database } = Config.get(Parse.applicationId);
250-
database.schemaCache.clear();
249+
Config.get(Parse.applicationId).schemaCache.clear();
251250

252251
const user = new Parse.User();
253252
await user.signUp({

spec/PointerPermissions.spec.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const Config = require('../lib/Config');
33

44
describe('Pointer Permissions', () => {
55
beforeEach(() => {
6-
Config.get(Parse.applicationId).database.schemaCache.clear();
6+
Config.get(Parse.applicationId).schemaCache.clear();
77
});
88

99
describe('using single user-pointers', () => {
@@ -2020,7 +2020,7 @@ describe('Pointer Permissions', () => {
20202020
let obj2;
20212021

20222022
async function initialize() {
2023-
await Config.get(Parse.applicationId).database.schemaCache.clear();
2023+
await Config.get(Parse.applicationId).schemaCache.clear();
20242024

20252025
[user1, user2] = await Promise.all([createUser('user1'), createUser('user2')]);
20262026

@@ -2442,7 +2442,7 @@ describe('Pointer Permissions', () => {
24422442
let objNobody;
24432443

24442444
async function initialize() {
2445-
await Config.get(Parse.applicationId).database.schemaCache.clear();
2445+
await Config.get(Parse.applicationId).schemaCache.clear();
24462446

24472447
[user1, user2, user3] = await Promise.all([
24482448
createUser('user1'),
@@ -2919,7 +2919,7 @@ describe('Pointer Permissions', () => {
29192919
let obj2;
29202920

29212921
async function initialize() {
2922-
await Config.get(Parse.applicationId).database.schemaCache.clear();
2922+
await Config.get(Parse.applicationId).schemaCache.clear();
29232923

29242924
[user1, user2] = await Promise.all([createUser('user1'), createUser('user2')]);
29252925

@@ -3033,7 +3033,7 @@ describe('Pointer Permissions', () => {
30333033
* Clear cache, create user and object, login user
30343034
*/
30353035
async function initialize() {
3036-
await Config.get(Parse.applicationId).database.schemaCache.clear();
3036+
await Config.get(Parse.applicationId).schemaCache.clear();
30373037

30383038
user1 = await createUser('user1');
30393039
user1 = await logIn(user1);

spec/ProtectedFields.spec.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ describe('ProtectedFields', function () {
135135
describe('using the pointer-permission variant', () => {
136136
let user1, user2;
137137
beforeEach(async () => {
138-
Config.get(Parse.applicationId).database.schemaCache.clear();
138+
Config.get(Parse.applicationId).schemaCache.clear();
139139
user1 = await Parse.User.signUp('user1', 'password');
140140
user2 = await Parse.User.signUp('user2', 'password');
141141
await Parse.User.logOut();
@@ -752,7 +752,7 @@ describe('ProtectedFields', function () {
752752
let object;
753753

754754
async function initialize() {
755-
await Config.get(Parse.applicationId).database.schemaCache.clear();
755+
await Config.get(Parse.applicationId).schemaCache.clear();
756756

757757
object = new Parse.Object(className);
758758

@@ -815,7 +815,7 @@ describe('ProtectedFields', function () {
815815
let obj1;
816816

817817
async function initialize() {
818-
await Config.get(Parse.applicationId).database.schemaCache.clear();
818+
await Config.get(Parse.applicationId).schemaCache.clear();
819819

820820
obj1 = new Parse.Object(className);
821821

@@ -924,7 +924,7 @@ describe('ProtectedFields', function () {
924924
let obj2;
925925

926926
async function initialize() {
927-
await Config.get(Parse.applicationId).database.schemaCache.clear();
927+
await Config.get(Parse.applicationId).schemaCache.clear();
928928

929929
await Parse.User.logOut();
930930

@@ -1125,7 +1125,7 @@ describe('ProtectedFields', function () {
11251125
let obj2;
11261126

11271127
async function initialize() {
1128-
await Config.get(Parse.applicationId).database.schemaCache.clear();
1128+
await Config.get(Parse.applicationId).schemaCache.clear();
11291129

11301130
[user1, user2] = await Promise.all([createUser('user1'), createUser('user2')]);
11311131

@@ -1477,7 +1477,7 @@ describe('ProtectedFields', function () {
14771477
* Clear cache, create user and object, login user and setup rest headers with token
14781478
*/
14791479
async function initialize() {
1480-
await Config.get(Parse.applicationId).database.schemaCache.clear();
1480+
await Config.get(Parse.applicationId).schemaCache.clear();
14811481

14821482
user1 = await createUser('user1');
14831483
user1 = await logIn(user1);

spec/SchemaPerformance.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe_only_db('mongo')('Schema Performance', function () {
88

99
beforeEach(async () => {
1010
config = Config.get('test');
11-
config.database.schemaCache.clear();
11+
config.schemaCache.clear();
1212
const databaseAdapter = new MongoStorageAdapter({ uri: mongoURI });
1313
await reconfigureServer({
1414
replicaSet: false,

spec/index.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('server', () => {
7171
}),
7272
}).catch(() => {
7373
const config = Config.get('test');
74-
config.database.schemaCache.clear();
74+
config.schemaCache.clear();
7575
//Need to use rest api because saving via JS SDK results in fail() not getting called
7676
request({
7777
method: 'POST',

src/Adapters/Cache/SchemaCache.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const SchemaCache = {};
2+
3+
export default {
4+
get() {
5+
return SchemaCache.allClasses || [];
6+
},
7+
8+
put(allSchema) {
9+
SchemaCache.allClasses = allSchema;
10+
},
11+
12+
del(className) {
13+
this.put(this.get().filter(cached => cached.className !== className));
14+
},
15+
16+
clear() {
17+
delete SchemaCache.allClasses;
18+
},
19+
};

src/Controllers/DatabaseController.js

+5-12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import deepcopy from 'deepcopy';
1313
import logger from '../logger';
1414
import * as SchemaController from './SchemaController';
1515
import { StorageAdapter } from '../Adapters/Storage/StorageAdapter';
16+
import MongoStorageAdapter from '../Adapters/Storage/Mongo/MongoStorageAdapter';
17+
import SchemaCache from '../Adapters/Cache/SchemaCache';
18+
import type { LoadSchemaOptions } from './types';
1619
import type { QueryOptions, FullQueryOptions } from '../Adapters/Storage/StorageAdapter';
1720

1821
function addWriteACL(query, acl) {
@@ -230,9 +233,6 @@ const filterSensitiveData = (
230233
return object;
231234
};
232235

233-
import type { LoadSchemaOptions } from './types';
234-
import MongoStorageAdapter from '../Adapters/Storage/Mongo/MongoStorageAdapter';
235-
236236
// Runs an update on the database.
237237
// Returns a promise for an object with the new values for field
238238
// modifications that don't know their results ahead of time, like
@@ -405,11 +405,6 @@ class DatabaseController {
405405
// it. Instead, use loadSchema to get a schema.
406406
this.schemaPromise = null;
407407
this._transactionalSession = null;
408-
// Used for Testing only
409-
this.schemaCache = {
410-
clear: () => SchemaController.clearSingleSchemaCache(),
411-
get: () => SchemaController.getSingleSchemaCache(),
412-
};
413408
}
414409

415410
collectionExists(className: string): Promise<boolean> {
@@ -920,7 +915,7 @@ class DatabaseController {
920915
*/
921916
deleteEverything(fast: boolean = false): Promise<any> {
922917
this.schemaPromise = null;
923-
this.schemaCache.clear();
918+
SchemaCache.clear();
924919
return this.adapter.deleteAllClasses(fast);
925920
}
926921

@@ -1365,9 +1360,7 @@ class DatabaseController {
13651360
this.adapter.deleteClass(joinTableName(className, name))
13661361
)
13671362
).then(() => {
1368-
schemaController._cache.allClasses = (
1369-
schemaController._cache.allClasses || []
1370-
).filter(cached => cached.className !== className);
1363+
SchemaCache.del(className);
13711364
return schemaController.reloadData();
13721365
});
13731366
} else {

src/Controllers/SchemaController.js

+12-22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// @flow-disable-next
1818
const Parse = require('parse/node').Parse;
1919
import { StorageAdapter } from '../Adapters/Storage/StorageAdapter';
20+
import SchemaCache from '../Adapters/Cache/SchemaCache';
2021
import DatabaseController from './DatabaseController';
2122
import Config from '../Config';
2223
// @flow-disable-next
@@ -682,15 +683,13 @@ const typeToString = (type: SchemaField | string): string => {
682683
export default class SchemaController {
683684
_dbAdapter: StorageAdapter;
684685
schemaData: { [string]: Schema };
685-
_cache: any;
686686
reloadDataPromise: ?Promise<any>;
687687
protectedFields: any;
688688
userIdRegEx: RegExp;
689689

690-
constructor(databaseAdapter: StorageAdapter, singleSchemaCache: Object) {
690+
constructor(databaseAdapter: StorageAdapter) {
691691
this._dbAdapter = databaseAdapter;
692-
this._cache = singleSchemaCache;
693-
this.schemaData = new SchemaData(this._cache.allClasses || [], this.protectedFields);
692+
this.schemaData = new SchemaData(SchemaCache.get(), this.protectedFields);
694693
this.protectedFields = Config.get(Parse.applicationId).protectedFields;
695694

696695
const customIds = Config.get(Parse.applicationId).allowCustomObjectId;
@@ -729,8 +728,9 @@ export default class SchemaController {
729728
if (options.clearCache) {
730729
return this.setAllClasses();
731730
}
732-
if (this._cache.allClasses && this._cache.allClasses.length) {
733-
return Promise.resolve(this._cache.allClasses);
731+
const cached = SchemaCache.get();
732+
if (cached && cached.length) {
733+
return Promise.resolve(cached);
734734
}
735735
return this.setAllClasses();
736736
}
@@ -740,7 +740,7 @@ export default class SchemaController {
740740
.getAllClasses()
741741
.then(allSchemas => allSchemas.map(injectDefaultSchema))
742742
.then(allSchemas => {
743-
this._cache.allClasses = allSchemas;
743+
SchemaCache.put(allSchemas);
744744
return allSchemas;
745745
});
746746
}
@@ -751,7 +751,7 @@ export default class SchemaController {
751751
options: LoadSchemaOptions = { clearCache: false }
752752
): Promise<Schema> {
753753
if (options.clearCache) {
754-
delete this._cache.allClasses;
754+
SchemaCache.clear();
755755
}
756756
if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) {
757757
const data = this.schemaData[className];
@@ -762,7 +762,7 @@ export default class SchemaController {
762762
indexes: data.indexes,
763763
});
764764
}
765-
const cached = (this._cache.allClasses || []).find(schema => schema.className === className);
765+
const cached = SchemaCache.get().find(schema => schema.className === className);
766766
if (cached && !options.clearCache) {
767767
return Promise.resolve(cached);
768768
}
@@ -1050,7 +1050,7 @@ export default class SchemaController {
10501050
}
10511051
validateCLP(perms, newSchema, this.userIdRegEx);
10521052
await this._dbAdapter.setClassLevelPermissions(className, perms);
1053-
const cached = (this._cache.allClasses || []).find(schema => schema.className === className);
1053+
const cached = SchemaCache.get().find(schema => schema.className === className);
10541054
if (cached) {
10551055
cached.classLevelPermissions = perms;
10561056
}
@@ -1202,7 +1202,7 @@ export default class SchemaController {
12021202
});
12031203
})
12041204
.then(() => {
1205-
delete this._cache.allClasses;
1205+
SchemaCache.clear();
12061206
});
12071207
}
12081208

@@ -1412,20 +1412,12 @@ export default class SchemaController {
14121412
}
14131413
}
14141414

1415-
const singleSchemaCache = {};
1416-
14171415
// Returns a promise for a new Schema.
14181416
const load = (dbAdapter: StorageAdapter, options: any): Promise<SchemaController> => {
1419-
const schema = new SchemaController(dbAdapter, singleSchemaCache);
1417+
const schema = new SchemaController(dbAdapter);
14201418
return schema.reloadData(options).then(() => schema);
14211419
};
14221420

1423-
const clearSingleSchemaCache = () => {
1424-
delete singleSchemaCache.allClasses;
1425-
};
1426-
1427-
const getSingleSchemaCache = () => singleSchemaCache.allClasses;
1428-
14291421
// Builds a new schema (in schema API response format) out of an
14301422
// existing mongo schema + a schemas API put request. This response
14311423
// does not include the default fields, as it is intended to be passed
@@ -1585,8 +1577,6 @@ function getObjectType(obj): ?(SchemaField | string) {
15851577

15861578
export {
15871579
load,
1588-
clearSingleSchemaCache,
1589-
getSingleSchemaCache,
15901580
classNameIsValid,
15911581
fieldNameIsValid,
15921582
invalidClassNameMessage,

src/Controllers/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import MongoStorageAdapter from '../Adapters/Storage/Mongo/MongoStorageAdapter';
2525
import PostgresStorageAdapter from '../Adapters/Storage/Postgres/PostgresStorageAdapter';
2626
import ParsePushAdapter from '@parse/push-adapter';
2727
import ParseGraphQLController from './ParseGraphQLController';
28+
import SchemaCache from '../Adapters/Cache/SchemaCache';
2829

2930
export function getControllers(options: ParseServerOptions) {
3031
const loggerController = getLoggerController(options);
@@ -63,6 +64,7 @@ export function getControllers(options: ParseServerOptions) {
6364
databaseController,
6465
hooksController,
6566
authDataManager,
67+
schemaCache: SchemaCache,
6668
};
6769
}
6870

src/GraphQL/ParseGraphQLSchema.js

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as defaultGraphQLQueries from './loaders/defaultGraphQLQueries';
1111
import * as defaultGraphQLMutations from './loaders/defaultGraphQLMutations';
1212
import ParseGraphQLController, { ParseGraphQLConfig } from '../Controllers/ParseGraphQLController';
1313
import DatabaseController from '../Controllers/DatabaseController';
14+
import SchemaCache from '../Adapters/Cache/SchemaCache';
1415
import { toGraphQLError } from './parseGraphQLUtils';
1516
import * as schemaDirectives from './loaders/schemaDirectives';
1617
import * as schemaTypes from './loaders/schemaTypes';
@@ -66,6 +67,7 @@ class ParseGraphQLSchema {
6667
log: any;
6768
appId: string;
6869
graphQLCustomTypeDefs: ?(string | GraphQLSchema | DocumentNode | GraphQLNamedType[]);
70+
schemaCache: any;
6971

7072
constructor(
7173
params: {
@@ -85,6 +87,7 @@ class ParseGraphQLSchema {
8587
this.log = params.log || requiredParameter('You must provide a log instance!');
8688
this.graphQLCustomTypeDefs = params.graphQLCustomTypeDefs;
8789
this.appId = params.appId || requiredParameter('You must provide the appId!');
90+
this.schemaCache = SchemaCache;
8891
}
8992

9093
async load() {

src/Routers/SchemasRouter.js

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ async function createSchema(req) {
6060
req.body.classLevelPermissions,
6161
req.body.indexes
6262
);
63+
// TODO: Improve by directly updating global schema cache
6364
await schema.reloadData({ clearCache: true });
6465
return { response: parseSchema };
6566
}

0 commit comments

Comments
 (0)