Add new connection properties

This commit is contained in:
Sharad Chandran R 2023-10-30 20:34:22 +05:30
parent 3b7d7a9060
commit 9b61c20068
8 changed files with 318 additions and 1 deletions

View File

@ -16,6 +16,13 @@ Thin Mode Changes
#) Improved overall pool connection creation time by caching information
during the first connection establishment.
#) Added new connection properties :attr:`connection.dbDomain`,
:attr:`connection.dbName`, :attr:`connection.maxOpenCursors`,
:attr:`connection.serviceName` and :attr:`connection.transactionInProgress`
that provide the database domain name, database instance name, maximum
number of cursors that can be opened per connection, database service name
and status of any ongoing transactions on the connection respectively.
node-oracledb `v6.2.0 <https://github.com/oracle/node-oracledb/compare/v6.1.0...v6.2.0>`__ (11 Oct 2023)
--------------------------------------------------------------------------------------------------------

View File

@ -971,6 +971,24 @@ class Connection extends EventEmitter {
this._impl.setExternalName(value);
}
//---------------------------------------------------------------------------
// dbDomain (READONLY)
//
// Property for identifying the dbDomain of the Oracle Database.
//---------------------------------------------------------------------------
get dbDomain() {
return this._impl && this._impl.getDbDomain();
}
//---------------------------------------------------------------------------
// dbName (READONLY)
//
// Property for identifying the dbName of the Oracle Database.
//---------------------------------------------------------------------------
get dbName() {
return this._impl && this._impl.getDbName();
}
//---------------------------------------------------------------------------
// getDbObjectClass()
//
@ -1080,6 +1098,15 @@ class Connection extends EventEmitter {
this._impl.isHealthy());
}
//---------------------------------------------------------------------------
// maxOpenCursors
//
// Returns maximum number of cursors that can be opened in one session.
//---------------------------------------------------------------------------
get maxOpenCursors() {
return this._impl && this._impl.getMaxOpenCursors();
}
//---------------------------------------------------------------------------
// module
//
@ -1117,6 +1144,25 @@ class Connection extends EventEmitter {
return undefined;
}
//---------------------------------------------------------------------------
// serviceName
//
// Returns the Oracle Database service name associated with the connection.
//---------------------------------------------------------------------------
get serviceName() {
return this._impl && this._impl.getServiceName();
}
//---------------------------------------------------------------------------
// transactionInProgress
//
// Returns a boolean value based on the presence of an active transaction
// on the connection
//---------------------------------------------------------------------------
get transactionInProgress() {
return this._impl && this._impl.getTransactionInProgress();
}
//---------------------------------------------------------------------------
// ping()
//

View File

@ -208,6 +208,24 @@ class ConnectionImpl {
errors.throwNotImplemented("getting current schema");
}
//---------------------------------------------------------------------------
// getDbDomain()
//
// Returns the Oracle Database domain name associated with the connection.
//---------------------------------------------------------------------------
getDbDomain() {
errors.throwNotImplemented("getting db domain");
}
//---------------------------------------------------------------------------
// getDbName()
//
// Returns the Oracle Database name associated with the connection.
//---------------------------------------------------------------------------
getDbName() {
errors.throwNotImplemented("getting db name");
}
//---------------------------------------------------------------------------
// getDbObjectClass()
//
@ -244,6 +262,15 @@ class ConnectionImpl {
errors.throwNotImplemented("getting the internal name");
}
//---------------------------------------------------------------------------
// getMaxOpenCursors()
//
// Returns maximum number of cursors that can be opened in one session.
//---------------------------------------------------------------------------
getMaxOpenCursors() {
errors.throwNotImplemented("getting max open cursors");
}
//---------------------------------------------------------------------------
// getOracleServerVersion()
//
@ -271,6 +298,15 @@ class ConnectionImpl {
errors.throwNotImplemented("getting a queue");
}
//---------------------------------------------------------------------------
// getServiceName()
//
// Returns the Oracle Database service name associated with the connection.
//---------------------------------------------------------------------------
getServiceName() {
errors.throwNotImplemented("getting service name");
}
//---------------------------------------------------------------------------
// getSodaDatabase()
//
@ -307,6 +343,17 @@ class ConnectionImpl {
errors.throwNotImplemented("getting the tag for the connection");
}
//---------------------------------------------------------------------------
// getTransactionInProgress()
//
// Returns boolean based on the presence of an active transaction on the
// connection
//---------------------------------------------------------------------------
getTransactionInProgress() {
errors.throwNotImplemented("getting the status of an active transaction" +
" on the connection");
}
//---------------------------------------------------------------------------
// isHealthy()
//

View File

@ -1085,6 +1085,40 @@ class ThinConnectionImpl extends ConnectionImpl {
getInstanceName() {
return this.instanceName;
}
}
//---------------------------------------------------------------------------
// Returns the Oracle Database domain name associated with the connection.
//---------------------------------------------------------------------------
getDbDomain() {
return this.dbDomain;
}
//---------------------------------------------------------------------------
// Returns the Oracle Database name associated with the connection.
//---------------------------------------------------------------------------
getDbName() {
return this.dbName;
}
//---------------------------------------------------------------------------
// Returns maximum number of cursors that can be opened in one session.
//---------------------------------------------------------------------------
getMaxOpenCursors() {
return this.maxOpenCursors;
}
//---------------------------------------------------------------------------
// Returns the Oracle Database service name associated with the connection.
//---------------------------------------------------------------------------
getServiceName() {
return this.serviceName;
}
//---------------------------------------------------------------------------
// Returns boolean based on this._protocol.txnInProgress value.
//---------------------------------------------------------------------------
getTransactionInProgress() {
return this._protocol.txnInProgress === constants.TNS_TXN_IN_PROGRESS;
}
}
module.exports = ThinConnectionImpl;

View File

@ -321,6 +321,10 @@ class AuthMessage extends Message {
let portReleaseNum;
let portUpdateNum;
this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'] || undefined;
this.conn.dbName = this.sessionData['AUTH_SC_DBUNIQUE_NAME'];
this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS']);
this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
const versionNum = (fullVersionNum >> 24) & 0xFF;

View File

@ -42,17 +42,22 @@ NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_createLob);
NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_execute);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getCallTimeout);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getCurrentSchema);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getDbName);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getDbDomain);
NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_getDbObjectClass);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getExternalName);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getInstanceName);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getInternalName);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getMaxOpenCursors);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getOracleServerVersion);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getOracleServerVersionString);
NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_getQueue);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getServiceName);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getSodaDatabase);
NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_getStatementInfo);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getStmtCacheSize);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getTag);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_getTransactionInProgress);
NJS_NAPI_METHOD_DECL_SYNC(njsConnection_isHealthy);
NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_ping);
NJS_NAPI_METHOD_DECL_ASYNC(njsConnection_rollback);
@ -137,6 +142,10 @@ static const napi_property_descriptor njsClassProperties[] = {
napi_default, NULL },
{ "getCurrentSchema", NULL, njsConnection_getCurrentSchema, NULL, NULL,
NULL, napi_default, NULL },
{ "getDbName", NULL, njsConnection_getDbName, NULL, NULL, NULL,
napi_default, NULL },
{ "getDbDomain", NULL, njsConnection_getDbDomain, NULL, NULL, NULL,
napi_default, NULL },
{ "getDbObjectClass", NULL, njsConnection_getDbObjectClass, NULL, NULL,
NULL, napi_default, NULL },
{ "getExternalName", NULL, njsConnection_getExternalName, NULL, NULL, NULL,
@ -145,6 +154,8 @@ static const napi_property_descriptor njsClassProperties[] = {
napi_default, NULL },
{ "getInternalName", NULL, njsConnection_getInternalName, NULL, NULL, NULL,
napi_default, NULL },
{ "getMaxOpenCursors", NULL, njsConnection_getMaxOpenCursors, NULL, NULL,
NULL, napi_default, NULL },
{ "getOracleServerVersion", NULL, njsConnection_getOracleServerVersion,
NULL, NULL, NULL, napi_default, NULL },
{ "getOracleServerVersionString", NULL,
@ -152,6 +163,8 @@ static const napi_property_descriptor njsClassProperties[] = {
napi_default, NULL },
{ "getQueue", NULL, njsConnection_getQueue, NULL, NULL, NULL,
napi_default, NULL },
{ "getServiceName", NULL, njsConnection_getServiceName, NULL, NULL, NULL,
napi_default, NULL },
{ "getSodaDatabase", NULL, njsConnection_getSodaDatabase, NULL, NULL,
NULL, napi_default, NULL },
{ "getStatementInfo", NULL, njsConnection_getStatementInfo, NULL,
@ -160,6 +173,8 @@ static const napi_property_descriptor njsClassProperties[] = {
NULL, napi_default, NULL },
{ "getTag", NULL, njsConnection_getTag, NULL, NULL, NULL, napi_default,
NULL },
{ "getTransactionInProgress", NULL, njsConnection_getTransactionInProgress,
NULL, NULL, NULL, napi_default, NULL },
{ "isHealthy", NULL, njsConnection_isHealthy, NULL, NULL, NULL,
napi_default, NULL },
{ "ping", NULL, njsConnection_ping, NULL, NULL, NULL, napi_default,
@ -1004,6 +1019,46 @@ NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getCurrentSchema, 0, NULL)
}
//-----------------------------------------------------------------------------
// njsConnection_getDbName()
// Get the Database Name of the current connection.
//-----------------------------------------------------------------------------
NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getDbName, 0, NULL)
{
njsConnection *conn = (njsConnection*) callingInstance;
uint32_t valueLength;
const char *value;
if (conn->handle) {
if (dpiConn_getDbName(conn->handle, &value, &valueLength) < 0)
return njsUtils_throwErrorDPI(env, globals);
NJS_CHECK_NAPI(env, napi_create_string_utf8(env, value, valueLength,
returnValue))
}
return true;
}
//-----------------------------------------------------------------------------
// njsConnection_getDbDomain()
// Get the database Domain of the current connection.
//----------------------------------------------------------------------------
NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getDbDomain, 0, NULL)
{
njsConnection *conn = (njsConnection*) callingInstance;
uint32_t valueLength;
const char *value;
if (conn->handle) {
if (dpiConn_getDbDomain(conn->handle, &value, &valueLength) < 0 )
return njsUtils_throwErrorDPI(env, globals);
NJS_CHECK_NAPI(env, napi_create_string_utf8(env, value, valueLength,
returnValue))
}
return true;
}
//-----------------------------------------------------------------------------
// njsConnection_getDbObjectClass()
// Looks up a database object type given its name and returns it to the
@ -1116,6 +1171,25 @@ NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getInternalName, 0, NULL)
}
//-----------------------------------------------------------------------------
// njsConnection_getMaxOpenCursors()
// Get accessor of "maxOpenCursors" property.
//-----------------------------------------------------------------------------
NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getMaxOpenCursors, 0, NULL)
{
njsConnection *conn = (njsConnection*) callingInstance;
uint32_t maxOpenCursors;
if (conn->handle) {
if (dpiConn_getMaxOpenCursors(conn->handle, &maxOpenCursors) < 0)
return njsUtils_throwErrorDPI(env, globals);
NJS_CHECK_NAPI(env, napi_create_uint32(env, maxOpenCursors,
returnValue))
}
return true;
}
//-----------------------------------------------------------------------------
// njsConnection_getExecuteManyOutBinds()
// Get the out binds as an array of objects/arrays.
@ -1407,6 +1481,26 @@ static bool njsConnection_getRowCounts(njsBaton *baton, napi_env env,
}
//-----------------------------------------------------------------------------
// njsConnection_getServiceName()
// Get Accessor for "serviceName" property.
//-----------------------------------------------------------------------------
NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getServiceName, 0, NULL)
{
njsConnection *conn = (njsConnection*) callingInstance;
uint32_t valueLength;
const char *value;
if (conn->handle) {
if (dpiConn_getServiceName(conn->handle, &value, &valueLength) < 0)
return njsUtils_throwErrorDPI(env, globals);
NJS_CHECK_NAPI(env, napi_create_string_utf8(env, value, valueLength,
returnValue))
}
return true;
}
//-----------------------------------------------------------------------------
// njsConnection_getSodaDatabase()
// Creates a top-level SODA object (pseudo) associated with the connection.
@ -1587,6 +1681,25 @@ NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getTag, 0, NULL)
}
//-----------------------------------------------------------------------------
// njsConnection_getTransactionInProgress()
// Get Accessor of "transactionInProgress" property
//-----------------------------------------------------------------------------
NJS_NAPI_METHOD_IMPL_SYNC(njsConnection_getTransactionInProgress, 0, NULL)
{
njsConnection *conn = (njsConnection*) callingInstance;
int txnInProgress;
if (conn->handle) {
if (dpiConn_getTransactionInProgress(conn->handle, &txnInProgress) < 0)
return njsUtils_throwErrorDPI(env, globals);
NJS_CHECK_NAPI(env, napi_get_boolean(env, txnInProgress, returnValue))
}
return true;
}
//-----------------------------------------------------------------------------
// njsConnection_newFromBaton()
// Called when a connection is being created from the baton.

View File

@ -166,4 +166,64 @@ describe('193. connProps.js', function() {
await conn.close();
}); // 193.4
it('193.5 Oracle Database service name associated with the connection', async () => {
const conn = await oracledb.getConnection(dbConfig);
const query = "SELECT upper(sys_context('userenv', 'service_name')) FROM DUAL";
const result = await conn.execute(query);
assert.deepStrictEqual(result.rows[0][0], conn.serviceName.toUpperCase());
await conn.close();
}); // 193.5
it('193.6 Oracle Database dbname associated with the connection', async () => {
const conn = await oracledb.getConnection(dbConfig);
const query = "SELECT upper(NAME) FROM v$database";
const result = await conn.execute(query);
assert.deepStrictEqual(result.rows[0][0], conn.dbName.toUpperCase());
await conn.close();
}); // 193.6
it('193.7 Oracle Database db domain associated with the connection', async () => {
const conn = await oracledb.getConnection(dbConfig);
const query = "SELECT upper(VALUE) FROM v$parameter WHERE name='db_domain'";
const result = await conn.execute(query);
if (result.rows[0][0]) {
assert.deepStrictEqual(result.rows[0][0], conn.dbDomain.toUpperCase());
} else {
assert.deepStrictEqual(conn.dbDomain, undefined);
}
await conn.close();
}); // 193.7
it('193.8 maximum cursors that can be opened on a connection', async () => {
const conn = await oracledb.getConnection(dbConfig);
const query = "SELECT value FROM v$parameter WHERE name='open_cursors'";
const result = await conn.execute(query);
assert.deepStrictEqual(Number(result.rows[0][0]), conn.maxOpenCursors);
await conn.close();
}); // 193.8
it('193.9 transactionInProgress = false on a connection for query', async () => {
const conn = await oracledb.getConnection(dbConfig);
const query = "SELECT * FROM DUAL";
await conn.execute(query);
assert.strictEqual(conn.transactionInProgress, false);
await conn.close();
}); // 193.9
it('193.10 transactionInProgress = true on a connection', async () => {
const conn = await oracledb.getConnection(dbConfig);
const TABLE = 'nodb_emp';
const createSql = `CREATE TABLE ${TABLE} (id number)`;
assert.strictEqual(conn.transactionInProgress, false);
await testsUtil.createTable(conn, TABLE, createSql);
assert.strictEqual(conn.transactionInProgress, false);
const sql = `INSERT INTO ${TABLE} VALUES(1)`;
await conn.execute(sql);
assert.strictEqual(conn.transactionInProgress, true);
await conn.commit();
assert.strictEqual(conn.transactionInProgress, false);
await conn.execute(`DROP TABLE ${TABLE} PURGE`);
await conn.close();
}); // 193.10
});

View File

@ -4478,6 +4478,12 @@ oracledb.OUT_FORMAT_OBJECT and resultSet = true
193.2 clientInfo and dbOp are write-only properties
193.3 check the results of setter()
193.4 Negative - invalid values
193.5 Oracle Database service name associated with the connection
193.6 Oracle Database dbname associated with the connection
193.7 Oracle Database db domain associated with the connection
193.8 maximum cursors that can be opened on a connection
193.9 transactionInProgress = false on a connection for query
193.10 transactionInProgress = true on a connection
196. getDataOfLob.js
196.1 getData() works on CLOB