mythix-orm
Advanced tools
Comparing version 1.12.0 to 1.13.1
@@ -246,5 +246,17 @@ 'use strict'; | ||
/// | ||
/// Arguments: | ||
/// connection?: <see>Connection</see> | ||
/// The connection to use to stringify the literal. If | ||
/// not provided, then a "representation" of the literal | ||
/// (for logging/debugging) will be returned instead. | ||
/// options?: object | ||
/// Any options needed to stringify the literal. These are often | ||
/// literal and/or database specific. | ||
/// | ||
/// Return: string | ||
/// The value provided to the `constructor` as a string. | ||
toString() { | ||
/// The stringified literal, ready to be used in the underlying database | ||
/// (if a `connection` was provided), or a logging/debugging representation | ||
/// of the literal if no `connection` is provided. | ||
// eslint-disable-next-line no-unused-vars | ||
toString(connection, options) { | ||
if (!this.literal) | ||
@@ -251,0 +263,0 @@ return ('' + this.literal); |
@@ -34,3 +34,3 @@ 'use strict'; | ||
let context = this.getOperationContext(); | ||
let order = this.margeFields( | ||
let order = this.mergeFields( | ||
context.order, | ||
@@ -338,4 +338,4 @@ entities, | ||
/// for the `Map` to be empty. | ||
margeFields(currentFields, incomingFields, extraData, options) { | ||
return QueryUtils.margeFields(this, currentFields, incomingFields, extraData, options); | ||
mergeFields(currentFields, incomingFields, extraData, options) { | ||
return QueryUtils.mergeFields(this, currentFields, incomingFields, extraData, options); | ||
} | ||
@@ -492,8 +492,8 @@ | ||
/// 1) `ORDER` - Alias for `ORDER.ASC`. | ||
/// 2) `ORDER.ASC` - Follow the rules of <see>ModelScope.margeFields</see>. Each field/literal added is in `ASC` order. | ||
/// 3) `ORDER.DESC` - Follow the rules of <see>ModelScope.margeFields</see>. Each field/literal added is in `DESC` order. | ||
/// 4) `ORDER.ADD` - **DO NOT** follow the rules of <see>ModelScope.margeFields</see>, and instead **add** all fields specified, with their sort order being specified instead by the `+` or `-` prefixes on each field. | ||
/// 5) `ORDER.REPLACE` - **DO NOT** follow the rules of <see>ModelScope.margeFields</see>, and instead **replace** the operation fields to the fields specified, with their sort order being specified instead by the `+` or `-` prefixes on each field. | ||
/// 2) `ORDER.ASC` - Follow the rules of <see>ModelScope.mergeFields</see>. Each field/literal added is in `ASC` order. | ||
/// 3) `ORDER.DESC` - Follow the rules of <see>ModelScope.mergeFields</see>. Each field/literal added is in `DESC` order. | ||
/// 4) `ORDER.ADD` - **DO NOT** follow the rules of <see>ModelScope.mergeFields</see>, and instead **add** all fields specified, with their sort order being specified instead by the `+` or `-` prefixes on each field. | ||
/// 5) `ORDER.REPLACE` - **DO NOT** follow the rules of <see>ModelScope.mergeFields</see>, and instead **replace** the operation fields to the fields specified, with their sort order being specified instead by the `+` or `-` prefixes on each field. | ||
/// | ||
/// See <see>ModelScope.margeFields</see> to better understand how this method works. | ||
/// See <see>ModelScope.mergeFields</see> to better understand how this method works. | ||
/// | ||
@@ -519,3 +519,3 @@ /// SyntaxType: FunctionDeclaration | ||
/// | ||
/// See <see>ModelScope.margeFields</see> to better understand how this method works. | ||
/// See <see>ModelScope.mergeFields</see> to better understand how this method works. | ||
/// | ||
@@ -555,3 +555,3 @@ /// Note: | ||
let context = this.getOperationContext(); | ||
let groupBy = this.margeFields( | ||
let groupBy = this.mergeFields( | ||
context.groupBy, | ||
@@ -651,3 +651,3 @@ entities, | ||
/// | ||
/// See <see>ModelScope.margeFields</see> to better understand how this method works. | ||
/// See <see>ModelScope.mergeFields</see> to better understand how this method works. | ||
/// | ||
@@ -700,3 +700,3 @@ /// Note: | ||
let context = this.getOperationContext(); | ||
let projection = this.margeFields( | ||
let projection = this.mergeFields( | ||
context.projection, | ||
@@ -703,0 +703,0 @@ entities, |
@@ -33,3 +33,3 @@ 'use strict'; | ||
generateQueryFromFilter, | ||
margeFields, | ||
mergeFields, | ||
} = QueryUtils; | ||
@@ -73,3 +73,3 @@ | ||
generateQueryFromFilter, | ||
margeFields, | ||
mergeFields, | ||
@@ -76,0 +76,0 @@ // AsyncStore |
@@ -0,1 +1,8 @@ | ||
///! import `var { Utils: { MiscUtils } } = require('mythix-orm');` | ||
///! | ||
///! MiscUtils utilities provide some miscellaneous utility | ||
///! functions for assisting with some common operations. | ||
///! | ||
///! DocScope: MiscUtils | ||
'use strict'; | ||
@@ -6,2 +13,12 @@ | ||
/// When provided an async iterator, | ||
/// collect all results from the iterator | ||
/// until the iterator is exhausted. | ||
/// | ||
/// Arguments: | ||
/// iterator: async * iterator | ||
/// The async generator iterator to collect items from. | ||
/// | ||
/// Return: Promise<Array<any>> | ||
/// Return the collected results as an array. | ||
async function collect(iterator) { | ||
@@ -16,2 +33,23 @@ let items = []; | ||
/// Take a timestamp, a string, a Date instance, | ||
/// or a Luxon [DateTime](https://moment.github.io/luxon/#/) instance | ||
/// and convert the input to a Luxon [DateTime](https://moment.github.io/luxon/#/) instance. | ||
/// | ||
/// Arguments: | ||
/// value: number | string | Date | [DateTime](https://moment.github.io/luxon/#/) | ||
/// The value to use to create a new Luxon [DateTime](https://moment.github.io/luxon/#/) instance. | ||
/// If this is a `number` or `bigint`, then it will be assumed this is a timestamp, and | ||
/// the provided `format` will be ignored. If this is a `string`, the provided `format` | ||
/// will be used to parse it into a `DateTime` instance. If this is a `Date` instance, then | ||
/// it will be converted to a Luxon `DateTime` instance. A Luxon `DateTime` instance will | ||
/// simply be returned. | ||
/// format?: string | ||
/// The Luxon [DateTime](https://moment.github.io/luxon/#/) format used to parse | ||
/// the date/time if the provided `value` is a string. This is only required if | ||
/// the format is something that Luxon doesn't natively understand (i.e. an ISO format). | ||
/// | ||
/// Return: [DateTime](https://moment.github.io/luxon/#/) | ||
/// The newly created Luxon `DateTime` instance. If a Luxon `DateTime` | ||
/// instance was provided as the `value` argument, then it will simply | ||
/// be returned. | ||
function valueToDateTime(value, format) { | ||
@@ -18,0 +56,0 @@ if (DateTime.isDateTime(value)) { |
@@ -14,3 +14,3 @@ import ConnectionBase from '../connection/connection-base'; | ||
export declare function margeFields( | ||
export declare function mergeFields( | ||
connection: ConnectionBase, | ||
@@ -17,0 +17,0 @@ currentFields: Map<string, any>, |
@@ -0,1 +1,9 @@ | ||
///! import `var { Utils: { QueryUtils } } = require('mythix-orm');` | ||
///! | ||
///! QueryUtils provide utility functions | ||
///! for creating and interacting with queries | ||
///! ([QueryEngine](https://github.com/th317erd/mythix-orm/wiki/QueryEngine)). | ||
///! | ||
///! DocScope: QueryUtils | ||
'use strict'; | ||
@@ -5,33 +13,2 @@ | ||
// The code below will take a "query object" | ||
// and convert it into Mythix ORM query. | ||
// | ||
// "query objects" are objects with a simple | ||
// structure and convention to build complex queries. | ||
// | ||
// Fields inside these objects can have operators, | ||
// which are postfixed to the field name. For example, | ||
// you could create a filter to find a user by name | ||
// with the following query object: | ||
// { "firstName=": "John", "lastName!=": "Bob" } | ||
// which would find all users with the first name | ||
// of "John", and any last name except "Bob". | ||
// | ||
// AND and OR conditions are also supported. These | ||
// work based of the structure of the object itself. | ||
// If an array is used, then OR is in effect. | ||
// If an object is used, then AND is in effect. | ||
// For example, the following query object: | ||
// [ { firstName: "John", lastName: "Brown" }, { firstName: "Mary", lastName: "Smith" } ] | ||
// would result in the following query: | ||
// WHERE ((firstName = 'John' AND lastName = 'Brown') OR (firstName = 'Mary' AND lastName = 'Smith')), | ||
// finding either user John Brown, or Mary Smith. | ||
// | ||
// IN and NOT IN operators are handled automatically | ||
// when the operator is either "=" or "!=", and the | ||
// provided value is an array. For example: | ||
// { firstName: [ 'John', 'Bob', 'Mary' ] } | ||
// would result in the following query: | ||
// WHERE firstName IN ('John', 'Bob', 'Mary') | ||
const FILTER_OPERATORS = { | ||
@@ -74,2 +51,20 @@ '=': (Model, fieldName, query, value) => { | ||
/// Take the provided `fieldName`, which might include | ||
/// an operator as a postfix, and return the operator | ||
/// and `fieldName` found. If no operator postfix is | ||
/// present, then the default `=` operator is returned. | ||
/// | ||
/// Refer to <see>QueryUtils.generateQueryFromFilter</see> for | ||
/// a better understanding of what this does and why it is needed. | ||
/// | ||
/// Arguments: | ||
/// fieldName: string | ||
/// The field name to parse, with an optional operator postfix added. | ||
/// | ||
/// Return: { field: string; operator: string; } | ||
/// Return the parsed `field`, and the parsed `operator`. If no | ||
/// operator postfix is on the field, then the default is the `=` | ||
/// operator. | ||
/// | ||
/// See: QueryUtils.generateQueryFromFilter | ||
function parseFilterFieldAndOperator(fieldName) { | ||
@@ -95,2 +90,70 @@ let operator = '='; | ||
/// Take a "query object" and convert it into Mythix ORM query. | ||
/// | ||
/// "query objects" are objects with a simple | ||
/// structure and convention to build complex queries. | ||
/// | ||
/// Fields inside these objects can have operators, | ||
/// which are postfixed to the field name. For example, | ||
/// you could create a filter to find a user by name | ||
/// with the following query object: | ||
/// `{ "firstName=": "John", "lastName!=": "Bob" }` | ||
/// which would find all users with the first name | ||
/// of "John", and any last name except "Bob". | ||
/// | ||
/// `AND` and `OR` conditions are also supported. These | ||
/// work based of the structure of the object itself. | ||
/// If an array is used, then `OR` is in effect. | ||
/// If an object is used, then `AND` is in effect. | ||
/// For example, the following query object: | ||
/// `[ { firstName: "John", lastName: "Brown" }, { firstName: "Mary", lastName: "Smith" } ]` | ||
/// would result in the following SQL query: | ||
/// `WHERE ((firstName = 'John' AND lastName = 'Brown') OR (firstName = 'Mary' AND lastName = 'Smith'))`, | ||
/// finding either user John Brown, or Mary Smith. | ||
/// | ||
/// `IN` and `NOT IN` operators are handled automatically | ||
/// when the operator is either `=` or `!=`, and the | ||
/// provided value is an array. For example: | ||
/// `{ firstName: [ 'John', 'Bob', 'Mary' ] }` | ||
/// would result in the following SQL query: | ||
/// `WHERE firstName IN ('John', 'Bob', 'Mary')`. | ||
/// | ||
/// Operators that can be postfixed to field names | ||
/// in the provided `filter` object are as follows: | ||
/// | Operator | Description | | ||
/// | `=` | Equality operator. If an `Array` of values is provided, then this will turn into a `IN` operation in the underlying database. | | ||
/// | `!=` | Inverse (not) equality operator. If an `Array` of values is provided, then this will turn into a `NOT IN` operation in the underlying database. | | ||
/// | `>` | Greater than operator. | | ||
/// | `>=` | Greater than or equal to operator. | | ||
/// | `<` | Less than operator. | | ||
/// | `<=` | Less than or equal to operator. | | ||
/// | `><` | Between operator. This operator requires that the provided value be an array with exactly two elements: `[ min, max ]`. | | ||
/// | `<>` | Inverse (not) between operator. This operator requires that the provided value be an array with exactly two elements: `[ min, max ]`. | | ||
/// | `*` | A `LIKE` wildcard matching operator. The provided value should use `%` for "zero or more" matches, and `_` for "any single character" match. | | ||
/// | `!*` | A `NOT LIKE` wildcard matching operator. The provided value should use `%` for "zero or more" matches, and `_` for "any single character" match. | | ||
/// | ||
/// Note: | ||
/// This is a simple interface to take an "object" and turn it into | ||
/// a <see>QueryEngine</see>. It doesn't allow multiple models | ||
/// to be defined at once (table-joins), nor other complex operations. | ||
/// If you need more complex operations on your query, you will need | ||
/// to manually create your query... though this method can be used | ||
/// as a starting point. | ||
/// | ||
/// Arguments: | ||
/// connection: <see>Connection</see> | ||
/// The connection used to create the <see>QueryEngine</see>. | ||
/// Model: class <see>Model</see> | ||
/// The model the query is being generated for. The specified | ||
/// fields provided via the `filter` argument should all be from | ||
/// this model. | ||
/// filter: object | Array | ||
/// An object or an array of objects to build a query from. Any | ||
/// object will have all its properties `AND`ed together... whereas | ||
/// any array will have its sub-objects `OR`ed together. i.e. | ||
/// `[ { prop1 AND prop2 AND prop3 } OR { prop1 AND prop2 AND prop3 } ]`. | ||
/// | ||
/// Return: <see>QueryEngine</see> | ||
/// The new query for the `Model` provided, generated from the | ||
/// provided `filter` argument. | ||
function generateQueryFromFilter(connection, Model, _filter, _depth) { | ||
@@ -186,3 +249,31 @@ const getOperator = (name) => { | ||
function margeFields(queryEngine, currentFields, _incomingFields, extraData, _options) { | ||
/// Merge fields for a `PROJECT`, `ORDER`, | ||
/// or `GROUP_BY` <see>QueryEngine</see> operation. | ||
/// | ||
/// See <see>ModelScope.mergeFields</see> for a more detailed description | ||
/// of what this method does and how it is used. | ||
/// | ||
/// Arguments: | ||
/// queryEngine: <see>QueryEngine</see> | ||
/// The <see>QueryEngine</see> instance that the `PROJECT`, | ||
/// `ORDER`, or `GROUP_BY` operation is being applied to. | ||
/// currentFields: Map<string, object> | ||
/// A map of the current fields that have been applied to the | ||
/// given operation. | ||
/// incomingFields: Array<string | Literal | Model | Field> | ||
/// A list of all the incoming fields that are supplied to the | ||
/// `PROJECT`, `ORDER`, or `GROUP_BY` operation that is being carried | ||
/// out. This will either merge will `currentFields`, or replace | ||
/// the `currentFields`, depending on the content of this argument. | ||
/// extraData?: object | ||
/// If supplied, then merge these extra properties into each field being | ||
/// added to the list of fields. This is used for example by the `ORDER` | ||
/// operation to define the `direction` property for each field added. | ||
/// options?: object | ||
/// Options for the operation. These are only used when stringifying | ||
/// literals that are being added to the field list. See <see>LiteralBase.toString</see> | ||
/// for more information. | ||
/// | ||
/// See: ModelScope.mergeFields | ||
function mergeFields(queryEngine, currentFields, _incomingFields, extraData, _options) { | ||
const RESET = 0; | ||
@@ -263,3 +354,3 @@ const ADD = 1; | ||
if (!connection) | ||
throw new Error('QueryUtils::margeFields: "connection" is required, but not found.'); | ||
throw new Error('QueryUtils::mergeFields: "connection" is required, but not found.'); | ||
@@ -286,3 +377,3 @@ let result = incomingField.toString(connection, options); | ||
if (!connection) | ||
throw new Error('QueryUtils::margeFields: "connection" is required, but not found.'); | ||
throw new Error('QueryUtils::mergeFields: "connection" is required, but not found.'); | ||
@@ -339,3 +430,3 @@ if (!incomingField) | ||
if (!Model) | ||
throw new Error(`QueryUtils::margeFields: Model "${def.modelName}" not found.`); | ||
throw new Error(`QueryUtils::mergeFields: Model "${def.modelName}" not found.`); | ||
@@ -351,3 +442,3 @@ if (Nife.isEmpty(def.fieldNames)) { | ||
if (!field) | ||
throw new Error(`QueryUtils::margeFields: Field "${fieldName}" not found.`); | ||
throw new Error(`QueryUtils::mergeFields: Field "${fieldName}" not found.`); | ||
@@ -364,3 +455,3 @@ let fullFieldName = `${modelName}:${fieldName}`; | ||
generateQueryFromFilter, | ||
margeFields, | ||
mergeFields, | ||
}; |
{ | ||
"name": "mythix-orm", | ||
"version": "1.12.0", | ||
"version": "1.13.1", | ||
"description": "ORM for Mythix framework", | ||
@@ -5,0 +5,0 @@ "main": "lib/index", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
842515
19477