Skip to content

Commit 288525b

Browse files
committed
add includeAll option
1 parent 2ef437a commit 288525b

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

spec/ParseQuery.spec.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3684,6 +3684,75 @@ describe('Parse.Query testing', () => {
36843684
});
36853685
});
36863686

3687+
it("includeAll", (done) => {
3688+
const child1 = new TestObject({ foo: 'bar', name: 'al' });
3689+
const child2 = new TestObject({ foo: 'baz', name: 'flo' });
3690+
const child3 = new TestObject({ foo: 'bad', name: 'mo' });
3691+
const parent = new Container({ child1, child2, child3 });
3692+
Parse.Object.saveAll([parent, child1, child2, child3]).then(() => {
3693+
const options = Object.assign({}, masterKeyOptions, {
3694+
body: {
3695+
where: { objectId: parent.id },
3696+
includeAll: true,
3697+
}
3698+
});
3699+
return rp.get(Parse.serverURL + "/classes/Container", options);
3700+
}).then((resp) => {
3701+
const result = resp.results[0];
3702+
equal(result.child1.foo, 'bar');
3703+
equal(result.child2.foo, 'baz');
3704+
equal(result.child3.foo, 'bad');
3705+
equal(result.child1.name, 'al');
3706+
equal(result.child2.name, 'flo');
3707+
equal(result.child3.name, 'mo');
3708+
done();
3709+
});
3710+
});
3711+
3712+
it('select nested keys 2 level includeAll', (done) => {
3713+
const Foobar = new Parse.Object('Foobar');
3714+
const BarBaz = new Parse.Object('Barbaz');
3715+
const Bazoo = new Parse.Object('Bazoo');
3716+
const Tang = new Parse.Object('Tang');
3717+
3718+
Bazoo.set('some', 'thing');
3719+
Bazoo.set('otherSome', 'value');
3720+
Bazoo.save().then(() => {
3721+
BarBaz.set('key', 'value');
3722+
BarBaz.set('otherKey', 'value');
3723+
BarBaz.set('bazoo', Bazoo);
3724+
return BarBaz.save();
3725+
}).then(() => {
3726+
Tang.set('clan', 'wu');
3727+
return Tang.save();
3728+
}).then(() => {
3729+
Foobar.set('foo', 'bar');
3730+
Foobar.set('fizz', 'buzz');
3731+
Foobar.set('barBaz', BarBaz);
3732+
Foobar.set('group', Tang);
3733+
return Foobar.save();
3734+
}).then((savedFoobar) => {
3735+
const options = Object.assign({}, masterKeyOptions, {
3736+
body: {
3737+
where: { objectId: savedFoobar.id },
3738+
includeAll: true,
3739+
keys: 'fizz,barBaz.key,barBaz.bazoo.some',
3740+
}
3741+
});
3742+
return rp.get(Parse.serverURL + "/classes/Foobar", options);
3743+
}).then((resp) => {
3744+
const result = resp.results[0];
3745+
equal(result.group.clan, 'wu');
3746+
equal(result.foo, undefined);
3747+
equal(result.fizz, 'buzz');
3748+
equal(result.barBaz.key, 'value');
3749+
equal(result.barBaz.otherKey, undefined);
3750+
equal(result.barBaz.bazoo.some, 'thing');
3751+
equal(result.barBaz.bazoo.otherSome, undefined);
3752+
done();
3753+
})
3754+
});
3755+
36873756
it('select nested keys 2 level without include (issue #3185)', function(done) {
36883757
const Foobar = new Parse.Object('Foobar');
36893758
const BarBaz = new Parse.Object('Barbaz');

src/RestQuery.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, cl
4444
}
4545

4646
this.doCount = false;
47+
this.includeAll = false;
4748

4849
// The format for this.include is not the same as the format for the
4950
// include option - it's the paths we should include, in order,
@@ -86,6 +87,9 @@ function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, cl
8687
case 'count':
8788
this.doCount = true;
8889
break;
90+
case 'includeAll':
91+
this.includeAll = true;
92+
break;
8993
case 'distinct':
9094
case 'pipeline':
9195
case 'skip':
@@ -149,6 +153,8 @@ function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, cl
149153
RestQuery.prototype.execute = function(executeOptions) {
150154
return Promise.resolve().then(() => {
151155
return this.buildRestWhere();
156+
}).then(() => {
157+
return this.handleIncludeAll();
152158
}).then(() => {
153159
return this.runFind(executeOptions);
154160
}).then(() => {
@@ -552,6 +558,29 @@ RestQuery.prototype.runCount = function() {
552558
});
553559
};
554560

561+
RestQuery.prototype.handleIncludeAll = function() {
562+
if (!this.includeAll) {
563+
return;
564+
}
565+
return this.config.database.loadSchema()
566+
.then(schemaController => schemaController.getOneSchema(this.className))
567+
.then(schema => {
568+
const includeFields = [];
569+
const keyFields = [];
570+
for (const field in schema.fields) {
571+
if (schema.fields[field].type && schema.fields[field].type === 'Pointer') {
572+
includeFields.push([field]);
573+
keyFields.push(field);
574+
}
575+
}
576+
// Add fields to include, keys, remove dups
577+
this.include = [...new Set([...this.include, ...includeFields])];
578+
if (this.keys) {
579+
this.keys = [...new Set([...this.keys, ...keyFields])];
580+
}
581+
});
582+
};
583+
555584
// Augments this.response with data at the paths provided in this.include.
556585
RestQuery.prototype.handleInclude = function() {
557586
if (this.include.length == 0) {

src/Routers/ClassesRouter.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class ClassesRouter extends PromiseRouter {
100100

101101
static optionsFromBody(body) {
102102
const allowConstraints = ['skip', 'limit', 'order', 'count', 'keys',
103-
'include', 'redirectClassNameForKey', 'where'];
103+
'include', 'includeAll', 'redirectClassNameForKey', 'where'];
104104

105105
for (const key of Object.keys(body)) {
106106
if (allowConstraints.indexOf(key) === -1) {
@@ -128,6 +128,9 @@ export class ClassesRouter extends PromiseRouter {
128128
if (body.include) {
129129
options.include = String(body.include);
130130
}
131+
if (body.includeAll) {
132+
options.includeAll = true;
133+
}
131134
return options;
132135
}
133136

0 commit comments

Comments
 (0)