Skip to content

Commit

Permalink
Fix oracledb driver v4 support (#3480)
Browse files Browse the repository at this point in the history
  • Loading branch information
maximelkin authored and kibertoad committed Oct 15, 2019
1 parent 767904c commit c9e3057
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -16,7 +16,7 @@ matrix:
env: TESTSCRIPT=test:everything DB="oracledb mssql mysql mysql2 postgres sqlite3" KNEX_TEST_TIMEOUT=60000
install:
- npm i
- (echo $DB | grep oracledb) && npm install oracledb@3.1.2 || true
- (echo $DB | grep oracledb) && npm install oracledb || true

before_script:
- npm run db:start
Expand Down
85 changes: 61 additions & 24 deletions lib/dialects/oracledb/index.js
Expand Up @@ -131,7 +131,11 @@ Client_Oracledb.prototype.acquireRawConnection = function() {
};
const fetchAsync = promisify(function(sql, bindParams, options, cb) {
options = options || {};
options.outFormat = client.driver.OBJECT;
options.outFormat =
client.driver.OUT_FORMAT_OBJECT || client.driver.OBJECT;
if (!options.outFormat) {
throw new Error('not found oracledb.outFormat constants');
}
if (options.resultSet) {
connection.execute(sql, bindParams || [], options, function(
err,
Expand Down Expand Up @@ -202,7 +206,10 @@ Client_Oracledb.prototype.acquireRawConnection = function() {

try {
for (const lob of lobs) {
results.rows[lob.index][lob.key] = await readStream(lob.stream);
// todo should be fetchAsString/fetchAsBuffer polyfill only
results.rows[lob.index][lob.key] = await lobProcessing(
lob.stream
);
}
} catch (e) {
await closeResultSet().catch(() => {});
Expand Down Expand Up @@ -328,30 +335,29 @@ Client_Oracledb.prototype._query = function(connection, obj) {
});
};

// Handle clob
const readStream = promisify((stream, cb) => {
const oracledb = require('oracledb');
let data = '';
/**
* @param stream
* @param {'string' | 'buffer'} type
*/
function readStream(stream, type) {
return new Promise((resolve, reject) => {
let data = '';

if (stream.iLob.type === oracledb.CLOB) {
stream.setEncoding('utf-8');
} else {
data = Buffer.alloc(0);
}
stream.on('error', function(err) {
cb(err);
});
stream.on('data', function(chunk) {
if (stream.iLob.type === oracledb.CLOB) {
data += chunk;
} else {
data = Buffer.concat([data, chunk]);
}
});
stream.on('end', function() {
cb(null, data);
stream.on('error', function(err) {
reject(err);
});
stream.on('data', function(chunk) {
if (type === 'string') {
data += chunk;
} else {
data = Buffer.concat([data, chunk]);
}
});
stream.on('end', function() {
resolve(data);
});
});
});
}

// Process the response as returned from the query.
Client_Oracledb.prototype.processResponse = function(obj, runner) {
Expand Down Expand Up @@ -387,6 +393,37 @@ Client_Oracledb.prototype.processResponse = function(obj, runner) {
}
};

const lobProcessing = function(stream) {
const oracledb = require('oracledb');

/**
* @type 'string' | 'buffer'
*/
let type;

if (stream.type) {
// v1.2-v4
if (stream.type === oracledb.BLOB) {
type = 'buffer';
} else if (stream.type === oracledb.CLOB) {
type = 'string';
}
} else if (stream.iLob) {
// v1
if (stream.iLob.type === oracledb.CLOB) {
type = 'string';
} else if (stream.iLob.type === oracledb.BLOB) {
type = 'buffer';
}
} else {
throw new Error('Unrecognized oracledb lob stream type');
}
if (type === 'string') {
stream.setEncoding('utf-8');
}
return readStream(stream, type);
};

class Oracledb_Formatter extends Oracle_Formatter {
// Checks whether a value is a function... if it is, we compile it
// otherwise we check whether it's a raw
Expand Down
9 changes: 9 additions & 0 deletions test/unit/dialects/oracledb.js
Expand Up @@ -71,6 +71,15 @@ describe('OracleDb parameters', function() {
});
});

it('on clob', function() {
return knexClient
.raw('select TO_CLOB(\'LONG CONTENT\') as "field" from dual')
.then(function(result) {
expect(result[0]).to.be.ok;
expect(result[0].field).to.be.equal('LONG CONTENT');
});
});

after(function() {
return knexClient.destroy();
});
Expand Down

0 comments on commit c9e3057

Please sign in to comment.