finish TreeModel implementation and updateMany builder method

This commit is contained in:
2022-09-12 12:36:33 -05:00
parent f63891ef99
commit c966904418
13 changed files with 580 additions and 44 deletions

View File

@@ -9,8 +9,8 @@ import {
SpecifiedField,
} from '../types'
import {Connection} from '../connection/Connection'
import {deepCopy, ErrorWithContext, Maybe} from '../../util'
import {EscapeValue, QuerySafeValue, raw} from '../dialect/SQLDialect'
import {Collectable, deepCopy, ErrorWithContext, Maybe} from '../../util'
import {EscapeValue, QuerySafeValue, raw, ScalarEscapeValue, VectorEscapeValue} from '../dialect/SQLDialect'
import {ResultCollection} from './result/ResultCollection'
import {AbstractResultIterable} from './result/AbstractResultIterable'
import {AppClass} from '../../lifecycle/AppClass'
@@ -310,7 +310,7 @@ export abstract class AbstractBuilder<T> extends AppClass {
* @param field
* @param values
*/
whereIn(field: string, values: EscapeValue): this {
whereIn<TConstraint extends ScalarEscapeValue>(field: string, values: VectorEscapeValue<TConstraint>): this {
this.constraints.push({
field,
operator: 'IN',
@@ -325,7 +325,7 @@ export abstract class AbstractBuilder<T> extends AppClass {
* @param field
* @param values
*/
whereNotIn(field: string, values: EscapeValue): this {
whereNotIn<TConstraint extends ScalarEscapeValue>(field: string, values: VectorEscapeValue<TConstraint>): this {
this.constraints.push({
field,
operator: 'NOT IN',
@@ -340,7 +340,7 @@ export abstract class AbstractBuilder<T> extends AppClass {
* @param field
* @param values
*/
orWhereIn(field: string, values: EscapeValue): this {
orWhereIn<TConstraint extends ScalarEscapeValue>(field: string, values: VectorEscapeValue<TConstraint>): this {
this.constraints.push({
field,
operator: 'IN',
@@ -355,7 +355,7 @@ export abstract class AbstractBuilder<T> extends AppClass {
* @param field
* @param values
*/
orWhereNotIn(field: string, values: EscapeValue): this {
orWhereNotIn<TConstraint extends ScalarEscapeValue>(field: string, values: VectorEscapeValue<TConstraint>): this {
this.constraints.push({
field,
operator: 'NOT IN',
@@ -528,6 +528,35 @@ export abstract class AbstractBuilder<T> extends AppClass {
return this.registeredConnection.query(query)
}
/**
* Run a batch update on all rows matched by this query, setting the values for discrete
* rows based on some key.
*
* This is a more efficient way of combining discrete update queries.
*
* @example
* ```ts
* query.table('my_table')
* .updateMany('id_col', [
* {id_col: 1, val1_col: 'a'},
* {id_col: 2, val2_col: 'b'},
* ])
* ```
*
* This will set the `val1_col` to `a` for rows where `id_col` is `1` and so on.
*
* @param key
* @param rows
*/
async updateMany(key: string, rows: Collectable<{[key: string]: EscapeValue}>): Promise<QueryResult> {
if ( !this.registeredConnection ) {
throw new ErrorWithContext(`No connection specified to execute update query.`)
}
const query = this.registeredConnection.dialect().renderBatchUpdate(this, key, rows)
return this.registeredConnection.query(query)
}
/**
* Execute a DELETE based on this query.
*
@@ -600,6 +629,15 @@ export abstract class AbstractBuilder<T> extends AppClass {
return Boolean(result.rows.first())
}
/** Render the query as a string. */
toString(): string {
if ( !this.registeredConnection ) {
throw new ErrorWithContext('No connection specified to render query.')
}
return this.registeredConnection.dialect().renderSelect(this.finalize())
}
/**
* Set the query manually. Overrides any builder methods.
* @example
@@ -615,6 +653,12 @@ export abstract class AbstractBuilder<T> extends AppClass {
return this
}
/** Pass this instance into a callback, then return this instance for chaining. */
tap(callback: (inst: this) => unknown): this {
callback(this)
return this
}
/**
* Adds a constraint to this query. This is used internally by the various `where`, `whereIn`, `orWhereNot`, &c.
* @param preop