Comparing version 0.6.8 to 0.7.0
@@ -24,4 +24,2 @@ (function(exports) { | ||
this.sql = ''; | ||
this.parts = {}; | ||
@@ -44,3 +42,4 @@ | ||
this.parts = { | ||
query: '', | ||
stmt: '', | ||
sql: '', | ||
join: [], | ||
@@ -73,3 +72,3 @@ where: '', | ||
this.parts.query = ["SELECT", col, "FROM", tbl].join(' '); | ||
this.parts.stmt = ["SELECT", col, "FROM", tbl].join(' '); | ||
@@ -157,3 +156,3 @@ return this; | ||
this.parts.query = ["INSERT INTO", tbl, col].join(' '); | ||
this.parts.stmt = ["INSERT INTO", tbl, col].join(' '); | ||
@@ -183,3 +182,3 @@ return this; | ||
this.parts.query = ["UPDATE", tbl, col].join(' '); | ||
this.parts.stmt = ["UPDATE", tbl, col].join(' '); | ||
@@ -191,4 +190,15 @@ return this; | ||
/** | ||
* Free-hand queries | ||
*/ | ||
Monologue.prototype.query = function query(stmt) { | ||
this.parts.stmt = stmt; | ||
return this; | ||
}; | ||
/** | ||
*/ | ||
Monologue.prototype.delete = function _delete( tbl, wh ) { | ||
@@ -199,3 +209,3 @@ if( this.opt.backquote ) { | ||
this.parts.query = "DELETE FROM " + tbl; | ||
this.parts.stmt = "DELETE FROM " + tbl; | ||
return ( wh ? this.where( wh ) : this ); | ||
@@ -355,3 +365,3 @@ }; | ||
: lim + ' OFFSET ' + off ); | ||
// : off + ", " + lim ); | ||
return this; | ||
@@ -371,7 +381,7 @@ }; | ||
var sql = this.query().sql; | ||
var sql = this.sql(); | ||
this.reset(); | ||
this.parts.query = sql += " UNION SELECT " + c + " FROM " + t; | ||
this.parts.stmt = sql += " UNION SELECT " + c + " FROM " + t; | ||
@@ -454,3 +464,3 @@ return this; | ||
Monologue.prototype.file = function file( f, t, e, l ) { | ||
if( typeof l === "undefined" ) { | ||
if( typeof l === 'undefined' ) { | ||
l = e; | ||
@@ -473,21 +483,33 @@ e = undefined; | ||
Monologue.prototype.query = function query() { | ||
Monologue.prototype.sql = function sql() { | ||
// start from scratch each time this is called | ||
this.parts.sql = this.parts.stmt; | ||
if( this.parts.join.length > 0 ) | ||
this.parts.query += ' ' + this.parts.join.join(' '); | ||
this.parts.sql += ' ' + this.parts.join.join(' '); | ||
if( this.parts.where.length > 0 ) | ||
this.parts.query += " WHERE " + this.parts.where; | ||
this.parts.sql += ' WHERE ' + this.parts.where; | ||
if( this.parts.group.length > 0 ) | ||
this.parts.query += " GROUP BY " + this.parts.group.join(','); | ||
this.parts.sql += ' GROUP BY ' + this.parts.group.join(','); | ||
if( this.parts.having.length > 0 ) | ||
this.parts.query += " HAVING " + this.parts.having; | ||
this.parts.sql += ' HAVING ' + this.parts.having; | ||
if( this.parts.order.length > 0 ) | ||
this.parts.query += " ORDER BY " + this.parts.order.join(','); | ||
this.parts.sql += ' ORDER BY ' + this.parts.order.join(','); | ||
if( this.parts.limit.length > 0 ) | ||
this.parts.query += " LIMIT " + this.parts.limit; | ||
this.parts.sql += ' LIMIT ' + this.parts.limit; | ||
if( this.parts.last.length > 0 ) | ||
this.parts.query += this.parts.last; | ||
this.parts.sql += this.parts.last; | ||
this.sql = this.parts.query; | ||
return this.parts.sql; | ||
}; | ||
return this; | ||
Monologue.prototype.explain = function explain() { | ||
return 'EXPLAIN ' + this.sql(); | ||
}; | ||
@@ -610,4 +632,4 @@ | ||
// if s and/or k is undefined, it is an array of values so just format value | ||
// and ditch the key and separator | ||
// if s and/or k is undefined, it is an array of values so just format | ||
// value and ditch the key and separator | ||
return ( k && s ? k + " " + s + " " : '' ) + v; | ||
@@ -708,2 +730,2 @@ } | ||
})( typeof window === 'undefined' ? module.exports : window ); | ||
})( typeof window === 'undefined' ? module.exports : window ); |
{ | ||
"name": "monologue", | ||
"version": "0.6.8", | ||
"version": "0.7.0", | ||
"description": "Streamlined MySQL query building", | ||
@@ -5,0 +5,0 @@ "main": "./monologue.js", |
175
README.md
@@ -6,84 +6,30 @@ Monologue - Streamlined query building | ||
**Security Notice & Breaking Changes** | ||
* In previous versions, monologue did not automatically escape column names (or table names), only values. So unless you were using `monologue().backquote()`, your queries may be at risk. Column names and table names are now automatically backquoted, so check your query output to make sure it doesn't break anything. This can be disabled by passing an option like this: `monologue({backquote: false})`. | ||
* Bound parameter-style queries have been removed since in 0.5.0. Documentation has been removed for quite a while, so this should affect very few, if any, users. | ||
* In previous versions, when doing multiple inserts(array of objects) the object keys were sorted alphabetically. Instead of doing this automatically, it is now optional and defaults to not sorting. This will make the output of the query more predictable based on input. If you would like to enable sorting, you can pass `monologue({sort_keys: true})` as an option. It is not necessary to sort keys, monologue puts your insert statements in the correct order (based on the order of the first object in the collection), but the option is there for unit testing compatibility and for analyzing output in testing. | ||
[Support Development](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9KXDJTKMBPXTE) | ||
**New features** | ||
***Breaking changes for 0.7.0*** | ||
New shortcut methods for joins, see examples below for usage of mono.join() | ||
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: | ||
mono().ljoin( table, statement ); // LEFT JOIN | ||
mono().rjoin( table, statement ); // RIGHT JOIN | ||
mono().lojoin( table, statement ); // LEFT OUTER JOIN | ||
mono().rojoin( table, statement ); // RIGHT OUTER JOIN | ||
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: | ||
New methods were added for doing different types of comparison. File a github issue if you have some feedback, maybe they're stupid/useless, you be the judge: | ||
monologue() | ||
.query('SHOW TABLES FROM table') | ||
.where({some: 'condition'}) | ||
.sql(); | ||
// new methods: .gt(), .lt(), .gte(), .lte(), and .not() | ||
No sanitization is performed as part of `.query()`, so use it carefully. Subsequent methods will sanitize per their normal behavior. | ||
// SELECT `username`, `password` FROM `users` WHERE id NOT IN (1,2,3,4) | ||
mono() | ||
.select(['username', 'password'], 'users') | ||
.where('id') | ||
.not([1,2,3,4]) | ||
.query().sql; | ||
***New Feature*** | ||
// SELECT * FROM `campsites` WHERE `reserved` != true AND `fishing` != \'slow\' | ||
mono() | ||
.select('*', 'campsites') | ||
.not({'reserved': true, fishing: 'slow'}) | ||
.query().sql; | ||
A new method was added in 0.7.0, taking advantage of the recent API changes. It's pretty self-explanatory: | ||
// SELECT * FROM `media` WHERE `type` IS NOT NULL AND `file_size` > 0 AND `seconds` > 24325 | ||
mono() | ||
.select('*', 'media') | ||
.not({'type': null}) | ||
.gt({file_size: 0, seconds: 24325}) | ||
.query().sql; | ||
// 'EXPLAIN SELECT * FROM `users` WHERE `email` = 'some@example.com' | ||
monologue().select('*', 'users').where({email: 'some@example.com'}).explain() | ||
// SELECT `username`, `password` FROM `users` WHERE `username` != \'joe\' AND `username` != \'bob\' | ||
mono() | ||
.select(['username', 'password'], 'users') | ||
.not([{username: 'joe'},{username: 'bob'}]) | ||
.query().sql; | ||
// SELECT * FROM `users` WHERE last_login NOT BETWEEN \'2015-10-01 00:00:00\' AND \'2015-11-30 23:59:59\' | ||
mono() | ||
.select('*', 'users') | ||
.where('last_login') | ||
.not() | ||
.between('2015-10-01 00:00:00', '2015-11-30 23:59:59') | ||
.query().sql; | ||
// SELECT `title`, `post` FROM `posts` WHERE status < 8 | ||
mono() | ||
.select(['title', 'post'], 'posts') | ||
.where('status').lt(8) | ||
.query().sql; | ||
// SELECT * FROM `posts` WHERE `favorited` <= 815 AND `commentors` <= 1516 OR `likes` <= 42 | ||
mono() | ||
.select('*', 'posts') | ||
.lte([{favorited: 815, commentors: 1516},{likes: 42}], 'OR') | ||
.query().sql; | ||
// SELECT `post_id`, `comments` FROM `comments` WHERE `post_id` = 23565 AND date_time > \'2015-12-01 00:00:00\' | ||
mono() | ||
.select(['post_id', 'comments'], 'comments') | ||
.where({post_id: 23565}) | ||
.where('date_time').gt('2015-12-01 00:00:00') | ||
// SELECT sum(id) as count FROM comments HAVING count >= 42 | ||
mono({backquote: false}) | ||
.select(['sum(id) as count'], 'comments') | ||
.having('count').gte(42) | ||
.query().sql; | ||
# API | ||
@@ -123,3 +69,3 @@ | ||
.or([ {flavor: 'salty', peanuts: true} ]) | ||
.query().sql | ||
.sql() | ||
@@ -138,3 +84,3 @@ // Less than basic SELECT statement | ||
.limit( '300', 1000 ) | ||
.query(); | ||
.sql(); | ||
@@ -145,2 +91,8 @@ console.log( mono.sql ); | ||
mono().ljoin( table, statement ); // LEFT JOIN | ||
mono().rjoin( table, statement ); // RIGHT JOIN | ||
mono().lojoin( table, statement ); // LEFT OUTER JOIN | ||
mono().rojoin( table, statement ); // RIGHT OUTER JOIN | ||
// JOIN (default is inner): | ||
@@ -153,3 +105,3 @@ // SELECT * FROM users u INNER JOIN posts p ON p.user_id = u.id WHERE category = '67' | ||
.where( { "category": "67" } ) | ||
.query().sql; | ||
.sql(); | ||
@@ -164,3 +116,3 @@ | ||
.where( { "category": "67" } ) | ||
.query().sql; | ||
.sql(); | ||
@@ -176,3 +128,3 @@ | ||
.file( "/tmp/datafile", ",", '"', "\\n" ) | ||
.query().sql; | ||
.sql(); | ||
@@ -187,3 +139,3 @@ | ||
.file( "/tmp/datafile", ",", "\\n" ) | ||
.query().sql; | ||
.sql(); | ||
@@ -199,3 +151,3 @@ | ||
] ) | ||
.query().sql; | ||
.sql(); | ||
@@ -210,3 +162,3 @@ | ||
} ) | ||
.query().sql; | ||
.sql(); | ||
@@ -220,3 +172,3 @@ | ||
.where( {id: 23} ) | ||
.query().sql; | ||
.sql(); | ||
@@ -229,3 +181,3 @@ | ||
.delete( 'users', { username: 'test', password: '1234', first_name: "me" } ) | ||
.query().sql; | ||
.sql(); | ||
@@ -243,2 +195,61 @@ | ||
.where({"company":"coName"}) | ||
.query().sql | ||
.sql(); | ||
// SELECT `username`, `password` FROM `users` WHERE id NOT IN (1,2,3,4) | ||
mono() | ||
.select(['username', 'password'], 'users') | ||
.where('id') | ||
.not([1,2,3,4]) | ||
.sql(); | ||
// SELECT * FROM `campsites` WHERE `reserved` != true AND `fishing` != \'slow\' | ||
mono() | ||
.select('*', 'campsites') | ||
.not({'reserved': true, fishing: 'slow'}) | ||
.sql(); | ||
// SELECT * FROM `media` WHERE `type` IS NOT NULL AND `file_size` > 0 AND `seconds` > 24325 | ||
mono() | ||
.select('*', 'media') | ||
.not({'type': null}) | ||
.gt({file_size: 0, seconds: 24325}) | ||
.sql(); | ||
// SELECT `username`, `password` FROM `users` WHERE `username` != \'joe\' AND `username` != \'bob\' | ||
mono() | ||
.select(['username', 'password'], 'users') | ||
.not([{username: 'joe'},{username: 'bob'}]) | ||
.sql(); | ||
// SELECT * FROM `users` WHERE last_login NOT BETWEEN \'2015-10-01 00:00:00\' AND \'2015-11-30 23:59:59\' | ||
mono() | ||
.select('*', 'users') | ||
.where('last_login') | ||
.not() | ||
.between('2015-10-01 00:00:00', '2015-11-30 23:59:59') | ||
.sql(); | ||
// SELECT `title`, `post` FROM `posts` WHERE status < 8 | ||
mono() | ||
.select(['title', 'post'], 'posts') | ||
.where('status').lt(8) | ||
.sql(); | ||
// SELECT * FROM `posts` WHERE `favorited` <= 815 AND `commentors` <= 1516 OR `likes` <= 42 | ||
mono() | ||
.select('*', 'posts') | ||
.lte([{favorited: 815, commentors: 1516},{likes: 42}], 'OR') | ||
.sql(); | ||
// SELECT `post_id`, `comments` FROM `comments` WHERE `post_id` = 23565 AND date_time > \'2015-12-01 00:00:00\' | ||
mono() | ||
.select(['post_id', 'comments'], 'comments') | ||
.where({post_id: 23565}) | ||
.where('date_time').gt('2015-12-01 00:00:00') | ||
.sql(); | ||
// SELECT sum(id) as count FROM comments HAVING count >= 42 | ||
mono({backquote: false}) | ||
.select(['sum(id) as count'], 'comments') | ||
.having('count').gte(42) | ||
.sql(); |
522
242
57663