mysql-emulator
Advanced tools
Comparing version 0.0.15 to 0.0.16
@@ -49,2 +49,10 @@ import { SelectQuery } from './select-query'; | ||
}; | ||
export type CaseType = { | ||
type: 'case'; | ||
when: { | ||
condition: Expression; | ||
value: Expression; | ||
}[]; | ||
else: Expression | null; | ||
}; | ||
export type SubQuery = { | ||
@@ -56,3 +64,3 @@ type: 'select'; | ||
isArray: boolean; | ||
}) | UnaryExpression | BinaryExpression | ColumnRef | FunctionType | NumberType | StringType | BooleanType | ArrayType | NullType | DefaultType | Star; | ||
}) | CaseType | UnaryExpression | BinaryExpression | ColumnRef | FunctionType | NumberType | StringType | BooleanType | ArrayType | NullType | DefaultType | Star; | ||
export declare const buildExpression: (ast: any) => Expression; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.buildExpression = void 0; | ||
const node_sql_parser_1 = require("node-sql-parser"); | ||
const parser_exception_1 = require("./parser.exception"); | ||
@@ -80,7 +79,5 @@ const select_query_1 = require("./select-query"); | ||
if (ast.type === 'expr_list' && ((_c = ast.value[0]) === null || _c === void 0 ? void 0 : _c.ast)) { | ||
const sqlParser = new node_sql_parser_1.Parser(); | ||
const subSql = sqlParser.sqlify(ast.value[0].ast, { database: 'MariaDB' }); | ||
return { | ||
type: 'select', | ||
query: select_query_1.SelectQuery.fromAst(ast.value[0].ast, subSql), | ||
query: select_query_1.SelectQuery.fromAst(ast.value[0].ast), | ||
isArray: true, | ||
@@ -95,14 +92,22 @@ }; | ||
} | ||
if (ast.type === 'case') { | ||
const when = ast.args.filter((a) => a.type === 'when') | ||
.map((a) => ({ condition: (0, exports.buildExpression)(a.cond), value: (0, exports.buildExpression)(a.result) })); | ||
const elseExpression = ast.args.find((a) => a.type === 'else'); | ||
return { | ||
type: 'case', | ||
when, | ||
else: elseExpression ? (0, exports.buildExpression)(elseExpression.result) : null, | ||
}; | ||
} | ||
if (ast.ast) { | ||
const sqlParser = new node_sql_parser_1.Parser(); | ||
const subSql = sqlParser.sqlify(ast.ast, { database: 'MariaDB' }); | ||
return { | ||
type: 'select', | ||
query: select_query_1.SelectQuery.fromAst(ast.ast, subSql), | ||
query: select_query_1.SelectQuery.fromAst(ast.ast), | ||
isArray: false, | ||
}; | ||
} | ||
throw new parser_exception_1.ParserException(`Unknown "${ast.type}" expression type`); | ||
throw new parser_exception_1.ParserException(`Unknown expression type '${ast.type}'`); | ||
}; | ||
exports.buildExpression = buildExpression; | ||
//# sourceMappingURL=expression.js.map |
export * from './parser'; | ||
export * from './column-name-parser'; | ||
export * from './transaction-query'; | ||
@@ -4,0 +3,0 @@ export * from './create-table-query'; |
@@ -18,3 +18,2 @@ "use strict"; | ||
__exportStar(require("./parser"), exports); | ||
__exportStar(require("./column-name-parser"), exports); | ||
__exportStar(require("./transaction-query"), exports); | ||
@@ -21,0 +20,0 @@ __exportStar(require("./create-table-query"), exports); |
@@ -45,3 +45,3 @@ "use strict"; | ||
case 'select': | ||
return select_query_1.SelectQuery.fromAst(ast, injectedSql); | ||
return select_query_1.SelectQuery.fromAst(ast); | ||
case 'update': | ||
@@ -48,0 +48,0 @@ return update_query_1.UpdateQuery.fromAst(ast); |
import { Select } from 'node-sql-parser'; | ||
import { BinaryExpression, BooleanType, ColumnRef, Expression, FunctionType, NullType, NumberType, Star, StringType, SubQuery } from './expression'; | ||
import { BinaryExpression, BooleanType, CaseType, ColumnRef, Expression, FunctionType, NullType, NumberType, Star, StringType, SubQuery } from './expression'; | ||
type WithJoin<T> = T & { | ||
@@ -18,3 +18,3 @@ join: 'INNER JOIN' | 'LEFT JOIN' | 'RIGHT JOIN' | 'CROSS JOIN' | null; | ||
}; | ||
export type SelectColumn = WithAlias<ColumnRef> | WithAlias<WithColumn<FunctionType>> | WithAlias<WithColumn<BinaryExpression>> | WithAlias<WithColumn<StringType>> | WithAlias<WithColumn<NumberType>> | WithAlias<WithColumn<BooleanType>> | WithAlias<WithColumn<NullType>> | WithAlias<WithColumn<SubQuery & { | ||
export type SelectColumn = WithAlias<ColumnRef> | WithAlias<WithColumn<FunctionType>> | WithAlias<WithColumn<BinaryExpression>> | WithAlias<WithColumn<StringType>> | WithAlias<WithColumn<NumberType>> | WithAlias<WithColumn<BooleanType>> | WithAlias<WithColumn<NullType>> | WithAlias<WithColumn<CaseType>> | WithAlias<WithColumn<SubQuery & { | ||
isArray: false; | ||
@@ -35,4 +35,4 @@ }>> | Star; | ||
constructor(from: From[], columns: SelectColumn[], where: Expression | null, groupBy: ColumnRef[], having: Expression | null, orderBy: OrderBy[], limit: number, offset: number); | ||
static fromAst(ast: Select, sql: string): SelectQuery; | ||
static fromAst(ast: Select): SelectQuery; | ||
} | ||
export {}; |
@@ -6,4 +6,13 @@ "use strict"; | ||
const expression_1 = require("./expression"); | ||
const column_name_parser_1 = require("./column-name-parser"); | ||
const parser_exception_1 = require("./parser.exception"); | ||
const sqlParser = new node_sql_parser_1.Parser(); | ||
const toSql = (expr) => { | ||
if (expr.type === 'single_quote_string' || expr.type === 'string') { | ||
return expr.value; | ||
} | ||
else if (expr.type === 'select') { | ||
return `(${sqlParser.sqlify(expr, { database: 'MariaDB' })})`; | ||
} | ||
return sqlParser.exprToSQL(expr, { database: 'MariaDB' }); | ||
}; | ||
class SelectQuery { | ||
@@ -20,12 +29,10 @@ constructor(from, columns, where, groupBy, having, orderBy, limit, offset) { | ||
} | ||
static fromAst(ast, sql) { | ||
static fromAst(ast) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
const sqlParser = new node_sql_parser_1.Parser(); | ||
const from = (ast.from || []).map((f) => { | ||
var _a; | ||
if ((_a = f.expr) === null || _a === void 0 ? void 0 : _a.ast) { | ||
const subSql = sqlParser.sqlify(f.expr.ast, { database: 'MariaDB' }); | ||
return { | ||
type: 'select', | ||
query: SelectQuery.fromAst(f.expr.ast, subSql), | ||
query: SelectQuery.fromAst(f.expr.ast), | ||
alias: f.as, | ||
@@ -45,3 +52,2 @@ join: f.join || null, | ||
}); | ||
const columnNames = (0, column_name_parser_1.parseColumnNames)(sql); | ||
const functions = ['aggr_func', 'function']; | ||
@@ -60,14 +66,7 @@ const primitives = ['bool', 'number', 'string', 'single_quote_string', 'null']; | ||
} | ||
else if (['binary_expr', ...functions, ...primitives].includes((_c = c.expr) === null || _c === void 0 ? void 0 : _c.type)) { | ||
return Object.assign(Object.assign({}, (0, expression_1.buildExpression)(c.expr)), { column: columnNames.shift(), alias: c.as }); | ||
else if (['case', 'binary_expr', ...functions, ...primitives].includes((_c = c.expr) === null || _c === void 0 ? void 0 : _c.type)) { | ||
return Object.assign(Object.assign({}, (0, expression_1.buildExpression)(c.expr)), { column: toSql(c.expr), alias: c.as }); | ||
} | ||
else if ((_d = c.expr) === null || _d === void 0 ? void 0 : _d.ast) { | ||
const subSql = columnNames.shift(); | ||
return { | ||
type: 'select', | ||
query: SelectQuery.fromAst(c.expr.ast, subSql), | ||
isArray: false, | ||
alias: c.as, | ||
column: subSql, | ||
}; | ||
return Object.assign(Object.assign({}, (0, expression_1.buildExpression)(c.expr)), { column: toSql(c.expr.ast), alias: c.as }); | ||
} | ||
@@ -74,0 +73,0 @@ throw new parser_exception_1.ParserException('Could not map columns'); |
@@ -1,2 +0,2 @@ | ||
import { BinaryExpression, ColumnRef, Expression, FunctionType, Star, SubQuery, UnaryExpression } from '../parser'; | ||
import { BinaryExpression, CaseType, ColumnRef, Expression, FunctionType, Star, SubQuery, UnaryExpression } from '../parser'; | ||
import { Server } from '../server'; | ||
@@ -15,4 +15,5 @@ export declare class Evaluator { | ||
protected evaluateBinaryExpression(be: BinaryExpression, row: object): any; | ||
protected evaluateCaseExpression(c: CaseType, row: object): any; | ||
protected evaluateColumnReference(c: ColumnRef, row: object): any; | ||
protected evaluateFunction(f: FunctionType, row: object, group: object[]): any; | ||
} |
@@ -27,2 +27,4 @@ "use strict"; | ||
return this.evaluateBinaryExpression(e, rowWithContext); | ||
case 'case': | ||
return this.evaluateCaseExpression(e, rowWithContext); | ||
case 'function': | ||
@@ -89,2 +91,10 @@ return this.evaluateFunction(e, rowWithContext, group); | ||
} | ||
evaluateCaseExpression(c, row) { | ||
for (const { condition, value } of c.when) { | ||
if (this.evaluateExpression(condition, row)) { | ||
return this.evaluateExpression(value, row); | ||
} | ||
} | ||
return c.else ? this.evaluateExpression(c.else, row) : null; | ||
} | ||
evaluateColumnReference(c, row) { | ||
@@ -91,0 +101,0 @@ const key = c.table ? `${c.table}::${c.column}` : Object.keys(row).find((key) => (0, utils_1.extractColumn)(key) === c.column); |
@@ -140,3 +140,3 @@ "use strict"; | ||
} | ||
const hasString = array.some((v) => typeof v === 'string'); | ||
const hasString = array.some(utils_1.isString); | ||
if (hasString) { | ||
@@ -181,2 +181,45 @@ const sorted = array.map(String).sort((a, b) => b.localeCompare(a)); | ||
}, | ||
isnull: (e, f, row) => { | ||
var _a; | ||
if (((_a = f.args) === null || _a === void 0 ? void 0 : _a.length) !== 1) { | ||
throw new evaluator_exception_1.EvaluatorException(`Incorrect parameter count in the call to native function '${f.name}'`); | ||
} | ||
return Number(e.evaluateExpression(getArgument(f), row) === null); | ||
}, | ||
ifnull: (e, f, row) => { | ||
var _a; | ||
if (((_a = f.args) === null || _a === void 0 ? void 0 : _a.length) !== 2) { | ||
throw new evaluator_exception_1.EvaluatorException(`Incorrect parameter count in the call to native function '${f.name}'`); | ||
} | ||
const [value, alternative] = f.args.map((arg) => e.evaluateExpression(arg, row)); | ||
if (value === null) { | ||
return alternative; | ||
} | ||
return (0, utils_1.isString)(alternative) ? String(value) : value; | ||
}, | ||
nullif: (e, f, row) => { | ||
var _a; | ||
if (((_a = f.args) === null || _a === void 0 ? void 0 : _a.length) !== 2) { | ||
throw new evaluator_exception_1.EvaluatorException(`Incorrect parameter count in the call to native function '${f.name}'`); | ||
} | ||
const [value1, value2] = f.args.map((arg) => e.evaluateExpression(arg, row)); | ||
return value1 == value2 ? null : value1; | ||
}, | ||
if: (e, f, row) => { | ||
var _a; | ||
if (((_a = f.args) === null || _a === void 0 ? void 0 : _a.length) !== 3) { | ||
throw new evaluator_exception_1.EvaluatorException(`Incorrect parameter count in the call to native function '${f.name}'`); | ||
} | ||
const [condition, value1, value2] = f.args.map((arg) => e.evaluateExpression(arg, row)); | ||
const value = condition ? value1 : value2; | ||
return (0, utils_1.isString)(value1) || (0, utils_1.isString)(value2) ? String(value) : value; | ||
}, | ||
coalesce: (e, f, row) => { | ||
var _a, _b; | ||
if (((_a = f.args) === null || _a === void 0 ? void 0 : _a.length) < 1) { | ||
throw new evaluator_exception_1.EvaluatorException(`Incorrect parameter count in the call to native function '${f.name}'`); | ||
} | ||
const array = f.args.map((arg) => e.evaluateExpression(arg, row)); | ||
return (_b = array.find((v) => v !== null)) !== null && _b !== void 0 ? _b : null; | ||
}, | ||
now: () => new Date(), | ||
@@ -183,0 +226,0 @@ current_timestamp: () => new Date(), |
@@ -27,3 +27,3 @@ "use strict"; | ||
if (column instanceof server_1.IntegerColumn && column.hasAutoIncrement()) { | ||
return column.getNextAutoIncrementValue(); | ||
return column.getAutoIncrementCursor() + 1; | ||
} | ||
@@ -64,2 +64,6 @@ const defaultValue = column.getDefaultValueExpression(); | ||
if (c instanceof server_1.IntegerColumn && c.hasAutoIncrement()) { | ||
const cursor = c.getAutoIncrementCursor(); | ||
if (value > cursor) { | ||
c.setAutoIncrementCursor(value); | ||
} | ||
insertId = value; | ||
@@ -66,0 +70,0 @@ } |
@@ -163,4 +163,5 @@ "use strict"; | ||
const hasExpressionColumn = this.query.columns.some((c) => c.type === 'binary_expression'); | ||
const hasCase = this.query.columns.some((c) => c.type === 'case'); | ||
const hasSubSelect = this.query.columns.some((c) => c.type === 'select'); | ||
if (this.rows.length === 0 && (hasFunctionColumn || hasExpressionColumn || hasPrimitiveColumn || hasSubSelect)) { | ||
if (this.rows.length === 0 && (hasFunctionColumn || hasExpressionColumn || hasPrimitiveColumn || hasCase || hasSubSelect)) { | ||
this.rows = [{}]; | ||
@@ -167,0 +168,0 @@ } |
@@ -13,3 +13,4 @@ import { Column } from '../column'; | ||
hasAutoIncrement(): boolean; | ||
getNextAutoIncrementValue(): number; | ||
getAutoIncrementCursor(): number; | ||
setAutoIncrementCursor(n: number): void; | ||
} |
@@ -38,7 +38,10 @@ "use strict"; | ||
} | ||
getNextAutoIncrementValue() { | ||
return ++this.autoIncrementCursor; | ||
getAutoIncrementCursor() { | ||
return this.autoIncrementCursor; | ||
} | ||
setAutoIncrementCursor(n) { | ||
this.autoIncrementCursor = n; | ||
} | ||
} | ||
exports.IntegerColumn = IntegerColumn; | ||
//# sourceMappingURL=integer-column.js.map |
@@ -11,1 +11,3 @@ export declare const mapKeys: (o: object, mapper: (key: string, value: any) => string, filter?: (key: string, value: any) => boolean) => object; | ||
export declare const toNumber: (n: any) => number; | ||
export declare const isObject: (o: any) => o is object; | ||
export declare const isString: (s: any) => s is string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toNumber = exports.hashCode = exports.sortBy = exports.extractTable = exports.extractColumn = exports.mapKeys = void 0; | ||
exports.isString = exports.isObject = exports.toNumber = exports.hashCode = exports.sortBy = exports.extractTable = exports.extractColumn = exports.mapKeys = void 0; | ||
const mapKeys = (o, mapper, filter = () => true) => { | ||
@@ -58,2 +58,10 @@ return Object.keys(o).reduce((res, key) => { | ||
exports.toNumber = toNumber; | ||
const isObject = (o) => { | ||
return o !== null && typeof o === 'object' && !Array.isArray(o); | ||
}; | ||
exports.isObject = isObject; | ||
const isString = (s) => { | ||
return typeof s === 'string' || s instanceof String; | ||
}; | ||
exports.isString = isString; | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "mysql-emulator", | ||
"version": "0.0.15", | ||
"version": "0.0.16", | ||
"description": "MySQL emulator", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
178421
2581
147