Skip to content

Commit

Permalink
feat: support ntext data type in bulk loads and regular requests
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurschreiber committed Aug 10, 2021
1 parent 573426f commit 4a10ccb
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/bulk-load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ class RowTransform extends Transform {
value: value
};

if (c.type.name === 'Text' || c.type.name === 'Image' || c.type.name === 'NText') {
if (value == null) {
this.push(textPointerNullBuffer);
continue;
Expand Down
57 changes: 47 additions & 10 deletions src/data-types/ntext.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,67 @@
import { DataType } from '../data-type';

const NULL_LENGTH = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF]);

const NText: DataType = {
id: 0x63,
type: 'NTEXT',
name: 'NText',

hasTableName: true,

declaration() {
throw new Error('not implemented');
declaration: function() {
return 'ntext';
},

resolveLength: function(parameter) {
const value = parameter.value as any; // Temporary solution. Remove 'any' later.

if (value != null) {
return value.length;
} else {
return -1;
}
},

generateTypeInfo() {
throw new Error('not implemented');
generateTypeInfo(parameter, _options) {
const buffer = Buffer.alloc(10);
buffer.writeUInt8(this.id, 0);
buffer.writeInt32LE(parameter.length!, 1);
// TODO: Collation handling
return buffer;
},

generateParameterLength() {
throw new Error('not implemented');
generateParameterLength(parameter, options) {
if (parameter.value == null) {
return NULL_LENGTH;
}

const buffer = Buffer.alloc(4);
buffer.writeInt32LE(Buffer.byteLength(parameter.value, 'ucs2'), 0);
return buffer;
},

generateParameterData() {
throw new Error('not implemented');
generateParameterData: function*(parameter, options) {
if (parameter.value == null) {
return;
}

yield Buffer.from(parameter.value.toString(), 'ucs2');
},

validate() {
throw new Error('not implemented');
validate: function(value): string | null {
if (value == null) {
return null;
}

if (typeof value !== 'string') {
if (typeof value.toString !== 'function') {
throw new TypeError('Invalid string.');
}
value = value.toString();
}

return value;
}
};

Expand Down
51 changes: 51 additions & 0 deletions test/integration/bulk-load-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1588,6 +1588,57 @@ describe('BulkLoad', function() {
connection.execSqlBatch(request);
});

it('supports bulk loading into a `ntext` column', function(done) {
const expectedRows = [
{ value: 'some text 中文' },
{ value: null }
];

const bulkLoad = connection.newBulkLoad('#tmpTestTable', (err, rowCount) => {
if (err) {
done(err);
}

assert.strictEqual(rowCount, expectedRows.length);

/** @type {unknown[]} */
const results = [];
const request = new Request(`
SELECT value FROM #tmpTestTable
`, (err) => {
if (err) {
done(err);
}

assert.deepEqual(results, expectedRows);

done();
});

request.on('row', (row) => {
results.push({ value: row[0].value });
});

connection.execSql(request);
});

bulkLoad.addColumn('value', TYPES.NText, { nullable: true });

const request = new Request(`
CREATE TABLE "#tmpTestTable" (
[value] ntext NULL
)
`, (err) => {
if (err) {
return done(err);
}

connection.execBulkLoad(bulkLoad, Readable.from(expectedRows));
});

connection.execSqlBatch(request);
});

it('supports bulk loading into a `image` column', function(done) {
const expectedRows = [
{ value: Buffer.from([0xDE, 0xAD, 0xBE, 0xEF]) },
Expand Down
22 changes: 22 additions & 0 deletions test/integration/parameterised-statements-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,28 @@ describe('Parameterised Statements Test', function() {
execSql(done, TYPES.NChar, null);
});

describe('`ntext`', function() {
it('should handle `null` values', function(done) {
execSql(done, TYPES.NText, null);
});

it('should handle empty strings', function(done) {
execSql(done, TYPES.NText, '');
});

it('should handle short strings', function(done) {
execSql(done, TYPES.NText, 'small');
});

it('should handle large strings', function(done) {
execSql(done, TYPES.NText, new Array(500000).join('x'));
});

it('should handle multibyte characters', function(done) {
execSql(done, TYPES.NText, 'some text 中文');
});
});

it('should test textNull', function(done) {
execSql(done, TYPES.Text, null);
});
Expand Down

0 comments on commit 4a10ccb

Please sign in to comment.