Skip to content

ColumnValue introduction #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions __tests__/transaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ test.only('Simple Transaction', async () => {
expect(results).toBe('Transaction Committed');

const endInfo = await rds.query(`SELECT COUNT(*) AS cn FROM ${TABLE}`);
const startCount = startInfo.data[0].cn.number;
const endCount = endInfo.data[0].cn.number;
const startCount = startInfo.data[0].cn.number || 0;
const endCount = endInfo.data[0].cn.number || 0;

expect(results).toBe('Transaction Committed');
expect(startCount).toBe(endCount! - 3);
expect(startCount).toBe(endCount - 3);
});

test('Rollback Transaction', async () => {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"test-pg": "jest --config jestconfig.json --group=pg",
"build": "tsc",
"format": "prettier --write \"src/**/*.ts\"",
"lint": "tslint -p tsconfig.json",
"lint": "tslint --project tsconfig.json",
"eslint": "eslint -c ./.eslintrc.yml 'src/*.{js,ts,tsx}' --color --fix",
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run lint",
Expand Down Expand Up @@ -72,4 +72,4 @@
"dependencies": {
"aws-sdk": "^2.682.0"
}
}
}
41 changes: 41 additions & 0 deletions src/ColumnValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { RDSDataService } from "aws-sdk";

class ColumnValue {
public field: RDSDataService.Field;

constructor(field: RDSDataService.Field) {
this.field = field;
}

get isNull(): boolean {
return !!this.field.isNull;
}

get date(): Date | null {
if (this.isNull) return null;
return new Date(this.field.stringValue!);
}

get string(): string | null {
if (this.isNull) return null;
return this.field.stringValue || null;
}

get number(): number | null {
if (this.isNull) return null;
return this.field.longValue || null;
}

get buffer(): Buffer | null {
if (this.isNull) return null;
return Buffer.isBuffer(this.field.blobValue) ? this.field.blobValue : Buffer.from(this.field.blobValue as Uint8Array);
}

get boolean(): boolean | null {
if (this.isNull) return null;
return this.field.booleanValue || null;
}

}

export default ColumnValue;
88 changes: 18 additions & 70 deletions src/RDSData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RDSDataService } from 'aws-sdk';
import { SqlParametersList } from 'aws-sdk/clients/rdsdataservice';
import ColumnValue from './ColumnValue';

export interface RDSDataOptions {
secretArn: string;
Expand All @@ -9,8 +10,7 @@ export interface RDSDataOptions {
rdsConfig?: RDSDataService.Types.ClientConfiguration;
}

// COLUMNS & PARAMETERS -------------------------
export interface RDSDataColumn {
export interface DataColumn {
name: string;
tableName: string;
type: string;
Expand All @@ -24,29 +24,19 @@ export interface RDSDataType {
}
export type RDSDataTypes = 'stringValue' | 'booleanValue' | 'longValue' | 'isNull' | 'blobValue' | undefined;

export type RDSDataParameterValue = string | Buffer | boolean | number | null | undefined;
export type ParameterValue = string | Buffer | boolean | number | null | undefined;
export interface RDSDataParameters {
[key: string]: RDSDataParameterValue;
[key: string]: ParameterValue;
}
export type RDSDataRow = { [key: string]: RDSDataResponseValue };
export type Row = { [key: string]: ColumnValue };

// RESPONSE TYPES -------------------------------
export interface RDSDataResponseValue {
isNull: boolean;
string?: string;
date?: Date;
boolean?: boolean;
buffer?: Buffer;
number?: number;
export interface ResponseData {
[key: string]: ColumnValue;
}

export interface RDSDataResponseData {
[key: string]: RDSDataResponseValue;
}

export interface RDSDataResponse {
columns: RDSDataColumn[];
data: RDSDataResponseData[];
export interface Response {
columns: DataColumn[];
data: ResponseData[];
numberOfRecordsUpdated: number;
insertId: number | undefined;
}
Expand Down Expand Up @@ -80,7 +70,7 @@ export class RDSData {
return this.rds;
}

public async query(sql: string, params?: RDSDataParameters, transactionId?: string): Promise<RDSDataResponse> {
public async query(sql: string, params?: RDSDataParameters, transactionId?: string): Promise<Response> {
const parameters = RDSData.formatParameters(params);
return new Promise((resolve, reject) => {
let queryParameters: RDSDataService.Types.ExecuteStatementRequest = {
Expand Down Expand Up @@ -113,7 +103,7 @@ export class RDSData {
return [];
}

const getType = (val: RDSDataParameterValue): RDSDataTypes => {
const getType = (val: ParameterValue): RDSDataTypes => {
const t = typeof val;
if (t === 'string') {
return 'stringValue';
Expand All @@ -133,7 +123,7 @@ export class RDSData {
return undefined;
};

const formatType = (name: string, value: RDSDataParameterValue, type: RDSDataTypes): RDSDataType => {
const formatType = (name: string, value: ParameterValue, type: RDSDataTypes): RDSDataType => {
if (!type) {
throw new Error(`Invalid Type for name: ${name} value: ${value} type: ${type} typeof: ${typeof value}`);
}
Expand Down Expand Up @@ -163,11 +153,11 @@ export class RDSData {
return parameters;
}

private static resultFormat(response: RDSDataService.Types.ExecuteStatementResponse): RDSDataResponse {
private static resultFormat(response: RDSDataService.Types.ExecuteStatementResponse): Response {
const insertId =
response.generatedFields && response.generatedFields.length > 0 ? response.generatedFields[0].longValue : 0;
const columns: RDSDataColumn[] = [];
const data: { [key: string]: RDSDataResponseValue }[] = [];
const columns: DataColumn[] = [];
const data: { [key: string]: ColumnValue }[] = [];
const numberOfRecordsUpdated = response.numberOfRecordsUpdated ?? 0;

if (response && response.columnMetadata && response.records) {
Expand All @@ -180,51 +170,9 @@ export class RDSData {
});

response.records.forEach((record) => {
const row: RDSDataRow = {};
const row: Row = {};
for (let c = 0; c < record.length; c += 1) {
/* tslint:disable:no-string-literal */
const isNull = record[c].isNull ?? false;
const v: RDSDataResponseValue = { isNull };
switch (columns[c].type) {
case 'BINARY':
v.buffer = isNull ? undefined : Buffer.from((record[c].blobValue || '').toString());
v.string = isNull ? undefined : v.buffer?.toString('base64');
break;
case 'BOOL':
case 'BIT':
v.boolean = isNull ? undefined : record[c].booleanValue;
v.number = v.boolean ? 1 : 0;
break;
case 'TIMESTAMP':
case 'DATETIME':
case 'DATE':
v.date = isNull ? undefined : new Date(record[c].stringValue ?? '');
v.string = isNull ? undefined : record[c].stringValue;
v.number = v.date ? v.date.getTime() : 0;
break;
case 'INTEGER':
case 'INTEGER UNSIGNED':
case 'INT':
case 'INT4':
case 'INT8':
case 'INT UNSIGNED':
case 'BIGINT':
case 'BIGINT UNSIGNED':
case 'SERIAL':
v.number = isNull ? undefined : record[c].longValue;
break;
case 'UUID':
case 'TEXT':
case 'CHAR':
case 'BPCHAR':
case 'VARCHAR':
v.string = isNull ? undefined : record[c].stringValue;
break;
default:
throw new Error(`Missing type: ${columns[c].type}`);
}
/* tslint:enable:no-string-literal */
row[columns[c].name] = v;
row[columns[c].name] = new ColumnValue(record[c]);
}
data.push(row);
});
Expand Down