Constructor
new CustomRepository(entityName)
Arguments:
-
entityName
(String)
 name of Entity we create for
Methods
using(methodName)
Retrieve a data from server using methodName
entity method.
By default select
method will be used.
Arguments:
-
methodName
(string)
attrs(attr) → CustomRepository
Add fields to collection.
Can take one attribute name as string or array of attributes.
Duplicate is not checked and in case of duplicate attribute caller got server error.
UB.Repository('tri_srf_reg').attrs('ID').attrs(['code', 'name']).attrs('fullName', 'newCode');
Can take expression as a field. In this case entity attribute name must be wrapped into [] brackets.
In case of client-side execution the only valid expression is one of:
- 'SUM', 'COUNT', 'AVG', 'MAX', 'MIN', 'CAST', 'COALESCE'
Example:
UB.Repository('tri_srf_reg').attrs('SUM([payment])').where('documentID', '=', value);
//will calculate sum of document payments
If case of server-side execution any valid SQL expression is accepted:
UB.Repository('uba_user').attrs('[ID] / 100 + 1').selectAsArray()
Arguments:
where(expression, condition, valuesopt, clauseNameopt) → CustomRepository
Add where expression. Fix some known issues:
if attribute name without brackets is passed to expression parameter then wrap attribute to brackets "ID" -> "[ID]"
transform some dummy expressions to more simple form: in ['one']
-> equal 'one',
in []->
0=1,
? null->
isNull` e.t.c.
expression may contains this functions: 'SUM', 'COUNT', 'AVG', 'MAX', 'MIN', 'CAST', 'COALESCE',
'LENGTH', 'LOWER', 'UPPER', 'DAY', 'MONTH', 'YEAR', 'ROUND', 'FLOOR', 'CEILING'
In
and 'notIn` conditions can take a sub-repository as a values parameter value. See CustomRepository.exists for a conplex example
Arguments:
-
expression
(String)
 Attribute name (with or without []) or valid expression with attributes in [].
-
condition
(WhereCondition|String)
 Any value from WhereCondition list.
-
[values]
(*)
 Condition value. In case expression is complex can take {Object} as value.
In case values === undefined no values property passed to where list
-
[clauseName]
(String)
 Optional clause name to be used in {CustomRepository.logicalPredicates}.
If not passed where will generate unique clause named 'c1', 'c2', ......
Example
UB.Repository('my_entity').attrs('id')
// code in ('1', '2', '3')
.where('code', 'in', ['1', '2', '3'])
// code in (select code from my_codes where id = 10)
.where('code', 'in', UB.Repository('my_codes').attr('code').where('ID', '<', 10)
// name like '%homer%'
.where('[name]', 'contains', 'Homer').
//(birtday >= '2012-01-01') AND (birtday <= '2012-01-02')
.where('[birtday]', 'geq', new Date()).where('birtday', 'leq', new Date() + 10)
// (age + 10 >= 15)
.where('[age] -10', '>=', {age: 15}, 'byAge')
.where('LENGTH([code]), '<', 5)
// for condition match expression not need
.where('', 'match', 'myvalue')
exists(subRepository, clauseNameopt) → CustomRepository
Add an expression with EXISTS
sub-query. Inside a sub-query there is two macro:
- {master} will be replaced by master entity alias
{self} will be replaced by sub-query entity alias
UB.Repository('uba_user').attrs(['ID', 'name']) //select users
// who are not disabled
.where('disabled', '=', 0)
// which allowed access from Kiev
.where('trustedIP', 'in',
UB.Repository('geo_ip').attrs('IPAddr')
.where('city', '=', 'Kiev')
)
// who do not login during this year
.notExists(
UB.Repository('uba_audit')
.correlation('actionUser', 'name') // here we link to uba_user.name
.where('actionTime', '>', new Date(2016, 1, 1))
.where('actionType', '=', 'LOGIN')
)
// but modify some data
.exists(
UB.Repository('uba_auditTrail')
.correlation('actionUser', 'ID') // here we link to uba_user.ID
.where('actionTime', '>', new Date(2016, 1, 1))
)
.select()
Arguments:
-
subRepository
(CustomRepository)
 Repository, what represent a sub-query to be execute inside EXISTS statement
-
[clauseName]
(String)
 Optional clause name
notExists(subRepository, clauseNameopt) → CustomRepository
Add an expression with NOT EXISTS
sub-query. See CustomRepository.exists for sample
Arguments:
-
subRepository
(CustomRepository)
 Repository, what represent a sub-query to be execute inside EXISTS statement
-
[clauseName]
(String)
 Optional clause name
correlation(subQueryAttribute, masterAttribute, conditionopt, clauseNameopt) → CustomRepository
If current repository are used as a sub-query for exists
, notExists
, in
or notIn
conditions
will add a correlation with a master repository
Arguments:
-
subQueryAttribute
(String)
-
masterAttribute
(String)
-
[condition=eq]
(WhereCondition|String)
 A subset from WhereCondition list applicable for correlation join
-
[clauseName]
(String)
 Optional clause name to be used in {CustomRepository.logicalPredicates}. If not passed where will generate unique clause named 'c1', 'c2', ......
logic(predicate) → CustomRepository
Arrange where expressions in logical order. By default where expressions is joined by AND logical predicate. Here is possible to join it in custom order.
UB.Repository('my_entity').attrs('id')
// code in ('1', '2', '3')
.where('code', 'in', ['1', '2', '3'], 'byCode')
// name like '%homer%'
.where('name', 'contains', 'Homer', 'byName')
//(birtday >= '2012-01-01') AND (birtday <= '2012-01-02')
.where('birtday', 'geq', new Date()).where('birtday', 'leq', new Date() + 10)
// (age + 10 >= 15)
.where('[age] -10', '>=', {age: 15}, 'byAge')
// (byCode OR byName) AND (all where items, not included in logic)
.logic('(([byCode]) OR ([byName]))')
Arguments:
-
predicate
(String)
 logical predicate.
join(whereItemName) → CustomRepository
Force where expressions to be used in join SQL statement instead of where. Applicable only for not cached entities.
// will generate
// SELECT A.ID, B.code FROM tst_document A LEFT JOIN tst_category B
// ON (B.instanceID = A.ID and B.ubUser = 10)
// instead of
// SELECT A.ID, B.code FROM tst_document A LEFT JOIN tst_category B
// ON B.instanceID = A.ID
// WHERE B.ubUser = 10
UB.Repository('tst_document').attrs(['ID', '[caregory.code]'])
.where('[caregory.ubUser]', '=', 10, 'wantInJoin')
.join('wantInJoin')
.selectAsObject().done(UB.logDebug);
Arguments:
-
whereItemName
(String)
 name of where item to use in join.
joinCondition(expression, condition, valuesopt, clauseNameopt) → CustomRepository
Add join condition. Fix some known issues
Arguments:
-
expression
(String)
 Attribute name (with or without []) or valid expression with attributes in [].
-
condition
(WhereCondition)
 Any value from WhereCondition list.
-
[values]
(*)
 Condition value. In case expression is complex can take {Object} as value.
In case values === undefined no values property passed to where list
-
[clauseName]
(String)
 Optional clause name to be used in {CustomRepository.logicalPredicates}. If not passed where will generate unique clause named 'c1', 'c2', ......
orderBy(attr, directionopt) → CustomRepository
Add sorting
UB.CustomRepository('my_entity').attrs('ID').orderBy('code')
Arguments:
-
attr
 Sorted attribute
-
[direction='asc']
 Sort direction ('asc'|'desc')
orderByDesc(attr) → CustomRepository
Add desc sorting. The same as orderBy(attr, 'desc')
UB.Repository('my_entity').attrs('ID')
// ORDER BY code, date_create DESC
.orderBy('code').orderByDesc('date_create')
Arguments:
-
attr
(String)
groupBy(attr) → CustomRepository
Add grouping
Can take one attribute name as string or array of attributes name
UB.Repository('my_entity').attrs('ID')
.groupBy('code')
UB.Repository('uba_user').attrs('disabled')
.groupBy('disabled').select()
UB.Repository('uba_user').attrs(['disabled','uPassword','COUNT([ID])'])
.groupBy(['disabled','uPassword']).select()
Arguments:
-
attr
 Grouped attribute
start(start) → CustomRepository
Add options.start value to retrieve first start
rows
let store = UB.Repository('my_entity').attrs('id')
//will return ID's from 15 to 25
.start(15).limit(10).select()
Arguments:
-
start
(Number)
limit(rowsLimit) → CustomRepository
Add options.limit value. Can be combined with start.
// will return first two ID's from my_entity
let store = UB.Repository('my_entity').attrs('id').limit(2).select()
Arguments:
-
rowsLimit
(number)
describe(value) → CustomRepository
For debug purpose only.
If set, in GUI mode will put this description into log before query execution
let store = UB.Repository('my_entity').attrs('ID').describe('Select all record for "my_entity"').select()
Arguments:
-
value
(String)
ubql() → Object
Construct a UBQL JSON request. Used in CustomRepository#select
let repo = UB.Repository('my_entity').attrs('ID').where('code', '=', 'a')
let inst = new TubDataStore(my_entity);
inst.run('select', repo.ubql());
selectAsObject()
abstract
Must be implemented in descendants and return (or resolved for async clients)
to array of object
representation of result, like this
[{"ID":3000000000004,"code":"uba_user"},{"ID":3000000000039,"code":"uba_auditTrail"}]
selectAsArray()
abstract
Must be implemented in descendants and return (or resolved for async clients)
to array of array
representation of result, like this
{"resultData":{"fields":["ID","name","ID.name"],"rowCount":1,"data":[[10,"admin","admin"]]},"total":1,"__totalRecCount": totolRecCountIfWithTotalRequest}
selectAsStore(storeConfigopt)
abstract
Must be implemented in descendants and return (or resolved for async clients)
to DataSet
class instance, implemented in caller level. It can be:
- {TubDataStore} for in-server context
- {UB.ux.data.UBStore} for UnityBase
adminUI
client
array of array
data representation for UnityBase remote connection
- etc.
Arguments:
-
[storeConfig]
select(storeConfigopt)
abstract
Must be implemented in descendants as a alias to the most appropriate method
Arguments:
-
[storeConfig]
selectSingle() → Object|undefined
abstract
Select a single row. If ubql result is empty - return {undefined}.
WARNING method do not check repository contains the single row and always return a first row from result.
selectScalar() → Object|undefined
abstract
Perform select and return a value of the first attribute from the first row
WARNING method do not check repository contains the single row
selectById(ID) → Object|undefined
abstract
Select a single row by ID. If ubql result is empty - return {undefined}
If result not empty - return a object
{attr1: val1, arrt2: val2}
for server side or Promise resolved to object for client
Arguments:
-
ID
(Number)
 Row identifier
misc(flags) → CustomRepository
Apply miscellaneous options to resulting ubRequest:
// this server-side call will select all currency, including deleted
UB.Repository('cdn_currency').attrs(['ID'])
.misc({__allowSelectSafeDeleted: true}).selectAsArray();
Arguments:
-
flags
(Object)
Properties
-
[__mip_ondate]
(Date)
 Specify date on which to select data for entities with dataHistory
mixin. Default to Now()
-
[__mip_recordhistory=false]
(Boolean)
 Select only record history data for specified ID (for entities with dataHistory
mixin)
-
[__mip_recordhistory_all=false]
(Boolean)
 Ignore __mip_ondate and select all data (acts as select for entities without dataHistory
mixin)
-
[__mip_disablecache=false]
(Boolean)
 For entities with cacheType in ["Session", "SessionEntity"] not check is data modified and always return result
-
[__skipOptimisticLock=false]
(Boolean)
 Skip optimistic lock for entities with mStorage.simpleAudit = true
-
[__allowSelectSafeDeleted=false]
(Boolean)
 Server-side only.
-
[__skipSelectAfterUpdate=false]
(Boolean)
 Server-side only.
-
[__skipSelectAfterInsert=false]
(Boolean)
 Server-side only.
-
[__skipRls=false]
(Boolean)
 Server-side only.
-
[__skipAclRls=false]
(Boolean)
 Server-side only.
withTotal() → CustomRepository
Calculate total row number. WARNING!! This is VERY slow operation on DB level in case of many record
Result of calculation is returned in __totalRecCount parameter value in case selectAsArray()
client call:
let result = UB.Repository('uba_user').attrs(['ID', 'description'])
.withTotal().selectAsArray();
console.log('Total count is:', result.__totalRecCount)
Or into TubDataStore.totalRowCount in case of server side selectAsStore()
call:
let store = UB.Repository('uba_user').attrs(['ID', 'description'])
.withTotal().selectAsStore();
console.log('Total count is:', store.totalRowCount);
methodName
entity method.
By default select
method will be used.
methodName
(string)
Add fields to collection. Can take one attribute name as string or array of attributes. Duplicate is not checked and in case of duplicate attribute caller got server error.
UB.Repository('tri_srf_reg').attrs('ID').attrs(['code', 'name']).attrs('fullName', 'newCode');
Can take expression as a field. In this case entity attribute name must be wrapped into [] brackets. In case of client-side execution the only valid expression is one of:
- 'SUM', 'COUNT', 'AVG', 'MAX', 'MIN', 'CAST', 'COALESCE'
Example:
UB.Repository('tri_srf_reg').attrs('SUM([payment])').where('documentID', '=', value);
//will calculate sum of document payments
If case of server-side execution any valid SQL expression is accepted:
UB.Repository('uba_user').attrs('[ID] / 100 + 1').selectAsArray()
if attribute name without brackets is passed to expression parameter then wrap attribute to brackets "ID" -> "[ID]"
transform some dummy expressions to more simple form:
in ['one']
->equal 'one',
in []->
0=1,
? null->
isNull` e.t.c.expression may contains this functions: 'SUM', 'COUNT', 'AVG', 'MAX', 'MIN', 'CAST', 'COALESCE', 'LENGTH', 'LOWER', 'UPPER', 'DAY', 'MONTH', 'YEAR', 'ROUND', 'FLOOR', 'CEILING'
In
and 'notIn` conditions can take a sub-repository as a values parameter value. See CustomRepository.exists for a conplex example
expression
(String)
 Attribute name (with or without []) or valid expression with attributes in [].
condition
(WhereCondition|String)
 Any value from WhereCondition list.
[values]
(*)
 Condition value. In case expression is complex can take {Object} as value.
In case values === undefined no values property passed to where list
[clauseName]
(String)
 Optional clause name to be used in {CustomRepository.logicalPredicates}.
If not passed where will generate unique clause named 'c1', 'c2', ......
UB.Repository('my_entity').attrs('id')
// code in ('1', '2', '3')
.where('code', 'in', ['1', '2', '3'])
// code in (select code from my_codes where id = 10)
.where('code', 'in', UB.Repository('my_codes').attr('code').where('ID', '<', 10)
// name like '%homer%'
.where('[name]', 'contains', 'Homer').
//(birtday >= '2012-01-01') AND (birtday <= '2012-01-02')
.where('[birtday]', 'geq', new Date()).where('birtday', 'leq', new Date() + 10)
// (age + 10 >= 15)
.where('[age] -10', '>=', {age: 15}, 'byAge')
.where('LENGTH([code]), '<', 5)
// for condition match expression not need
.where('', 'match', 'myvalue')
Add an expression with EXISTS
sub-query. Inside a sub-query there is two macro:
- {master} will be replaced by master entity alias
{self} will be replaced by sub-query entity alias
UB.Repository('uba_user').attrs(['ID', 'name']) //select users
// who are not disabled .where('disabled', '=', 0) // which allowed access from Kiev .where('trustedIP', 'in', UB.Repository('geo_ip').attrs('IPAddr') .where('city', '=', 'Kiev') ) // who do not login during this year .notExists( UB.Repository('uba_audit') .correlation('actionUser', 'name') // here we link to uba_user.name .where('actionTime', '>', new Date(2016, 1, 1)) .where('actionType', '=', 'LOGIN') ) // but modify some data .exists( UB.Repository('uba_auditTrail') .correlation('actionUser', 'ID') // here we link to uba_user.ID .where('actionTime', '>', new Date(2016, 1, 1)) ) .select()
subRepository
(CustomRepository)
 Repository, what represent a sub-query to be execute inside EXISTS statement
[clauseName]
(String)
 Optional clause name
NOT EXISTS
sub-query. See CustomRepository.exists for sample
subRepository
(CustomRepository)
 Repository, what represent a sub-query to be execute inside EXISTS statement
[clauseName]
(String)
 Optional clause name
exists
, notExists
, in
or notIn
conditions
will add a correlation with a master repository
subQueryAttribute
(String)
masterAttribute
(String)
[condition=eq]
(WhereCondition|String)
 A subset from WhereCondition list applicable for correlation join
[clauseName]
(String)
 Optional clause name to be used in {CustomRepository.logicalPredicates}. If not passed where will generate unique clause named 'c1', 'c2', ......
Arrange where expressions in logical order. By default where expressions is joined by AND logical predicate. Here is possible to join it in custom order.
UB.Repository('my_entity').attrs('id')
// code in ('1', '2', '3')
.where('code', 'in', ['1', '2', '3'], 'byCode')
// name like '%homer%'
.where('name', 'contains', 'Homer', 'byName')
//(birtday >= '2012-01-01') AND (birtday <= '2012-01-02')
.where('birtday', 'geq', new Date()).where('birtday', 'leq', new Date() + 10)
// (age + 10 >= 15)
.where('[age] -10', '>=', {age: 15}, 'byAge')
// (byCode OR byName) AND (all where items, not included in logic)
.logic('(([byCode]) OR ([byName]))')
predicate
(String)
 logical predicate.
Force where expressions to be used in join SQL statement instead of where. Applicable only for not cached entities.
// will generate
// SELECT A.ID, B.code FROM tst_document A LEFT JOIN tst_category B
// ON (B.instanceID = A.ID and B.ubUser = 10)
// instead of
// SELECT A.ID, B.code FROM tst_document A LEFT JOIN tst_category B
// ON B.instanceID = A.ID
// WHERE B.ubUser = 10
UB.Repository('tst_document').attrs(['ID', '[caregory.code]'])
.where('[caregory.ubUser]', '=', 10, 'wantInJoin')
.join('wantInJoin')
.selectAsObject().done(UB.logDebug);
whereItemName
(String)
 name of where item to use in join.
expression
(String)
 Attribute name (with or without []) or valid expression with attributes in [].
condition
(WhereCondition)
 Any value from WhereCondition list.
[values]
(*)
 Condition value. In case expression is complex can take {Object} as value.
In case values === undefined no values property passed to where list
[clauseName]
(String)
 Optional clause name to be used in {CustomRepository.logicalPredicates}. If not passed where will generate unique clause named 'c1', 'c2', ......
Add sorting
UB.CustomRepository('my_entity').attrs('ID').orderBy('code')
attr
 Sorted attribute
[direction='asc']
 Sort direction ('asc'|'desc')
Add desc sorting. The same as orderBy(attr, 'desc')
UB.Repository('my_entity').attrs('ID')
// ORDER BY code, date_create DESC
.orderBy('code').orderByDesc('date_create')
attr
(String)
Add grouping Can take one attribute name as string or array of attributes name
UB.Repository('my_entity').attrs('ID')
.groupBy('code')
UB.Repository('uba_user').attrs('disabled')
.groupBy('disabled').select()
UB.Repository('uba_user').attrs(['disabled','uPassword','COUNT([ID])'])
.groupBy(['disabled','uPassword']).select()
attr
 Grouped attribute
Add options.start value to retrieve first start
rows
let store = UB.Repository('my_entity').attrs('id')
//will return ID's from 15 to 25
.start(15).limit(10).select()
start
(Number)
Add options.limit value. Can be combined with start.
// will return first two ID's from my_entity
let store = UB.Repository('my_entity').attrs('id').limit(2).select()
rowsLimit
(number)
For debug purpose only.
If set, in GUI mode will put this description into log before query execution
let store = UB.Repository('my_entity').attrs('ID').describe('Select all record for "my_entity"').select()
value
(String)
Construct a UBQL JSON request. Used in CustomRepository#select
let repo = UB.Repository('my_entity').attrs('ID').where('code', '=', 'a')
let inst = new TubDataStore(my_entity);
inst.run('select', repo.ubql());
Must be implemented in descendants and return (or resolved for async clients)
to array of object
representation of result, like this
[{"ID":3000000000004,"code":"uba_user"},{"ID":3000000000039,"code":"uba_auditTrail"}]
Must be implemented in descendants and return (or resolved for async clients)
to array of array
representation of result, like this
{"resultData":{"fields":["ID","name","ID.name"],"rowCount":1,"data":[[10,"admin","admin"]]},"total":1,"__totalRecCount": totolRecCountIfWithTotalRequest}
Must be implemented in descendants and return (or resolved for async clients)
to DataSet
class instance, implemented in caller level. It can be:
- {TubDataStore} for in-server context
- {UB.ux.data.UBStore} for UnityBase
adminUI
client array of array
data representation for UnityBase remote connection- etc.
[storeConfig]
[storeConfig]
WARNING method do not check repository contains the single row and always return a first row from result.
WARNING method do not check repository contains the single row
If result not empty - return a object
{attr1: val1, arrt2: val2}
for server side or Promise resolved to object for client
ID
(Number)
 Row identifier
Apply miscellaneous options to resulting ubRequest:
// this server-side call will select all currency, including deleted
UB.Repository('cdn_currency').attrs(['ID'])
.misc({__allowSelectSafeDeleted: true}).selectAsArray();
flags
(Object)
Properties
-
[__mip_ondate]
(Date)
 Specify date on which to select data for entities withdataHistory
mixin. Default to Now() -
[__mip_recordhistory=false]
(Boolean)
 Select only record history data for specified ID (for entities withdataHistory
mixin) -
[__mip_recordhistory_all=false]
(Boolean)
 Ignore __mip_ondate and select all data (acts as select for entities withoutdataHistory
mixin) -
[__mip_disablecache=false]
(Boolean)
 For entities with cacheType in ["Session", "SessionEntity"] not check is data modified and always return result -
[__skipOptimisticLock=false]
(Boolean)
 Skip optimistic lock for entities withmStorage.simpleAudit = true
-
[__allowSelectSafeDeleted=false]
(Boolean)
 Server-side only. -
[__skipSelectAfterUpdate=false]
(Boolean)
 Server-side only. -
[__skipSelectAfterInsert=false]
(Boolean)
 Server-side only. -
[__skipRls=false]
(Boolean)
 Server-side only. -
[__skipAclRls=false]
(Boolean)
 Server-side only.
Calculate total row number. WARNING!! This is VERY slow operation on DB level in case of many record
Result of calculation is returned in __totalRecCount parameter value in case selectAsArray()
client call:
let result = UB.Repository('uba_user').attrs(['ID', 'description'])
.withTotal().selectAsArray();
console.log('Total count is:', result.__totalRecCount)
Or into TubDataStore.totalRowCount in case of server side selectAsStore()
call:
let store = UB.Repository('uba_user').attrs(['ID', 'description'])
.withTotal().selectAsStore();
console.log('Total count is:', store.totalRowCount);