Skip to content

Commit

Permalink
feat: allow empty sql tags (fixes #93)
Browse files Browse the repository at this point in the history
  • Loading branch information
gajus committed Oct 23, 2019
1 parent fcb6488 commit dfd9575
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 32 deletions.
11 changes: 0 additions & 11 deletions src/factories/createSqlTag.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ import {
SqlToken,
UnnestToken,
} from '../tokens';
import {
InvalidInputError,
} from '../errors';
import createSqlTokenSqlFragment from './createSqlTokenSqlFragment';

const log = Logger.child({
Expand Down Expand Up @@ -80,14 +77,6 @@ export default () => {
}
}

if (rawSql.trim() === '') {
throw new InvalidInputError('Unexpected SQL input. Query cannot be empty.');
}

if (rawSql.trim() === '$1') {
throw new InvalidInputError('Unexpected SQL input. Query cannot be empty. Found only value binding.');
}

const query = deepFreeze({
sql: rawSql,
type: SqlToken,
Expand Down
9 changes: 9 additions & 0 deletions src/routines/executeQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
BackendTerminatedError,
CheckIntegrityConstraintViolationError,
ForeignKeyIntegrityConstraintViolationError,
InvalidInputError,
NotNullIntegrityConstraintViolationError,
QueryCancelledError,
UnexpectedStateError,
Expand Down Expand Up @@ -51,6 +52,14 @@ export default async (
throw new UnexpectedStateError('Cannot use terminated connection.');
}

if (rawSql.trim() === '') {
throw new InvalidInputError('Unexpected SQL input. Query cannot be empty.');
}

if (rawSql.trim() === '$1') {
throw new InvalidInputError('Unexpected SQL input. Query cannot be empty. Found only value binding.');
}

const queryInputTime = process.hrtime.bigint();

let stackTrace = null;
Expand Down
61 changes: 61 additions & 0 deletions test/slonik/routines/executeQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// @flow

import Roarr from 'roarr';
import test, {
beforeEach,
} from 'ava';
import executeQuery from '../../../src/routines/executeQuery';
import {
InvalidInputError,
} from '../../../src/errors';
import createClientConfiguration from '../../helpers/createClientConfiguration';

const createConnectionStub = () => {
return {
connection: {
slonik: {
terminated: false,
},
},
};
};

beforeEach((t) => {
t.context.logger = Roarr;
t.context.connection = createConnectionStub();
t.context.executionRoutine = () => {};
});

test('throws a descriptive error if query is empty', async (t) => {
const error = await t.throwsAsync(() => {
return executeQuery(
t.context.logger,
t.context.connection,
createClientConfiguration(),
'',
[],
'foo',
t.context.executionRoutine
);
});

t.assert(error instanceof InvalidInputError);
t.assert(error.message === 'Unexpected SQL input. Query cannot be empty.');
});

test('throws a descriptive error if the entire query is a value binding', async (t) => {
const error = await t.throwsAsync(() => {
return executeQuery(
t.context.logger,
t.context.connection,
createClientConfiguration(),
'$1',
[],
'foo',
t.context.executionRoutine
);
});

t.assert(error instanceof InvalidInputError);
t.assert(error.message === 'Unexpected SQL input. Query cannot be empty. Found only value binding.');
});
21 changes: 0 additions & 21 deletions test/slonik/templateTags/sql/sql.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import createSqlTag from '../../../../src/factories/createSqlTag';
import {
SqlToken,
} from '../../../../src/tokens';
import {
InvalidInputError,
} from '../../../../src/errors';

const sql = createSqlTag();

Expand All @@ -21,24 +18,6 @@ test('creates an object describing a query', (t) => {
});
});

test('throws a descriptive error if query is empty', (t) => {
const error = t.throws(() => {
sql``;
});

t.assert(error instanceof InvalidInputError);
t.assert(error.message === 'Unexpected SQL input. Query cannot be empty.');
});

test('throws a descriptive error if the entire query is a value binding', (t) => {
const error = t.throws(() => {
sql`${1}`;
});

t.assert(error instanceof InvalidInputError);
t.assert(error.message === 'Unexpected SQL input. Query cannot be empty. Found only value binding.');
});

test('creates an object describing query value bindings', (t) => {
const query = sql`SELECT ${'foo'}`;

Expand Down

0 comments on commit dfd9575

Please sign in to comment.