monologue
Advanced tools
Comparing version 0.7.4 to 0.8.0
188
monologue.js
(function(exports) { | ||
"use strict"; | ||
function condition(cond, sep, part) { | ||
sep = ( typeof sep === "undefined" ? "AND" : sep ); | ||
function condition(cond, sep = 'AND', part) { | ||
sep = ( sep.length > 0 ? " " + sep + " " : sep ); | ||
if( cond instanceof Array && Object(cond[0]) === cond[0] ) { | ||
cond.forEach(function(v, k, arr) { | ||
arr[k] = this.stringify( v ).join(' AND '); | ||
}.bind(this)); | ||
cond = cond.map((v, k, arr) => { | ||
return arr[k] = this.stringify( v ).join(' AND '); | ||
}).join(' OR '); | ||
// join an array of objects with OR | ||
cond = '(' + cond.join(' OR ') + ')'; | ||
// cond = cond.join(' OR ') | ||
// cond = `(${cond})`; | ||
cond = `(${cond})`; | ||
} | ||
@@ -25,3 +22,3 @@ | ||
// stringify the where statements | ||
cond = this.stringify( cond ).join( sep ); | ||
cond = this.stringify( cond, '=', 'IS' ).join( sep ); | ||
} | ||
@@ -104,7 +101,6 @@ | ||
if( col instanceof Array ) { | ||
col = col.join( ", " ); | ||
col = col.join( ', ' ); | ||
} | ||
this.parts.stmt = ["SELECT", col, "FROM", tbl].join(' '); | ||
// this.parts.stmt = `SELECT ${col} FROM ${tbl}`; | ||
this.parts.stmt = `SELECT ${col} FROM ${tbl}`; | ||
@@ -121,6 +117,6 @@ return this; | ||
// default to inner join if not specified (parity with mysql) | ||
if( typeof stmt === "undefined" ) { | ||
if( typeof stmt === 'undefined' ) { | ||
stmt = tbl; | ||
tbl = dir; | ||
dir = "INNER"; | ||
dir = 'INNER'; | ||
} | ||
@@ -132,3 +128,3 @@ | ||
if( typeof stmt === "object" ) { | ||
if( typeof stmt === 'object' ) { | ||
if( this.opt.backquote ) { | ||
@@ -138,13 +134,11 @@ stmt = this.backquote(stmt); | ||
var fields = []; | ||
for( var ii in stmt ) { | ||
fields.push( ii + " = " + stmt[ii] ); | ||
// fields.push( `${ii} = ${stmt[ii]}` ); | ||
const fields = []; | ||
for( let ii in stmt ) { | ||
fields.push( `${ii} = ${stmt[ii]}` ); | ||
} | ||
stmt = fields.join(" AND "); | ||
stmt = fields.join(' AND '); | ||
} | ||
this.parts.join.push( [dir, "JOIN", tbl, "ON", stmt].join(' ') ); | ||
// this.parts.join.push( `${dir} JOIN ${tbl} ON ${stmt}` ); | ||
this.parts.join.push( `${dir} JOIN ${tbl} ON ${stmt}` ); | ||
@@ -176,3 +170,3 @@ return this; | ||
Monologue.prototype.insert = function insert( tbl, p, d ) { | ||
var col = ''; | ||
let col = ''; | ||
@@ -184,4 +178,4 @@ if( this.opt.backquote ) { | ||
if( p instanceof Array && d instanceof Array ) { | ||
var p = this.backquote( p ).join(','); | ||
var d = this.stringify( d, ""); | ||
p = this.backquote( p ).join(','); | ||
var d = this.stringify( d, "", ""); | ||
// stringify should be refactored a bit so this isn't necessary | ||
@@ -191,3 +185,3 @@ d.shift(); | ||
col = "(" + p + ") VALUES " + d; | ||
col = `(${p}) VALUES ${d}`; | ||
} | ||
@@ -202,5 +196,5 @@ | ||
var a = this.stringify( p, ""); | ||
col = "(" + a.shift() + ") VALUES " + a.join(','); | ||
// col = `(${a.shift()}) VALUES ${a.join(',')}`; | ||
let a = this.stringify( p, "", ""); | ||
col = `(${a.shift()}) VALUES ${a.join(',')}`; | ||
} | ||
@@ -212,4 +206,3 @@ | ||
this.parts.stmt = ["INSERT INTO", tbl, col].join(' '); | ||
// this.parts.stmt = `INSERT INTO ${tbl} ${col}`; | ||
this.parts.stmt = `INSERT INTO ${tbl} ${col}`; | ||
@@ -225,3 +218,3 @@ return this; | ||
Monologue.prototype.update = function update( tbl, p ) { | ||
var col = ''; | ||
let col = ''; | ||
@@ -232,4 +225,5 @@ if( this.opt.backquote ) { | ||
if( typeof p === "object" ) { | ||
col = "SET " + this.stringify( p ).join( ', ' ); | ||
if( typeof p === 'object' ) { | ||
col = this.stringify( p ).join( ', ' ); | ||
col = `SET ${col}`; | ||
} | ||
@@ -241,4 +235,3 @@ | ||
this.parts.stmt = 'UPDATE ' + tbl + ' ' + col; | ||
// this.parts.stmt = `UPDATE ${tbl} ${col}`; | ||
this.parts.stmt = `UPDATE ${tbl} ${col}`; | ||
@@ -248,3 +241,7 @@ return this; | ||
Monologue.prototype.on_duplicate = function on_duplicate(tbl, p) { | ||
}; | ||
/** | ||
@@ -269,4 +266,3 @@ * Free-hand queries | ||
this.parts.stmt = "DELETE FROM " + tbl; | ||
// this.parts.stmt = `DELETE FROM ${tbl}`; | ||
this.parts.stmt = `DELETE FROM ${tbl}`; | ||
return ( wh ? this.where( wh ) : this ); | ||
@@ -326,4 +322,3 @@ }; | ||
return this.where(" LIKE " + like, ''); | ||
// return this.where(` LIKE ${like}`, ''); | ||
return this.where(` LIKE ${like}`, ''); | ||
}; | ||
@@ -341,4 +336,3 @@ | ||
return this.where(" BETWEEN " + one + " AND " + two, ''); | ||
// return this.where(` BETWEEN ${one} AND ${two}`, ''); | ||
return this.where(` BETWEEN ${one} AND ${two}`, ''); | ||
}; | ||
@@ -350,5 +344,3 @@ | ||
Monologue.prototype.group = function group( grp, dir ) { | ||
dir = dir || 'ASC'; | ||
Monologue.prototype.group = function group( grp, dir = 'ASC' ) { | ||
if( this.opt.backquote ) { | ||
@@ -361,4 +353,3 @@ grp = this.backquote(grp); | ||
this.parts.group.push( grp + " " + dir ); | ||
// this.parts.group.push( `${grp} ${dir}` ); | ||
this.parts.group.push( `${grp} ${dir}` ); | ||
@@ -372,5 +363,3 @@ return this; | ||
Monologue.prototype.order = function order( ord, dir ) { | ||
dir = dir || 'ASC'; | ||
Monologue.prototype.order = function order( ord, dir = 'ASC' ) { | ||
if( this.opt.backquote ) { | ||
@@ -383,4 +372,3 @@ ord = this.backquote(ord); | ||
this.parts.order.push( ord + " " + dir ); | ||
// this.parts.order.push( `${ord} ${dir}` ); | ||
this.parts.order.push( `${ord} ${dir}` ); | ||
@@ -396,5 +384,4 @@ return this; | ||
this.parts.limit = ( typeof off === "undefined" | ||
? '' + lim | ||
: lim + ' OFFSET ' + off ); | ||
// : `${lim} OFFSET ${off}` ); | ||
? `${lim}` | ||
: `${lim} OFFSET ${off}` ); | ||
@@ -415,8 +402,7 @@ return this; | ||
var sql = this.sql(); | ||
let sql = this.sql(); | ||
this.reset(); | ||
this.parts.stmt = sql += " UNION SELECT " + c + " FROM " + t; | ||
// this.parts.stmt = `${sql} UNION SELECT ${c} FROM ${t}`; | ||
this.parts.stmt = `${sql} UNION SELECT ${c} FROM ${t}`; | ||
@@ -427,5 +413,4 @@ return this; | ||
Monologue.prototype.not = function not(p, sep) { | ||
sep = sep || 'AND'; | ||
sep = ' ' + sep + ' '; | ||
Monologue.prototype.not = function not(p, sep = 'AND') { | ||
sep = ` ${sep} `; | ||
@@ -443,3 +428,3 @@ if( p instanceof Array && Object(p[0]) === p[0] ) { | ||
else if( Object(p) === p ) { | ||
this.where( this.stringify(p, '!=').join(sep) ); | ||
this.where( this.stringify(p, '!=', 'IS NOT').join(sep) ); | ||
} | ||
@@ -485,5 +470,4 @@ | ||
Monologue.prototype.comparison = function comparison(p, sep, eq) { | ||
sep = sep || 'AND'; | ||
sep = ' ' + sep + ' '; | ||
Monologue.prototype.comparison = function comparison(p, sep = 'AND', eq) { | ||
sep = ` ${sep} `; | ||
@@ -493,6 +477,5 @@ if( p instanceof Array && Object(p[0]) === p[0] ) { | ||
this.last_condition.call( this, p.map(function(val) { | ||
var str = this.stringify( val, eq ).join(' AND '); | ||
return str; | ||
}.bind(this)), sep ); | ||
this.last_condition.call( this, p.map((val) => { | ||
return this.stringify( val, eq ).join(' AND '); | ||
}), sep ); | ||
} | ||
@@ -564,3 +547,3 @@ else if( Object(p) === p ) { | ||
Monologue.prototype.explain = function explain() { | ||
return 'EXPLAIN ' + this.sql(); | ||
return `EXPLAIN ${this.sql()}`; | ||
}; | ||
@@ -574,9 +557,7 @@ | ||
Monologue.prototype.stringify = function stringify( p, s, j ) { | ||
j = j || ', '; | ||
s = ( typeof s === "undefined" ? "=" : s ); | ||
var c = []; | ||
Monologue.prototype.stringify = function stringify( p, s = '=', ns = '=', j = ', ' ) { | ||
const c = []; | ||
if( p instanceof Array ) { | ||
for( var ii = 0, l = p.length; ii < l; ++ii ) { | ||
for( let ii = 0, l = p.length; ii < l; ++ii ) { | ||
// if parent is an array and child is an object, | ||
@@ -594,3 +575,3 @@ // generate an encapsulated list of values (for inserts) | ||
// so do it here, if applicable | ||
var cols = ( this.opt.backquote | ||
let cols = ( this.opt.backquote | ||
? this.backquote( this.parts.columns ) | ||
@@ -602,3 +583,5 @@ : this.parts.columns ); | ||
c.push( "(" + this.stringify( p[ii], "" ).join(j) + ")" ); | ||
let str = this.stringify( p[ii], s, ns ).join(j); | ||
c.push( `(${str})` ); | ||
} | ||
@@ -627,3 +610,3 @@ | ||
for( var jj = 0, len = col.length; jj < len; ++jj ) { | ||
c.push( this.format( p[col[jj]], col[jj], s ) ); | ||
c.push( this.format( p[col[jj]], col[jj], s, ns ) ); | ||
} | ||
@@ -640,13 +623,10 @@ } | ||
Monologue.prototype.format = function format( v, k, s ) { | ||
Monologue.prototype.format = function format( v, k = '', s, ns ) { | ||
if( v instanceof Array ) { | ||
k = k || ''; | ||
var vs = v.map(function(v) { | ||
let vesc = v.map( (v) => { | ||
return this.escape(v); | ||
}.bind(this)).join(','); | ||
}).join(','); | ||
var ret = ( this.opt.backquote && k ? this.backquote( k ) : k ) | ||
+ " IN (" + vs + ")"; | ||
// + ` IN (${vs})`; | ||
let ret = ( this.opt.backquote && k ? this.backquote( k ) : k ) | ||
+ ` IN (${vesc})`; | ||
@@ -664,5 +644,7 @@ return ret; | ||
if( v === 'NULL' && s ) { | ||
s = ( s === '=' ? 'IS' : 'IS NOT' ); | ||
} | ||
// if( v === 'NULL' && s ) { | ||
// s = ( s === '=' ? 'IS' : 'IS NOT' ); | ||
// } | ||
if( v === 'NULL' ) | ||
s = ns; | ||
} | ||
@@ -672,3 +654,3 @@ | ||
// value and ditch the key and separator | ||
return ( k && s ? k + " " + s + " " : '' ) + v; | ||
return ( k && s ? `${k} ${s} ` : '' ) + v; | ||
} | ||
@@ -689,12 +671,10 @@ | ||
if( val instanceof Array ) { | ||
return val.map(function(v) { | ||
return val.map( (v) => { | ||
return this.escape(v); | ||
// maintaining execution scope to avoid setting a var | ||
// (can't wait to upgrade node 4+) | ||
}.bind(this)); | ||
}); | ||
} | ||
else if( Object(val) === val ) { | ||
var obj = {}; | ||
for( var i in val ) { | ||
const obj = {}; | ||
for( let i in val ) { | ||
obj[i] = val[i]; | ||
@@ -723,4 +703,3 @@ } | ||
return "'" + val + "'"; | ||
// return `'${val}'`; | ||
return `'${val}'`; | ||
}; | ||
@@ -731,12 +710,10 @@ | ||
if( col instanceof Array ) { | ||
return col.map(function(v) { | ||
return col.map( (v) => { | ||
return this.backquote(v, pre); | ||
// maintaining execution scope to avoid setting a var | ||
// (can't wait to upgrade node 4+) | ||
}.bind(this)); | ||
}); | ||
} | ||
else if( col === Object(col) ){ | ||
var obj = {}; | ||
for( var i in col ) { | ||
const obj = {}; | ||
for( let i in col ) { | ||
obj[this.backquote(i, pre)] = col[i]; | ||
@@ -762,4 +739,3 @@ } | ||
return '`' + pre + col + '`'; | ||
// return `\`${pre}${col}\``; | ||
return `\`${pre}${col}\``; | ||
} | ||
@@ -766,0 +742,0 @@ }; |
{ | ||
"name": "monologue", | ||
"version": "0.7.4", | ||
"version": "0.8.0", | ||
"description": "Streamlined MySQL query building", | ||
@@ -5,0 +5,0 @@ "main": "./monologue.js", |
@@ -8,54 +8,2 @@ Monologue - Streamlined query building | ||
***NOTICE*** | ||
Starting in version 0.8.0, Monologue will only be compatible with 4.latest and up to take advantage of ES6 features. Do not upgrade if you are still using 0.12 or lower. | ||
***Breaking changes for 0.7.0*** | ||
The API was reworked to clear up some annoyances and allow for free-hand queries to be written when a specific method does not exist. When a query is ready to be compiled, instead of calling `.query()` and referencing `.sql`, you simply call `.sql()`. Example: | ||
monologue() | ||
.select( "*", "users u" ) | ||
.join( "posts p", "p.user_id = u.id" ) | ||
.where( { "category": "67" } ) | ||
.sql(); | ||
The old method for compiling queries, `.query()`, has been repurposed for constructing queries that do not have a built in starter method (like `.select()`, `.insert()`, etc). These queries can be started like this: | ||
monologue() | ||
.query('SHOW TABLES FROM table') | ||
.where({some: 'condition'}) | ||
.sql(); | ||
No sanitization is performed as part of `.query()`, so use it carefully. Subsequent methods will sanitize per their normal behavior. | ||
***New Feature*** | ||
`.select()` was updated in 0.7.1 to *optionally* accept a table name only, making '*' the implicit column selection. Example: | ||
// 'SELECT * FROM `users` WHERE `email` = 'some@example.com' | ||
monologue().select('users').where({email: 'some@example.com'}).sql() | ||
A new method was added in 0.7.0, taking advantage of the recent API changes. It's pretty self-explanatory: | ||
// 'EXPLAIN SELECT * FROM `users` WHERE `email` = 'some@example.com' | ||
monologue().select('*', 'users').where({email: 'some@example.com'}).explain() | ||
# API | ||
This area needs a ton of work. You can get some great examples in the section by the same name. For now, here's a quick rundown of `monologue().backquote()`: | ||
// result: [ '`email`', '`password`', '`type`' ] | ||
monologue().backquote(['email', 'password', 'type']); | ||
// result: { '`pizza`': "hawaiin bbq chicken", '`drink`': "chocolate milk", '`dessert`': "german chocolate cake" } | ||
monologue().backquote({ | ||
pizza: "hawaiin bbq chicken", | ||
drink: "chocolate milk", | ||
dessert: "german chocolate cake" | ||
}); | ||
// result: '`cupcake`' | ||
monologue().backquote('cupcake'); | ||
# Examples | ||
@@ -94,3 +42,2 @@ | ||
console.log( mono.sql ); | ||
// output: SELECT * FROM users WHERE id IN (1,2,3,4,5,6) AND date_time BETWEEN '2012-09-12' AND '2013-01-20' OR name LIKE 'ro%en' GROUP BY type, hamster ASC ORDER BY id ASC LIMIT 1000, 300 | ||
@@ -166,3 +113,12 @@ | ||
// INSERT, passing array of column names and array of values | ||
// output: INSERT INTO `users` (`email`,`first_name`,`last_name`) VALUES ('test@user.com', 'Test', 'User'),('example@sample.com', 'Sample', 'Person'),('fake@name.com', 'Fake', 'Name') | ||
monologue() | ||
.insert( 'users', ['email', 'first_name', 'last_name'], [ | ||
['test@user.com', 'Test', 'User'], | ||
['example@sample.com', 'Sample', 'Person'], | ||
['fake@name.com', 'Fake', 'Name'] | ||
]).sql(); | ||
// UPDATE | ||
@@ -252,4 +208,4 @@ // output: UPDATE users SET email = 'some@email.com', password = 'abcdefg', username = 'yoyo' WHERE id = 23 | ||
mono({backquote: false}) | ||
.select(['sum(id) as count'], 'comments') | ||
.select('sum(id) as count', 'comments') | ||
.having('count').gte(42) | ||
.sql(); |
56446
519
207