Skip to content

Commit

Permalink
feat: support text and image data type in bulk loads
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurschreiber committed Aug 9, 2021
1 parent 3ecb650 commit 573426f
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/bulk-load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ interface ColumnOptions {
}

const rowTokenBuffer = Buffer.from([ TOKEN_TYPE.ROW ]);
const textPointerAndTimestampBuffer = Buffer.from([
// TextPointer length
0x10,

// TextPointer
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

// Timestamp
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]);
const textPointerNullBuffer = Buffer.from([0x00]);

// A transform that converts rows to packets.
class RowTransform extends Transform {
Expand Down Expand Up @@ -183,6 +194,14 @@ class RowTransform extends Transform {
value: value
};

if (value == null) {
this.push(textPointerNullBuffer);
continue;
}

this.push(textPointerAndTimestampBuffer);
}

this.push(c.type.generateParameterLength(parameter, this.mainOptions));
for (const chunk of c.type.generateParameterData(parameter, this.mainOptions)) {
this.push(chunk);
Expand Down Expand Up @@ -611,6 +630,11 @@ class BulkLoad extends EventEmitter {
// TYPE_INFO
tBuf.writeBuffer(c.type.generateTypeInfo(c, this.options));

// TableName
if (c.type.hasTableName) {
tBuf.writeUsVarchar(this.table, 'ucs2');
}

// ColName
tBuf.writeBVarchar(c.name, 'ucs2');
}
Expand Down
2 changes: 1 addition & 1 deletion src/data-types/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const Image: DataType = {
}

const buffer = Buffer.alloc(4);
buffer.writeInt32LE(parameter.length!, 0);
buffer.writeInt32LE(parameter.value.length!, 0);
return buffer;
},

Expand Down
2 changes: 1 addition & 1 deletion src/data-types/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const Text: DataType = {
}

const buffer = Buffer.alloc(4);
buffer.writeInt32LE(parameter.length!, 0);
buffer.writeInt32LE(parameter.value.length!, 0);
return buffer;
},

Expand Down
103 changes: 103 additions & 0 deletions test/integration/bulk-load-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,109 @@ describe('BulkLoad', function() {
done();
}
});

it('supports bulk loading into a `text` 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.Text, { nullable: true });

const request = new Request(`
CREATE TABLE "#tmpTestTable" (
[value] text 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]) },
{ 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.Image, { nullable: true });

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

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

connection.execSqlBatch(request);
});
});

describe('Bulk Loads when `config.options.validateBulkLoadParameters` is `true`', () => {
Expand Down

0 comments on commit 573426f

Please sign in to comment.