Skip to content

Commit

Permalink
implement type casting methods (#97)
Browse files Browse the repository at this point in the history
* implement type casting methods

* no-unused-vars

* update type declaration

* no-unused-vars

* 2.14.2
  • Loading branch information
kbarbounakis authored Aug 20, 2024
1 parent d3768c7 commit 898b00d
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 7 deletions.
21 changes: 19 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@themost/query",
"version": "2.14.1",
"version": "2.14.2",
"description": "MOST Web Framework Codename ZeroGravity - Query Module",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
Expand Down
78 changes: 78 additions & 0 deletions spec/TypeCast.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { SqlFormatter, QueryEntity, QueryExpression, QueryField } from '../src/index';
import { MemoryAdapter } from './test/TestMemoryAdapter';
import { MemoryFormatter } from './test/TestMemoryFormatter';

describe('Type Casting', () => {

/**
* @type {MemoryAdapter}
*/
let db;
beforeAll(() => {
db = new MemoryAdapter({
name: 'local',
database: './spec/db/local.db'
});
});
afterAll((done) => {
if (db) {
db.close();
return done();
}
})
it('should use $toString function', async () => {
const Product = new QueryEntity('ProductData');
const Order = new QueryEntity('OrderData');
const id = new QueryField('id').from(Product);
let orderedItem = new QueryField('orderedItem').from(Order);
let expr = new QueryExpression().where(id).equal(orderedItem);
const formatter = new MemoryFormatter();
let sql = formatter.formatWhere(expr.$where);
expect(sql).toEqual('(`ProductData`.`id`=`OrderData`.`orderedItem`)');
orderedItem =new QueryField({
'$toString': [
new QueryField('orderedItem').from(Order)
]
});
expr = new QueryExpression().where(id).equal(orderedItem);
sql = formatter.formatWhere(expr.$where);
expect(sql).toEqual('(`ProductData`.`id`=CAST(`OrderData`.`orderedItem` AS TEXT))');
});

it('should use $toString inside closure', async () => {
const Products = new QueryEntity('ProductData');
const q = new QueryExpression().select(({id, name, price}) => {
return {
id,
price,
priceString: price.toString(),
name
}
}).from(Products);
const formatter = new MemoryFormatter();
const items = await db.executeAsync(q);
items.forEach(({price, priceString}) => {
expect(typeof priceString).toEqual('string');
const fromString = parseFloat(priceString);
expect(price).toEqual(fromString);
});
});

it('should use $toInt inside closure', async () => {
const Products = new QueryEntity('ProductData');
const q = new QueryExpression().select(({id, name, price}) => {
return {
id,
price,
priceInt: parseInt(price),
name
}
}).from(Products);
const items = await db.executeAsync(q);
items.forEach(({price, priceInt}) => {
expect(typeof priceInt).toEqual('number');
const fromInt = parseInt(price);
expect(priceInt).toEqual(fromInt);
});
});
});
18 changes: 18 additions & 0 deletions spec/test/TestMemoryFormatter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@

import { SqliteFormatter } from '@themost/sqlite';

Object.assign(SqliteFormatter.prototype, {
$toString(arg) {
return `CAST(${this.escape(arg)} AS TEXT)`;
},
$toDouble(arg) {
return `CAST(${this.escape(arg)} AS NUMERIC)`;
},
$toDecimal(arg) {
return `CAST(${this.escape(arg)} AS NUMERIC)`;
},
$toInt(arg) {
return `CAST(${this.escape(arg)} AS INTEGER)`;
},
$toLong(arg) {
return `CAST(${this.escape(arg)} AS INTEGER)`;
}
});

// noinspection JSUnusedGlobalSymbols
/**
* @augments {SqlFormatter}
Expand Down
6 changes: 6 additions & 0 deletions src/closures/FallbackMethodParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ class FallbackMethodParser {
static now() {
return new SimpleMethodCallExpression('now', []);
}
static parseInt(args) {
return new SimpleMethodCallExpression('toInt', args);
}
static parseFloat(args) {
return new SimpleMethodCallExpression('toDouble', args);
}
}

export {
Expand Down
8 changes: 4 additions & 4 deletions src/closures/PrototypeMethodParser.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// MOST Web Framework Codename Zero Gravity Copyright (c) 2017-2022, THEMOST LP All rights reserved
import { SimpleMethodCallExpression } from '../expressions';

class PrototypeMethodParser {
constructor() {
}
test(name) {
if (name === 'toString') {
return;
}
if (typeof this[name] === 'function') {
return this[name];
}
}
toString(args) {
return new SimpleMethodCallExpression('toString', args);
}
}

export {
Expand Down
5 changes: 5 additions & 0 deletions src/formatter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ export declare class SqlFormatter {
$switch(expr: {
branches: {case: any, then: any}[], defaultValue?: any
}): string | any;
$toString(arg0:any): string | any;
$toInt(arg0:any): string | any;
$toDouble(arg0:any): string | any;
$toLong(arg0:any): string | any;
$toDecimal(arg0:any): string | any;
formatWhere(where: any): any;
formatCount(query: QueryExpression | any): any;
formatFixedSelect(query: QueryExpression | any): any;
Expand Down
55 changes: 55 additions & 0 deletions src/formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import './polyfills';
import { ObjectNameValidator } from './object-name.validator';
import { isNameReference, trimNameReference } from './name-reference';

class AbstractMethodError extends Error {
constructor() {
super('Abstract method error')
}
}

const ALIAS_KEYWORD = ' AS ';
const DEFAULT_COUNT_ALIAS = '__count__';
/**
Expand Down Expand Up @@ -1363,6 +1369,55 @@ class SqlFormatter {
sql += ')';
return sql;
}

/**
* @abstract
* @param {*} arg
* @returns {string}
*/
/* eslint-disable-next-line no-unused-vars */
$toString(arg) {
throw new AbstractMethodError();
}
/**
* @abstract
* @param {*} arg
* @returns {string}
*/
/* eslint-disable-next-line no-unused-vars */
$toDouble(arg) {
throw new AbstractMethodError();
}

/**
* @abstract
* @param {*} arg
* @returns {string}
*/
/* eslint-disable-next-line no-unused-vars */
$toDecimal(arg) {
throw new AbstractMethodError();
}

/**
* @abstract
* @param {*} arg
* @returns {string}
*/
/* eslint-disable-next-line no-unused-vars */
$toInt(arg) {
throw new AbstractMethodError();
}

/**
* @abstract
* @param {*} arg
* @returns {string}
*/
/* eslint-disable-next-line no-unused-vars */
$toLong(arg) {
throw new AbstractMethodError();
}
}

export {
Expand Down

0 comments on commit 898b00d

Please sign in to comment.