sphinxql
Version:
SphinxQL query builder for Node.JS. Supports Sphinx search(2.x and 3.x) and Manticore search
84 lines (72 loc) • 2.68 kB
text/typescript
import { escape } from 'sqlstring';
import ClientInterface from '../ClientInterface';
import BaseStatement from './BaseStatement';
const template = require('es6-template-strings');
/**
* INSERT INTO rtindex VALUES (val1, val2, ...), (val1, val2, ...);
*/
export default class InsertStatement extends BaseStatement {
protected index: string;
protected values: any;
protected type: string;
constructor(connection: ClientInterface, index: string, values: any, insertType: string = 'INSERT') {
super(connection);
if (!index.length) {
throw Error('real-time index must be valid but empty name provided');
}
if (!(values instanceof Array) && (typeof values !== 'object')) {
throw Error(`Provide an array or an object (key-value pair) values`);
}
if ((values instanceof Array) && !values.length) {
throw Error(`No document to insert`);
}
this.connection = connection;
this.index = index;
this.values = values;
this.type = insertType
}
/**
* Formats the VALUES of the document between parenthesis and escapes them.
* values attribute can be of this types:
*
* [{id: 1, title: 'title...'}, {id: 2, title: 'other title'}]
* OR
* {id: 1, title: 'title...'}
*/
protected renderValues(values: object, columns: string[]): string {
let tmpl: string = columns.map(column => '${'+ column +'}').join(', ');
for (let i = 0; i < columns.length; i++) {
if (typeof values[columns[i]] === 'string') {
values[columns[i]] = escape(values[columns[i]]);
}
}
const compiledTemplate = template(tmpl, values);
return `(${compiledTemplate})`;
}
public generate() : string {
let valuesFields: string[] = [];
// array of documents
if (this.values instanceof Array) {
const columns: string[] = Object.keys(this.values[0]);
let expression: string = `${this.type} INTO ${this.index} `;
expression += `${this.renderColumnList(columns)} VALUES `;
valuesFields = this.values.map((values) => {
return this.renderValues(values, columns);
});
return `${expression}${valuesFields.join(', ')}`;
}
// case of key-value object
const columns: string[] = Object.keys(this.values);
return `${this.type} INTO ${this.index} ${this.renderColumnList(columns)} ` +
`VALUES ${this.renderValues(this.values, columns)}`;
}
/**
* Compiles the list of columns to insert in the correct order
* the document/s. It goes before VALUES keyword.
*
* Example output: (id, title, content)
*/
protected renderColumnList(columns: string[]) : string {
return `(${ columns.join(', ') })`;
}
}