import Model from "../src/db/Model.js"; import ModelFactory from "../src/db/ModelFactory.js"; import ModelQuery, {SelectFieldValue, WhereOperator} from "../src/db/ModelQuery.js"; describe('Test ModelQuery', () => { test('select', () => { const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory, 'f1', '"Test" as f2') .where('f4', 'v4') .where('f5', true) .where('f6', null) .where('f7', undefined); expect(query.toString(true)).toBe('SELECT `model`.`f1`,"Test" as f2 FROM `model` WHERE `f4`=? AND `f5`=true AND `f6` IS null AND `f7` IS null'); expect(query.variables).toStrictEqual(['v4']); }); test('order by', () => { const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory) .sortBy('model.f2', 'ASC'); expect(query.toString(true)).toBe('SELECT `model`.* FROM `model` ORDER BY `model`.`f2` ASC'); const queryRaw = ModelQuery.select({table: 'model'} as unknown as ModelFactory) .sortBy('coalesce(model.f1, model.f2)', 'ASC', true); expect(queryRaw.toString(true)).toBe('SELECT `model`.* FROM `model` ORDER BY coalesce(model.f1, model.f2) ASC'); }); test('create (insert into)', () => { const date = new Date(); const query = ModelQuery.insert( {table: 'model'} as unknown as ModelFactory, { 'boolean': true, 'null': null, 'undefined': undefined, 'string': 'string', 'date': date, 'sensitive': 'sensitive', // Reserved word }, ); expect(query.toString(true)).toBe('INSERT INTO `model` (`boolean`,`null`,`undefined`,`string`,`date`,`sensitive`) VALUES(true,null,null,?,?,?)'); expect(query.variables).toStrictEqual([ 'string', date, 'sensitive', ]); }); test('update', () => { const date = new Date(); const query = ModelQuery.update({table: 'model'} as unknown as ModelFactory, { 'boolean': true, 'null': null, 'undefined': undefined, 'string': 'string', 'date': date, 'sensitive': 'sensitive', // Reserved word }).where('f4', 'v4') .where('f5', true) .where('f6', null) .where('f7', undefined); expect(query.toString(true)).toBe('UPDATE `model` SET `model`.`boolean`=true,`model`.`null`=null,`model`.`undefined`=null,`model`.`string`=?,`model`.`date`=?,`model`.`sensitive`=? WHERE `f4`=? AND `f5`=true AND `f6` IS null AND `f7` IS null'); expect(query.variables).toStrictEqual([ 'string', date, 'sensitive', 'v4', ]); }); test('function select', () => { const query = ModelQuery.select( {table: 'model'} as unknown as ModelFactory, 'f1', new SelectFieldValue('_count', 'COUNT(*)', true), ); expect(query.toString(true)).toBe('SELECT `model`.`f1`,(COUNT(*)) AS `_count` FROM `model`'); expect(query.variables).toStrictEqual([]); }); test('pivot', () => { const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory, 'f1'); query.pivot('pivot.f2', 'f3'); expect(query.toString(true)).toBe('SELECT `model`.`f1`,`pivot`.`f2`,`model`.`f3` FROM `model`'); expect(query.variables).toStrictEqual([]); }); test('groupWhere generates proper query', () => { const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory, '*'); query.where('f1', 'v1'); query.groupWhere(q => q.where('f2', 'v2').where('f3', 'v3') .groupWhere(q => q.where('f4', 'v4'), WhereOperator.OR)) .where('f5', 'v5'); expect(query.toString(true)).toBe('SELECT `model`.* FROM `model` WHERE `f1`=? AND (`f2`=? AND `f3`=? OR (`f4`=?)) AND `f5`=?'); expect(query.variables).toStrictEqual(['v1', 'v2', 'v3', 'v4', 'v5']); }); test('recursive queries', () => { const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory, '*'); query.where('f1', 'v1'); query.leftJoin('test').on('model.j1', 'test.j2'); query.recursive({localKey: 'local', foreignKey: 'foreign'}, false); query.limit(8); expect(query.toString(true)).toBe("WITH RECURSIVE cte AS (SELECT `model`.*,1 AS __depth, CONCAT(`local`) AS __path FROM `model` WHERE `f1`=? UNION SELECT o.*,c.__depth + 1,CONCAT(c.__path,'/',o.`local`) AS __path FROM `model` AS o, cte AS c WHERE o.`foreign`=c.`local`) SELECT * FROM cte LEFT JOIN `test` ON `model`.`j1`=`test`.`j2` ORDER BY __path ASC LIMIT 8"); expect(query.variables).toStrictEqual(['v1']); const reversedQuery = ModelQuery.select({table: 'model'} as unknown as ModelFactory, '*'); reversedQuery.where('f1', 'v1'); reversedQuery.leftJoin('test').on('model.j1', 'test.j2'); reversedQuery.recursive({localKey: 'local', foreignKey: 'foreign'}, true); expect(reversedQuery.toString(true)).toBe("WITH RECURSIVE cte AS (SELECT `model`.*,1 AS __depth, CONCAT(`foreign`) AS __path FROM `model` WHERE `f1`=? UNION SELECT o.*,c.__depth + 1,CONCAT(c.__path,'/',o.`foreign`) AS __path FROM `model` AS o, cte AS c WHERE o.`foreign`=c.`local`) SELECT * FROM cte LEFT JOIN `test` ON `model`.`j1`=`test`.`j2` ORDER BY __path DESC"); expect(reversedQuery.variables).toStrictEqual(['v1']); }); test('union queries', () => { const query = ModelQuery.select({table: 'model'} as unknown as ModelFactory, '*'); const query2 = ModelQuery.select({table: 'model2'} as unknown as ModelFactory, '*'); query2.where('f2', 'v2'); query.union(query2, 'model.f1', 'DESC', false, 8); expect(query.toString(true)).toBe("(SELECT `model`.* FROM `model`) UNION (SELECT `model2`.* FROM `model2` WHERE `f2`=?) ORDER BY `model`.`f1` DESC LIMIT 8"); expect(query.variables).toStrictEqual(['v2']); }); });