Permalink
Browse files

Added the ability to turn off automatic quoting of string field value…

…s in UPDATE and INSERT queries.

This was accomplished through the addition of an "options" parameter to squel.update() and squel.insert():

autoQuote - if true (default) then string field values are automatically single-quoted; if false then not.
  • Loading branch information...
1 parent 22ae927 commit 050ecf1c130c48fa1bc759196c6d842bdac65639 @hiddentao committed Jan 19, 2012
Showing with 199 additions and 96 deletions.
  1. +84 −70 docs/squel.html
  2. +3 −3 package.json
  3. +33 −12 squel.js
  4. +1 −1 squel.min.js
  5. +33 −8 src/squel.coffee
  6. +24 −1 test/insert.coffee
  7. +21 −1 test/update.coffee
View
Oops, something went wrong.
View
@@ -8,9 +8,9 @@
"devDependencies": {
"coffee-script": ">= 1.2.0",
"rimraf": "latest",
- "docco": ">= 0.3.0",
- "vows": ">= 0.6.0",
- "uglify-js": ">= 1.2.2"
+ "docco": "0.3.0",
+ "vows": "0.6.0",
+ "uglify-js": "1.2.2"
},
"keywords": ["sql", "database", "rdbms"],
"main": "squel",
View
@@ -25,11 +25,22 @@ OTHER DEALINGS IN THE SOFTWARE.
*/
(function() {
- var Delete, Expression, ExpressionClassName, Insert, Select, Update, WhereOrderLimit, formatValue, getObjectClassName, sanitizeAlias, sanitizeCondition, sanitizeField, sanitizeLimitOffset, sanitizeName, sanitizeTable, sanitizeValue, _export,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+ var Delete, Expression, ExpressionClassName, Insert, Select, Update, WhereOrderLimit, formatValue, getObjectClassName, sanitizeAlias, sanitizeCondition, sanitizeField, sanitizeLimitOffset, sanitizeName, sanitizeTable, sanitizeValue, _export, _extend,
__hasProp = Object.prototype.hasOwnProperty,
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
+ _extend = function(dst, src) {
+ var k, v;
+ if (src == null) src = {};
+ for (k in src) {
+ if (!__hasProp.call(src, k)) continue;
+ v = src[k];
+ dst[k] = v;
+ }
+ return dst;
+ };
+
Expression = (function() {
var _toString;
@@ -184,13 +195,13 @@ OTHER DEALINGS IN THE SOFTWARE.
return item;
};
- formatValue = function(value) {
+ formatValue = function(value, formattingOptions) {
if (null === value) {
value = "NULL";
} else if ("boolean" === typeof value) {
value = value ? "TRUE" : "FALSE";
} else if ("number" !== typeof value) {
- value = "\"" + value + "\"";
+ if (formattingOptions.autoQuotes) value = "\"" + value + "\"";
}
return value;
};
@@ -442,12 +453,17 @@ OTHER DEALINGS IN THE SOFTWARE.
Update.prototype.fields = null;
- function Update() {
+ Update.prototype.formattingOptions = null;
+
+ function Update(options) {
this.toString = __bind(this.toString, this);
this.set = __bind(this.set, this);
this.table = __bind(this.table, this); Update.__super__.constructor.apply(this, arguments);
this.tables = [];
this.fields = {};
+ this.formattingOptions = _extend({
+ autoQuotes: true
+ }, options);
}
Update.prototype.table = function(table, alias) {
@@ -496,7 +512,7 @@ OTHER DEALINGS IN THE SOFTWARE.
for (_j = 0, _len2 = fieldNames.length; _j < _len2; _j++) {
field = fieldNames[_j];
if ("" !== fields) fields += ", ";
- fields += "" + field + " = " + (formatValue(this.fields[field]));
+ fields += "" + field + " = " + (formatValue(this.fields[field], this.formattingOptions));
}
ret += " SET " + fields;
ret += this.whereString();
@@ -547,10 +563,15 @@ OTHER DEALINGS IN THE SOFTWARE.
Insert.prototype.fields = null;
- function Insert() {
+ Insert.prototype.formattingOptions = null;
+
+ function Insert(options) {
this.toString = __bind(this.toString, this);
this.set = __bind(this.set, this);
this.into = __bind(this.into, this); this.fields = {};
+ this.formattingOptions = _extend({
+ autoQuotes: true
+ }, options);
}
Insert.prototype.into = function(table) {
@@ -587,7 +608,7 @@ OTHER DEALINGS IN THE SOFTWARE.
if ("" !== fields) fields += ", ";
fields += field;
if ("" !== values) values += ", ";
- values += formatValue(this.fields[field]);
+ values += formatValue(this.fields[field], this.formattingOptions);
}
return "INSERT INTO " + this.table + " (" + fields + ") VALUES (" + values + ")";
};
@@ -603,11 +624,11 @@ OTHER DEALINGS IN THE SOFTWARE.
select: function() {
return new Select;
},
- update: function() {
- return new Update;
+ update: function(options) {
+ return new Update(options);
},
- insert: function() {
- return new Insert;
+ insert: function(options) {
+ return new Insert(options);
},
"delete": function() {
return new Delete;
View
Oops, something went wrong.
View
@@ -23,6 +23,14 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
###
+
+# Extend given object's with another object's properties, overriding existing ones if necessary
+_extend = (dst, src = {}) ->
+ for own k,v of src
+ dst[k] = v
+ dst
+
+
# An SQL expression builder.
#
# SQL expressions are used in WHERE and ON clauses to filter data by various criteria.
@@ -171,13 +179,17 @@ sanitizeValue = (item) ->
item
# Format the given field value for inclusion into the query string
-formatValue = (value) ->
+#
+# formattingOptions:
+# autoQuotes: if true (default) then string field values are automatically single-quoted; if false then not.
+formatValue = (value, formattingOptions) ->
if null is value
value = "NULL"
else if "boolean" is typeof value
value = if value then "TRUE" else "FALSE"
else if "number" isnt typeof value
- value = "\"#{value}\""
+ if formattingOptions.autoQuotes
+ value = "\"#{value}\""
value
@@ -438,11 +450,17 @@ class Select extends WhereOrderLimit
class Update extends WhereOrderLimit
tables: null
fields: null
+ formattingOptions: null
- constructor: ->
+ # Options can currently include the following keys:
+ # autoQuotes: if true (default) then string field values are automatically single-quoted; if false then not.
+ constructor: (options) ->
super
@tables = []
@fields = {}
+ @formattingOptions = _extend({
+ autoQuotes: true
+ }, options)
# Update the given table.
@@ -488,7 +506,7 @@ class Update extends WhereOrderLimit
fields = ""
for field in fieldNames
fields += ", " if "" isnt fields
- fields += "#{field} = #{formatValue(@fields[field])}"
+ fields += "#{field} = #{formatValue(@fields[field], @formattingOptions)}"
ret += " SET #{fields}"
# where
@@ -548,9 +566,16 @@ class Delete extends WhereOrderLimit
class Insert
table: null
fields: null
+ formattingOptions: null
- constructor: ->
+ # Options can currently include the following keys:
+ # autoQuotes: if true (default) then string field values are automatically single-quoted; if false then not.
+ constructor: (options) ->
@fields = {}
+ @formattingOptions = _extend({
+ autoQuotes: true
+ }, options)
+
# The table to insert into.
# This will override any previously set value.
@@ -581,7 +606,7 @@ class Insert
fields += ", " if "" isnt fields
fields += field
values += ", " if "" isnt values
- values += formatValue(@fields[field])
+ values += formatValue(@fields[field], @formattingOptions)
"INSERT INTO #{@table} (#{fields}) VALUES (#{values})"
@@ -591,8 +616,8 @@ class Insert
_export =
expr: -> new Expression
select: -> new Select
- update: -> new Update
- insert: -> new Insert
+ update: (options) -> new Update(options)
+ insert: (options) -> new Insert(options)
delete: -> new Delete
module?.exports = _export
window?.squel = _export
View
@@ -29,7 +29,7 @@ assert = require "assert"
squel = require "../squel.min"
tu = require "./testutils"
-inst = -> squel.insert()
+inst = (options) -> squel.insert(options)
expr = -> squel.expr()
@@ -94,6 +94,29 @@ suite.addBatch
'then when toString() is called': tu.contextAssertStringEqual 'INSERT INTO test (f1, f2, f3, f4, f5, f6) VALUES (1, 1.2, TRUE, FALSE, "blah", NULL)'
+
+suite.addBatch
+ 'when auto-quotes are turned off':
+ topic: -> inst(autoQuotes: false)
+ 'when into("test") is called':
+ topic: (obj) -> obj.into("test")
+ 'when set("f1",1) is called':
+ topic: (obj) -> obj.set("f1",1)
+ 'when set("f2",1.2) is called':
+ topic: (obj) -> obj.set("f2",1.2)
+ 'when set("f3",true) is called':
+ topic: (obj) -> obj.set("f3",true)
+ 'when set("f4",false) is called':
+ topic: (obj) -> obj.set("f4",false)
+ 'when set("f5","blah") is called':
+ topic: (obj) -> obj.set("f5","blah")
+ 'then when set("f6",null) is called':
+ topic: (obj) -> obj.set("f6",null)
+ 'then when toString() is called': tu.contextAssertStringEqual 'INSERT INTO test (f1, f2, f3, f4, f5, f6) VALUES (1, 1.2, TRUE, FALSE, blah, NULL)'
+
+
+
+
suite.addBatch
'when into("test") is called':
topic: -> inst().into("test")
View
@@ -29,7 +29,7 @@ assert = require "assert"
squel = require "../squel.min"
tu = require "./testutils"
-inst = -> squel.update()
+inst = (options) -> squel.update(options)
expr = -> squel.expr()
@@ -134,6 +134,26 @@ suite.addBatch
'then when toString() is called': tu.contextAssertStringEqual 'UPDATE test SET f1 = 1, f2 = 1.2, f3 = TRUE, f4 = FALSE, f5 = "blah", f6 = NULL'
+suite.addBatch
+ 'when auto-quotes are turned off':
+ topic: -> inst(autoQuotes: off)
+ 'when table("test") is called':
+ topic: (obj) -> obj.table("test")
+ 'when set("f1",1) is called':
+ topic: (obj) -> obj.set("f1",1)
+ 'when set("f2",1.2) is called':
+ topic: (obj) -> obj.set("f2",1.2)
+ 'when set("f3",true) is called':
+ topic: (obj) -> obj.set("f3",true)
+ 'when set("f4",false) is called':
+ topic: (obj) -> obj.set("f4",false)
+ 'when set("f5","blah") is called':
+ topic: (obj) -> obj.set("f5","blah")
+ 'then when set("f6",null) is called':
+ topic: (obj) -> obj.set("f6",null)
+ 'then when toString() is called': tu.contextAssertStringEqual 'UPDATE test SET f1 = 1, f2 = 1.2, f3 = TRUE, f4 = FALSE, f5 = blah, f6 = NULL'
+
+
suite.addBatch
'when table("test") is called':

0 comments on commit 050ecf1

Please sign in to comment.