@stoqey/sofa
Version:
Couchbase utilities
457 lines • 16.1 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Query = void 0;
var base_query_1 = require("./base-query");
var exceptions_1 = require("./exceptions");
var helpers_1 = require("./helpers");
var Query = /** @class */ (function (_super) {
__extends(Query, _super);
/**
* @summary Create an instance of Query.
* @name Query
* @class
* @public
*
* @param conditions List of SELECT clause conditions
* @param collection Collection name
* @returns Query
*
* @example
* ```ts
* const query = new Query({$select: [{$field: 'address'}], $where: {$nill: [{ address: { $like: '%57-59%' } }, { free_breakfast: true }, { free_lunch: [1] }]}}, 'travel-sample');
* ```
*/
function Query(conditions, collection) {
var _this = _super.call(this, conditions, collection) || this;
if (conditions) {
_this.compileFromConditions(conditions);
}
return _this;
}
/**
* Add result selectors to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample`
*/
Query.prototype.select = function (value) {
if (this.queryType === undefined || this.queryType === 'SELECT') {
this.queryType = 'SELECT';
if (!value) {
this.selectExpr = '*';
}
else if (typeof value === 'string') {
this.selectExpr = value;
}
else if (typeof value === 'object') {
this.selectExpr = __spreadArray(__spreadArray([], __read((this.selectExpr || [])), false), __read(value), false);
}
return this;
}
throw new exceptions_1.MultipleQueryTypesException('SELECT', this.queryType);
};
/**
* Add index type and name to INDEX clause.
* @method
* @public
*
* @example
* ```ts
* const result = new Query({}, 'travel-sample').index('DROP', 'travel_sample_id_test').build();
* console.log(result)
* ```
* > DROP INDEX `travel-sample`.`travel_sample_id_test`
*/
Query.prototype.index = function (type, name) {
if (this.queryType === undefined) {
if (name.search(/^[A-Za-z][A-Za-z0-9#_]*$/g) === -1) {
throw new Error('Valid GSI index names can contain any of the following characters: A-Z a-z 0-9 # _, and must start with a letter, [A-Z a-z]');
}
this.queryType = 'INDEX';
this.indexType = type;
this.indexName = name;
return this;
}
throw new exceptions_1.MultipleQueryTypesException('INDEX', this.queryType);
};
/**
* Add items to ON clause in INDEX clause.
* @method
* @public
*
* @example
* ```ts
* const on = [{ name: 'travel-sample.callsing', sort: 'ASC' }];
* const result = new Query({}, 'travel-sample').index('CREATE', 'travel_sample_id_test').on(on).build();
* console.log(result)
* ```
* > CREATE INDEX `travel_sample_id_test` ON `travel-sample`(`travel-sample.callsing`['ASC'])
*/
Query.prototype.on = function (value) {
if (this.queryType === 'INDEX' &&
['CREATE', 'CREATE PRIMARY', 'BUILD'].includes(this.indexType || '')) {
this.indexOn = value;
return this;
}
throw new exceptions_1.IndexParamsOnExceptions(['CREATE', 'CREATE PRIMARY', 'BUILD']);
};
/**
* Create INDEX using General Secondary Index(GSI).
* @method
* @public
*
* @example
* ```ts
* const result = new Query({}, 'travel-sample').index('CREATE', 'travel_sample_id_test').usingGSI().build();
* console.log(result)
* ```
* > CREATE INDEX `travel_sample_id_test` USING GSI)
*/
Query.prototype.usingGSI = function () {
if (this.queryType === 'INDEX') {
this.indexUsingGSI = true;
return this;
}
throw new exceptions_1.IndexParamsUsingGSIExceptions(['CREATE', 'CREATE PRIMARY', 'BUILD']);
};
/**
* Add items to WITH clause in INDEX clause.
* @method
* @public
*
* @example
* ```ts
* const withExpr = {nodes: ['192.168.1.1:8078'],defer_build: true,num_replica: 2};
* const result = new Query({}, 'travel-sample').index('CREATE', 'travel_sample_id_test').with(withExpr).build();
* console.log(result)
* ```
* > CREATE INDEX `travel_sample_id_test` WITH {'nodes': ['192.168.1.1:8078'],'defer_build': true,'num_replica': 2})
*/
Query.prototype.with = function (value) {
if (this.queryType === 'INDEX') {
this.indexWith = value;
return this;
}
throw new Error('The WITH clause is only available for Indexes');
};
/**
* Add WHERE expression to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const expr_where = {$or: [{ address: { $like: '%57-59%' } }, { free_breakfast: true }]};
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).where(expr_where).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample WHERE (address LIKE '%57-59%' OR free_breakfast = true)`
*/
Query.prototype.where = function (value) {
this.whereExpr = value;
return this;
};
/**
* Add JOIN expression to SELECT clause.
* @method
* @public
*
* @example
* ```tS
* const query = new Query({}, 'beer-sample brewery');
* const result = query.select([{$field: 'address'}]).plainJoin('JOIN `beer-sample` beer ON beer.brewery_id = LOWER(REPLACE(brewery.name, " ", "_"))').build()
* console.log(result)
* ```
* > SELECT address FROM `beer-sample brewery` JOIN `beer-sample` beer ON beer.brewery_id = LOWER(REPLACE(brewery.name, " ", "_")) LIMIT 1`
*/
Query.prototype.plainJoin = function (value) {
this.plainJoinExpr = value;
return this;
};
/**
* Add ORDER BY expression to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).orderBy({ size: 'DESC' }).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample ORDER BY size = 'DESC'`
*/
Query.prototype.orderBy = function (value) {
this.orderExpr = value;
return this;
};
/**
* Add LIMIT expression to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).limit(10).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample LIMIT 10`
*/
Query.prototype.limit = function (value) {
this.limitExpr = value;
return this;
};
/**
* Add OFFSET expression to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).offset(10).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample OFFSET 10`
*/
Query.prototype.offset = function (value) {
this.offSetExpr = value;
return this;
};
/**
* Add LET expression to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const letExpr = [{ key: 'amount_val', value: 10 }];
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).let(letExpr).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample LET amount_val = 10`
*/
Query.prototype.let = function (value) {
this.letExpr = value;
return this;
};
/**
* Add GROUP BY expression to GROUP BY clause.
* @method
* @public
*
* @example
* ```ts
* const groupByExpr = [{ expr: 'COUNT(amount_val)', as: 'amount' }];
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).groupBy(groupByExpr).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample GROUP BY COUNT(amount) AS amount`
*/
Query.prototype.groupBy = function (value) {
this.groupByExpr = value;
return this;
};
/**
* Add LETTING expression to GROUP BY clause.
* @method
* @public
*
* @example
* ```ts
* const groupByExpr = [{ expr: 'COUNT(amount_val)', as: 'amount' }];
* const letExpr = [{ key: 'amount_val', value: 10 }];
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).groupBy(groupByExpr).let(letExpr).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample GROUP BY COUNT(amount) AS amount LETTING amount = 10`
*/
Query.prototype.letting = function (value) {
this.lettingExpr = value;
return this;
};
/**
* Add HAVING expression to GROUP BY clause.
* @method
* @public
*
* @example
* ```ts
* const groupByExpr = [{ expr: 'COUNT(amount_val)', as: 'amount' }];
* const having = {address: {$like: '%58%'}};
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).groupBy(groupByExpr).having(having).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample GROUP BY COUNT(amount) AS amount HAVING address LIKE '%58%'`
*/
Query.prototype.having = function (value) {
this.havingExpr = value;
return this;
};
/**
* Add USE KEYS expression to SELECT clause.
* @method
* @public
*
* @example
* ```ts
* const query = new Query({}, 'travel-sample');
* const result = query.select([{$field: 'address'}]).useKeys(['airlineR_8093']).build()
* console.log(result)
* ```
* > SELECT address FROM `travel-sample USE KEYS ['airlineR_8093']`
*/
Query.prototype.useKeys = function (value) {
this.useKeysExpr = value;
return this;
};
/**
* Converts the conditional parameters passed to the constructor to the properties of the N1QL Query.
* @method
* @public
*
*/
Query.prototype.compileFromConditions = function (conditionals) {
var _this = this;
Object.keys(conditionals).forEach(function (value) {
switch (value) {
case 'select':
_this.select(conditionals[value]);
break;
case 'let':
!!conditionals[value] && _this.let(conditionals[value]);
break;
case 'where':
!!conditionals[value] && _this.where(conditionals[value]);
break;
case 'plainJoin':
!!conditionals[value] && _this.plainJoin(conditionals[value]);
break;
case 'groupBy':
!!conditionals[value] && _this.groupBy(conditionals[value]);
break;
case 'letting':
!!conditionals[value] && _this.letting(conditionals[value]);
break;
case 'having':
!!conditionals[value] && _this.having(conditionals[value]);
break;
case 'orderBy':
!!conditionals[value] &&
_this.orderBy(conditionals[value]);
break;
case 'limit':
!!conditionals[value] && _this.limit(conditionals[value]);
break;
case 'offset':
!!conditionals[value] && _this.offset(conditionals[value]);
break;
case 'use':
!!conditionals[value] && _this.useKeys(conditionals[value]);
break;
}
});
};
/**
* Build a n1ql query from the defined parameters.
* @method
* @public
*
*/
Query.prototype.build = function () {
switch (this.queryType) {
case 'INDEX':
switch (this.indexType) {
case 'BUILD':
case 'CREATE':
case 'CREATE PRIMARY':
if (this.indexOn) {
return (0, helpers_1.buildIndexExpr)(this.collection, this.indexType, this.indexName || '', this.indexOn, this.whereExpr, this.indexUsingGSI, this.indexWith);
}
case 'DROP':
return (0, helpers_1.buildIndexExpr)(this.collection, this.indexType, this.indexName || '', undefined, undefined, this.indexUsingGSI);
}
case 'SELECT':
if (this.selectExpr) {
return (0, helpers_1.selectBuilder)(this.collection, this.selectExpr, this.letExpr, this.whereExpr, this.orderExpr, this.limitExpr, this.offSetExpr, this.useKeysExpr, this.groupByExpr, this.lettingExpr, this.havingExpr, this.plainJoinExpr);
}
}
return '';
};
Object.defineProperty(Query.prototype, "conditions", {
get: function () {
return this._conditions;
},
set: function (value) {
this._conditions = value;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Query.prototype, "collection", {
get: function () {
return this._collection;
},
set: function (value) {
this._collection = value;
},
enumerable: false,
configurable: true
});
return Query;
}(base_query_1.BaseQuery));
exports.Query = Query;
//# sourceMappingURL=query.js.map