Skip to content

Commit

Permalink
Fix mapReduce reduce function return type, mapReduce parameter valida…
Browse files Browse the repository at this point in the history
…tion and add new tests
  • Loading branch information
RagibHasin committed May 28, 2017
1 parent db0d44e commit c79b2a4
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib/MapReduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export interface MapFunction<TDocument> {
* @param {Value[]} values The values to reduce
*/
export interface ReduceFunction<Key, Value> {
(key: Key, values: Value[]): Value
(key: Key, values: Value[]): Value | Value[] | any
}

/**
Expand Down
34 changes: 19 additions & 15 deletions lib/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export class Model<TDocument extends { _id?: any }, TInstance> {
conditions = this._helpers.convertToDB(conditions);

let cursor = this.collection.find(conditions);

if(fields)
cursor = cursor.project(fields);

Expand Down Expand Up @@ -383,18 +383,18 @@ export class Model<TDocument extends { _id?: any }, TInstance> {
if (cachedDocument) return cachedDocument;
return new Bluebird<TDocument|null>((resolve, reject) => {
let cursor = this.collection.find(conditions);

if(options!.sort)
cursor = cursor.sort(options!.sort!);

if(typeof options!.skip === "number")
cursor = cursor.skip(options!.skip!);

cursor = cursor.limit(1);

if(options!.fields)
cursor = cursor.project(options!.fields!);

return cursor.next((err, result) => {
if (err) return reject(err);
return resolve(result);
Expand Down Expand Up @@ -573,7 +573,7 @@ export class Model<TDocument extends { _id?: any }, TInstance> {

if (opts.multi)
return this.collection.updateMany(conditions, changes, opts, callback);

return this.collection.updateOne(conditions, changes, opts, callback)
})
}).nodeify(callback);
Expand Down Expand Up @@ -671,7 +671,7 @@ export class Model<TDocument extends { _id?: any }, TInstance> {
if (err) return reject(err);
return resolve(response.result.n);
});

this.collection.deleteMany(conditions, options!, (err, response) => {
if (err) return reject(err);
return resolve(response.result.n);
Expand Down Expand Up @@ -706,11 +706,12 @@ export class Model<TDocument extends { _id?: any }, TInstance> {
* @param options Options used to configure how MongoDB runs the mapReduce operation on your collection.
* @return A promise which completes when the mapReduce operation has written its results to the provided collection.
*/
mapReduce<Key, Value>(instanceType: InstanceImplementation<MapReducedDocument<Key, Value>, any> & { mapReduceOptions: MapReduceFunctions<TDocument, Key, Value> },
mapReduce<Key, Value>(instanceType: InstanceImplementation<MapReducedDocument<Key, Value>, any>,
options: MapReduceOptions): Bluebird<void>;
mapReduce<Key, Value>(functions: (InstanceImplementation<MapReducedDocument<Key, Value>, any> & { mapReduceOptions: MapReduceFunctions<TDocument, Key, Value> }) |
mapReduce<Key, Value>(functions: InstanceImplementation<MapReducedDocument<Key, Value>, any> |
MapReduceFunctions<TDocument, Key, Value>, options: MapReduceOptions) {
type fn = MapReduceFunctions<TDocument, Key, Value>;
type instance = InstanceImplementation<MapReducedDocument<Key, Value>, any>

if ((<fn>functions).map) {
return new Bluebird<MapReducedDocument<Key, Value>[]>((resolve, reject) => {
Expand All @@ -725,18 +726,21 @@ export class Model<TDocument extends { _id?: any }, TInstance> {
})
}
else {
let instanceType = <InstanceImplementation<MapReducedDocument<Key, Value>, any> & { mapReduceOptions: MapReduceFunctions<TDocument, Key, Value> }>functions;
let instanceType = <instance>functions;
return new Bluebird<void>((resolve, reject) => {
if (options.out && options.out == "inline")
return reject(new Error("Expected a non-inline mapReduce output mode for this method signature"));
let opts = <MongoDB.MapReduceOptions>options;
let out : {[op: string]: string} = {};
out[(<string>options.out)] = instanceType.collection;
opts.out = out;
this.collection.mapReduce(instanceType.mapReduceOptions.map, instanceType.mapReduceOptions.reduce, opts, (err, data) => {
if (err) return reject(err);
return resolve();
});
if (instanceType.mapReduceOptions) {
this.collection.mapReduce(instanceType.mapReduceOptions.map, instanceType.mapReduceOptions.reduce, opts, (err, data) => {
if (err) return reject(err);
return resolve();
});
}
else return reject("mapReduceOptions not provided");
})
}
}
Expand Down
32 changes: 32 additions & 0 deletions test/MapReduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ class MapReducedInstance extends Iridium.Instance<Iridium.MapReducedDocument<str
value: number;
}

@Iridium.MapReduce(function (this: TestDocument) {
emit(this.cust_id, this.amount);
}, function (key: string, values: number[]) {
return values.reduce((sum, val) => sum + val, 0);
})
class DecoratedMapReducedInstance extends Iridium.Instance<Iridium.MapReducedDocument<string, number>, MapReducedInstance>{
static collection = "decoratedMapReduced";
_id: string;
value: number;
}

class NotMapReducedInstance extends Iridium.Instance<Iridium.MapReducedDocument<string, number>, MapReducedInstance>{
static collection = "notMapReduced";
_id: string;
value: number;
}

describe("Model", () => {
let core = new Iridium.Core({ database: "test" });

Expand All @@ -61,6 +78,14 @@ describe("Model", () => {
]));
});

it("should correctly map and reduce with model and decorator", () => {
let reducedModel = new Iridium.Model<Iridium.MapReducedDocument<string, number>, DecoratedMapReducedInstance>(core, DecoratedMapReducedInstance);
let t = reducedModel.remove().then(() => model.mapReduce(DecoratedMapReducedInstance, {
out: "replace", query: { status: "A" }
}).then(() => reducedModel.find().toArray()));
return chai.expect(t).to.eventually.exist.and.have.length(2);
});

it("should correctly map and reduce with model", () => {
let reducedModel = new Iridium.Model<Iridium.MapReducedDocument<string, number>, MapReducedInstance>(core, MapReducedInstance);
let t = reducedModel.remove().then(() => model.mapReduce(MapReducedInstance, {
Expand Down Expand Up @@ -97,5 +122,12 @@ describe("Model", () => {
});
return chai.expect(t).to.eventually.be.rejected;
});

it("should reject with no mapReduce info in Instance type", () => {
let t = model.mapReduce(NotMapReducedInstance, {
out: "replace", query: { status: "A" }
});
return chai.expect(t).to.eventually.be.rejected;
});
});
});

0 comments on commit c79b2a4

Please sign in to comment.