Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add overrideable identifier preparation methods #124

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions sql-bricks.js
Original file line number Diff line number Diff line change
Expand Up @@ -938,19 +938,33 @@
sql._handleTables = handleTables;

function handleTable(table, opts) {
return handleColumn(expandAlias(table), opts);
if (typeof table === 'string') {
return sql._prepareTableIdentifier(table, opts);
}
return prepareTableIdentifier(table, opts);
}

function prepareTableIdentifier(table, opts) {
return prepareColumnIdentifier(expandAlias(table), opts);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This intentionally points to prepareColumnIdentifier rather than sql._prepareColumnIdentifier so that changing the column escaping behavior doesn't incidentally change the table escaping behavior.

}
sql._handleTable = handleTable;
sql._prepareTableIdentifier = prepareTableIdentifier;

function handleColumns(cols, opts) {
return cols.map(function(col) { return handleColumn(col, opts); }).join(', ');
}
sql._handleColumns = handleColumns;

var function_regex = /\(/g;
function handleColumn(expr, opts) {
if (typeof expr === 'string' && !function_regex.test(expr)) {
return sql._prepareColumnIdentifier(expr, opts);
}
return prepareColumnIdentifier(expr, opts);
}
// handles prefixes before a '.' and suffixes after a ' '
// for example: 'tbl.order AS tbl_order' -> 'tbl."order" AS tbl_order'
var unquoted_regex = /^[\w\.]+(( AS)? \w+)?$/i;
function handleColumn(expr, opts) {
function prepareColumnIdentifier(expr, opts) {
if (expr instanceof Statement)
return expr._toNestedString(opts);

Expand All @@ -965,7 +979,7 @@
else
return expr;
}
sql._handleColumn = handleColumn;
sql._prepareColumnIdentifier = prepareColumnIdentifier;

function quoteColOrTbl(expr) {
var prefix = '';
Expand Down
77 changes: 77 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,83 @@ describe('SQL Bricks', function() {
});
});

describe('overriding _prepareTableIdentifier', function() {
var sql;
var oldFunc;
before('override _prepareTableIdentifier', function() {
sql = is_common_js ? require('../sql-bricks.js') : window.SqlBricks;
oldFunc = sql._prepareTableIdentifier;
sql._prepareTableIdentifier = function(expr, opts) {
if (typeof expr === 'string') {
var snake = expr.replace(/[A-Z]/g, l => `_${l.toLowerCase()}`).replace(/^_/, '');
return oldFunc(snake, opts);
}
return oldFunc(expr, opts);
};
});

after('restore _prepareTableIdentifier', function() {
sql._prepareTableIdentifier = oldFunc;
});
it('should allow camelCase conversions', function() {
check(sql.select('myColumn').from('myTable'),
'SELECT "myColumn" FROM my_table')
});
});

describe('overriding _prepareColumnIdentifier', function() {
var sql;
var oldFunc;
before('override _prepareColumnIdentifier', function() {
sql = is_common_js ? require('../sql-bricks.js') : window.SqlBricks;
oldFunc = sql._prepareColumnIdentifier;
sql._prepareColumnIdentifier = function(expr, opts) {
var snake = expr.replace(/[A-Z]/g, l => `_${l.toLowerCase()}`).replace(/^_/, '');
return oldFunc(snake, opts);
};
});

after('restore _prepareColumnIdentifier', function() {
sql._prepareColumnIdentifier = oldFunc;
});
it('should allow camelCase conversions', function() {
check(sql.select('myColumn').from('my_table'),
'SELECT my_column FROM my_table')
});
it('should not affect table names', function() {
check(sql.select('myColumn').from('myTable'),
'SELECT my_column FROM "myTable"')
});
it('should not affect functions', function() {
check(sql.select('COUNT(*)').from('myTable'),
'SELECT COUNT(*) FROM "myTable"')
});
});

describe('overriding _prepareColumnIdentifier 2', function() {
var sql;
var oldFunc;
before('override _prepareColumnIdentifier', function() {
sql = is_common_js ? require('../sql-bricks.js') : window.SqlBricks;
oldFunc = sql._prepareColumnIdentifier;
sql._prepareColumnIdentifier = function(expr, opts) {
if (/[A-Z]/g.test(expr)) {
var snake = expr.replace(/[A-Z]/g, l => `_${l.toLowerCase()}`).replace(/^_/, '');
return oldFunc(`${snake} AS "${expr}"`, opts);
}
return oldFunc(expr, opts);
};
});

after('restore _prepareColumnIdentifier', function() {
sql._prepareColumnIdentifier = oldFunc;
});
it('should allow emitting complex expressions', function() {
check(sql.select('myColumn').from('my_table'),
'SELECT my_column AS "myColumn" FROM my_table')
});
});

describe('_extension()', function() {
it('should shield base', function() {
var ext = sql._extension();
Expand Down