@zakodium/lucid-mongo
Advanced tools
Comparing version 4.0.0-1 to 4.0.0-2
@@ -5,3 +5,3 @@ { | ||
"main": "index.js", | ||
"version": "4.0.0-1", | ||
"version": "4.0.0-2", | ||
"scripts": { | ||
@@ -8,0 +8,0 @@ "pretest": "npm run test:cleanup && npm run lint", |
@@ -1,2 +0,2 @@ | ||
'use strict' | ||
'use strict'; | ||
@@ -10,11 +10,11 @@ /** | ||
* file that was distributed with this source code. | ||
*/ | ||
*/ | ||
const { MongoClient } = require('mongodb') | ||
const mquery = require('mquery') | ||
const CE = require('../Exceptions') | ||
const util = require('../../lib/util') | ||
const _ = require('lodash') | ||
const mongoUriBuilder = require('mongo-uri-builder') | ||
const mongoUrl = require('mongodb-url') | ||
const { MongoClient } = require('mongodb'); | ||
const mquery = require('mquery'); | ||
const CE = require('../Exceptions'); | ||
const util = require('../../lib/util'); | ||
const _ = require('lodash'); | ||
const mongoUriBuilder = require('mongo-uri-builder'); | ||
const mongoUrl = require('mongodb-url'); | ||
@@ -24,14 +24,14 @@ mquery.Promise = global.Promise; | ||
const proxyHandler = { | ||
get (target, name) { | ||
if (typeof (name) === 'symbol' || name === 'inspect') { | ||
return target[name] | ||
get(target, name) { | ||
if (typeof name === 'symbol' || name === 'inspect') { | ||
return target[name]; | ||
} | ||
if (typeof (target[name]) !== 'undefined') { | ||
return target[name] | ||
if (typeof target[name] !== 'undefined') { | ||
return target[name]; | ||
} | ||
const queryBuilder = target.query() | ||
if (typeof (queryBuilder[name]) !== 'function') { | ||
throw new Error(`Database.${name} is not a function`) | ||
const queryBuilder = target.query(); | ||
if (typeof queryBuilder[name] !== 'function') { | ||
throw new Error(`Database.${name} is not a function`); | ||
} | ||
@@ -44,53 +44,57 @@ | ||
if (target._globalTrx) { | ||
queryBuilder.transacting(target._globalTrx) | ||
queryBuilder.transacting(target._globalTrx); | ||
} | ||
return queryBuilder[name].bind(queryBuilder) | ||
return queryBuilder[name].bind(queryBuilder); | ||
} | ||
} | ||
}; | ||
class SchemaBuilder { | ||
constructor (collection) { | ||
this.collection = collection | ||
this.createIndexes = [] | ||
this.dropIndexes = [] | ||
constructor(collection) { | ||
this.collection = collection; | ||
this.createIndexes = []; | ||
this.dropIndexes = []; | ||
this.increments = () => this | ||
this.timestamps = () => this | ||
this.softDeletes = () => this | ||
this.string = () => this | ||
this.timestamp = () => this | ||
this.boolean = () => this | ||
this.integer = () => this | ||
this.double = () => this | ||
this.nullable = () => this | ||
this.defaultTo = () => this | ||
this.unsigned = () => this | ||
this.references = () => this | ||
this.increments = () => this; | ||
this.timestamps = () => this; | ||
this.softDeletes = () => this; | ||
this.string = () => this; | ||
this.timestamp = () => this; | ||
this.boolean = () => this; | ||
this.integer = () => this; | ||
this.double = () => this; | ||
this.nullable = () => this; | ||
this.defaultTo = () => this; | ||
this.unsigned = () => this; | ||
this.references = () => this; | ||
} | ||
index (name, keys, options) { | ||
index(name, keys, options) { | ||
if (!name) { | ||
throw new CE.InvalidArgumentException(`param name is required to create index`) | ||
throw new CE.InvalidArgumentException( | ||
`param name is required to create index` | ||
); | ||
} | ||
if (!keys || !_.size(keys)) { | ||
throw new CE.InvalidArgumentException(`param keys is required to create index`) | ||
throw new CE.InvalidArgumentException( | ||
`param keys is required to create index` | ||
); | ||
} | ||
options = options || {} | ||
options['name'] = name | ||
this.createIndexes.push({ keys, options }) | ||
options = options || {}; | ||
options['name'] = name; | ||
this.createIndexes.push({ keys, options }); | ||
} | ||
dropIndex (name) { | ||
this.dropIndexes.push(name) | ||
dropIndex(name) { | ||
this.dropIndexes.push(name); | ||
} | ||
async build () { | ||
async build() { | ||
for (var i in this.createIndexes) { | ||
var createIndex = this.createIndexes[i] | ||
await this.collection.createIndex(createIndex.keys, createIndex.options) | ||
var createIndex = this.createIndexes[i]; | ||
await this.collection.createIndex(createIndex.keys, createIndex.options); | ||
} | ||
for (var j in this.dropIndexes) { | ||
var dropIndex = this.dropIndexes[j] | ||
await this.collection.dropIndex(dropIndex) | ||
var dropIndex = this.dropIndexes[j]; | ||
await this.collection.dropIndex(dropIndex); | ||
} | ||
@@ -112,47 +116,56 @@ } | ||
class Database { | ||
constructor (config) { | ||
constructor(config) { | ||
if (config.client !== 'mongodb') { | ||
throw new CE.RuntimeException('invalid connection type') | ||
throw new CE.RuntimeException('invalid connection type'); | ||
} | ||
if (config.connectionString) { | ||
this.connectionString = config.connectionString | ||
const parsedUri = mongoUrl(this.connectionString) | ||
this.databaseName = parsedUri.dbName || config.connection.database | ||
this.connectionString = config.connectionString; | ||
const parsedUri = mongoUrl(this.connectionString); | ||
this.databaseName = parsedUri.dbName || config.connection.database; | ||
} else { | ||
this.connectionString = mongoUriBuilder(config.connection) | ||
this.databaseName = config.connection.database | ||
this.connectionString = mongoUriBuilder(config.connection); | ||
this.databaseName = config.connection.database; | ||
} | ||
this.connectionOptions = _.assign({ | ||
useNewUrlParser: true | ||
}, config.connectionOptions || {}) | ||
this.connectionOptions = _.assign( | ||
{ | ||
useNewUrlParser: true | ||
}, | ||
config.connectionOptions || {} | ||
); | ||
this.connection = null | ||
this.db = null | ||
this._globalTrx = null | ||
this.query() | ||
return new Proxy(this, proxyHandler) | ||
this.connection = null; | ||
this.db = null; | ||
this._globalTrx = null; | ||
this.query(); | ||
return new Proxy(this, proxyHandler); | ||
} | ||
async connect (collectionName) { | ||
async connect(collectionName) { | ||
if (!this.db) { | ||
this.connection = await MongoClient.connect(this.connectionString, this.connectionOptions) | ||
this.db = this.connection.db(this.databaseName) | ||
this.connection = await MongoClient.connect( | ||
this.connectionString, | ||
this.connectionOptions | ||
); | ||
this.db = this.connection.db(this.databaseName); | ||
} | ||
return Promise.resolve(this.db) | ||
return Promise.resolve(this.db); | ||
} | ||
async getCollection (collectionName) { | ||
async getCollection(collectionName) { | ||
if (!this.db) { | ||
this.connection = await MongoClient.connect(this.connectionString, this.connectionOptions) | ||
this.db = this.connection.db(this.databaseName) | ||
this.connection = await MongoClient.connect( | ||
this.connectionString, | ||
this.connectionOptions | ||
); | ||
this.db = this.connection.db(this.databaseName); | ||
} | ||
return Promise.resolve(this.db.collection(collectionName)) | ||
return Promise.resolve(this.db.collection(collectionName)); | ||
} | ||
collection (collectionName) { | ||
this.collectionName = collectionName | ||
this.query() | ||
return this | ||
collection(collectionName) { | ||
this.collectionName = collectionName; | ||
this.query(); | ||
return this; | ||
} | ||
@@ -186,33 +199,43 @@ | ||
*/ | ||
get schema () { | ||
get schema() { | ||
return { | ||
collection: async (collectionName, callback) => { | ||
// debug('create collection', { collectionName }) | ||
const db = await this.connect() | ||
const collection = await db.collection(collectionName) | ||
const schemaBuilder = new SchemaBuilder(collection) | ||
callback(schemaBuilder) | ||
return schemaBuilder.build() | ||
const db = await this.connect(); | ||
const collection = await db.collection(collectionName); | ||
const schemaBuilder = new SchemaBuilder(collection); | ||
callback(schemaBuilder); | ||
return schemaBuilder.build(); | ||
}, | ||
createCollection: async (collectionName, callback) => { | ||
// debug('create collection', {collectionName}) | ||
const db = await this.connect() | ||
const collections = await db.listCollections().toArray() | ||
if (_.find(collections, collection => collection.name === collectionName)) { | ||
throw new Error('already exists') | ||
const db = await this.connect(); | ||
const collections = await db.listCollections().toArray(); | ||
if ( | ||
_.find( | ||
collections, | ||
(collection) => collection.name === collectionName | ||
) | ||
) { | ||
throw new Error('already exists'); | ||
} | ||
const collection = await db.createCollection(collectionName) | ||
const schemaBuilder = new SchemaBuilder(collection) | ||
callback(schemaBuilder) | ||
return schemaBuilder.build() | ||
const collection = await db.createCollection(collectionName); | ||
const schemaBuilder = new SchemaBuilder(collection); | ||
callback(schemaBuilder); | ||
return schemaBuilder.build(); | ||
}, | ||
createCollectionIfNotExists: async (collectionName, callback) => { | ||
// debug('create collection if not exists', { collectionName }) | ||
const db = await this.connect() | ||
const collections = await db.listCollections().toArray() | ||
if (!_.find(collections, collection => collection.name === collectionName)) { | ||
const collection = await db.createCollection(collectionName) | ||
const schemaBuilder = new SchemaBuilder(collection) | ||
callback(schemaBuilder) | ||
return schemaBuilder.build() | ||
const db = await this.connect(); | ||
const collections = await db.listCollections().toArray(); | ||
if ( | ||
!_.find( | ||
collections, | ||
(collection) => collection.name === collectionName | ||
) | ||
) { | ||
const collection = await db.createCollection(collectionName); | ||
const schemaBuilder = new SchemaBuilder(collection); | ||
callback(schemaBuilder); | ||
return schemaBuilder.build(); | ||
} | ||
@@ -222,11 +245,16 @@ }, | ||
// debug('drop collection', { collectionName }) | ||
const db = await this.connect() | ||
return db.dropCollection(collectionName) | ||
const db = await this.connect(); | ||
return db.dropCollection(collectionName); | ||
}, | ||
dropCollectionIfExists: async (collectionName) => { | ||
// debug('drop collection if not exists', { collectionName }) | ||
const db = await this.connect() | ||
const collections = await db.listCollections().toArray() | ||
if (_.find(collections, collection => collection.name === collectionName)) { | ||
return db.dropCollection(collectionName) | ||
const db = await this.connect(); | ||
const collections = await db.listCollections().toArray(); | ||
if ( | ||
_.find( | ||
collections, | ||
(collection) => collection.name === collectionName | ||
) | ||
) { | ||
return db.dropCollection(collectionName); | ||
} | ||
@@ -236,11 +264,14 @@ }, | ||
// debug('rename collection', { collectionName, target }) | ||
const db = await this.connect() | ||
return db.collection(collectionName).rename(target) | ||
const db = await this.connect(); | ||
return db.collection(collectionName).rename(target); | ||
}, | ||
hasCollection: async (collectionName) => { | ||
const db = await this.connect() | ||
const collections = await db.listCollections().toArray() | ||
return !!_.find(collections, collection => collection.name === collectionName) | ||
const db = await this.connect(); | ||
const collections = await db.listCollections().toArray(); | ||
return !!_.find( | ||
collections, | ||
(collection) => collection.name === collectionName | ||
); | ||
} | ||
} | ||
}; | ||
} | ||
@@ -255,5 +286,5 @@ | ||
*/ | ||
sort (...arg) { | ||
this.queryBuilder.sort(...arg) | ||
return this | ||
sort(...arg) { | ||
this.queryBuilder.sort(...arg); | ||
return this; | ||
} | ||
@@ -268,5 +299,5 @@ | ||
*/ | ||
limit (...arg) { | ||
this.queryBuilder.limit(...arg) | ||
return this | ||
limit(...arg) { | ||
this.queryBuilder.limit(...arg); | ||
return this; | ||
} | ||
@@ -281,5 +312,5 @@ | ||
*/ | ||
skip (...arg) { | ||
this.queryBuilder.skip(...arg) | ||
return this | ||
skip(...arg) { | ||
this.queryBuilder.skip(...arg); | ||
return this; | ||
} | ||
@@ -294,5 +325,5 @@ | ||
*/ | ||
select (...arg) { | ||
this.queryBuilder.select(...arg) | ||
return this | ||
select(...arg) { | ||
this.queryBuilder.select(...arg); | ||
return this; | ||
} | ||
@@ -307,6 +338,7 @@ | ||
*/ | ||
query () { | ||
this.queryBuilder = mquery() | ||
this.replaceMethods() | ||
return this.queryBuilder | ||
query() { | ||
this.queryBuilder = mquery(); | ||
this.queryBuilder.$useProjection = true; | ||
this.replaceMethods(); | ||
return this.queryBuilder; | ||
} | ||
@@ -321,7 +353,7 @@ | ||
*/ | ||
get fn () { | ||
get fn() { | ||
return { | ||
remove: (path) => console.log('remove', path), | ||
now: () => new Date() | ||
} | ||
}; | ||
} | ||
@@ -335,4 +367,4 @@ | ||
*/ | ||
get conditions () { | ||
return this.queryBuilder._conditions | ||
get conditions() { | ||
return this.queryBuilder._conditions; | ||
} | ||
@@ -345,4 +377,4 @@ | ||
*/ | ||
clone () { | ||
return _.cloneDeep(this.queryBuilder) | ||
clone() { | ||
return _.cloneDeep(this.queryBuilder); | ||
} | ||
@@ -358,4 +390,4 @@ | ||
*/ | ||
close () { | ||
return this.connection.close() | ||
close() { | ||
return this.connection.close(); | ||
} | ||
@@ -370,6 +402,6 @@ | ||
*/ | ||
async find () { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
return this.queryBuilder.collection(collection).find() | ||
async find() { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
return this.queryBuilder.collection(collection).find(); | ||
} | ||
@@ -384,6 +416,6 @@ | ||
*/ | ||
async findOne () { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
return this.queryBuilder.collection(collection).findOne() | ||
async findOne() { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
return this.queryBuilder.collection(collection).findOne(); | ||
} | ||
@@ -398,4 +430,4 @@ | ||
*/ | ||
async first () { | ||
return this.findOne() | ||
async first() { | ||
return this.findOne(); | ||
} | ||
@@ -410,6 +442,6 @@ | ||
*/ | ||
async pluck (field) { | ||
this.queryBuilder.select(field) | ||
const result = await this.find() | ||
return _.map(result, field) | ||
async pluck(field) { | ||
this.queryBuilder.select(field); | ||
const result = await this.find(); | ||
return _.map(result, field); | ||
} | ||
@@ -424,6 +456,6 @@ | ||
*/ | ||
async update () { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
return this.queryBuilder.collection(collection).update(...arguments) | ||
async update() { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
return this.queryBuilder.collection(collection).update(...arguments); | ||
} | ||
@@ -438,6 +470,6 @@ | ||
*/ | ||
async delete () { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
return this.queryBuilder.collection(collection).remove(...arguments) | ||
async delete() { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
return this.queryBuilder.collection(collection).remove(...arguments); | ||
} | ||
@@ -452,10 +484,14 @@ | ||
*/ | ||
async paginate (page, limit) { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
const countByQuery = await this.aggregate('count') | ||
const rows = await this.queryBuilder.collection(collection).limit(limit).skip((page || 1) * limit).find() | ||
const result = util.makePaginateMeta(countByQuery || 0, page, limit) | ||
result.data = rows | ||
return result | ||
async paginate(page, limit) { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
const countByQuery = await this.aggregate('count'); | ||
const rows = await this.queryBuilder | ||
.collection(collection) | ||
.limit(limit) | ||
.skip((page || 1) * limit) | ||
.find(); | ||
const result = util.makePaginateMeta(countByQuery || 0, page, limit); | ||
result.data = rows; | ||
return result; | ||
} | ||
@@ -470,6 +506,6 @@ | ||
*/ | ||
async insert (row) { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
return collection.insert(row) | ||
async insert(row) { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
return collection.insert(row); | ||
} | ||
@@ -484,4 +520,4 @@ | ||
*/ | ||
count (...args) { | ||
return this.aggregate('count', null, ...args) | ||
count(...args) { | ||
return this.aggregate('count', null, ...args); | ||
} | ||
@@ -496,4 +532,4 @@ | ||
*/ | ||
sum (...args) { | ||
return this.aggregate('sum', ...args) | ||
sum(...args) { | ||
return this.aggregate('sum', ...args); | ||
} | ||
@@ -508,4 +544,4 @@ | ||
*/ | ||
avg (...args) { | ||
return this.aggregate('avg', ...args) | ||
avg(...args) { | ||
return this.aggregate('avg', ...args); | ||
} | ||
@@ -520,4 +556,4 @@ | ||
*/ | ||
max (...args) { | ||
return this.aggregate('max', ...args) | ||
max(...args) { | ||
return this.aggregate('max', ...args); | ||
} | ||
@@ -532,4 +568,4 @@ | ||
*/ | ||
min (...args) { | ||
return this.aggregate('min', ...args) | ||
min(...args) { | ||
return this.aggregate('min', ...args); | ||
} | ||
@@ -544,29 +580,31 @@ | ||
*/ | ||
async aggregate (aggregator, key, groupBy) { | ||
const $match = this.conditions | ||
const $group = { _id: '$' + groupBy } | ||
async aggregate(aggregator, key, groupBy) { | ||
const $match = this.conditions; | ||
const $group = { _id: '$' + groupBy }; | ||
switch (aggregator) { | ||
case 'count': | ||
$group[aggregator] = { $sum: 1 } | ||
break | ||
$group[aggregator] = { $sum: 1 }; | ||
break; | ||
case 'max': | ||
$group[aggregator] = { $max: '$' + key } | ||
break | ||
$group[aggregator] = { $max: '$' + key }; | ||
break; | ||
case 'min': | ||
$group[aggregator] = { $min: '$' + key } | ||
break | ||
$group[aggregator] = { $min: '$' + key }; | ||
break; | ||
case 'sum': | ||
$group[aggregator] = { $sum: '$' + key } | ||
break | ||
$group[aggregator] = { $sum: '$' + key }; | ||
break; | ||
case 'avg': | ||
$group[aggregator] = { $avg: '$' + key } | ||
break | ||
$group[aggregator] = { $avg: '$' + key }; | ||
break; | ||
default: | ||
break | ||
break; | ||
} | ||
// debug('count', this.collectionName, $match, $group) | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
const result = await collection.aggregate([{ $match }, { $group }]).toArray() | ||
return groupBy ? result : !_.isEmpty(result) ? result[0][aggregator] : null | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
const result = await collection | ||
.aggregate([{ $match }, { $group }]) | ||
.toArray(); | ||
return groupBy ? result : !_.isEmpty(result) ? result[0][aggregator] : null; | ||
} | ||
@@ -581,6 +619,6 @@ | ||
*/ | ||
async distinct () { | ||
const connection = await this.connect() | ||
const collection = connection.collection(this.collectionName) | ||
return this.queryBuilder.collection(collection).distinct(...arguments) | ||
async distinct() { | ||
const connection = await this.connect(); | ||
const collection = connection.collection(this.collectionName); | ||
return this.queryBuilder.collection(collection).distinct(...arguments); | ||
} | ||
@@ -595,3 +633,3 @@ | ||
*/ | ||
static get conditionMethods () { | ||
static get conditionMethods() { | ||
return [ | ||
@@ -615,3 +653,3 @@ 'eq', | ||
'intersects' | ||
] | ||
]; | ||
} | ||
@@ -624,9 +662,9 @@ | ||
*/ | ||
replaceMethods () { | ||
replaceMethods() { | ||
for (let name of this.constructor.conditionMethods) { | ||
let originMethod = this.queryBuilder[name] | ||
let originMethod = this.queryBuilder[name]; | ||
this.queryBuilder[name] = (param) => { | ||
originMethod.apply(this.queryBuilder, [param]) | ||
return this | ||
} | ||
originMethod.apply(this.queryBuilder, [param]); | ||
return this; | ||
}; | ||
} | ||
@@ -641,35 +679,37 @@ } | ||
*/ | ||
where () { | ||
where() { | ||
if (arguments.length === 3) { | ||
switch (arguments[1]) { | ||
case '=': | ||
this.queryBuilder.where(arguments[0]).eq(arguments[2]) | ||
break | ||
this.queryBuilder.where(arguments[0]).eq(arguments[2]); | ||
break; | ||
case '>': | ||
this.queryBuilder.where(arguments[0]).gt(arguments[2]) | ||
break | ||
this.queryBuilder.where(arguments[0]).gt(arguments[2]); | ||
break; | ||
case '>=': | ||
this.queryBuilder.where(arguments[0]).gte(arguments[2]) | ||
break | ||
this.queryBuilder.where(arguments[0]).gte(arguments[2]); | ||
break; | ||
case '<': | ||
this.queryBuilder.where(arguments[0]).lt(arguments[2]) | ||
break | ||
this.queryBuilder.where(arguments[0]).lt(arguments[2]); | ||
break; | ||
case '<=': | ||
this.queryBuilder.where(arguments[0]).lte(arguments[2]) | ||
break | ||
this.queryBuilder.where(arguments[0]).lte(arguments[2]); | ||
break; | ||
case '<>': | ||
this.queryBuilder.where(arguments[0]).ne(arguments[2]) | ||
break | ||
this.queryBuilder.where(arguments[0]).ne(arguments[2]); | ||
break; | ||
default: | ||
throw new CE.InvalidArgumentException(`Method "$${arguments[1]}" is not support by query builder`) | ||
throw new CE.InvalidArgumentException( | ||
`Method "$${arguments[1]}" is not support by query builder` | ||
); | ||
} | ||
} else if (arguments.length === 2 || _.isPlainObject(arguments[0])) { | ||
this.queryBuilder.where(...arguments) | ||
this.queryBuilder.where(...arguments); | ||
} else { | ||
return this.queryBuilder.where(...arguments) | ||
return this.queryBuilder.where(...arguments); | ||
} | ||
return this | ||
return this; | ||
} | ||
} | ||
module.exports = Database | ||
module.exports = Database; |
@@ -1,2 +0,2 @@ | ||
'use strict' | ||
'use strict'; | ||
@@ -10,19 +10,19 @@ /* | ||
* file that was distributed with this source code. | ||
*/ | ||
*/ | ||
const _ = require('lodash') | ||
const query = require('mquery') | ||
const debug = require('debug')('mquery') | ||
const _ = require('lodash'); | ||
const mquery = require('mquery'); | ||
const debug = require('debug')('mquery'); | ||
// const GeoPoint = require('geo-point') | ||
const EagerLoad = require('../EagerLoad') | ||
const EagerLoad = require('../EagerLoad'); | ||
// const RelationsParser = require('../Relations/Parser') | ||
const CE = require('../../Exceptions') | ||
const CE = require('../../Exceptions'); | ||
const proxyGet = require('../../../lib/proxyGet') | ||
const util = require('../../../lib/util') | ||
const { ioc } = require('../../../lib/iocResolver') | ||
const proxyGet = require('../../../lib/proxyGet'); | ||
const util = require('../../../lib/util'); | ||
const { ioc } = require('../../../lib/iocResolver'); | ||
const proxyHandler = { | ||
get: proxyGet('query', false, function (target, name) { | ||
const queryScope = util.makeScopeName(name) | ||
get: proxyGet('query', false, function(target, name) { | ||
const queryScope = util.makeScopeName(name); | ||
@@ -33,10 +33,10 @@ /** | ||
*/ | ||
if (typeof (target.Model[queryScope]) === 'function') { | ||
return function (...args) { | ||
target.Model[queryScope](this, ...args) | ||
return this | ||
} | ||
if (typeof target.Model[queryScope] === 'function') { | ||
return function(...args) { | ||
target.Model[queryScope](this, ...args); | ||
return this; | ||
}; | ||
} | ||
}) | ||
} | ||
}; | ||
@@ -51,5 +51,7 @@ /** | ||
class QueryBuilder { | ||
constructor (Model, connection) { | ||
this.Model = Model | ||
this.collection = this.Model.prefix ? `${this.Model.prefix}${this.Model.collection}` : this.Model.collection | ||
constructor(Model, connection) { | ||
this.Model = Model; | ||
this.collection = this.Model.prefix | ||
? `${this.Model.prefix}${this.Model.collection}` | ||
: this.Model.collection; | ||
@@ -59,3 +61,3 @@ /** | ||
*/ | ||
this.db = ioc.use('Adonis/Src/Database').connection(connection) | ||
this.db = ioc.use('Adonis/Src/Database').connection(connection); | ||
@@ -65,3 +67,4 @@ /** | ||
*/ | ||
this.query = query() | ||
this.query = mquery(); | ||
this.query.$useProjection = true; | ||
@@ -75,3 +78,3 @@ /** | ||
*/ | ||
this._ignoreScopes = [] | ||
this._ignoreScopes = []; | ||
@@ -83,3 +86,3 @@ /** | ||
*/ | ||
this._eagerLoads = {} | ||
this._eagerLoads = {}; | ||
@@ -91,3 +94,3 @@ /** | ||
*/ | ||
this._sideLoaded = [] | ||
this._sideLoaded = []; | ||
@@ -97,3 +100,3 @@ /** | ||
*/ | ||
this.replaceMethods() | ||
this.replaceMethods(); | ||
@@ -105,3 +108,3 @@ /** | ||
*/ | ||
this._visibleFields = this.Model.visible | ||
this._visibleFields = this.Model.visible; | ||
@@ -113,5 +116,5 @@ /** | ||
*/ | ||
this._hiddenFields = this.Model.hidden | ||
this._hiddenFields = this.Model.hidden; | ||
return new Proxy(this, proxyHandler) | ||
return new Proxy(this, proxyHandler); | ||
} | ||
@@ -125,5 +128,5 @@ | ||
*/ | ||
async getCollection () { | ||
const connection = await this.db.connect() | ||
return connection.collection(this.collection) | ||
async getCollection() { | ||
const connection = await this.db.connect(); | ||
return connection.collection(this.collection); | ||
} | ||
@@ -137,6 +140,4 @@ | ||
*/ | ||
on (event, callback) { | ||
on(event, callback) {} | ||
} | ||
/** | ||
@@ -150,5 +151,5 @@ * This method will apply all the global query scopes | ||
*/ | ||
_applyScopes () { | ||
_applyScopes() { | ||
if (this._ignoreScopes.indexOf('*') > -1) { | ||
return this | ||
return this; | ||
} | ||
@@ -159,6 +160,6 @@ | ||
.each((scope) => { | ||
scope.callback(this) | ||
}) | ||
scope.callback(this); | ||
}); | ||
return this | ||
return this; | ||
} | ||
@@ -177,4 +178,4 @@ | ||
*/ | ||
_mapRowsToInstances (rows) { | ||
return rows.map((row) => this._mapRowToInstance(row)) | ||
_mapRowsToInstances(rows) { | ||
return rows.map((row) => this._mapRowToInstance(row)); | ||
} | ||
@@ -191,4 +192,4 @@ | ||
*/ | ||
_mapRowToInstance (row) { | ||
const modelInstance = new this.Model() | ||
_mapRowToInstance(row) { | ||
const modelInstance = new this.Model(); | ||
@@ -200,13 +201,15 @@ /** | ||
*/ | ||
modelInstance.newUp(_.omitBy(row, (value, field) => { | ||
if (this._sideLoaded.indexOf(field) > -1) { | ||
modelInstance.$sideLoaded[field] = value | ||
return true | ||
} | ||
modelInstance.newUp( | ||
_.omitBy(row, (value, field) => { | ||
if (this._sideLoaded.indexOf(field) > -1) { | ||
modelInstance.$sideLoaded[field] = value; | ||
return true; | ||
} | ||
modelInstance.$visible = this._visibleFields | ||
modelInstance.$hidden = this._hiddenFields | ||
})) | ||
modelInstance.$visible = this._visibleFields; | ||
modelInstance.$hidden = this._hiddenFields; | ||
}) | ||
); | ||
return modelInstance | ||
return modelInstance; | ||
} | ||
@@ -225,5 +228,5 @@ | ||
*/ | ||
async _eagerLoad (modelInstances) { | ||
async _eagerLoad(modelInstances) { | ||
if (_.size(modelInstances)) { | ||
await new EagerLoad(this._eagerLoads).load(modelInstances) | ||
await new EagerLoad(this._eagerLoads).load(modelInstances); | ||
} | ||
@@ -245,3 +248,3 @@ } | ||
*/ | ||
ignoreScopes (scopes) { | ||
ignoreScopes(scopes) { | ||
/** | ||
@@ -251,5 +254,5 @@ * Don't do anything when array is empty or value is not | ||
*/ | ||
const scopesToIgnore = Array.isArray(scopes) ? scopes : ['*'] | ||
this._ignoreScopes = this._ignoreScopes.concat(scopesToIgnore) | ||
return this | ||
const scopesToIgnore = Array.isArray(scopes) ? scopes : ['*']; | ||
this._ignoreScopes = this._ignoreScopes.concat(scopesToIgnore); | ||
return this; | ||
} | ||
@@ -265,3 +268,3 @@ | ||
*/ | ||
async fetch () { | ||
async fetch() { | ||
/** | ||
@@ -271,3 +274,3 @@ * Apply all the scopes before fetching | ||
*/ | ||
this._applyScopes() | ||
this._applyScopes(); | ||
@@ -277,4 +280,4 @@ /** | ||
*/ | ||
const collection = await this.db.getCollection(this.collection) | ||
const rows = await this.query.collection(collection).find() | ||
const collection = await this.db.getCollection(this.collection); | ||
const rows = await this.query.collection(collection).find(); | ||
@@ -284,4 +287,4 @@ /** | ||
*/ | ||
const modelInstances = this._mapRowsToInstances(rows) | ||
await this._eagerLoad(modelInstances) | ||
const modelInstances = this._mapRowsToInstances(rows); | ||
await this._eagerLoad(modelInstances); | ||
@@ -292,3 +295,3 @@ /** | ||
if (this.Model.$hooks) { | ||
await this.Model.$hooks.after.exec('fetch', modelInstances) | ||
await this.Model.$hooks.after.exec('fetch', modelInstances); | ||
} | ||
@@ -299,4 +302,4 @@ | ||
*/ | ||
const Serializer = this.Model.resolveSerializer() | ||
return new Serializer(modelInstances) | ||
const Serializer = this.Model.resolveSerializer(); | ||
return new Serializer(modelInstances); | ||
} | ||
@@ -312,3 +315,3 @@ | ||
*/ | ||
async first () { | ||
async first() { | ||
/** | ||
@@ -318,12 +321,12 @@ * Apply all the scopes before fetching | ||
*/ | ||
this._applyScopes() | ||
this._applyScopes(); | ||
const collection = await this.db.getCollection(this.collection) | ||
const row = await this.query.collection(collection).findOne() | ||
const collection = await this.db.getCollection(this.collection); | ||
const row = await this.query.collection(collection).findOne(); | ||
if (!row) { | ||
return null | ||
return null; | ||
} | ||
const modelInstance = this._mapRowToInstance(row) | ||
const modelInstance = this._mapRowToInstance(row); | ||
// await this._eagerLoad([modelInstance]) | ||
@@ -334,10 +337,10 @@ /** | ||
if (_.size(this._eagerLoads)) { | ||
await modelInstance.loadMany(this._eagerLoads) | ||
await modelInstance.loadMany(this._eagerLoads); | ||
} | ||
if (this.Model.$hooks) { | ||
await this.Model.$hooks.after.exec('find', modelInstance) | ||
await this.Model.$hooks.after.exec('find', modelInstance); | ||
} | ||
return modelInstance | ||
return modelInstance; | ||
} | ||
@@ -356,9 +359,9 @@ | ||
*/ | ||
async firstOrFail () { | ||
const returnValue = await this.first() | ||
async firstOrFail() { | ||
const returnValue = await this.first(); | ||
if (!returnValue) { | ||
throw CE.ModelNotFoundException.raise(this.Model.name) | ||
throw CE.ModelNotFoundException.raise(this.Model.name); | ||
} | ||
return returnValue | ||
return returnValue; | ||
} | ||
@@ -376,4 +379,4 @@ | ||
*/ | ||
find (id) { | ||
return this.where(this.Model.primaryKey, id).first() | ||
find(id) { | ||
return this.where(this.Model.primaryKey, id).first(); | ||
} | ||
@@ -393,3 +396,3 @@ | ||
*/ | ||
async paginate (page = 1, limit = 20) { | ||
async paginate(page = 1, limit = 20) { | ||
/** | ||
@@ -399,11 +402,11 @@ * Apply all the scopes before fetching | ||
*/ | ||
this._applyScopes() | ||
const collection = await this.db.getCollection(this.collection) | ||
const countQuery = _.clone(this.query) | ||
countQuery._fields = undefined | ||
const countByQuery = await countQuery.collection(collection).count() | ||
this.query.limit(limit).skip((page - 1) * limit) | ||
const rows = await this.query.collection(collection).find() | ||
this._applyScopes(); | ||
const collection = await this.db.getCollection(this.collection); | ||
const countQuery = _.clone(this.query); | ||
countQuery._fields = undefined; | ||
const countByQuery = await countQuery.collection(collection).count(); | ||
this.query.limit(limit).skip((page - 1) * limit); | ||
const rows = await this.query.collection(collection).find(); | ||
const result = util.makePaginateMeta(countByQuery || 0, page, limit) | ||
const result = util.makePaginateMeta(countByQuery || 0, page, limit); | ||
@@ -413,4 +416,4 @@ /** | ||
*/ | ||
const modelInstances = this._mapRowsToInstances(rows) | ||
await this._eagerLoad(modelInstances) | ||
const modelInstances = this._mapRowsToInstances(rows); | ||
await this._eagerLoad(modelInstances); | ||
@@ -420,3 +423,3 @@ /** | ||
*/ | ||
const pages = _.omit(result, ['data']) | ||
const pages = _.omit(result, ['data']); | ||
@@ -427,3 +430,3 @@ /** | ||
if (this.Model.$hooks) { | ||
await this.Model.$hooks.after.exec('paginate', modelInstances, pages) | ||
await this.Model.$hooks.after.exec('paginate', modelInstances, pages); | ||
} | ||
@@ -434,4 +437,4 @@ | ||
*/ | ||
const Serializer = this.Model.resolveSerializer() | ||
return new Serializer(modelInstances, pages) | ||
const Serializer = this.Model.resolveSerializer(); | ||
return new Serializer(modelInstances, pages); | ||
} | ||
@@ -450,7 +453,7 @@ | ||
*/ | ||
async update (values) { | ||
const valuesCopy = _.clone(values) | ||
const fakeModel = new this.Model() | ||
fakeModel._setUpdatedAt(valuesCopy) | ||
fakeModel._formatFields(valuesCopy) | ||
async update(values) { | ||
const valuesCopy = _.clone(values); | ||
const fakeModel = new this.Model(); | ||
fakeModel._setUpdatedAt(valuesCopy); | ||
fakeModel._formatFields(valuesCopy); | ||
@@ -460,5 +463,8 @@ /** | ||
*/ | ||
this._applyScopes() | ||
const collection = await this.db.getCollection(this.collection) | ||
return this.query.collection(collection).setOptions({ multi: true }).update(valuesCopy) | ||
this._applyScopes(); | ||
const collection = await this.db.getCollection(this.collection); | ||
return this.query | ||
.collection(collection) | ||
.setOptions({ multi: true }) | ||
.update(valuesCopy); | ||
} | ||
@@ -474,6 +480,9 @@ | ||
*/ | ||
async delete () { | ||
this._applyScopes() | ||
const collection = await this.db.getCollection(this.collection) | ||
return this.query.collection(collection).setOptions({ multi: true }).remove() | ||
async delete() { | ||
this._applyScopes(); | ||
const collection = await this.db.getCollection(this.collection); | ||
return this.query | ||
.collection(collection) | ||
.setOptions({ multi: true }) | ||
.remove(); | ||
} | ||
@@ -489,6 +498,6 @@ | ||
*/ | ||
async insert (attributes) { | ||
debug('insert', this.collection, attributes) | ||
const collection = await this.db.getCollection(this.collection) | ||
return collection.insert(attributes) | ||
async insert(attributes) { | ||
debug('insert', this.collection, attributes); | ||
const collection = await this.db.getCollection(this.collection); | ||
return collection.insert(attributes); | ||
} | ||
@@ -504,19 +513,19 @@ | ||
*/ | ||
ids () { | ||
return this.pluck(this.Model.primaryKey) | ||
ids() { | ||
return this.pluck(this.Model.primaryKey); | ||
} | ||
/** | ||
* Returns an array of selected field | ||
* | ||
* @method pluck | ||
* @param {String} field | ||
* @async | ||
* | ||
* @return {Array} | ||
*/ | ||
async pluck (field) { | ||
this._applyScopes() | ||
const rows = await this.select(field).fetch() | ||
return rows.rows.map((row) => row[field]) | ||
* Returns an array of selected field | ||
* | ||
* @method pluck | ||
* @param {String} field | ||
* @async | ||
* | ||
* @return {Array} | ||
*/ | ||
async pluck(field) { | ||
this._applyScopes(); | ||
const rows = await this.select(field).fetch(); | ||
return rows.rows.map((row) => row[field]); | ||
} | ||
@@ -536,8 +545,12 @@ | ||
*/ | ||
async pair (lhs, rhs) { | ||
const collection = await this.fetch() | ||
return _.transform(collection.rows, (result, row) => { | ||
result[row[lhs]] = row[rhs] | ||
return result | ||
}, {}) | ||
async pair(lhs, rhs) { | ||
const collection = await this.fetch(); | ||
return _.transform( | ||
collection.rows, | ||
(result, row) => { | ||
result[row[lhs]] = row[rhs]; | ||
return result; | ||
}, | ||
{} | ||
); | ||
} | ||
@@ -555,5 +568,5 @@ | ||
*/ | ||
pickInverse (limit = 1) { | ||
this.query.sort(`-${this.Model.primaryKey}`).limit(limit) | ||
return this.fetch() | ||
pickInverse(limit = 1) { | ||
this.query.sort(`-${this.Model.primaryKey}`).limit(limit); | ||
return this.fetch(); | ||
} | ||
@@ -571,5 +584,5 @@ | ||
*/ | ||
pick (limit = 1) { | ||
this.query.sort(this.Model.primaryKey).limit(limit) | ||
return this.fetch() | ||
pick(limit = 1) { | ||
this.query.sort(this.Model.primaryKey).limit(limit); | ||
return this.fetch(); | ||
} | ||
@@ -588,17 +601,17 @@ | ||
*/ | ||
with (...args) { | ||
with(...args) { | ||
if (args[1] && _.isFunction(args[1])) { | ||
this._eagerLoads[args[0]] = args[1] | ||
this._eagerLoads[args[0]] = args[1]; | ||
} else if (args[1] && _.isObject(args[1])) { | ||
this._eagerLoads[args[0]] = (builder) => { | ||
_.forEach(args[1], (value, key) => builder[key](value)) | ||
} | ||
_.forEach(args[1], (value, key) => builder[key](value)); | ||
}; | ||
} else if (Array.isArray(args[0])) { | ||
_.forEach(args[0], related => this.with(related)) | ||
_.forEach(args[0], (related) => this.with(related)); | ||
} else if (_.isObject(args[0])) { | ||
_.forEach(args[0], (scope, key) => this.with(key, scope)) | ||
_.forEach(args[0], (scope, key) => this.with(key, scope)); | ||
} else { | ||
this._eagerLoads[args[0]] = (builder) => { } | ||
this._eagerLoads[args[0]] = (builder) => {}; | ||
} | ||
return this | ||
return this; | ||
} | ||
@@ -682,3 +695,3 @@ | ||
*/ | ||
static get conditionMethods () { | ||
static get conditionMethods() { | ||
return [ | ||
@@ -702,3 +715,3 @@ 'eq', | ||
'intersects' | ||
] | ||
]; | ||
} | ||
@@ -711,11 +724,11 @@ | ||
*/ | ||
replaceMethods () { | ||
replaceMethods() { | ||
for (let name of this.constructor.conditionMethods) { | ||
let originMethod = this.query[name] | ||
let originMethod = this.query[name]; | ||
this.query[name] = (param) => { | ||
const key = this.query._path | ||
param = this.Model.formatField(key, param) | ||
originMethod.apply(this.query, [param]) | ||
return this | ||
} | ||
const key = this.query._path; | ||
param = this.Model.formatField(key, param); | ||
originMethod.apply(this.query, [param]); | ||
return this; | ||
}; | ||
} | ||
@@ -730,63 +743,73 @@ } | ||
*/ | ||
where () { | ||
where() { | ||
if (_.isPlainObject(arguments[0])) { | ||
let queryObject = arguments[0] | ||
let queryObject = arguments[0]; | ||
for (const key in queryObject) { | ||
const conditions = queryObject[key] | ||
const conditions = queryObject[key]; | ||
if (key === '$and' || key === '$or' || key === '$nor') { | ||
if (!Array.isArray(conditions)) { | ||
throw new CE.InvalidArgumentException(`Method "$${key}"'s param must be an array`) | ||
throw new CE.InvalidArgumentException( | ||
`Method "$${key}"'s param must be an array` | ||
); | ||
} | ||
let formatedConditions = [] | ||
let formatedConditions = []; | ||
for (const condition of conditions) { | ||
const cloneQuery = _.clone(this) | ||
cloneQuery.query = query() | ||
formatedConditions.push(cloneQuery.where(condition).query._conditions) | ||
const cloneQuery = _.clone(this); | ||
cloneQuery.query = mquery(); | ||
cloneQuery.$useProjection = true; | ||
formatedConditions.push( | ||
cloneQuery.where(condition).query._conditions | ||
); | ||
} | ||
queryObject[key] = formatedConditions | ||
queryObject[key] = formatedConditions; | ||
} else if (_.isPlainObject(conditions)) { | ||
for (const subKey in conditions) { | ||
const reg = /^\$(eq|ne|gt|gte|lt|lte|in|nin|all|near|intersects|elemMatch|includes)$/ | ||
const reg = /^\$(eq|ne|gt|gte|lt|lte|in|nin|all|near|intersects|elemMatch|includes)$/; | ||
if (reg.test(subKey)) { | ||
queryObject[key][subKey] = this.Model.formatField(key, queryObject[key][subKey]) | ||
queryObject[key][subKey] = this.Model.formatField( | ||
key, | ||
queryObject[key][subKey] | ||
); | ||
} | ||
} | ||
} else { | ||
queryObject[key] = this.Model.formatField(key, queryObject[key]) | ||
queryObject[key] = this.Model.formatField(key, queryObject[key]); | ||
} | ||
} | ||
this.query.where(queryObject) | ||
this.query.where(queryObject); | ||
} else if (_.isFunction(arguments[0])) { | ||
arguments[0].bind(this).call() | ||
arguments[0].bind(this).call(); | ||
} else { | ||
if (arguments.length === 2) { | ||
this.query.where(arguments[0]).eq(arguments[1]) | ||
this.query.where(arguments[0]).eq(arguments[1]); | ||
} else if (arguments.length === 3) { | ||
switch (arguments[1]) { | ||
case '=': | ||
this.query.where(arguments[0]).eq(arguments[2]) | ||
break | ||
this.query.where(arguments[0]).eq(arguments[2]); | ||
break; | ||
case '>': | ||
this.query.where(arguments[0]).gt(arguments[2]) | ||
break | ||
this.query.where(arguments[0]).gt(arguments[2]); | ||
break; | ||
case '>=': | ||
this.query.where(arguments[0]).gte(arguments[2]) | ||
break | ||
this.query.where(arguments[0]).gte(arguments[2]); | ||
break; | ||
case '<': | ||
this.query.where(arguments[0]).lt(arguments[2]) | ||
break | ||
this.query.where(arguments[0]).lt(arguments[2]); | ||
break; | ||
case '<=': | ||
this.query.where(arguments[0]).lte(arguments[2]) | ||
break | ||
this.query.where(arguments[0]).lte(arguments[2]); | ||
break; | ||
case '<>': | ||
this.query.where(arguments[0]).ne(arguments[2]) | ||
break | ||
this.query.where(arguments[0]).ne(arguments[2]); | ||
break; | ||
default: | ||
throw new CE.RuntimeException(`Method "$${arguments[1]}" is not support by query builder`) | ||
throw new CE.RuntimeException( | ||
`Method "$${arguments[1]}" is not support by query builder` | ||
); | ||
} | ||
} else { | ||
return this.query.where(arguments[0]) | ||
return this.query.where(arguments[0]); | ||
} | ||
} | ||
return this | ||
return this; | ||
} | ||
@@ -802,5 +825,5 @@ | ||
*/ | ||
whereNull (key) { | ||
this.query.where(key).exists(false) | ||
return this | ||
whereNull(key) { | ||
this.query.where(key).exists(false); | ||
return this; | ||
} | ||
@@ -816,5 +839,5 @@ | ||
*/ | ||
whereNotNull (key) { | ||
this.query.where(key).exists() | ||
return this | ||
whereNotNull(key) { | ||
this.query.where(key).exists(); | ||
return this; | ||
} | ||
@@ -830,5 +853,5 @@ | ||
*/ | ||
whereIn (key, values) { | ||
this.query.where(key).in(values) | ||
return this | ||
whereIn(key, values) { | ||
this.query.where(key).in(values); | ||
return this; | ||
} | ||
@@ -844,5 +867,5 @@ | ||
*/ | ||
whereNotIn (key, values) { | ||
this.query.where(key).nin(values) | ||
return this | ||
whereNotIn(key, values) { | ||
this.query.where(key).nin(values); | ||
return this; | ||
} | ||
@@ -855,11 +878,11 @@ | ||
*/ | ||
select () { | ||
let arg = null | ||
select() { | ||
let arg = null; | ||
if (arguments.length > 1) { | ||
arg = _.values(arguments).join(' ') | ||
arg = _.values(arguments).join(' '); | ||
} else { | ||
arg = arguments[0] | ||
arg = arguments[0]; | ||
} | ||
this.query.select(arg) | ||
return this | ||
this.query.select(arg); | ||
return this; | ||
} | ||
@@ -873,11 +896,11 @@ | ||
*/ | ||
orderBy () { | ||
let arg = null | ||
orderBy() { | ||
let arg = null; | ||
if (arguments.length > 1) { | ||
arg = _.set({}, arguments[0], arguments[1]) | ||
arg = _.set({}, arguments[0], arguments[1]); | ||
} else { | ||
arg = arguments[0] | ||
arg = arguments[0]; | ||
} | ||
this.query.sort(arg) | ||
return this | ||
this.query.sort(arg); | ||
return this; | ||
} | ||
@@ -892,4 +915,4 @@ | ||
*/ | ||
count (groupBy) { | ||
return this._aggregate('count', null, groupBy) | ||
count(groupBy) { | ||
return this._aggregate('count', null, groupBy); | ||
} | ||
@@ -904,4 +927,4 @@ | ||
*/ | ||
max (key, groupBy) { | ||
return this._aggregate('max', key, groupBy) | ||
max(key, groupBy) { | ||
return this._aggregate('max', key, groupBy); | ||
} | ||
@@ -916,4 +939,4 @@ | ||
*/ | ||
min (key, groupBy) { | ||
return this._aggregate('min', key, groupBy) | ||
min(key, groupBy) { | ||
return this._aggregate('min', key, groupBy); | ||
} | ||
@@ -928,4 +951,4 @@ | ||
*/ | ||
sum (key, groupBy) { | ||
return this._aggregate('sum', key, groupBy) | ||
sum(key, groupBy) { | ||
return this._aggregate('sum', key, groupBy); | ||
} | ||
@@ -940,4 +963,4 @@ | ||
*/ | ||
avg (key, groupBy) { | ||
return this._aggregate('avg', key, groupBy) | ||
avg(key, groupBy) { | ||
return this._aggregate('avg', key, groupBy); | ||
} | ||
@@ -952,10 +975,10 @@ | ||
*/ | ||
async _aggregate (aggregator, key, groupBy) { | ||
this._applyScopes() | ||
const $match = this.query._conditions | ||
const $group = {} | ||
async _aggregate(aggregator, key, groupBy) { | ||
this._applyScopes(); | ||
const $match = this.query._conditions; | ||
const $group = {}; | ||
if (_.isString(groupBy)) { | ||
$group._id = '$' + groupBy | ||
$group._id = '$' + groupBy; | ||
} else if (_.isObject) { | ||
$group._id = groupBy | ||
$group._id = groupBy; | ||
} | ||
@@ -965,29 +988,31 @@ | ||
case 'count': | ||
$group[aggregator] = { $sum: 1 } | ||
break | ||
$group[aggregator] = { $sum: 1 }; | ||
break; | ||
case 'max': | ||
$group[aggregator] = { $max: '$' + key } | ||
break | ||
$group[aggregator] = { $max: '$' + key }; | ||
break; | ||
case 'min': | ||
$group[aggregator] = { $min: '$' + key } | ||
break | ||
$group[aggregator] = { $min: '$' + key }; | ||
break; | ||
case 'sum': | ||
$group[aggregator] = { $sum: '$' + key } | ||
break | ||
$group[aggregator] = { $sum: '$' + key }; | ||
break; | ||
case 'avg': | ||
$group[aggregator] = { $avg: '$' + key } | ||
break | ||
$group[aggregator] = { $avg: '$' + key }; | ||
break; | ||
default: | ||
break | ||
break; | ||
} | ||
const collection = await this.getCollection() | ||
debug(aggregator, this.collection, $match, $group) | ||
const result = await collection.aggregate([{ $match }, { $group }]).toArray() | ||
return groupBy ? result : !_.isEmpty(result) ? result[0][aggregator] : null | ||
const collection = await this.getCollection(); | ||
debug(aggregator, this.collection, $match, $group); | ||
const result = await collection | ||
.aggregate([{ $match }, { $group }]) | ||
.toArray(); | ||
return groupBy ? result : !_.isEmpty(result) ? result[0][aggregator] : null; | ||
} | ||
async aggregate (...args) { | ||
const collection = await this.getCollection() | ||
debug(...args, this.collection) | ||
return collection.aggregate(...args).toArray() | ||
async aggregate(...args) { | ||
const collection = await this.getCollection(); | ||
debug(...args, this.collection); | ||
return collection.aggregate(...args).toArray(); | ||
} | ||
@@ -1002,6 +1027,6 @@ | ||
*/ | ||
async distinct (field) { | ||
this._applyScopes() | ||
const collection = await this.getCollection() | ||
return this.query.collection(collection).distinct(...arguments) | ||
async distinct(field) { | ||
this._applyScopes(); | ||
const collection = await this.getCollection(); | ||
return this.query.collection(collection).distinct(...arguments); | ||
} | ||
@@ -1016,4 +1041,4 @@ | ||
*/ | ||
toSQL () { | ||
return JSON.stringify(this.query) | ||
toSQL() { | ||
return JSON.stringify(this.query); | ||
} | ||
@@ -1028,4 +1053,4 @@ | ||
*/ | ||
toString () { | ||
return this.query.toString() | ||
toString() { | ||
return this.query.toString(); | ||
} | ||
@@ -1045,5 +1070,5 @@ | ||
*/ | ||
setVisible (fields) { | ||
this._visibleFields = fields | ||
return this | ||
setVisible(fields) { | ||
this._visibleFields = fields; | ||
return this; | ||
} | ||
@@ -1063,8 +1088,8 @@ | ||
*/ | ||
setHidden (fields) { | ||
this._hiddenFields = fields | ||
return this | ||
setHidden(fields) { | ||
this._hiddenFields = fields; | ||
return this; | ||
} | ||
} | ||
module.exports = QueryBuilder | ||
module.exports = QueryBuilder; |
307629
10445