mohair
Version:
sql query builder
364 lines (279 loc) • 11.6 kB
text/coffeescript
mohair = require './index'
module.exports =
'raw':
'without bindings': (test) ->
string = 'SELECT * FROM `project`;'
m = mohair()
m.raw string
test.equals m.sql(), string
test.done()
'with bindings': (test) ->
string = 'SELECT * FROM `project` WHERE `id` = ? AND `owner_id` = ?;'
m = mohair()
m.raw string, 7, 4
test.equals m.sql(), string
test.deepEqual m.params(), [7, 4]
test.done()
'twice': (test) ->
m = mohair()
m.raw 'SELECT * FROM `project` WHERE `id` = ?;', 7
m.raw 'SELECT * FROM `project` WHERE `id` = ?;', 4
test.equals m.sql(), 'SELECT * FROM `project` WHERE `id` = ?;SELECT * FROM `project` WHERE `id` = ?;'
test.deepEqual m.params(), [7, 4]
test.done()
'insert':
'empty': (test) ->
m = mohair()
m.insert 'project', []
test.equals m.sql(), 'INSERT INTO `project` () VALUES ();\n'
test.deepEqual m.params(), []
test.done()
'bindings': (test) ->
m = mohair()
m.insert 'project',
name: 'Amazing Project'
owner_id: 5
hidden: false
test.equals m.sql(), 'INSERT INTO `project` (`name`, `owner_id`, `hidden`) VALUES (?, ?, ?);\n'
test.deepEqual m.params(), ['Amazing Project', 5, false]
test.done()
'bindings and raw': (test) ->
m = mohair()
m.insert 'project',
name: 'Another Project'
created_on: -> m.raw 'NOW()'
test.equals m.sql(), 'INSERT INTO `project` (`name`, `created_on`) VALUES (?, NOW());\n'
test.deepEqual m.params(), ['Another Project']
test.done()
'multiple': (test) ->
m = mohair()
m.insert 'project', [
{
name: 'First Project'
created_on: -> m.raw 'NOW()'
}
{
name: 'Second Project'
created_on: '1988.09.11'
}
]
test.equals m.sql(), 'INSERT INTO `project` (`name`, `created_on`) VALUES (?, NOW()), (?, ?);\n'
test.deepEqual m.params(), ['First Project', 'Second Project', '1988.09.11']
test.done()
'with update': (test) ->
m = mohair()
m.insert 'project', {
name: 'Amazing Project'
owner_id: 5
hidden: false
}, {
name: 'Not so amazing project'
id: -> m.raw 'LAST_INSERT_ID()'
}
test.equals m.sql(), 'INSERT INTO `project` (`name`, `owner_id`, `hidden`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `name` = ?, `id` = LAST_INSERT_ID();\n'
test.deepEqual m.params(), ['Amazing Project', 5, false, 'Not so amazing project']
test.done()
'update':
'bindings': (test) ->
changes =
name: 'Even more amazing project'
hidden: true
m = mohair()
m.update 'project', changes, {id: 7}
test.equals m.sql(), 'UPDATE `project` SET `name` = ?, `hidden` = ? WHERE `id` = ?;\n'
test.deepEqual m.params(), ['Even more amazing project', true, 7]
test.done()
'bindings and raw': (test) ->
m = mohair()
changes =
name: 'Even more amazing project'
updated_on: -> m.raw 'NOW()'
m.update 'project', changes, {id: 7}
test.equals m.sql(), 'UPDATE `project` SET `name` = ?, `updated_on` = NOW() WHERE `id` = ?;\n'
test.deepEqual m.params(), ['Even more amazing project', 7]
test.done()
'delete': (test) ->
m = mohair()
m.delete 'project', {id: 7, hidden: true}
test.equals m.sql(), 'DELETE FROM `project` WHERE `id` = ? AND `hidden` = ?;\n'
test.deepEqual m.params(), [7, true]
test.done()
'transaction': (test) ->
m = mohair()
m.transaction ->
m.delete 'project', {id: 7}
m.update 'project', {name: 'New name'}, {id: 8}
test.equals m.sql(), 'BEGIN;\nDELETE FROM `project` WHERE `id` = ?;\nUPDATE `project` SET `name` = ? WHERE `id` = ?;\nCOMMIT;\n'
test.deepEqual m.params(), [7, 'New name', 8]
test.done()
'select':
'implicit star': (test) ->
m = mohair()
m.select 'project'
test.equals m.sql(), 'SELECT * FROM `project`;\n'
test.deepEqual m.params(), []
test.done()
'explicit column list and where clause': (test) ->
m = mohair()
m.select 'project', ['name', 'id'], {hidden: true}
test.equals m.sql(), 'SELECT name, id FROM `project` WHERE `hidden` = ?;\n'
test.deepEqual m.params(), [true]
test.done()
'join, groupBy and orderBy': (test) ->
m = mohair()
m.select 'project', ['count(task.id) AS taskCount', 'project.*'], ->
m.where {id: 7}
m.leftJoin 'task', 'project.id' , 'task.project_id'
m.groupBy 'project.id'
m.orderBy 'project.created_on', 'DESC'
m.limit 5
m.skip -> m.raw '6'
test.equals m.sql(), 'SELECT count(task.id) AS taskCount, project.* FROM `project` WHERE `id` = ? LEFT JOIN `task` ON `project`.`id` = `task`.`project_id` GROUP BY `project`.`id` ORDER BY `project`.`created_on` DESC LIMIT ? SKIP 6;\n'
test.deepEqual m.params(), [7, 5]
test.done()
'query':
'toplevel': (test) ->
m = mohair()
m.query
'project.id': 6
hidden: true
name: -> m.quoted 'Another Project'
test.equals m.sql(), "`project`.`id` = ? AND `hidden` = ? AND `name` = 'Another Project'"
test.deepEqual m.params(), [6, true]
test.done()
'$or': (test) ->
m = mohair()
m.query
$or: [
{'project.id': 6}
{hidden: true}
{name: -> m.quoted 'Another Project'}
]
test.equals m.sql(), "(`project`.`id` = ? OR `hidden` = ? OR `name` = 'Another Project')"
test.deepEqual m.params(), [6, true]
test.done()
'or and and': (test) ->
m = mohair()
m.query
'project.id': 6
$or: [
{hidden: true}
{$and: [
{name: -> m.quoted 'Another Project'}
{owner_id: 8}
]}
]
test.equals m.sql(), "`project`.`id` = ? AND (`hidden` = ? OR `name` = 'Another Project' AND `owner_id` = ?)"
test.deepEqual m.params(), [6, true, 8]
test.done()
'comparison operators': (test) ->
m = mohair()
m.query
'project.id': {$lt: 6}
$or: [
{hidden: true}
{$and: [
{name: {$ne: -> m.quoted 'Another Project'}}
{'owner.id': {$gte: 8}}
]}
]
test.equals m.sql(), "`project`.`id` < ? AND (`hidden` = ? OR `name` != 'Another Project' AND `owner`.`id` >= ?)"
test.deepEqual m.params(), [6, true, 8]
test.done()
'nested query': (test) ->
m = mohair()
m.query
id: 7
$or: [
{'owner.id': 10}
$and: [
{cost: {$gt: 500}}
{cost: {$lt: 1000}}
]
]
test.equals m.sql(), "`id` = ? AND (`owner`.`id` = ? OR `cost` > ? AND `cost` < ?)"
test.deepEqual m.params(), [7, 10, 500, 1000]
test.done()
'$in': (test) ->
m = mohair()
m.query
id: {$in: [3, 5, 8, 9]}
'owner.id': {$in: [10]}
name: {$in: ['Ann', 'Rick']}
test.equals m.sql(), '`id` IN (?, ?, ?, ?) AND `owner`.`id` IN (?) AND `name` IN (?, ?)'
test.deepEqual m.params(), [3, 5, 8, 9, 10, 'Ann', 'Rick']
test.done()
'$not': (test) ->
m = mohair()
m.query
$not:
id: 9
name: 'Ann'
test.equals m.sql(), 'NOT (`id` = ? AND `name` = ?)'
test.deepEqual m.params(), [9, 'Ann']
test.done()
'$not and $or': (test) ->
m = mohair()
m.query
$or: [
{name: 'Ann'}
{$not: {
id: 9
name: 'Rick'
}}
]
test.equals m.sql(), '(`name` = ? OR NOT (`id` = ? AND `name` = ?))'
test.deepEqual m.params(), ['Ann', 9, 'Rick']
test.done()
'$nor': (test) ->
m = mohair()
m.query
$nor: [
{name: 'Ann'}
{
id: 9
name: 'Rick'
}
]
test.equals m.sql(), 'NOT (`name` = ? OR `id` = ? AND `name` = ?)'
test.deepEqual m.params(), ['Ann', 9, 'Rick']
test.done()
'$nin': (test) ->
m = mohair()
m.query
id: {$nin: [3, 5, 8, 9]}
'owner.id': {$nin: [10]}
name: {$nin: ['Ann', 'Rick']}
test.equals m.sql(), '`id` NOT IN (?, ?, ?, ?) AND `owner`.`id` NOT IN (?) AND `name` NOT IN (?, ?)'
test.deepEqual m.params(), [3, 5, 8, 9, 10, 'Ann', 'Rick']
test.done()
'string as value in query is not interpreted as test': (test) ->
m = mohair()
m.query
$or: [
{id: 'foo'}
{foo: 'id'}
]
test.equals m.sql(), '(`id` = ? OR `foo` = ?)'
test.deepEqual m.params(), ['foo', 'id']
test.done()
'invalid $or query throws': (test) ->
m = mohair()
test.throws ->
m.query
$or:
id: 'foo'
foo: 'id'
test.done()
'postgres': (test) ->
m = mohair.postgres()
m.select 'project', ['count(task.id) AS taskCount', 'project.*'], ->
m.where {$or: [{id: 7}, {foo: 'id'}]}
m.leftJoin 'task', 'project.id' , 'task.project_id'
m.groupBy 'project.id'
m.orderBy 'project.created_on', 'DESC'
m.limit 5
m.skip -> m.raw '6'
test.equals m.sql(), 'SELECT count(task.id) AS taskCount, project.* FROM "project" WHERE ("id" = $1 OR "foo" = $2) LEFT JOIN "task" ON "project"."id" = "task"."project_id" GROUP BY "project"."id" ORDER BY "project"."created_on" DESC LIMIT $3 SKIP 6;\n'
test.deepEqual m.params(), [7, 'id', 5]
test.done()