Skip to content

Commit

Permalink
Merge f50633b into 11f1582
Browse files Browse the repository at this point in the history
  • Loading branch information
kadishmal committed Mar 17, 2015
2 parents 11f1582 + f50633b commit 0629116
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 191 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# node-cubrid change log

## Version 2.2.3 (Mar 17, 2015)

- Enh #40: No need to escape double quotes when wrapped in single quotes.

## Version 2.2.2 (Feb 24, 2015)

- Fix #15: When closing a query, if connection is reset, consider the request was successful.
Expand Down
61 changes: 45 additions & 16 deletions README.md
Expand Up @@ -555,20 +555,49 @@ All READ queries **must be** closed explicitly.

#### WRITE queries

// `sql` is a string which represents a WRITE query or an array of strings
// for batch processing.
// `callback(err)` function accepts one argument: an error object if any.
client.execute(sql, callback);

##### Example

client.execute('CREATE TABLE tbl_test(id INT)', function (err) {
if (err) {
throw err;
} else {
// Do something else.
}
});
// `execute(sql, callback)` function accepts two arguments.
// 1. `sql`: a string which represents a WRITE query or an array
// of strings for batch processing.
// 2. `callback(err)`: a function that accepts one argument:
1. `err`: an error object if any.

client.execute("INSERT INTO a VALUES(1, 2, 'val')", function callback(err) {});

// `executeWithParams(sql, params, paramDelimiters, callback)`
// function accepts four arguments.
// 1. `sql`: a string which represents a WRITE query. **Note**
// not an array of strings.
// 2. `params`: an array of parameter values or the value itself
// which a user wants to bind instead of `?` placeholders
// in the `sql` query. If no placeholder is found, the `sql`
// will not be modified.
// 3. `paramDelimiters`: an optional array of delimiters which
// must be used to wrap parameter values. If omitted,
// it will try to guess the type and apply a default
// delimiter of that type.
// - `null` is passed as an unwrapped SQL equivalent `NULL`.
// - `number` is not wrapped.
// - `Date` instance is wrapped by a single quote and
// converted into CUBRID's `DATETIME` format such as
// `'mm/dd/yyyy hh:mi:ss.ff am|pm'` omitting the
// timezone information as CUBRID as of version 9
// does not support timezones.
// - Everything else, including `string`, is wrapped
// by a single quote.
// 4. `callback(err)`: a function that accepts one argument:
1. `err`: an error object if any.
// Under the hood, `executeWithParams()` as well as `query()` and
// `queryWithParams()` all call `Helpers._sqlFormat()` function
// to perform the actual formatting.

var sql = 'INSERT INTO a VALUES(?, ?, ?, ?)',
params = [1, 2, 'val', new Date()],
paramDelimiters = ["", "", "'", "'"];

client.executeWithParams(sql, params, paramDelimiters, function callback(err) {});
// Will send to the server the following formatted SQL:
// `INSERT INTO a VALUES(1, 2, 'val', '02/24/2015 03:09:20.12 pm')`

After executing WRITE queries there is no need to close the query.

Expand Down Expand Up @@ -860,10 +889,10 @@ repository
3. Start the container by mounting the node-cubrid directory to `/node-cubrid`
inside the container:

docker run --name node-cubrid -v $NODE_CUBRID_SRC:/node-cubrid lighthopper/node-cubrid:dev
docker run -it --name node-cubrid -v $NODE_CUBRID_SRC:/node-cubrid lighthopper/node-cubrid:dev

4. This will enter into the bash inside the container. At this point all commands you type
will be executed inside this container. Install all NPM dependencies.
will be executed inside this container. Now install all NPM dependencies.

npm install

Expand Down
80 changes: 48 additions & 32 deletions src/utils/Helpers.js
Expand Up @@ -164,31 +164,47 @@ Number.prototype.formatAsMoney = function (decimals, decimal_sep, thousands_sep)
* @return {*}
* @private
*/
var _escapeString = function (val) {
val = val.replace(/[\0\n\r\b\t\\'"\x1a]/g, function (s) {
switch (s) {
case "\0":
return "\\0";
case "\n":
return "\\n";
case "\r":
return "\\r";
case "\b":
return "\\b";
case "\t":
return "\\t";
case "\x1a":
return "\\Z";
case "'":
return "''";
case '"':
return '""';
default:
return "\\" + s;
}
});
var _escapeString = function (val, delimiter) {
val = val.replace(/[\0\n\r\b\t\\'"\x1a]/g, function (s) {
switch (s) {
case "\0":
return "\\0";
case "\n":
return "\\n";
case "\r":
return "\\r";
case "\b":
return "\\b";
case "\t":
return "\\t";
case "\x1a":
return "\\Z";
case "'":
// If the string includes a single quote and we are wrapping
// the string with single quotes, then we need to escape these single quotes.
if (!delimiter || s == delimiter) {
return "''";
}

// Otherwise, no need to escape single quotes if the string is
// wrapped by double quotes.
return s;
case '"':
// If the string includes a double quote and we are wrapping
// the string with double quotes, then we need to escape these double quotes.
if (!delimiter || s == delimiter) {
return '""';
}

// Otherwise, no need to escape double quotes if the string is
// wrapped by single quotes.
return s;
default:
return "\\" + s;
}
});

return val;
return val;
};

exports._escapeString = _escapeString;
Expand Down Expand Up @@ -238,6 +254,11 @@ exports._sqlFormat = function (sql, arrValues, arrDelimiters) {
return val;
}

// Delimiters must be specified as strings.
if (typeof delimiter !== 'string') {
delimiter = DEFAULT_DELIMITER;
}

// If the value is of Date type, convert it into
// CUBRID compatible DATETIME format strings.
if (val instanceof Date) {
Expand All @@ -248,22 +269,17 @@ exports._sqlFormat = function (sql, arrValues, arrDelimiters) {
// Broker we choose the
// `'mm/dd[/yyyy] hh:mi[:ss[.ff]] [am|pm]'` format.

return DEFAULT_DELIMITER +
return delimiter +
// Month value in JavaScript is 0 based, i.e. 0-11,
// but CUBRID is 1-12. Also CUBRID doesn't care if
// dates are zero-padded or not.
(val.getMonth() + 1) + '/' + val.getDate() + '/' + val.getFullYear() +
' ' + val.getHours() + ':' + val.getMinutes() + ':' + val.getSeconds() +
'.' + val.getMilliseconds() + DEFAULT_DELIMITER;
'.' + val.getMilliseconds() + delimiter;
}

// Delimiters must be specified as strings.
if (typeof delimiter !== 'string') {
delimiter = DEFAULT_DELIMITER;
}

// Otherwise, safely escape the string.
return delimiter + _escapeString(val) + delimiter;
return delimiter + _escapeString(val, delimiter) + delimiter;
});
};

Expand Down

0 comments on commit 0629116

Please sign in to comment.