ServerQueryBuilder
sourceServer-side query builder.
Queries are written by starting from a context and a model, and applying join, filter, and sort clauses to refine the row selection. Then, the query is materialised into a View, at which point it is evaluated.
The most basic form of query just selects rows of a model:
from(Account).select() // get all rows
from(Account).selectFirst() // get the first row
from(Account).selectCount() // get the total number of rows
Left joins can be done on foreign key fields.
from(AccountUser).leftJoin("Account").select()
Joins may also be done upon joined foreign key fields.
from(AccountUser)
.leftJoin("Account")
.leftJoin("Account.ParentAccount")
.select()
Filtering and sorting can be done using the where() and orderBy() clauses.
from(AccountUser)
.leftJoin("Account")
.where(ne("Account.Deleted", true))
.orderBy(asc("Account.Name"))
.select()
By default, queries exclude deleted records. To include deleted records, opt-in using the .includeDeleted() method:
from(Account)
.includeDeleted()
.select()
Constructors
new ServerQueryBuilder<T extends Model<string, T> = Model<string>, F extends string | number | symbol = keyof T, LeftJoined = never, InnerJoined = never>(context: Context, sourceModel: ModelType<T>): ServerQueryBuildersource
Properties
context: Contextsource
filter: FilterPredicate[]source
inherited from
Query.filter
Filter predicates to reduce the resultset. These can refer to joined fields.
inherited from
Query.joins
Join specifications for adding columns from other models.
model: ModelType<T>source
inherited from
Query.model
The primary source model for the query.
selectedFields: keyof T[]source
sort: SortPredicate[]source
inherited from
Query.sort
Sort predicates to order the resultset. These can refer to joined fields.
cookInputs: booleansource
Whether or not to preparse filter predicates.
This is used by the websocket-server REPL, to allow predicates to be entered in a more convenient fashion (e.g. using strings instead of fully qualified enums). This adds some overhead, so it is not enabled all the time.
Within this library we have no way of knowing whether or not we are executing within a REPL context, so we have the REPL server set this flag while evaluating user input.
Methods
Static methods
fromContextAndModel<T extends Model<string, T>>(context: Context, model: ModelType<T>): ServerQueryBuildersource
For internal use. Use from instead.
fromContextAndQuery<T extends Model<string, T>>(context: Context, query: Query): ServerQueryBuildersource
For internal use. Use from instead.
fromExistingView<T extends Model<string, T>>(view: View): ServerQueryBuildersource
For internal use. Use from instead.
Instance methods
all(): T[]source
Executes the query and returns the resultset as an array.
get(id: Id<T>): undefined | Tsource
Fetch a single record using its primary key.
innerJoin<FKs extends Exclude<ForeignKeyIn<T>, InnerJoined>[]>(foreignKeyFields: FKs): ServerQueryBuildersource
Nominates the foreign key fields upon which to perform a inner join. Multiple foreign key fields may be specified in a single innerJoin() call. If joining on joined fields, each stage of the join must be a separate call. For example:
from(Foo).innerJoin("Bar", "Baz").innerJoin("Baz.Luhrmann")
innerJoinOnPredicates<U extends Model<string, U>, AsName extends string>(rightQuery: ServerQueryBuilder, asName: AsName, joinPredicates: ExactJoinPredicate[]): ServerQueryBuildersource
Nominates a second query upon which to perform an inner join. The first argument is the query; the second argument is the name with which to prefix the joined fields; the remaining arguments are the boolean predicates upon which to conduct the join. For example:
from(Model.SecurityValues)
.innerJoinOnPredicates(
from(Model.Security),
"ParentSecurity",
eq("SecurityValues.Security", "ParentSecurity.Id"),
)
The join performed is an inner join. Only the first of each matching tuple will be selected, so as to preserve the uniqueness of the key field on the left-hand side. To control which record is matched, use filter and/or sort clauses on the right-hand query. For example:
from(Model.SecurityValues)
.innerJoinOnPredicates(
from(Model.Security)
.where(contains("Label", "ABC-"))
.orderBy(asc("Issuer")),
"ParentSecurity",
eq("SecurityValues.Security", "ParentSecurity.Id"),
)
This is the generic form of inner join. If the join is on a foreign key, the simpler form .innerJoin("ForeignField") should be used instead.
leftJoin<FKs extends Exclude<ForeignKeyIn<T>, LeftJoined>[]>(foreignKeyFields: FKs): ServerQueryBuildersource
Nominates the foreign key fields upon which to perform a left equijoin. Multiple foreign key fields may be specified in a single leftJoin() call. If joining on joined fields, each stage of the join must be a separate call. For example:
from(Foo).leftJoin("Bar", "Baz").leftJoin("Baz.Luhrmann")
leftJoinOnPredicates<U extends Model<string, U>, AsName extends string>(rightQuery: ServerQueryBuilder, asName: AsName, joinPredicates: ExactJoinPredicate[]): ServerQueryBuildersource
Nominates a second query upon which to perform a left outer join. The first argument is the query; the second argument is the name with which to prefix the joined fields; the remaining arguments are the boolean predicates upon which to conduct the join. For example:
from(SecurityValues)
.leftJoinOnPredicates(
from(Model.Security),
"ParentSecurity",
eq("SecurityValues.Security", "ParentSecurity.Id"),
)
The join performed is a left outer join, but only the first matching record from the right-hand side will be selected, so as to preserve the uniqueness of the key field on the left-hand side. To control which record is matched, use filter and/or sort clauses on the right-hand query. For example:
from(SecurityValues)
.leftJoinOnPredicates(
from(Security)
.where(contains("Label", "ABC-"))
.orderBy(asc("Issuer")),
"ParentSecurity",
eq("SecurityValues.Security", "ParentSecurity.Id"),
)
This is the generic form of left join. If the join is on a foreign key, the simpler form .leftJoin("ForeignField") should be used instead.
map<U>(transformFn: Function): U[]source
Executes the query and returns an array constructed by applying the given transformation function to each record of the resultset.
orderBy(predicates: undefined | SortPredicate<T>[]): ServerQueryBuildersource
Nominates the order by which to sort the resultset. The ordering consists of one or more sort predicates. For example:
from(Account).orderBy(desc("OpenDate"), asc("Name"))
select<Fs extends keyof T[]>(fields: Fs): ServerQueryBuildersource
Selects which fields to include in the resultset.
selectCount(): numbersource
Returns the total number of records in the resultset.
selectFirst(): undefined | Tsource
Returns the first record in the resultset.
toMetadata(): QueryReflectionMetadatasource
Returns the reflection metadata for this query.
toPersistentView(): Handlesource
Materialises this query into a live updating View.
useSlice(slice: Slice): Pagesource
Returns a live Page of the resultset.
useSlice(offset: number, count: number): Pagesource
where(predicates: FilterPredicate[]): ServerQueryBuildersource
Sets the criteria by which to filter the resultset. The filter consists of one or more filter predicates. For example:
from(Account).where(eq("AccountType", AccountType.Issuer))
from(Account).where(not(isNull("ClosedDate")))
Conjunctions may be created by nesting predicates such as all, any, and not. There is (currently) no limit to the level of nesting permitted, although very complex expressions should be avoided.
whereIf<V>(maybeValue: undefined | V, receiver: Function): ServerQueryBuildersource
Conditionally adds filter criteria. The second argument must be a function that accepts a value and returns a filter predicate. If the first argument is not undefined, its value is passed to the second argument. This is useful for adding conditional clauses without breaking out of the builder chain. For example:
from(AuctionAccount)
.where(eq("Auction", auctionId))
.whereIf(accountId, accountId => eq("Account", accountId))
This filters the AuctionAccount model by the Auction field, and then also by Account field if the value of accountId is not undefined.
Inherited methods
as<U extends Model<string, U>>(): Querysource
inherited from
Query.as
getFromClause(): stringsource
inherited from
Query.getFromClause
getJoinClauses(): string[]source
inherited from
Query.getJoinClauses
getOrderByClauses(): string[]source
inherited from
Query.getOrderByClauses
getWhereClauses(): string[]source
inherited from
Query.getWhereClauses
inherited from
Query.toHash
toJSON(): objectsource
inherited from
Query.toJSON
toString(): stringsource
inherited from
Query.toString
applyFieldGuards<T>(target: AbstractCtor<T>, item: any, tracer: Tracer): Maybe<T>source
inherited from
Query.applyFieldGuards
isModelType(value: any): undefined | ModelType<Model<string>>source
inherited from
Query.isModelType
validate<T extends ValidatableType<T>>(this: AbstractCtor<T> & CanHaveValidateHook<T>, item: any, tracer: Tracer = ...): Maybe<T>source
inherited from
Query.validate
validateHook<K extends keyof Query<Model<string>>>(field: K, item: Query, tracer: Tracer): undefined | Maybe<Query<Model<string>>[K]>source
inherited from
Query.validateHook
withFields<T extends FieldDict>(fields: T): Validatable<MaterialisedType<T>> & Ctor<MaterialisedType<T>>source
inherited from
Query.withFields