UNPKG

@leansdk/leanrc

Version:

LeanRC is a MVC framework for creating graceful applications

295 lines (269 loc) 9.32 kB
# This file is part of LeanRC. # # LeanRC is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # LeanRC is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with LeanRC. If not, see <https://www.gnu.org/licenses/>. ### в Ember app это может выглядить так. ```coffee cucumber = {id: 123} @store.query 'user', $and: [ '@doc.cucumberId': {$eq: cucumber.id} '@doc.price': {$gt: 85} ] ``` ### # надо определить символ, который будет говорить об использовании объявленной переменной (ссылки), чтобы в случае когда должна ретюрниться простая строка, в объявлении просто не было символа. можно заиспользовать '@' ### example ```coffee new Query() .forIn '@doc': 'users' .forIn '@tomato': 'tomatos' .let '@user_cucumbers': $forIn: '@cucumber': 'cucumbers' $filter: $and: [ '@doc.cucumberId': {$eq: '@cucumber._key'} '@cucumber.price': {$gt: 85} ] $return: '@cucumber' .join '@doc.tomatoId': {$eq: '@tomato._key'} '@tomato.active': {$eq: yes} .filter '@doc.active': {$eq: yes} .sort '@doc.firstName': 'DESC' .limit 10 .offset 10 .return {user: '@user', cucumbers: '@user_cucumbers', tomato: '@tomato'} ``` But it equvalent json ``` { $forIn: '@doc': 'users', '@tomato': 'tomatos' $let: '@user_cucumbers': $forIn: '@cucumber': 'cucumbers' $filter: $and: [ '@doc.cucumberId': {$eq: '@cucumber._key'} '@cucumber.price': {$gt: 85} ] $return: '@cucumber' $join: $and: [ '@doc.tomatoId': {$eq: '@tomato._key'} '@tomato.active': {$eq: yes} ] $filter: '@doc.active': {$eq: yes} $sort: ['@doc.firstName': 'DESC'] $limit: 10 $offset: 10 $return: {user: '@user', cucumbers: '@user_cucumbers', tomato: '@tomato'} } ``` example for collect ``` { $forIn: '@doc': 'users' $filter: '@doc.active': {$eq: yes} $collect: '@country': '@doc.country', '@city': '@doc.city' $into: '@groups': {name: '@doc.name', isActive: '@doc.active'} $having: '@country': {$nin: ['Australia', 'Ukraine']} $return: {country: '@country', city: '@city', usersInCity: '@groups'} } # or { $forIn: '@doc': 'users' $filter: '@doc.active': {$eq: yes} $collect: '@ageGroup': 'FLOOR(@doc.age / 5) * 5' $aggregate: '@minAge': 'MIN(@doc.age)', '@maxAge': 'MAX(@doc.age)' $return: {ageGroup: '@ageGroup', minAge: '@minAge', maxAge: '@maxAge'} } ``` ### module.exports = (Module)-> { AnyT FuncG, SubsetG, UnionG, MaybeG QueryInterface CoreObject Utils: { _ } } = Module:: class Query extends CoreObject @inheritProtected() @implements QueryInterface @module Module # TODO: это надо переделать на нормальную проверку типа в $filter @public @static operatorsMap: Object, default: $and: Array $or: Array $not: Object $nor: Array # not or # !(a||b) === !a && !b # без вложенных условий и операторов - value конечное значение для сравнения $eq: AnyT # == $ne: AnyT # != $lt: AnyT # < $lte: AnyT # <= $gt: AnyT # > $gte: AnyT # >= $in: Array # check value present in array $nin: Array # ... not present in array # field has array of values $all: Array # contains some values $elemMatch: Object # conditions for complex item $size: Number # condition for array length $exists: Boolean # condition for check present some value in field $type: String # check value type $mod: Array # [divisor, remainder] for example [4,0] делится ли на 4 $regex: UnionG RegExp, String # value must be string. ckeck it by RegExp. $td: Boolean # this day (today) $ld: Boolean # last day (yesterday) $tw: Boolean # this week $lw: Boolean # last week $tm: Boolean # this month $lm: Boolean # last month $ty: Boolean # this year $ly: Boolean # last year @public $forIn: MaybeG Object @public $join: MaybeG Object @public $let: MaybeG Object @public $filter: MaybeG Object @public $collect: MaybeG Object @public $into: MaybeG UnionG String, Object @public $having: MaybeG Object @public $sort: MaybeG Array @public $limit: MaybeG Number @public $offset: MaybeG Number @public $avg: MaybeG String # '@doc.price' @public $sum: MaybeG String # '@doc.price' @public $min: MaybeG String # '@doc.price' @public $max: MaybeG String # '@doc.price' @public $count: MaybeG Boolean # yes or not present @public $distinct: MaybeG Boolean # yes or not present @public $remove: MaybeG UnionG String, Object @public $patch: MaybeG Object @public $return: MaybeG UnionG String, Object @public forIn: FuncG(Object, QueryInterface), default: (aoDefinitions)-> for own k, v of aoDefinitions @$forIn[k] = v return @ @public join: FuncG(Object, QueryInterface), # критерии связывания как в SQL JOIN ... ON default: (aoDefinitions)-> @$join = aoDefinitions return @ @public filter: FuncG(Object, QueryInterface), default: (aoDefinitions)-> @$filter = aoDefinitions return @ @public let: FuncG(Object, QueryInterface), default: (aoDefinitions)-> @$let ?= {} for own k, v of aoDefinitions @$let[k] = v return @ @public collect: FuncG(Object, QueryInterface), default: (aoDefinition)-> @$collect = aoDefinition return @ @public into: FuncG([UnionG String, Object], QueryInterface), default: (aoDefinition)-> @$into = aoDefinition return @ @public having: FuncG(Object, QueryInterface), default: (aoDefinition)-> @$having = aoDefinition return @ @public sort: FuncG(Object, QueryInterface), default: (aoDefinition)-> @$sort ?= [] @$sort.push aoDefinition return @ @public limit: FuncG(Number, QueryInterface), default: (anValue)-> @$limit = anValue return @ @public offset: FuncG(Number, QueryInterface), default: (anValue)-> @$offset = anValue return @ @public distinct: FuncG([], QueryInterface), default: -> @$distinct = yes return @ @public remove: FuncG([UnionG String, Object], QueryInterface), default: (expr = yes)-> @$remove = expr return @ @public patch: FuncG(Object, QueryInterface), default: (aoDefinition)-> @$patch = aoDefinition return @ @public return: FuncG([UnionG String, Object], QueryInterface), default: (aoDefinition)-> @$return = aoDefinition return @ @public count: FuncG([], QueryInterface), default: -> @$count = yes return @ @public avg: FuncG(String, QueryInterface), default: (asDefinition)-> @$avg = asDefinition return @ @public min: FuncG(String, QueryInterface), default: (asDefinition)-> @$min = asDefinition return @ @public max: FuncG(String, QueryInterface), default: (asDefinition)-> @$max = asDefinition return @ @public sum: FuncG(String, QueryInterface), default: (asDefinition)-> @$sum = asDefinition return @ @public @static @async restoreObject: FuncG([SubsetG(Module), Object], QueryInterface), default: (_Module, replica)-> if replica?.class is @name and replica?.type is 'instance' instance = @new replica.query yield return instance else return yield @super _Module, replica @public @static @async replicateObject: FuncG(QueryInterface, Object), default: (instance)-> replica = yield @super instance replica.query = instance.toJSON() yield return replica @public init: FuncG([MaybeG Object]), default: (aoQuery)-> @super arguments... @$forIn = {} if aoQuery? for own key, value of aoQuery do (key, value)=> @[key] = value return @public toJSON: FuncG([], Object), default: -> res = {} for k in [ '$forIn', '$join', '$let', '$filter', '$collect', '$into', '$having' '$sort', '$limit', '$offset', '$avg', '$sum', '$min', '$max', '$count' '$distinct', '$remove', '$patch', '$return' ] when @[k]? res[k] = @[k] return res @initialize()