Skip to content
Merged
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: 11 additions & 11 deletions lib/mapping/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class QueryGenerator {
*/
static getSelect(tableName, keyspace, propertiesInfo, fieldsInfo, orderByColumns, limit) {
let query = 'SELECT ';
query += fieldsInfo.length > 0 ? fieldsInfo.map(p => p.columnName).join(', ') : '*';
query += fieldsInfo.length > 0 ? fieldsInfo.map(p => `"${p.columnName}"`).join(', ') : '*';
query += ` FROM ${keyspace}.${tableName}`;

if (propertiesInfo.length > 0) {
Expand All @@ -52,7 +52,7 @@ class QueryGenerator {

if (orderByColumns.length > 0) {
query += ' ORDER BY ';
query += orderByColumns.map(order => order[0] + ' ' + order[1]).join(', ');
query += orderByColumns.map(order => `"${order[0]}" ${order[1]}`).join(', ');
}

if (typeof limit === 'number') {
Expand Down Expand Up @@ -116,7 +116,7 @@ class QueryGenerator {
*/
static _getInsertQuery(tableName, keyspace, propertiesInfo, ifNotExists, ttl) {
let query = `INSERT INTO ${keyspace}.${tableName} (`;
query += propertiesInfo.map(pInfo => pInfo.columnName).join(', ');
query += propertiesInfo.map(pInfo => `"${pInfo.columnName}"`).join(', ');
query += ') VALUES (';
query += propertiesInfo.map(() => '?').join(', ');
query += ')';
Expand Down Expand Up @@ -217,18 +217,18 @@ class QueryGenerator {
if (p.value instanceof QueryAssignment) {
if (p.value.inverted) {
// e.g: prepend "col1 = ? + col1"
return `${p.columnName} = ? ${p.value.sign} ${p.columnName}`;
return `"${p.columnName}" = ? ${p.value.sign} "${p.columnName}"`;
}
// e.g: increment "col1 = col1 + ?"
return `${p.columnName} = ${p.columnName} ${p.value.sign} ?`;
return `"${p.columnName}" = "${p.columnName}" ${p.value.sign} ?`;
}

return p.columnName + ' = ?';
return `"${p.columnName}" = ?`;
})
.join(', ');

query += ' WHERE ';
query += propertiesInfo.filter(p => primaryKeys.has(p.columnName)).map(p => p.columnName + ' = ?').join(' AND ');
query += propertiesInfo.filter(p => primaryKeys.has(p.columnName)).map(p => `"${p.columnName}" = ?`).join(' AND ');

if (ifExists === true) {
query += ' IF EXISTS';
Expand Down Expand Up @@ -318,7 +318,7 @@ class QueryGenerator {

if (deleteOnlyColumns) {
const columnsToDelete = propertiesInfo.filter(p => !primaryKeys.has(p.columnName))
.map(p => p.columnName)
.map(p => `"${p.columnName}"`)
.join(', ');

if (columnsToDelete !== '') {
Expand All @@ -327,7 +327,7 @@ class QueryGenerator {
}

query += ` FROM ${keyspace}.${tableName} WHERE `;
query += propertiesInfo.filter(p => primaryKeys.has(p.columnName)).map(p => p.columnName + ' = ?').join(' AND ');
query += propertiesInfo.filter(p => primaryKeys.has(p.columnName)).map(p => `"${p.columnName}" = ?`).join(' AND ');

if (ifExists === true) {
query += ' IF EXISTS';
Expand Down Expand Up @@ -437,9 +437,9 @@ class QueryGenerator {
return `${QueryGenerator._getSingleCondition(columnName, value.value[0])}` +
` ${value.key} ${QueryGenerator._getSingleCondition(columnName, value.value[1])}`;
}
return `${columnName} ${value.key} ?`;
return `"${columnName}" ${value.key} ?`;
}
return `${columnName} = ?`;
return `"${columnName}" = ?`;
}
}

Expand Down
40 changes: 20 additions & 20 deletions test/unit/mapping/model-mapper-mutation-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('ModelMapper', () => {
.then(() => {
assert.strictEqual(clientInfo.executions.length, 1);
const execution = clientInfo.executions[0];
assert.strictEqual(execution.query, 'INSERT INTO ks1.table1 (id2, id1) VALUES (?, ?)');
assert.strictEqual(execution.query, 'INSERT INTO ks1.table1 ("id2", "id1") VALUES (?, ?)');
assert.deepStrictEqual(execution.params, Object.keys(doc).map(key => doc[key]));
helper.assertProperties(execution.options, { prepare: true, isIdempotent: true });
});
Expand All @@ -46,7 +46,7 @@ describe('ModelMapper', () => {
{
doc: { id2: 'value2' , id1: 'value1', name: 'name1' },
docInfo: { ifNotExists: true },
query: 'INSERT INTO ks1.table1 (id2, id1, name) VALUES (?, ?, ?) IF NOT EXISTS',
query: 'INSERT INTO ks1.table1 ("id2", "id1", "name") VALUES (?, ?, ?) IF NOT EXISTS',
params: [ 'value2', 'value1', 'name1' ],
isIdempotent: false
}
Expand All @@ -56,7 +56,7 @@ describe('ModelMapper', () => {
{
doc: { id2: 'value2' , id1: 'value1', name: 'name1' },
docInfo: { ttl: 1000 },
query: 'INSERT INTO ks1.table1 (id2, id1, name) VALUES (?, ?, ?) USING TTL ?',
query: 'INSERT INTO ks1.table1 ("id2", "id1", "name") VALUES (?, ?, ?) USING TTL ?',
params: [ 'value2', 'value1', 'name1', 1000 ]
}
]));
Expand Down Expand Up @@ -137,7 +137,7 @@ describe('ModelMapper', () => {
items: [
{
doc: { id1: 'value_id1', id2: 'value_id2', name: { prop1: 1, prop2: 'two' } },
query: 'INSERT INTO ks1.table1 (id1, id2, name) VALUES (?, ?, ?)',
query: 'INSERT INTO ks1.table1 ("id1", "id2", "name") VALUES (?, ?, ?)',
params: [ 'value_id1', 'value_id2', '{"prop1":1,"prop2":"two"}']
}
]
Expand All @@ -150,7 +150,7 @@ describe('ModelMapper', () => {
it('should retrieve the table that apply and make a single execution', () => testQueries('update', [
{
doc: { id2: 'value2' , id1: 'value1', name: 'name1' },
query: 'UPDATE ks1.table1 SET name = ? WHERE id2 = ? AND id1 = ?',
query: 'UPDATE ks1.table1 SET "name" = ? WHERE "id2" = ? AND "id1" = ?',
params: ['name1', 'value2', 'value1'],
isIdempotent: true
}]));
Expand All @@ -159,20 +159,20 @@ describe('ModelMapper', () => {
{
doc: {id2: 'value2', id1: 'value1', name: 'name1'},
docInfo: {when: {name: 'previous name'}},
query: 'UPDATE ks1.table1 SET name = ? WHERE id2 = ? AND id1 = ? IF name = ?',
query: 'UPDATE ks1.table1 SET "name" = ? WHERE "id2" = ? AND "id1" = ? IF "name" = ?',
params: ['name1', 'value2', 'value1', 'previous name'],
isIdempotent: false
}]));

it('should append/prepend to a list', () => testQueries('update', [
{
doc: { id2: 'value2' , id1: 'value1', name: 'name1', list1: q.append(['a', 'b']) },
query: 'UPDATE ks1.table1 SET name = ?, list1 = list1 + ? WHERE id2 = ? AND id1 = ?',
query: 'UPDATE ks1.table1 SET "name" = ?, "list1" = "list1" + ? WHERE "id2" = ? AND "id1" = ?',
params: ['name1', ['a', 'b'], 'value2', 'value1'],
isIdempotent: false
}, {
doc: { id2: 'value2' , id1: 'value1', name: 'name1', list1: q.prepend(['a', 'b']) },
query: 'UPDATE ks1.table1 SET name = ?, list1 = ? + list1 WHERE id2 = ? AND id1 = ?',
query: 'UPDATE ks1.table1 SET "name" = ?, "list1" = ? + "list1" WHERE "id2" = ? AND "id1" = ?',
params: ['name1', ['a', 'b'], 'value2', 'value1'],
isIdempotent: false
}]));
Expand All @@ -183,10 +183,10 @@ describe('ModelMapper', () => {
const items = [
{
doc: { id2: 'value2' , id1: 'value1', c1: q.incr(10) },
query: 'UPDATE ks1.table1 SET c1 = c1 + ? WHERE id2 = ? AND id1 = ?'
query: 'UPDATE ks1.table1 SET "c1" = "c1" + ? WHERE "id2" = ? AND "id1" = ?'
}, {
doc: { id2: 'another id 2' , id1: 'another id 1', c1: q.decr(10) },
query: 'UPDATE ks1.table1 SET c1 = c1 - ? WHERE id2 = ? AND id1 = ?'
query: 'UPDATE ks1.table1 SET "c1" = "c1" - ? WHERE "id2" = ? AND "id1" = ?'
}];

return Promise.all(items.map((item, index) => modelMapper.update(item.doc).then(() => {
Expand Down Expand Up @@ -226,15 +226,15 @@ describe('ModelMapper', () => {
{
doc: { id2: 'value2', id1: 'value1', name: 'name1', description: 'description1' },
docInfo: { fields: [ 'id1', 'id2', 'description' ] },
query: 'UPDATE ks1.table1 SET description = ? WHERE id1 = ? AND id2 = ?',
query: 'UPDATE ks1.table1 SET "description" = ? WHERE "id1" = ? AND "id2" = ?',
params: ['description1', 'value1', 'value2']
}]));

it('should set TTL', () => testQueries('update', [
{
doc: { id1: 'value_id1', id2: 'value_id2', name: 'value_name1' },
docInfo: { ttl: 360 },
query: 'UPDATE ks1.table1 USING TTL ? SET name = ? WHERE id1 = ? AND id2 = ?',
query: 'UPDATE ks1.table1 USING TTL ? SET "name" = ? WHERE "id1" = ? AND "id2" = ?',
params: [ 360, 'value_name1', 'value_id1', 'value_id2' ]
}
]));
Expand All @@ -253,13 +253,13 @@ describe('ModelMapper', () => {
items: [
{
doc: { id1: 'value_id1', id2: 'value_id2', name: { prop1: 1, prop2: 'two' } },
query: 'UPDATE ks1.table1 SET name = ? WHERE id1 = ? AND id2 = ?',
query: 'UPDATE ks1.table1 SET "name" = ? WHERE "id1" = ? AND "id2" = ?',
params: [ '{"prop1":1,"prop2":"two"}', 'value_id1', 'value_id2_suffix' ]
},
{
doc: { id1: 'value_id1', id2: 'value_id2', description: 'my description' },
docInfo: { when: { name: { a: 'a', b: 2 } } },
query: 'UPDATE ks1.table1 SET description = ? WHERE id1 = ? AND id2 = ? IF name = ?',
query: 'UPDATE ks1.table1 SET "description" = ? WHERE "id1" = ? AND "id2" = ? IF "name" = ?',
params: [ 'my description', 'value_id1', 'value_id2_suffix', '{"a":"a","b":2}' ],
isIdempotent: false
}
Expand Down Expand Up @@ -294,24 +294,24 @@ describe('ModelMapper', () => {
it('should generate the query, params and set the idempotency', () => testQueries('remove', [
{
doc: { id1: 'x', 'id2': 'y' },
query: 'DELETE FROM ks1.table1 WHERE id1 = ? AND id2 = ?',
query: 'DELETE FROM ks1.table1 WHERE "id1" = ? AND "id2" = ?',
params: [ 'x', 'y' ]
}, {
doc: { id1: 'x', 'id2': 'y' },
docInfo: { when: { name: 'a' }},
query: 'DELETE FROM ks1.table1 WHERE id1 = ? AND id2 = ? IF name = ?',
query: 'DELETE FROM ks1.table1 WHERE "id1" = ? AND "id2" = ? IF "name" = ?',
params: [ 'x', 'y', 'a' ],
isIdempotent: false
}, {
doc: { id1: 'x', 'id2': 'y' },
docInfo: { ifExists: true },
query: 'DELETE FROM ks1.table1 WHERE id1 = ? AND id2 = ? IF EXISTS',
query: 'DELETE FROM ks1.table1 WHERE "id1" = ? AND "id2" = ? IF EXISTS',
params: [ 'x', 'y' ],
isIdempotent: false
}, {
doc: { id1: 'x', 'id2': 'y' },
docInfo: { fields: [ 'id1', 'id2', 'name' ], deleteOnlyColumns: true },
query: 'DELETE name FROM ks1.table1 WHERE id1 = ? AND id2 = ?',
query: 'DELETE "name" FROM ks1.table1 WHERE "id1" = ? AND "id2" = ?',
params: [ 'x', 'y' ]
}
]));
Expand All @@ -330,13 +330,13 @@ describe('ModelMapper', () => {
items: [
{
doc: { id1: 'value_id1', id2: 'value_id2' },
query: 'DELETE FROM ks1.table1 WHERE id1 = ? AND id2 = ?',
query: 'DELETE FROM ks1.table1 WHERE "id1" = ? AND "id2" = ?',
params: [ 'value_id1', 'value_id2_suffix' ]
},
{
doc: { id1: 'value_id1', id2: 'value_id2' },
docInfo: { when: { name: { a: 1 } }},
query: 'DELETE FROM ks1.table1 WHERE id1 = ? AND id2 = ? IF name = ?',
query: 'DELETE FROM ks1.table1 WHERE "id1" = ? AND "id2" = ? IF "name" = ?',
params: [ 'value_id1', 'value_id2_suffix', '{"a":1}' ],
isIdempotent: false
},
Expand Down
38 changes: 19 additions & 19 deletions test/unit/mapping/model-mapper-select-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,30 @@ describe('ModelMapper', () => {
{
doc: { id1: 'value1', id2: q.gte('e') },
docInfo: { limit: 100 },
query: 'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 >= ? LIMIT ?',
query: 'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ? LIMIT ?',
params: [ 'value1', 'e', 100 ]
}]));

it('should support fields to specify the selection columns', () => testQueries('find', [
{
doc: { id1: 'value1', id2: q.gte('e') },
docInfo: { fields: ['name', 'description', 'locationType'] },
query: 'SELECT name, description, location_type FROM ks1.table1 WHERE id1 = ? AND id2 >= ?',
query: 'SELECT "name", "description", "location_type" FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ?',
params: [ 'value1', 'e' ]
}]));

it('should support relational operators, orderBy, limit and fields', () => testQueries('find', [
{
doc: {id1: 'value1', id2: q.gte('m')},
query: 'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 >= ?',
query: 'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ?',
params: ['value1', 'm']
}, {
doc: {id1: 'value1', id2: q.and(q.gte('a'), q.lt('z'))},
query: 'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 >= ? AND id2 < ?',
query: 'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ? AND "id2" < ?',
params: ['value1', 'a', 'z']
}, {
doc: {id1: 'value1', id2: q.and(q.gte('a'), q.and(q.gte('e'), q.lt('z')))},
query: 'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 >= ? AND id2 >= ? AND id2 < ?',
query: 'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ? AND "id2" >= ? AND "id2" < ?',
params: ['value1', 'a', 'e', 'z']
}]));

Expand All @@ -64,19 +64,19 @@ describe('ModelMapper', () => {
doc: { id1: 'value2' },
docInfo: { orderBy: {'id2': 'desc' }},
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? ORDER BY id2 DESC',
'SELECT * FROM ks1.table1 WHERE "id1" = ? ORDER BY "id2" DESC',
params: [ 'value2' ]
}, {
doc: { id1: 'value3' },
docInfo: { orderBy: {'id2': 'asc' }},
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? ORDER BY id2 ASC',
'SELECT * FROM ks1.table1 WHERE "id1" = ? ORDER BY "id2" ASC',
params: [ 'value3' ]
}, {
doc: { id1: 'value1', id2: q.gte('e') },
docInfo: { fields: ['name'], limit: 20, orderBy: {'id2': 'asc' }},
query:
'SELECT name FROM ks1.table1 WHERE id1 = ? AND id2 >= ? ORDER BY id2 ASC LIMIT ?',
'SELECT "name" FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ? ORDER BY "id2" ASC LIMIT ?',
params: [ 'value1', 'e', 20 ]
}]));

Expand All @@ -85,7 +85,7 @@ describe('ModelMapper', () => {
doc: { id1: 'value2' },
docInfo: { orderBy: {'id2': 'asc' }},
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? ORDER BY id2 ASC',
'SELECT * FROM ks1.table1 WHERE "id1" = ? ORDER BY "id2" ASC',
params: [ 'value2' ]
}]));

Expand All @@ -108,19 +108,19 @@ describe('ModelMapper', () => {
{
doc: { id1: 'value_id1', id2: 'value_id2' },
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 = ?',
'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" = ?',
params: [ 'value_id1', 'value_id2' + suffix ]
},
{
doc: { id1: 'value_id1', id2: q.gt('value_id2') },
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 > ?',
'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" > ?',
params: [ 'value_id1', 'value_id2' + suffix ]
},
{
doc: { id1: 'value_id1', id2: q.and(q.gte('a'), q.lt('z')) },
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 >= ? AND id2 < ?',
'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" >= ? AND "id2" < ?',
params: [ 'value_id1', 'a' + suffix, 'z' + suffix ]
}
]
Expand All @@ -141,7 +141,7 @@ describe('ModelMapper', () => {
{
doc: { id1: 'value_id1', id2: q.in_(['first', 'second']) },
query:
'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 IN ?',
'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" IN ?',
params: [ 'value_id1', ['first_mapped_value', 'second_mapped_value'] ]
}
]
Expand Down Expand Up @@ -191,7 +191,7 @@ describe('ModelMapper', () => {

return modelMapper.find({ id1: 'x', id2: 'y'}).then(() => {
const execution = clientInfo.executions[0];
assert.strictEqual(execution.query, 'SELECT * FROM ks1.table1 WHERE id1 = ? AND id2 = ?');
assert.strictEqual(execution.query, 'SELECT * FROM ks1.table1 WHERE "id1" = ? AND "id2" = ?');
});
});

Expand All @@ -203,7 +203,7 @@ describe('ModelMapper', () => {

return modelMapper.find({ id1: 'x', id2: 'y'}).then(() => {
const execution = clientInfo.executions[0];
assert.strictEqual(execution.query, 'SELECT * FROM ks1.NoTableSpecified WHERE id1 = ? AND id2 = ?');
assert.strictEqual(execution.query, 'SELECT * FROM ks1.NoTableSpecified WHERE "id1" = ? AND "id2" = ?');
});
});

Expand Down Expand Up @@ -234,11 +234,11 @@ describe('ModelMapper', () => {
.then(() => {
[
// Selected "table2" for the first query
'SELECT * FROM ks1.table2 WHERE id1 = ? ORDER BY id3 ASC',
'SELECT * FROM ks1.table2 WHERE "id1" = ? ORDER BY "id3" ASC',
// Selected "table1" for the second query
'SELECT * FROM ks1.table1 WHERE id1 = ? ORDER BY id2 DESC, id3 DESC',
'SELECT * FROM ks1.table1 WHERE "id1" = ? ORDER BY "id2" DESC, "id3" DESC',
// Selected "table1" for the third query
'SELECT * FROM ks1.table1 WHERE id1 = ? ORDER BY id2 ASC'
'SELECT * FROM ks1.table1 WHERE "id1" = ? ORDER BY "id2" ASC'
].forEach((query, index) => {
assert.strictEqual(clientInfo.executions[index].query, query);
assert.deepStrictEqual(clientInfo.executions[index].params, [ 'a' ]);
Expand Down Expand Up @@ -279,7 +279,7 @@ describe('ModelMapper', () => {
it('should support fields to specify the selection columns', () => testQueries('findAll', [
{
docInfo: { fields: ['name', 'description', 'locationType'] },
query: 'SELECT name, description, location_type FROM ks1.table1',
query: 'SELECT "name", "description", "location_type" FROM ks1.table1',
params: []
}]));
});
Expand Down