Commit 7ac36b1a authored by William Naslund's avatar William Naslund

Added some basic conditions

parent f6f5cd84
import { DBCompoundCondition } from "./compound-condition";
/** A condition where all contained conditions must be met */
export class DBAnd extends DBCompoundCondition {
joiningSQL() {
return 'AND';
}
}
import { DBCondition } from "./db-condition";
/** A condition that combines other conditions */
export abstract class DBCompoundCondition implements DBCondition {
/** The parameters from each condition */
private conditionParameters: any[];
constructor(
protected readonly conditions: DBCondition[]
) { }
/** Returns the SQL to be placed in between each condition */
protected abstract joiningSQL(): string;
sql() {
const conditionSQL: string[] = [];
this.conditionParameters = [];
for(const condition of this.conditions) {
conditionSQL.push( offsetPlaceholders(condition.sql(), this.conditionParameters.length) );
if(condition.parameters != null) {
for(const param of condition.parameters()) {
this.conditionParameters.push(param);
}
}
}
if(conditionSQL.length < 1) return '';
else return `(${conditionSQL.join(' ' + this.joiningSQL() + ' ')})`;
}
parameters() {
if(this.conditionParameters == null) {
this.sql();
}
return this.conditionParameters;
}
}
/** Updates all placeholder arguments ($X) by adding a number to them */
export function offsetPlaceholders(sql: string, offset: number): string {
if(sql == null) return null;
return sql.replace(/\$(\d+)/g, (_, numberText) => {
const originalNumber = parseInt(numberText, 10);
return `$${originalNumber + offset}`;
});
}
/** Base interface for classes that are used to filter based on a certain condition */
export interface DBCondition {
/** Returns the SQL for this condition, to be used in a the WHERE section of a SELECT */
sql(): string;
/** Returns any query parameters that need to be included in the query */
parameters?(): any[];
}
import { DBCondition } from "./db-condition";
/** A condition where a value is exactly equal */
export class DBEquals implements DBCondition {
constructor(
private readonly value: any
) { }
sql() {
return `= $1`;
}
parameters() {
return [ this.value ];
}
}
import { DBCondition } from "./db-condition";
/** A condition where a value is in a collection of values */
export class DBIn implements DBCondition {
/** The values for the condition */
private readonly values: any[];
constructor(values: any[]);
constructor(iterable: IterableIterator<any>);
constructor(values: any) {
if(values == null) {
this.values = [];
}
else if(Array.isArray(values)) {
this.values = values;
}
else if(typeof values[Symbol.iterator] === 'function') {
this.values = [];
for(const val of values) {
this.values.push(val);
}
}
else {
throw new Error(`Unsupported argument for DBIn: ${values}`);
}
}
sql() {
return `IN $1`;
}
parameters() {
return [ this.values ];
}
}
export * from './db-condition';
export * from './equals';
export * from './in';
export * from './and';
export * from './or';
\ No newline at end of file
import { DBCompoundCondition } from "./compound-condition";
/** A condition where any of the containing conditions is met */
export class DBOr extends DBCompoundCondition {
joiningSQL() {
return 'OR';
}
}
......@@ -8,3 +8,4 @@ export * from './decorators/index';
export * from './adapter/index';
export * from './types/index';
export * from './constraints/index';
export * from './conditions/index';
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment