Skip to content

Commit

Permalink
feat: write collation for nvarchar, nchar, ntext , varchar, `…
Browse files Browse the repository at this point in the history
…char` and `text` data types
  • Loading branch information
arthurschreiber authored Aug 16, 2021
1 parent d27a7e0 commit b1db199
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/always-encrypted/get-parameter-encryption-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,5 @@ export const getParameterEncryptionMetadata = (connection: Connection, request:
resultRows.push(columns);
});

connection.makeRequest(metadataRequest, TYPE.RPC_REQUEST, new RpcRequestPayload(metadataRequest.sqlTextOrProcedure!, metadataRequest.parameters, connection.currentTransactionDescriptor(), connection.config.options));
connection.makeRequest(metadataRequest, TYPE.RPC_REQUEST, new RpcRequestPayload(metadataRequest.sqlTextOrProcedure!, metadataRequest.parameters, connection.currentTransactionDescriptor(), connection.config.options, connection.databaseCollation));
};
10 changes: 5 additions & 5 deletions src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2808,7 +2808,7 @@ class Connection extends EventEmitter {
parameters.push(...request.parameters);
}

this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_executesql', parameters, this.currentTransactionDescriptor(), this.config.options));
this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_executesql', parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
}

/**
Expand Down Expand Up @@ -3022,7 +3022,7 @@ class Connection extends EventEmitter {
}
});

this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_prepare', parameters, this.currentTransactionDescriptor(), this.config.options));
this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_prepare', parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
}

/**
Expand All @@ -3046,7 +3046,7 @@ class Connection extends EventEmitter {
scale: undefined
});

this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_unprepare', parameters, this.currentTransactionDescriptor(), this.config.options));
this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_unprepare', parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
}

/**
Expand Down Expand Up @@ -3092,7 +3092,7 @@ class Connection extends EventEmitter {
return;
}

this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_execute', executeParameters, this.currentTransactionDescriptor(), this.config.options));
this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload('sp_execute', executeParameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
}

/**
Expand All @@ -3114,7 +3114,7 @@ class Connection extends EventEmitter {
return;
}

this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload(request.sqlTextOrProcedure!, request.parameters, this.currentTransactionDescriptor(), this.config.options));
this.makeRequest(request, TYPE.RPC_REQUEST, new RpcRequestPayload(request.sqlTextOrProcedure!, request.parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
}

/**
Expand Down
9 changes: 3 additions & 6 deletions src/data-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import Variant from './data-types/sql-variant';
import { CryptoMetadata } from './always-encrypted/types';

import { InternalConnectionOptions } from './connection';
import { Collation } from './collation';

export interface Parameter {
type: DataType;
Expand All @@ -51,12 +52,6 @@ export interface Parameter {
length?: number;
precision?: number;
scale?: number;
collation?: {
lcid: number;
flags: number;
version: number;
sortId: number;
};

nullable?: boolean;

Expand All @@ -71,6 +66,8 @@ export interface ParameterData<T = any> {
scale?: number;
precision?: number;

collation?: Collation;

value: T;
}

Expand Down
5 changes: 5 additions & 0 deletions src/data-types/char.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ const Char: { maximumLength: number } & DataType = {
const buffer = Buffer.alloc(8);
buffer.writeUInt8(this.id, 0);
buffer.writeUInt16LE(parameter.length!, 1);

if (parameter.collation) {
parameter.collation.toBuffer().copy(buffer, 3, 0, 5);
}

return buffer;
},

Expand Down
5 changes: 5 additions & 0 deletions src/data-types/nchar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ const NChar: DataType & { maximumLength: number } = {
const buffer = Buffer.alloc(8);
buffer.writeUInt8(this.id, 0);
buffer.writeUInt16LE(parameter.length! * 2, 1);

if (parameter.collation) {
parameter.collation.toBuffer().copy(buffer, 3, 0, 5);
}

return buffer;
},

Expand Down
6 changes: 5 additions & 1 deletion src/data-types/ntext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ const NText: DataType = {
const buffer = Buffer.alloc(10);
buffer.writeUInt8(this.id, 0);
buffer.writeInt32LE(parameter.length!, 1);
// TODO: Collation handling

if (parameter.collation) {
parameter.collation.toBuffer().copy(buffer, 5, 0, 5);
}

return buffer;
},

Expand Down
4 changes: 4 additions & 0 deletions src/data-types/nvarchar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ const NVarChar: { maximumLength: number } & DataType = {
buffer.writeUInt16LE(MAX, 1);
}

if (parameter.collation) {
parameter.collation.toBuffer().copy(buffer, 3, 0, 5);
}

return buffer;
},

Expand Down
7 changes: 6 additions & 1 deletion src/data-types/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ const Text: DataType = {
const buffer = Buffer.alloc(10);
buffer.writeUInt8(this.id, 0);
buffer.writeInt32LE(parameter.length!, 1);
// TODO: Collation handling

if (parameter.collation) {
parameter.collation.toBuffer().copy(buffer, 5, 0, 5);
}

return buffer;
},

Expand All @@ -53,6 +57,7 @@ const Text: DataType = {
if (value == null) {
return null;
}

if (typeof value !== 'string') {
if (typeof value.toString !== 'function') {
throw new TypeError('Invalid string.');
Expand Down
4 changes: 4 additions & 0 deletions src/data-types/varchar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ const VarChar: { maximumLength: number } & DataType = {
buffer.writeUInt16LE(MAX, 1);
}

if (parameter.collation) {
parameter.collation.toBuffer().copy(buffer, 3, 0, 5);
}

return buffer;
},

Expand Down
9 changes: 8 additions & 1 deletion src/rpcrequest-payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import WritableTrackingBuffer from './tracking-buffer/writable-tracking-buffer';
import { writeToTrackingBuffer } from './all-headers';
import { Parameter, ParameterData } from './data-type';
import { InternalConnectionOptions } from './connection';
import { Collation } from './collation';

// const OPTION = {
// WITH_RECOMPILE: 0x01,
Expand All @@ -23,12 +24,14 @@ class RpcRequestPayload implements Iterable<Buffer> {

options: InternalConnectionOptions;
txnDescriptor: Buffer;
collation: Collation | undefined;

constructor(procedure: string | number, parameters: Parameter[], txnDescriptor: Buffer, options: InternalConnectionOptions) {
constructor(procedure: string | number, parameters: Parameter[], txnDescriptor: Buffer, options: InternalConnectionOptions, collation: Collation | undefined) {
this.procedure = procedure;
this.parameters = parameters;
this.options = options;
this.txnDescriptor = txnDescriptor;
this.collation = collation;
}

[Symbol.iterator]() {
Expand Down Expand Up @@ -99,6 +102,10 @@ class RpcRequestPayload implements Iterable<Buffer> {
param.scale = type.resolveScale(parameter);
}

if (this.collation) {
param.collation = this.collation;
}

yield type.generateTypeInfo(param, this.options);
yield type.generateParameterLength(param, this.options);
yield * type.generateParameterData(param, this.options);
Expand Down

0 comments on commit b1db199

Please sign in to comment.