Skip to content

Commit

Permalink
fix: execute (file) function do not start new dedicated connection wh…
Browse files Browse the repository at this point in the history
…en run in one, add support for /* */ comment
  • Loading branch information
Laszlo Radics committed Apr 29, 2020
1 parent e0fce7a commit d5a03d5
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 41 deletions.
2 changes: 1 addition & 1 deletion lib/pgDb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export declare class PgDb extends QueryAble {
transactionCommit(): Promise<PgDb>;
transactionRollback(): Promise<PgDb>;
isTransactionActive(): boolean;
execute(fileName: any, statementTransformerFunction?: (string) => string): Promise<void>;
execute(fileName: string, statementTransformerFunction?: (string) => string): Promise<void>;
private listeners;
listen(channel: string, callback: (notification: Notification) => void): Promise<void>;
unlisten(channel: string, callback?: (Notification) => void): Promise<void>;
Expand Down
38 changes: 23 additions & 15 deletions lib/pgDb.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/pgDb.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/queryAble.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export declare class QueryAble {
constructor();
setLogger(logger: PgDbLogger): void;
getLogger(useConsoleAsDefault?: boolean): any;
run(sql: string): Promise<any[]>;
run(sql: string, params?: any[] | {}, options?: SqlQueryOptions): Promise<any[]>;
query(sql: string, params?: any[] | {}, options?: SqlQueryOptions): Promise<any[]>;
protected internalQuery(options: {
connection;
Expand Down
4 changes: 2 additions & 2 deletions lib/queryAble.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/queryAble.js.map

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion spec/resources/tricky.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
--insert into "groups" (name) values ('joe');
select * from __SCHEMA__."groups" where name like 'joe--'; ; ; -- select * from "groups" where name like 'joe';
select * from __SCHEMA__."groups" where name like 'joe --''"/*-- '; ; ; -- select * from "groups" where name like 'joe';
select * from __SCHEMA__."groups" where name like $$joe2'"-- ;
-- not a comment ;
$$;
-- unbalanced quote '" $$
/*
multi line comment '" $$
*/

select * from __SCHEMA__."groups" where name like 'joe--';
39 changes: 23 additions & 16 deletions src/pgDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {ConnectionOptions} from './connectionOptions';
import * as EventEmitter from 'events';

const CONNECTION_URL_REGEXP = /^postgres:\/\/(?:([^:]+)(?::([^@]*))?@)?([^\/:]+)?(?::([^\/]+))?\/(.*)$/;
const SQL_TOKENIZER_REGEXP = /''|'|""|"|;|\$|--|(.+?)/g;
const SQL_TOKENIZER_REGEXP = /''|'|""|"|;|\$|--|\/\*|\*\/|(.+?)/g;
const SQL_$_ESCAPE_REGEXP = /\$[^$]*\$/g;

/** looks like we only get back those that we have access to */
Expand Down Expand Up @@ -389,9 +389,10 @@ export class PgDb extends QueryAble {
return this.connection != null;
}

async execute(fileName, statementTransformerFunction?: (string) => string): Promise<void> {
async execute(fileName: string, statementTransformerFunction?: (string) => string): Promise<void> {
let isTransactionInPlace = this.isTransactionActive();
let pgdb = await this.dedicatedConnectionBegin();
// statements must be run in a dedicated connection
let pgdb = isTransactionInPlace ? this : await this.dedicatedConnectionBegin();

/** run statements one after the other */
let runStatementList = (statementList) => {
Expand Down Expand Up @@ -423,25 +424,25 @@ export class PgDb extends QueryAble {
let lineCounter = 0;
let promise = new Promise<void>((resolve, reject) => {
let statementList = [];
let tmp = '', m;
let tmp = '', t: RegExpExecArray;
let consumer;
let inQuotedString;
let inQuotedString:string;
let rl = readline.createInterface({
input: fs.createReadStream(fileName),
terminal: false
}).on('line', (line) => {
lineCounter++;
try {
//console.log('Line: ' + line);
while (m = SQL_TOKENIZER_REGEXP.exec(line)) {
if (m[0] == '"' || m[0] == "'") {
while (t = SQL_TOKENIZER_REGEXP.exec(line)) {
if (!inQuotedString && (t[0] == '"' || t[0] == "'") || inQuotedString == '"' || inQuotedString == "'") {
if (!inQuotedString) {
inQuotedString = m[0];
} else if (inQuotedString == m[0]) {
inQuotedString = t[0];
} else if (inQuotedString == t[0]) {
inQuotedString = null;
}
tmp += m[0];
} else if (m[0] == '$' && (!inQuotedString || inQuotedString[0] == '$')) {
tmp += t[0];
} else if (!inQuotedString && t[0] == '$' || inQuotedString && inQuotedString[0] == '$') {
if (!inQuotedString) {
let s = line.slice(SQL_TOKENIZER_REGEXP.lastIndex - 1);
let token = s.match(SQL_$_ESCAPE_REGEXP);
Expand All @@ -452,12 +453,20 @@ export class PgDb extends QueryAble {
SQL_TOKENIZER_REGEXP.lastIndex += inQuotedString.length - 1;
tmp += inQuotedString;
} else {
tmp += m[0];
tmp += t[0];
if (tmp.endsWith(inQuotedString)) {
inQuotedString = null;
}
}
} else if (!inQuotedString && m[0] == ';') {
} else if (!inQuotedString && t[0] == '/*' || inQuotedString == '/*') {
if (!inQuotedString) {
inQuotedString = t[0];
} else if (t[0] == '*/') {
inQuotedString = null;
}
} else if (!inQuotedString && t[0] == '--') {
line = '';
} else if (!inQuotedString && t[0] == ';') {
//console.log('push ' + tmp);
if (tmp.trim() != '') {
statementList.push(tmp);
Expand All @@ -472,10 +481,8 @@ export class PgDb extends QueryAble {
}
}
tmp = '';
} else if (!inQuotedString && m[0].substring(0, 2) == '--') {
line = '';
} else {
tmp += m[0];
tmp += t[0];
}
}
if (tmp && line) {
Expand Down
5 changes: 3 additions & 2 deletions src/queryAble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ export class QueryAble {
return this.logger || this.schema && this.schema.logger || this.db.logger || (useConsoleAsDefault ? console : defaultLogger);
}

async run(sql: string): Promise<any[]> {
return this.query(sql);
/** alias to {@link query} */
async run(sql: string, params?: any[] | {}, options?: SqlQueryOptions): Promise<any[]> {
return this.query(sql, params, options);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/test/pgDbSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ describe("pgdb", () => {
await table.query(`INSERT INTO ${table} (name, created, createdtz) values ('A2', '${d}'::timestamptz, '${d}'::timestamptz)`);
res = await table.findOne({name: 'A2'});

expect(res.created).toEqual(new Date('2000-01-01 00:00:00'));
// this expectation is depend on machine timezone
// expect(res.created).toEqual(new Date('2000-01-01 00:00:00'));
expect(res.createdtz).toEqual(new Date('2000-01-01 00:00:00'));

res = await table.query(`SELECT * FROM ${table} WHERE name='A2' AND created='${d}'::timestamptz`);
Expand Down

0 comments on commit d5a03d5

Please sign in to comment.