Skip to content
This repository has been archived by the owner on Mar 4, 2019. It is now read-only.

Commit

Permalink
fix: fields can be restricted in document searches (fixes #595)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmfay committed May 12, 2018
1 parent 8b49661 commit 162b3d9
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 11 deletions.
37 changes: 31 additions & 6 deletions lib/statement/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,36 @@ const Select = function (source, criteria = {}, options = {}) {
this.fields = [];
}

_.castArray(options.fields || []).forEach((f) => {
// add user-defined fields
this.fields = _.castArray(options.fields || []).reduce((all, field) => {
if (options.document) {
this.fields.push(parseKey(`body.${f}`).field);
// document fields need to be aliased
all.push({
value: parseKey(`body.${field}`).field,
alias: field
});
} else {
all.push(parseKey(field).field);
}

this.fields.push(parseKey(f).field);
});
return all;
}, this.fields);

// interpolate unsafe user-defined expressions
_.forEach(options.exprs, (expr, name) => {
this.fields.push(`${expr} AS ${name}`);
this.fields.push({
value: expr,
alias: name
});
});

if (this.fields.length === 0) {
// if the user didn't specify anything
this.fields = ['*'];
} else if (options.document) {
// if the user *did* specify something, but we're querying a document table
// and so require the id field in addition to whatever they're after
this.fields.push('id');
}

if (Object.prototype.hasOwnProperty.call(criteria, 'conditions') && Object.prototype.hasOwnProperty.call(criteria, 'params')) {
Expand Down Expand Up @@ -89,7 +105,16 @@ const Select = function (source, criteria = {}, options = {}) {
* @return {String} A SQL SELECT statement.
*/
Select.prototype.format = function () {
let sql = `SELECT ${this.fields.join(',')} FROM `;
const selectList = this.fields.map(f => {
if (_.isPlainObject(f)) {
// aliased definitions for document fields
return `${f.value} AS "${f.alias}"`;
}

return f;
});

let sql = `SELECT ${selectList.join(',')} FROM `;

if (this.only) { sql += 'ONLY '; }

Expand Down
10 changes: 7 additions & 3 deletions lib/util/docify.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ exports = module.exports = function (result) {
return null;
}

const returnDoc = _.cloneDeep(row.body);
if (row.body) {
const returnDoc = _.cloneDeep(row.body);

returnDoc.id = row.id;
returnDoc.id = row.id;

return returnDoc;
return returnDoc;
}

return row;
}

if (_.isArray(result)) {
Expand Down
9 changes: 9 additions & 0 deletions test/queryable/findDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ describe('findDoc', function () {
});
});

it('restricts fields', function () {
return db.docs.findDoc({title: 'Document 1'}, {fields: ['title']}).then(docs => {
assert.lengthOf(docs, 1);
assert.equal(docs[0].id, 1);
assert.equal(docs[0].title, 'Document 1');
assert.isUndefined(docs[0].description);
});
});

it('passing object without hasOwnProperty method', function () {
const criteria = Object.create(null);
criteria.title = 'Document 1';
Expand Down
13 changes: 11 additions & 2 deletions test/statement/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ describe('Select', function () {
assert.equal(result.format(), `SELECT "field"->>'element',"field"#>>'{array,0}',"field"#>>'{array,1,nested,2,element}' FROM testsource WHERE TRUE ORDER BY 1`);
});

it('should alias fields in document mode', function () {
const result = new Select(source, {}, {
fields: ['one', 'two'],
document: true
});

assert.equal(result.format(), `SELECT "body"->>'one' AS "one","body"->>'two' AS "two",id FROM testsource WHERE TRUE ORDER BY 1`);
});

it('should add expressions', function () {
const result = new Select(source, {}, {
exprs: {
Expand All @@ -75,7 +84,7 @@ describe('Select', function () {
}
});

assert.equal(result.format(), 'SELECT col1 + col2 AS colsum,col1 - col2 AS coldiff FROM testsource WHERE TRUE ORDER BY 1');
assert.equal(result.format(), 'SELECT col1 + col2 AS "colsum",col1 - col2 AS "coldiff" FROM testsource WHERE TRUE ORDER BY 1');
});

it('should add fields and expressions', function () {
Expand All @@ -87,7 +96,7 @@ describe('Select', function () {
}
});

assert.equal(result.format(), 'SELECT "col1","col2",col1 + col2 AS colsum,col1 - col2 AS coldiff FROM testsource WHERE TRUE ORDER BY 1');
assert.equal(result.format(), 'SELECT "col1","col2",col1 + col2 AS "colsum",col1 - col2 AS "coldiff" FROM testsource WHERE TRUE ORDER BY 1');
});

it('should add an offset', function () {
Expand Down
4 changes: 4 additions & 0 deletions test/util/docify.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ describe('docify', function () {
assert.deepEqual(docs, [{id: 1, val: 'val1'}, {id: 2, val: 'val2'}]);
});

it('docifies a row without a body', function () {
assert.deepEqual(docify({id: 1, field: 'value'}), {id: 1, field: 'value'});
});

it('returns null if there is no row', function () {
assert.equal(docify(), null);
});
Expand Down

0 comments on commit 162b3d9

Please sign in to comment.