Skip to content

Commit 37dbf08

Browse files
authored
fix(aggregations): output stage destination name COMPASS-6407 (#3944)
1 parent fc84b2c commit 37dbf08

File tree

2 files changed

+142
-62
lines changed

2 files changed

+142
-62
lines changed

packages/compass-aggregations/src/utils/stage.js

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,60 @@ export function getStageOperator(stage) {
103103
}
104104
const stageOperator = getStageOperator(stage);
105105
const stageValue = stage[stageOperator];
106-
const { database } = toNS(namespace);
106+
107+
if (!stageValue) {
108+
return null;
109+
}
110+
107111
if (stageOperator === '$merge') {
108-
const ns = typeof stageValue === 'string' ? stageValue : stageValue.into;
109-
if (ns.atlas) {
110-
// TODO: Not handled currently and we need some time to figure out how to
111-
// handle it so just skipping for now
112-
return null;
113-
}
114-
return typeof ns === 'object' ? `${ns.db}.${ns.coll}` : `${database}.${ns}`;
112+
return getDestinationNamespaceFromMergeStage(namespace, stageValue);
115113
}
116114
if (stageOperator === '$out') {
117-
if (stageValue.s3 || stageValue.atlas) {
118-
// TODO: Not handled currently and we need some time to figure out how to
119-
// handle it so just skipping for now
120-
return null;
121-
}
122-
const ns = stageValue;
123-
return typeof ns === 'object' ? `${ns.db}.${ns.coll}` : `${database}.${ns}`;
115+
return getDestinationNamespaceFromOutStage(namespace, stageValue);
116+
}
117+
return null;
118+
}
119+
120+
function getDestinationNamespaceFromMergeStage(namespace, stageValue) {
121+
const { database } = toNS(namespace);
122+
123+
const ns = typeof stageValue === 'string' ? stageValue : stageValue.into;
124+
125+
if (!ns) {
126+
return null;
127+
}
128+
129+
if (typeof ns === 'string') {
130+
return `${database}.${ns}`;
131+
}
132+
133+
if (ns.atlas) {
134+
// TODO: Not handled currently and we need some time to figure out how to
135+
// handle it so just skipping for now
136+
return null;
137+
}
138+
139+
if (ns.db && ns.coll) {
140+
return `${ns.db}.${ns.coll}`;
141+
}
142+
return null;
143+
}
144+
145+
function getDestinationNamespaceFromOutStage(namespace, stageValue) {
146+
const { database } = toNS(namespace);
147+
148+
if (typeof stageValue === 'string') {
149+
return `${database}.${stageValue}`;
150+
}
151+
152+
if (stageValue.s3 || stageValue.atlas) {
153+
// TODO: Not handled currently and we need some time to figure out how to
154+
// handle it so just skipping for now
155+
return null;
156+
}
157+
158+
if (stageValue.db && stageValue.coll) {
159+
return `${stageValue.db}.${stageValue.coll}`;
124160
}
125161
return null;
126162
}

packages/compass-aggregations/src/utils/stage.spec.js

Lines changed: 91 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -151,60 +151,104 @@ describe('utils', function() {
151151
});
152152

153153
context('getDestinationNamespaceFromStage', function() {
154+
const invalidNamespaces = [
155+
null,
156+
undefined,
157+
'',
158+
{},
159+
{db: '', coll: null},
160+
{db: '', coll: undefined},
161+
{db: '', coll: ''},
162+
{db: '', coll: 'users'},
163+
{db: 'airbnb', coll: ''},
164+
{db: '', coll: ''},
165+
];
154166
it('returns null when stage is not defined', function() {
155167
expect(getDestinationNamespaceFromStage('airbnb.users')).to.equal(null);
156168
});
157-
it('handles $out stage with scaler value', function() {
158-
expect(getDestinationNamespaceFromStage('airbnb.users', {
159-
$out: 'users_out'
160-
})).to.equal('airbnb.users_out');
161-
});
162-
it('handles $out stage with db and coll in object', function() {
163-
expect(getDestinationNamespaceFromStage('airbnb.users', {
164-
$out: {
165-
db: 'another',
166-
coll: 'users_out'
167-
}
168-
})).to.equal('another.users_out');
169-
});
170-
it('does not handle $out s3 yet', function() {
171-
expect(getDestinationNamespaceFromStage('airbnb.users', {
172-
$out: {
173-
s3: {}
174-
}
175-
})).to.equal(null);
176-
});
177-
it('does not handle $out atlas yet', function() {
178-
expect(getDestinationNamespaceFromStage('airbnb.users', {
179-
$out: {
180-
atlas: {}
181-
}
182-
})).to.equal(null);
183-
});
184-
185-
it('handles $merge stage with scaler value', function() {
186-
expect(getDestinationNamespaceFromStage('airbnb.users', {
187-
$merge: 'users_merge'
188-
})).to.equal('airbnb.users_merge');
189-
});
190-
it('handles $merge stage with db and coll in object', function() {
191-
expect(getDestinationNamespaceFromStage('airbnb.users', {
192-
$merge: {
193-
into: {
169+
context('$out stage', function() {
170+
it('returns null for invalid stage value', function () {
171+
const invalidStageValues = [
172+
null,
173+
undefined,
174+
'',
175+
{},
176+
...invalidNamespaces
177+
];
178+
invalidStageValues.forEach((invalidStageValue) => {
179+
expect(getDestinationNamespaceFromStage('airbnb.users', {
180+
$merge: invalidStageValue
181+
})).to.be.null;
182+
});
183+
});
184+
it('handles $out stage with scaler value', function() {
185+
expect(getDestinationNamespaceFromStage('airbnb.users', {
186+
$out: 'users_out'
187+
})).to.equal('airbnb.users_out');
188+
});
189+
it('handles $out stage with db and coll in object', function() {
190+
expect(getDestinationNamespaceFromStage('airbnb.users', {
191+
$out: {
194192
db: 'another',
195-
coll: 'users_merge'
193+
coll: 'users_out'
196194
}
197-
}
198-
})).to.equal('another.users_merge');
199-
});
200-
it('does not handle $merge atlas yet', function() {
201-
expect(getDestinationNamespaceFromStage('airbnb.users', {
202-
$merge: {
203-
into: {
195+
})).to.equal('another.users_out');
196+
});
197+
it('does not handle $out s3 yet', function() {
198+
expect(getDestinationNamespaceFromStage('airbnb.users', {
199+
$out: {
200+
s3: {}
201+
}
202+
})).to.equal(null);
203+
});
204+
it('does not handle $out atlas yet', function() {
205+
expect(getDestinationNamespaceFromStage('airbnb.users', {
206+
$out: {
204207
atlas: {}
205208
}
206-
}
207-
})).to.equal(null);
209+
})).to.equal(null);
210+
});
211+
});
212+
213+
context('$merge stage', function() {
214+
it('returns null for invalid stage value', function () {
215+
const invalidStageValues = [
216+
null,
217+
undefined,
218+
'',
219+
{},
220+
...invalidNamespaces.map((ns) => ({into: ns}))
221+
];
222+
invalidStageValues.forEach((invalidStageValue) => {
223+
expect(getDestinationNamespaceFromStage('airbnb.users', {
224+
$merge: invalidStageValue
225+
})).to.be.null;
226+
});
227+
});
228+
it('handles $merge stage with scaler value', function() {
229+
expect(getDestinationNamespaceFromStage('airbnb.users', {
230+
$merge: 'users_merge'
231+
})).to.equal('airbnb.users_merge');
232+
});
233+
it('handles $merge stage with db and coll in object', function() {
234+
expect(getDestinationNamespaceFromStage('airbnb.users', {
235+
$merge: {
236+
into: {
237+
db: 'another',
238+
coll: 'users_merge'
239+
}
240+
}
241+
})).to.equal('another.users_merge');
242+
});
243+
it('does not handle $merge atlas yet', function() {
244+
expect(getDestinationNamespaceFromStage('airbnb.users', {
245+
$merge: {
246+
into: {
247+
atlas: {}
248+
}
249+
}
250+
})).to.equal(null);
251+
});
208252
});
209253
});
210254
});

0 commit comments

Comments
 (0)