Skip to content

Commit 8691c01

Browse files
feat: Refactor SchemaControler to make it stateless
1 parent 590808c commit 8691c01

16 files changed

+354
-282
lines changed

spec/DatabaseController.spec.js

+21-21
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,16 @@ describe('DatabaseController', function () {
6969
'getExpectedType',
7070
]);
7171

72-
it('should not decorate query if no pointer CLPs are present', done => {
72+
it('should not decorate query if no pointer CLPs are present', async done => {
7373
const clp = buildCLP();
7474
const query = { a: 'b' };
7575

7676
schemaController.testPermissionsForClassName
7777
.withArgs(CLASS_NAME, ACL_GROUP, OPERATION)
7878
.and.returnValue(true);
79-
schemaController.getClassLevelPermissions.withArgs(CLASS_NAME).and.returnValue(clp);
79+
await schemaController.getClassLevelPermissions.withArgs(CLASS_NAME).and.returnValue(clp);
8080

81-
const output = databaseController.addPointerPermissions(
81+
const output = await databaseController.addPointerPermissions(
8282
schemaController,
8383
CLASS_NAME,
8484
OPERATION,
@@ -91,7 +91,7 @@ describe('DatabaseController', function () {
9191
done();
9292
});
9393

94-
it('should decorate query if a pointer CLP entry is present', done => {
94+
it('should decorate query if a pointer CLP entry is present', async done => {
9595
const clp = buildCLP(['user']);
9696
const query = { a: 'b' };
9797

@@ -103,7 +103,7 @@ describe('DatabaseController', function () {
103103
.withArgs(CLASS_NAME, 'user')
104104
.and.returnValue({ type: 'Pointer' });
105105

106-
const output = databaseController.addPointerPermissions(
106+
const output = await databaseController.addPointerPermissions(
107107
schemaController,
108108
CLASS_NAME,
109109
OPERATION,
@@ -116,7 +116,7 @@ describe('DatabaseController', function () {
116116
done();
117117
});
118118

119-
it('should decorate query if an array CLP entry is present', done => {
119+
it('should decorate query if an array CLP entry is present', async done => {
120120
const clp = buildCLP(['users']);
121121
const query = { a: 'b' };
122122

@@ -128,7 +128,7 @@ describe('DatabaseController', function () {
128128
.withArgs(CLASS_NAME, 'users')
129129
.and.returnValue({ type: 'Array' });
130130

131-
const output = databaseController.addPointerPermissions(
131+
const output = await databaseController.addPointerPermissions(
132132
schemaController,
133133
CLASS_NAME,
134134
OPERATION,
@@ -144,7 +144,7 @@ describe('DatabaseController', function () {
144144
done();
145145
});
146146

147-
it('should decorate query if an object CLP entry is present', done => {
147+
it('should decorate query if an object CLP entry is present', async done => {
148148
const clp = buildCLP(['user']);
149149
const query = { a: 'b' };
150150

@@ -156,7 +156,7 @@ describe('DatabaseController', function () {
156156
.withArgs(CLASS_NAME, 'user')
157157
.and.returnValue({ type: 'Object' });
158158

159-
const output = databaseController.addPointerPermissions(
159+
const output = await databaseController.addPointerPermissions(
160160
schemaController,
161161
CLASS_NAME,
162162
OPERATION,
@@ -172,7 +172,7 @@ describe('DatabaseController', function () {
172172
done();
173173
});
174174

175-
it('should decorate query if a pointer CLP is present and the same field is part of the query', done => {
175+
it('should decorate query if a pointer CLP is present and the same field is part of the query', async done => {
176176
const clp = buildCLP(['user']);
177177
const query = { a: 'b', user: 'a' };
178178

@@ -184,7 +184,7 @@ describe('DatabaseController', function () {
184184
.withArgs(CLASS_NAME, 'user')
185185
.and.returnValue({ type: 'Pointer' });
186186

187-
const output = databaseController.addPointerPermissions(
187+
const output = await databaseController.addPointerPermissions(
188188
schemaController,
189189
CLASS_NAME,
190190
OPERATION,
@@ -199,7 +199,7 @@ describe('DatabaseController', function () {
199199
done();
200200
});
201201

202-
it('should transform the query to an $or query if multiple array/pointer CLPs are present', done => {
202+
it('should transform the query to an $or query if multiple array/pointer CLPs are present', async done => {
203203
const clp = buildCLP(['user', 'users', 'userObject']);
204204
const query = { a: 'b' };
205205

@@ -217,7 +217,7 @@ describe('DatabaseController', function () {
217217
.withArgs(CLASS_NAME, 'userObject')
218218
.and.returnValue({ type: 'Object' });
219219

220-
const output = databaseController.addPointerPermissions(
220+
const output = await databaseController.addPointerPermissions(
221221
schemaController,
222222
CLASS_NAME,
223223
OPERATION,
@@ -236,7 +236,7 @@ describe('DatabaseController', function () {
236236
done();
237237
});
238238

239-
it('should not return a $or operation if the query involves one of the two fields also used as array/pointer permissions', done => {
239+
it('should not return a $or operation if the query involves one of the two fields also used as array/pointer permissions', async done => {
240240
const clp = buildCLP(['users', 'user']);
241241
const query = { a: 'b', user: createUserPointer(USER_ID) };
242242
schemaController.testPermissionsForClassName
@@ -249,7 +249,7 @@ describe('DatabaseController', function () {
249249
schemaController.getExpectedType
250250
.withArgs(CLASS_NAME, 'users')
251251
.and.returnValue({ type: 'Array' });
252-
const output = databaseController.addPointerPermissions(
252+
const output = await databaseController.addPointerPermissions(
253253
schemaController,
254254
CLASS_NAME,
255255
OPERATION,
@@ -260,7 +260,7 @@ describe('DatabaseController', function () {
260260
done();
261261
});
262262

263-
it('should not return a $or operation if the query involves one of the fields also used as array/pointer permissions', done => {
263+
it('should not return a $or operation if the query involves one of the fields also used as array/pointer permissions', async done => {
264264
const clp = buildCLP(['user', 'users', 'userObject']);
265265
const query = { a: 'b', user: createUserPointer(USER_ID) };
266266
schemaController.testPermissionsForClassName
@@ -276,7 +276,7 @@ describe('DatabaseController', function () {
276276
schemaController.getExpectedType
277277
.withArgs(CLASS_NAME, 'userObject')
278278
.and.returnValue({ type: 'Object' });
279-
const output = databaseController.addPointerPermissions(
279+
const output = await databaseController.addPointerPermissions(
280280
schemaController,
281281
CLASS_NAME,
282282
OPERATION,
@@ -287,7 +287,7 @@ describe('DatabaseController', function () {
287287
done();
288288
});
289289

290-
it('should throw an error if for some unexpected reason the property specified in the CLP is neither a pointer nor an array', done => {
290+
it('should throw an error if for some unexpected reason the property specified in the CLP is neither a pointer nor an array', async done => {
291291
const clp = buildCLP(['user']);
292292
const query = { a: 'b' };
293293

@@ -299,15 +299,15 @@ describe('DatabaseController', function () {
299299
.withArgs(CLASS_NAME, 'user')
300300
.and.returnValue({ type: 'Number' });
301301

302-
expect(() => {
302+
await expectAsync(
303303
databaseController.addPointerPermissions(
304304
schemaController,
305305
CLASS_NAME,
306306
OPERATION,
307307
query,
308308
ACL_GROUP
309-
);
310-
}).toThrow(
309+
)
310+
).toBeRejectedWith(
311311
Error(
312312
`An unexpected condition occurred when resolving pointer permissions: ${CLASS_NAME} user`
313313
)

spec/Schema.spec.js

+18-7
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,14 @@ describe('SchemaController', () => {
875875
addField: { '*': true },
876876
protectedFields: { '*': [] },
877877
},
878+
indexes: {
879+
_id_: {
880+
_id: 1,
881+
},
882+
name_1: {
883+
name: 1,
884+
},
885+
},
878886
};
879887
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
880888
done();
@@ -1097,14 +1105,15 @@ describe('SchemaController', () => {
10971105
})
10981106
.then(() => schema.deleteField('relationField', 'NewClass', config.database))
10991107
.then(() => schema.reloadData())
1100-
.then(() => {
1108+
.then(async () => {
11011109
const expectedSchema = {
11021110
objectId: { type: 'String' },
11031111
updatedAt: { type: 'Date' },
11041112
createdAt: { type: 'Date' },
11051113
ACL: { type: 'ACL' },
11061114
};
1107-
expect(dd(schema.schemaData.NewClass.fields, expectedSchema)).toEqual(undefined);
1115+
const schemaData = await schema.getSchemaData();
1116+
expect(dd(schemaData.NewClass.fields, expectedSchema)).toEqual(undefined);
11081117
})
11091118
.then(done)
11101119
.catch(done.fail);
@@ -1331,14 +1340,16 @@ describe('SchemaController', () => {
13311340
schema = s;
13321341
return schema.getOneSchema('_User', false);
13331342
})
1334-
.then(userSchema => {
1343+
.then(async userSchema => {
13351344
validateSchemaStructure(userSchema);
1336-
validateSchemaDataStructure(schema.schemaData);
1345+
const schemaData = await schema.getSchemaData();
1346+
validateSchemaDataStructure(schemaData);
13371347
return schema.getOneSchema('_PushStatus', true);
13381348
})
1339-
.then(pushStatusSchema => {
1349+
.then(async pushStatusSchema => {
1350+
const schemaData = await schema.getSchemaData();
13401351
validateSchemaStructure(pushStatusSchema);
1341-
validateSchemaDataStructure(schema.schemaData);
1352+
validateSchemaDataStructure(schemaData);
13421353
})
13431354
.then(done)
13441355
.catch(done.fail);
@@ -1353,7 +1364,7 @@ describe('SchemaController', () => {
13531364
it('ensureFields should throw when schema is not set', async () => {
13541365
const schema = await config.database.loadSchema();
13551366
try {
1356-
schema.ensureFields([
1367+
await schema.ensureFields([
13571368
{
13581369
className: 'NewClass',
13591370
fieldName: 'fieldName',

spec/SchemaPerformance.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,6 @@ describe('Schema Performance', function () {
202202
{},
203203
config.database
204204
);
205-
expect(getAllSpy.calls.count()).toBe(2);
205+
expect(getAllSpy.calls.count()).toBe(4);
206206
});
207207
});

spec/schemas.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,7 @@ describe('schemas', () => {
15561556

15571557
it('ensure refresh cache after deleting a class', async done => {
15581558
config = Config.get('test');
1559-
spyOn(config.schemaCache, 'del').and.callFake(() => {});
1559+
spyOn(config.schemaCache, 'clear').and.callFake(() => {});
15601560
spyOn(SchemaController.prototype, 'reloadData').and.callFake(() => Promise.resolve());
15611561
await request({
15621562
url: 'http://localhost:8378/1/schemas',

src/Adapters/Cache/SchemaCache.js

-23
This file was deleted.

src/Adapters/Cache/SchemaCacheAdapter.js

-36
This file was deleted.
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type { Schema } from '../../Controllers/types';
2+
import { SchemaData } from '../../Controllers/SchemaController';
3+
4+
export default class InMemorySchemaCache {
5+
dataProvider: () => Promise<{ allClasses: Array<Schema>, schemaData: SchemaData }>;
6+
fetchingSchemaPromise: any;
7+
cache = {};
8+
9+
setDataProvider(
10+
dataProvider: () => Promise<{ allClasses: Array<Schema>, schemaData: SchemaData }>
11+
) {
12+
this.dataProvider = dataProvider;
13+
}
14+
15+
async fetchSchema(): Promise<{ allClasses: Array<Schema>, schemaData: SchemaData }> {
16+
if (this.cache.isCached) {
17+
return {
18+
allClasses: this.cache.allClasses,
19+
schemaData: this.cache.schemaData,
20+
};
21+
}
22+
if (!this.fetchingSchemaPromise) {
23+
this.fetchingSchemaPromise = this.dataProvider();
24+
}
25+
const result = await this.fetchingSchemaPromise;
26+
this.cache.isCached = true;
27+
this.cache.allClasses = result ? result.allClasses : undefined;
28+
this.cache.schemaData = result ? result.schemaData : undefined;
29+
30+
return {
31+
allClasses: this.cache.allClasses,
32+
schemaData: this.cache.schemaData,
33+
};
34+
}
35+
36+
clear(): Promise<void> {
37+
this.cache.isCached = false;
38+
this.cache.allClasses = undefined;
39+
this.cache.schemaData = undefined;
40+
this.fetchingSchemaPromise = undefined;
41+
}
42+
}

0 commit comments

Comments
 (0)