Skip to content

Commit

Permalink
ScriptExecutor test passing
Browse files Browse the repository at this point in the history
  • Loading branch information
erayhanoglu committed Nov 8, 2020
1 parent 6ba0ed5 commit 79ee783
Show file tree
Hide file tree
Showing 15 changed files with 18,764 additions and 179 deletions.
14 changes: 8 additions & 6 deletions src/Portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class Portal {
private readonly _socket: PgSocket;
private readonly _statement: PreparedStatement;
private readonly _name?: string;
private _binaryColumns: boolean | boolean[] = false;
private _columnFormat: Protocol.DataFormat | Protocol.DataFormat[] = Protocol.DataFormat.binary;

constructor(statement: PreparedStatement, name: string) {
this._statement = statement;
Expand All @@ -36,7 +36,8 @@ export class Portal {
async bind(params: Maybe<any[]>,
fetchOptions: FetchOptions): Promise<void> {
const socket = this._socket;
this._binaryColumns = fetchOptions.binaryColumns || false;
this._columnFormat = fetchOptions.columnFormat != null ?
fetchOptions.columnFormat : Protocol.DataFormat.binary;
socket.sendBindMessage({
statement: this._statement.name,
portal: this.name,
Expand Down Expand Up @@ -93,11 +94,12 @@ export class Portal {
done(undefined, {code});
break;
case Protocol.BackendMessageCode.DataRow:
if (this._binaryColumns == true)
rows.push(msg.columns);
else if (Array.isArray(this._binaryColumns))
if (Array.isArray(this._columnFormat)) {
rows.push(msg.columns.map((buf: Buffer, i) =>
this._binaryColumns[i] ? buf : buf.toString('utf8')));
this._columnFormat[i] === Protocol.DataFormat.text ?
buf.toString('utf8') : buf));
} else if (this._columnFormat === Protocol.DataFormat.binary)
rows.push(msg.columns);
else rows.push(msg.columns.map((buf: Buffer) => buf.toString('utf8')));
break;
case Protocol.BackendMessageCode.PortalSuspended:
Expand Down
8 changes: 4 additions & 4 deletions src/ScriptExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ export class ScriptExecutor extends SafeEventEmitter {
current.rows = [];
break;
case Protocol.BackendMessageCode.DataRow:
const data = msg.columns.map((x: Buffer) => x.toString('utf8'));
parseRow(parsers, data, options);
const row = options.objectRows ?
convertRowToObject(fields, msg.columns) : msg.columns;
let row = msg.columns.map((x: Buffer) => x.toString('utf8'));
parseRow(parsers, row, options);
if (options.objectRows)
row = convertRowToObject(fields, row);
this.emit('row', row);
current.rows = current.rows || [];
current.rows.push(row);
Expand Down
5 changes: 3 additions & 2 deletions src/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import tls from "tls";
import {Cursor} from './Cursor';
import {SmartBuffer} from './protocol/SmartBuffer';
import {Protocol} from './protocol/protocol';
import DataFormat = Protocol.DataFormat;

export type OID = number;
export type Maybe<T> = T | undefined;
Expand Down Expand Up @@ -156,7 +158,7 @@ export interface FetchOptions {
fetchCount?: number;
objectRows?: boolean;
utcDates?: boolean;
binaryColumns?: boolean | boolean[];
columnFormat?: DataFormat | DataFormat[];
}

export interface ScriptExecuteOptions extends FetchOptions {
Expand Down Expand Up @@ -190,7 +192,6 @@ export interface QueryResult extends CommandResult {
totalTime?: number;
}


export type DecodeBinaryFunction = (buf: Buffer, options: FetchOptions) => any;
export type EncodeBinaryFunction = (buf: SmartBuffer, v: any, options: FetchOptions) => void;
export type ParseTextFunction = (v: any, options: FetchOptions) => any;
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/stringify-arrayliteral.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {EncodeTextFunction, FetchOptions} from '../definitions';
import {arrayCalculateDim} from './array-calculatedim';

export function stringifyArrayLiteral(value: any[], options: FetchOptions, encode?: EncodeTextFunction): string {
export function stringifyArrayLiteral(value: any[], options?: FetchOptions, encode?: EncodeTextFunction): string {
const dim = arrayCalculateDim(value);
const writeDim = (arr: any[], level: number) => {
const elemCount = dim[level];
Expand All @@ -24,7 +24,7 @@ export function stringifyArrayLiteral(value: any[], options: FetchOptions, encod
continue;
}
if (encode)
x = encode(x, options);
x = encode(x, options || {});
out.push(escapeArrayItem('' + x));
}
return '{' + out.join(',') + '}';
Expand Down
23 changes: 0 additions & 23 deletions src/helpers/stringify-arraysql.ts

This file was deleted.

25 changes: 25 additions & 0 deletions src/helpers/stringify-for-sql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {EncodeTextFunction, FetchOptions} from '../definitions';
import {escapeLiteral} from './escape-literal';

export function stringifyArrayForSQL(v: any[], options?: FetchOptions, encode?: EncodeTextFunction): string {
const arr = v.map(x => stringifyValueForSQL(x, options, encode));
return 'ARRAY[' + arr.join(',') + ']';
}

export function stringifyValueForSQL(v: any, options?: FetchOptions, encode?: EncodeTextFunction): string {
if (v == null)
return 'null';
if (typeof v === 'boolean')
return v ? 'true' : 'false';
if (Array.isArray(v))
return stringifyArrayForSQL(v, options, encode);
if (encode)
v = encode(v, options || {});
if (typeof v === 'number')
return '' + v;
if (typeof v === 'bigint')
return v.toString();
if (typeof v === 'object')
return escapeLiteral(JSON.stringify(v));
return escapeLiteral('' + v);
}
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@ export * from './definitions';
export * from './Connection';
export * from './ScriptExecutor';
export * from './BindParam';
export * from './helpers/stringify-arrayliteral';
export * from './helpers/stringify-for-sql';
export * from './helpers/escape-literal';
export * from './helpers/fast-parseint';
export * from './helpers/parse-connectionstring';
export * from './helpers/parse-datetime';
16 changes: 9 additions & 7 deletions src/protocol/Frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {FetchOptions, Maybe, OID} from '../definitions';
import {DataTypeRegistry} from '../DataTypeRegistry';
import {encodeBinaryArray} from '../helpers/encode-binaryarray';
import {stringifyArrayLiteral} from '../helpers/stringify-arrayliteral';
import DataFormat = Protocol.DataFormat;

const StaticFlushBuffer = Buffer.from([Protocol.FrontendMessageCode.Flush, 0x00, 0x00, 0x00, 0x04]);
const StaticTerminateBuffer = Buffer.from([Protocol.FrontendMessageCode.Terminate, 0x00, 0x00, 0x00, 0x04]);
Expand Down Expand Up @@ -136,7 +137,8 @@ export class Frontend {
.writeCString(args.portal || '', 'utf8')
.writeCString(args.statement || '', 'utf8');
const {params, paramTypes, fetchOptions} = args;
const binaryColumns = fetchOptions.binaryColumns;
const columnFormat = fetchOptions.columnFormat != null ? fetchOptions.columnFormat:
DataFormat.binary;

if (params && params.length) {
io.writeInt16BE(params.length);
Expand Down Expand Up @@ -193,14 +195,14 @@ export class Frontend {
io.writeUInt16BE(0);
}

if (Array.isArray(binaryColumns)) {
io.writeUInt16BE(binaryColumns.length);
for (let i = 0; i < binaryColumns.length; i++) {
io.writeUInt16BE(binaryColumns[i] ? 1 : 0);
if (Array.isArray(columnFormat)) {
io.writeUInt16BE(columnFormat.length);
for (let i = 0; i < columnFormat.length; i++) {
io.writeUInt16BE(columnFormat[i]);
}
} else if (binaryColumns === true) {
io.writeUInt16BE(1);
} else if (columnFormat === DataFormat.binary) {
io.writeUInt16BE(1);
io.writeUInt16BE(DataFormat.binary);
} else io.writeUInt16BE(0);

return setLengthAndFlush(io, 1);
Expand Down
2 changes: 1 addition & 1 deletion src/protocol/PgSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {DatabaseError} from './DatabaseError';
import {SASL} from './sasl';

const DEFAULT_PORT_NUMBER = 5432;
const COMMAND_RESULT_PATTERN = /^([A-Za-z]+)(?: (\d+)(?: (\d+))?)?$/;
const COMMAND_RESULT_PATTERN = /^([^\d]+)(?: (\d+)(?: (\d+))?)?$/;

export type CaptureCallback = (code: Protocol.BackendMessageCode, msg: any,
done: (err: Maybe<Error>, result?: any) => void) => void | Promise<void>;
Expand Down

0 comments on commit 79ee783

Please sign in to comment.