You may also be interested in the research Bill is doing into pre-creating binaries so you don't need to compile yourself: github.com/oracle/node-oracledb/issues/18.
Article on installing node-oracledb on Windows
Application Development with Node.js, Python, PHP, R, C, and C++ at OOW
- Application Development with Node.js, Python, PHP, R, C, and C++
- .NET Development with Oracle Database
- Application Development for Oracle Database Development with a SQL focus
These lists should help you work out a great schedule!
node-oracledb 1.4.0 supports Node 0.10, 0.12, 4.2 and 5 (Node.js add-on for Oracle Database)
Version 1.4 of node-oracledb, the add-on for Node.js that powers high performance Oracle Database applications, is available on NPM.
Since the recent releases of Node 4 LTS and Node 5, after the reconciliation and merge of the io.js and Node.js forks, there has been strong interest in a compatible node-oracledb driver. This is now possible. Node-oracledb 1.4 works with Node.js 0.10, 0.12, 4.2, and 5.0. Thanks to everyone for their perseverance.
The code change making this possible was a patch contributed by Richard Natal bumping the dependency on NAN from v1 to v2. Note: a compiler with support for C++11 is required to build with Node 4.2 and 5. (Oracle Linux 6 users will need to move to Oracle Linux 7 or install a newer compiler, such as from the Software Collection Library for Oracle Linux).
Other changes in this release are:
Fixed a statement cursor leak occuring when statements failed.
Fixed a crash accessing Pool properties on Windows.
A new
testWindows
target to help run the tests on Windows was added to package.json. Instructions on how to run tests are in test/README.md.Fixed compilation warnings seen on some platforms with newer compilers.
Issues and questions about node-oracledb can be posted on GitHub.
node-oracledb installation instructions are here.
node-oracledb documentation is here.
Major news: PHP 7.0.0 has been released
Congratulations to the PHP community - the whole community - on the release of PHP 7.0.0. Thanks also to the Oracle staff who have worked on the internal rewrite necessary to make the OCI8 and PDO_OCI extensions work with PHP 7's completely revamped Extension API.
The Oracle Database OCI8 and PDO_OCI extensions are included in the PHP source distribution. The feature sets are unchanged.
The equivalent standalone OCI8 package compatible with PHP 7 will be released as version 2.1 on PECL soon. PDO_OCI will remain solely part of the core PHP source distribution.
For those interested in performance, Zend have put some benchmark figures here showing the significant improvements, which were a key feature of this release.
Other features are listed in the release announcement:
- Significantly reduced memory usage
- Abstract Syntax Tree
- Consistent 64-bit support
- Improved Exception hierarchy
- Many fatal errors converted to Exceptions
- Secure random number generator
- Removed old and unsupported SAPIs and extensions
- The null coalescing operator (??)
- Return and Scalar Type Declarations
- Anonymous Classes
- Zero cost asserts
See the migration documentation for all the fine details.
PHP 7 OCI8 2.1.0 available on PECL
I've released PHP 7 OCI8 2.1 on PECL and simultaneously made a patch release OCI8 2.0.10 which is compatible with PHP 5.2 - PHP 5.6.
To install OCI8 for PHP 7 use:
pecl install oci8
This installs OCI8 2.1 which, as I'm sure you can guess, had a lot of internal changes to make it compatible with the vastly changed internals of PHP 7.
If you want to install OCI8 for PHP 5.2, 5.3, 5.4, or 5.6 use:
pecl install oci8-2.0.10
Functionality in 2.0.10 and 2.1.0 is equivalent. They both contain the fix for bug 68298, an overflow when binding 64bit numbers.
At time of writing, Windows DLLs were not yet built on PECL. If you need them, you can grab them from the full PHP Windows bundle.
node-oracledb 1.5.0 is on NPM (Node.js add-on for Oracle Database)
A number of bugs have been squashed in this release.
We now treat Oracle Database 'Success With Info' warnings as success.
Thanks to Francisco Trevino for his pull request. After investigating and discussing, we decided for 1.5 to pick up the straightforward fix proposed. In a future release we will revisit allowing these warnings to be caught and handled.
Extended rollback-on-connection-release with 11g Oracle Clients to occur for all non-query executions.
The natural behavior of OCI is to commit when a connection is released. This is the opposite of node-oracledb, which therefore has to determine whether to rollback or not.
When node-oracledb is linked with 11g client a heuristic is used to guess whether to rollback when a connection is released. This heuristic needed to be changed to cover more cases. The result is that there will be sometimes be some unnecessary rollbacks issued.
The bug didn't occur node-oracledb was linked with 12c client libraries due to this code that uses a new API available in 12c to indicate whether a connection has a transaction open.
Bottom line: use Oracle 12c client libraries if possible to get optimal behavior.
Updated OS X install instructions to work on El Capitan.
The instructions now use symbolic links in
/usr/local/lib
for the Oracle client libraries. This removes the need to setDYLD_LIBRARY_PATH
, which has some restrictions on it introduced in El Capitan.Display an error and prevent connection release while database calls are in progress.
This was a bigger transaction, that 'fixed' a number of seemingly random crashes which were occurring when applications released connections that were in fact still in use. Node-oracledb will now print an error and not release the connection, thus preventing a crash. Note that since the release fails, connection pools can max out in this scenario. If you experience the errors NJS-030, NJS-031 or NJS-032 you should fix your app so the connection release occurs after all database operations have concluded.
The new messages are:
"NJS-030: Connection cannot be released because Lob operations are in progress""NJS-031: Connection cannot be released because ResultSet operations are in progress""NJS-032: Connection cannot be released because a database call is in progress"
Fixed an intermittent crash while selecting data from CLOB column.
We had an incorrect buffer expansion ratio in use. This has been fixed.
Fixed crash when trying to set invalid values for connection properties.
Enough said.
Work for node-oracledb 1.6 will begin. We are trying to reproduce and understand some reported LOB issues and memory growth reports. We're also looking forward to evaluating a big pull request from Dieter Oberkofler that addsPL/SQL bind support.
Issues and questions about node-oracledb can be posted on GitHub. We value your input to help prioritize work on the add-on. Drop us a line!
node-oracledb installation instructions are here.
Node-oracledb documentation is here.
node-oracledb 1.6.0 is on NPM (Node.js add-on for Oracle Database)
In this release a comprehensive pull request by Dieter Oberkofler adds support for binding PL/SQL Collection Associative Array (Index-by) types. Strings and numbers can now be bound and passed to and from PL/SQL blocks. Dieter tells us that nowadays he only gets to code for a hobby - keep it up Dieter!
Using PL/SQL Associative Arrays can be a very efficient way of transferring database between an application and the database because it can reduce the number of 'round trips' between the two.
As an example, consider this table and PL/SQL package:
CREATE TABLE mytab (numcol NUMBER); CREATE OR REPLACE PACKAGE mypkg IS TYPE numtype IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; PROCEDURE myinproc(p IN numtype); END; / CREATE OR REPLACE PACKAGE BODY mypkg IS PROCEDURE myinproc(p IN numtype) IS BEGIN FORALL i IN INDICES OF p INSERT INTO mytab (numcol) VALUES (p(i)); END; END; /
With this schema, the following JavaScript will result inmytab
containing five rows:
connection.execute("BEGIN mypkg.myinproc(:bv); END;", { bv: { type : oracledb.NUMBER, dir: oracledb.BIND_IN, val: [1, 2, 23, 4, 10] } }, function (err) { . . . });
There is a fuller example in examples/plsqlarray.sql and check out the documentation.
Other changes in node-oracledb 1.6 are
@KevinSheedy sent a GitHub Pull Request for the README to help the first time reader have the right pre-requisites and avoid the resulting pitfalls.
Fixed a LOB problem causing an uncaught error to be generated.
- Removed the 'close' event that was being generated for LOB Writables Streams. The Node.js Streams doc specifies it only for Readable Streams.
Updated the LOB examples to show connection release.
Extended the OS X install section with a way to install on El Capitan that doesn't need root access for Instant Client 11.2. Thanks to @raymondfeng for pointing this out.
Added RPATH to the link line when building on OS X in preparation for future client.
TypeScript users will be happy to hear Richard Natal recently had anode-oracledb TypeScript type definition file added to the DefinitelyTyped project. This is not part of node-oracledb itself but Richard later mentioned he found a way it could be incorporated. Hopefully he will submit a pull request and it will make it directly to the project so it can be kept in sync.
Thanks to everyone who has worked on this release and kept the momentum going.
What's coming up for the next release? There is discussion about adding a JavaScript layer. This was kicked off by a pull request from Sagie Gur-Ari which has lead to some work by Oracle's Dan McGhan. See the discussion and let us know what you think. Having this layer could make it quicker and easier for JavaScript coders to contribute node-oracledb and do things like reduce API inconsistency, make it easier to add a promise API in future, and of course provide a place to directly add Sagie's Streaming query result suggestion that started the whole thing.
I know a few contributors have recently submitted the Oracle Contributor Agreement ready to do big and small things - every bit counts. I look forward to being able to incorporate your work.
I've heard a couple of reports that Node LTS 4.2.6 on Windows is having some issues building native add-ons. 0.10, 0.12, 5.x and 4.2.5 don't have issues. Drop me a line if you encounter a problem.
Issues and questions about node-oracledb can be posted on GitHub. We value your input to help prioritize work on the add-on. Drop us a line!
node-oracledb installation instructions are here.
Node-oracledb documentation is here.
Node-oracledb: Avoiding "ORA-01000: maximum open cursors exceeded"
Developers starting out with Node have to get to grips with the'different' programming style of JavaScript that seems to cause methods to be
called when least expected! While you are still in the initial
hacking-around-with-node-oracledb phase you may sometimes encounter
the error ORA-01000: maximum open cursors exceeded
. A cursor is "a handle for the session-specific private SQL area that holds a parsed SQL statement and other processing information"
Here are things to do when you see an ORA-1000
:
Avoid having too many incompletely processed statements open at one time:
If cursors are opened with
dbms_sql.open_cursor()
in a PL/SQL block, close them before the block returns - except for REF CURSORS being passed back to node-oracledb. (And if a future node-oracledb version supports Oracle Database 12c Implicit Result Sets, these cursors should likewise not be closed in the PL/SQL block)Make sure your application is handling connections and statements in the order you expect.
Choose the appropriate Statement Cache size. Node-oracledb has a statement cache per connection. When node-oracledb internally releases a statement it will be put into the statement cache of that connection, but its cursor will remain open. This makes statement re-execution very efficient.
The cache size is settable with the
stmtCacheSize
attribute. The appropriate statement cache size you choose will depend on your knowledge of the locality of the statements, and of the resources available to the application: are statements re-executed; will they still be in the cache when they get executed; how many statements do you want to be cached? In rare cases when statements are not re-executed, or are likely not to be in the cache, you might even want to disable the cache to eliminate its management overheads.Incorrectly sizing the statement cache will reduce application efficiency. Luckily with Oracle 12.1, the cache can be automatically tuned using an
oraaccess.xml
file.More information on node-oracledb statement caching ishere.
Don't forget to use bind variables otherwise each variant of the statement will have its own statement cache entry and cursor. With appropriate binding, only one entry and cursor will be needed.
Set the database's
open_cursors
parameter appropriately. This parameter specifies the maximum number of cursors that each "session" (i.e each node-oracle connection) can use. When a connection exceeds the value, theORA-1000
error is thrown. Documentation onopen_cursors
is here.Along with a cursor per entry in the connection's statement cache, any new statements that a connection is currently executing, or ResultSets that haven't been released (in neither situation are these yet cached), will also consume a cursor. Make sure that
open_cursors
is large enough to accommodate the maximum open cursors any connection may have. The upper bound required isstmtCacheSize
+ the maximum number of executing statements in a connection.Remember this is all per connection. Also cache management happens when statements are internally released. The majority of your connections may use less than
open_cursors
cursors, but if one connection is at the limit and it then tries to execute a new statement, that connection will getORA-1000: maximum open cursors exceeded
.
Node in the Cloud: Oracle DBaaS, App Container Cloud and node-oracle
The node-oracledb driver is pre-installed on the Oracle Application Container Cloud when you create a Node service! Yay!
I've posted a video on deploying a Node application to the cloud and connecting to Oracle Database Cloud Service. (Blatent plug: subscribe to the YouTube channel!)
The brief summary is that I developed a Node application in my local environment. I then created a database service, I zipped all the JavaScript files along with a manifest telling the App Container Cloud which source file to run, amd this zip was uploaded to a Node cloud service. DB credentials are referenced in the app by environment variables; the variables are made available by the App Container Cloud when a DBaaS instance is associated with it.
You can try it all out by applying for a 30 day free trial on the Oracle Cloud.
All the JavaScript modules except native add-ons like node-oracledb should be included in your application zip bundle - you might have been developing on a different OS than used in the container so native adds-on won't work. The container simply unzips your bundle and runs. It will find the node-oracledb installed globally on the container just fine.
node-oracledb 1.7.0 has a connection pool queue (Node.js add-on for Oracle Database)
Node-oracledb 1.7.0, the Node.js add-on for Oracle Database, is onNPM.
Top features: a new connection pool queue to make apps more resilient, and "Bind by position" syntax for PL/SQL Index-by array binds.
This release has a couple of interesting changes as well as some small bind fixes. A few reported build warnings with some compilers were also squashed.
Extended PL/SQL Index-by Array Bind Syntax
To start with, a followup PR from @doberkofler completes his PL/SQL Index-by array binding support project. In node-oracledb 1.7 he has added "bind by position" syntax to the already existing "bind by name" support. Thanks Dieter! The "bind by position" syntax looks like:
connection.execute("BEGIN mypkg.myinproc(:id, :vals); END;", [ 1234, { type: oracledb.NUMBER, dir: oracledb.BIND_IN, val: [1, 2, 23, 4, 10] } ], function (err) { . . . });
Personally I'd recommend using bind by name for clarity, but this PR makes the feature congruent with binding scalar values, which is always a good thing.
Documentation is at PL/SQL Collection Associative Array (Index-by) Bind Parameters.
New Transparent JavaScript Wrapper for Existing Classes
The other major change in 1.7 is a new JavaScript wrapper over the current node-oracledb C++ API implementation, courtesy of some community discussion and the direction that users seemed to have been heading in: creating similar wrappers. It was also the result of some'above and beyond' overtime from Dan McGhan who did the project. This wrapper should be transparent to most users. It gives a framework that will make it easier to extend node-oracledb in a consistent way and also let developers who know JavaScript better than C++ contribute to node-oracledb.
New Connection Pool Queue Enabled by Default
The layer has let Dan add his first new user feature: a request
queue for connection pooling. It is enabled by a new Boolean pool attributequeueRequests
. If a pool.getConnection()
request is made but there are no free connections (aka sessions) in
the pool, the request will now be queued until an in-use connection is
released back to the pool. At this time the first request in the
queue will be dequeued, and the underlying C++ implementation ofpool.getConnection()
will be called to return the now
available connection to the waiting requester.
A second new pool attribute queueTimeout
usessetTimeout
to automatically dequeue and return an error
for any request that has been waiting in the queue too long. The
default value is 60000 milliseconds, i.e. 60 seconds. In normal
cases, when requests are dequeued because a connection does become
available, the timer is stopped before the underlying C++ layer gets
called to return the connection.
The pool queue is enabled by default. If it is turned off, you get
pre-1.7 behavior. For example if more requests are concurrently
thrown at an app than the poolMax
value, then some of thepool.getConnection()
calls would likely return an errorORA-24418: Cannot open further sessions
. When enabled,
the new queue nicely stops this error occurring and lets apps be more
resilient.
The pool option attribute _enableStats
turns on
lightweight gathering of basic pool and queue statistics. It is false
by default. If it is enabled, applications can output stats to the
console by calling pool._logStats()
whenever needed. I
think it will be wise to monitor the queue statistics to make sure your
pool configuration is suitable for the load. You don't want the queue
to be an invisible bottle neck when too manypool.getConnection()
requests end up in the queue for too
long. Statistics and the API may change in future, so the attribute
and method have an underscore prefix to indicate they are
internal.
Connection Queue Example
To look at an example, I used ab
to throw some load at
an app based on examples/webapp.js
I used a load concurrency of 25
parallel requests. The pool had a maximum of 20 sessions in its pool.
The extra load was nicely handled by the connection queue without the
application experiencing any connection failures.
I'd modified the app to check for a particular URL and dump statistics on request:
. . . var hs = http.createServer ( function(request, response) { var urlparts = request.url.split("/"); var arg = urlparts[1]; if (arg === 'stats') { pool._logStats(); } . . .
Here is snapshot of the output from _logStats()
at one
point during the test:
Pool statistics: ...total connection requests: 26624147 ...total requests enqueued: 5821874 ...total requests dequeued: 5821874 ...total requests failed: 0 ...total request timeouts: 0 ...max queue length: 6 ...sum of time in queue (milliseconds): 13920717 ...min time in queue (milliseconds): 0 ...max time in queue (milliseconds): 1506 ...avg time in queue (milliseconds): 2 ...pool connections in use: 12 ...pool connections open: 20 Related pool attributes: ...queueRequests: true ...queueTimeout (milliseconds): 0 ...poolMin: 10 ...poolMax: 20 ...poolIncrement: 10 ...poolTimeout: 0 ...stmtCacheSize: 30 Related environment variables: ...process.env.UV_THREADPOOL_SIZE: undefined
The connection pool was semi-arbitrarily configured for testing.
It started out with 10 sessions open (poolMin
) and as
soon as they were in use, the pool would have grown by another 10
sessions (poolIncrement
) to the maximum of 20
(poolMax
).
What the stats show is that not allpool.getConnection()
requests could get a pooled
connection immediately. About 20% of requests ended up waiting in the
queue. The connection pool poolMax
is smaller than
optimal for this load.
If this were a real app, I might decide to increasepoolMax
so no pool.getConnection()
call ever
waited. (I might also want to set poolTimeout
so that
when the pool was quiet, it could shrink, freeing up DB resources.)
However the average wait time of 2 milliseconds is small. If I don't
have DB resources to handle the extra sessions from a bigger pool, I
might decide that a 2 millisecond wait is OK and that the pool size is
fine.
At least one connection spent 1.5 seconds in the queue. Since I
know my test infrastructure I'm guessing this was when the pool ramped
up in size and my small, loaded DB took some time to create the second
set of 10 sessions. Maybe I should experiment with a smallerpoolIncrement
or bigger poolMin
?
Another important variable shown in the stats isUV_THREADPOOL_SIZE
. I'd not set it so there were the
default four worker threads in the Node process. Blindly increasingpoolMax
may not always help throughput. If DB operations
take some time, you might find all threads get blocked waiting for
their respective DB response. Increasing UV_THREADPOOL_SIZE
may help improve application
throughput.
The best settings for pool configuration,UV_THREADPOOL_SIZE
, and any DRCP pool size will depend on
your application and environment.
Connection Pool Queue Statistics
The table below shows the node-oracledb 1.7 pool statistics descriptions. These stats and the APIs to enable and log them may change in future versions of node-oracledb. I look forward to getting some PRs, for example to add a standard logging capability which the stats generation can be part of.
Connection Pool Metric | Description |
---|---|
total connection requests | Number of |
total requests enqueued | Number of connections that couldn't be satisfied because every session in the the pool was already being used, and so they had to be queued waiting for a session to be returned to the pool |
total requests dequeued | Number of
connection requests that were removed from the queue when a free
connection has become available. This is triggered when the app has
finished with a connection and calls |
total requests failed | Number of
connection calls that invoked the underlying C++ |
total request timeouts | Number of connection
requests that were waiting in the queue but exceeded the |
max queue length | Maximum number of connection requests that were ever waiting at one time |
sum of time in queue | Total sum of time that connection requests have been waiting in the queue |
min time in queue | Smallest amount of time that any request waited in the queue |
max time in queue | Longest amount of time that any request waited in the queue |
avg time in queue | Derived from the sum of time value divided by the number of requests enqueued |
pool connections in use | A metric returned by the underlying Oracle C client session pool implementation. It is the number of currently active connections in the connection pool |
pool connections open | Also returned by the underlying library. It shows the number of currently open sessions in the underlying connection pool |
Note that the sum of time in queue
, the min time
in queue
and the max time in queue
values are
calculated when queued requests are removed from the queue, so they
don't record the amount of time for requests still waiting in the
queue.
Resources
Issues and questions about node-oracledb can be posted on GitHub. We value your input to help prioritize work on the add-on. Drop us a line!
node-oracledb installation instructions are here.
Node-oracledb documentation is here.
Using SQL*Plus Instant Client 11.2 on OS X El Capitan
The installation steps for using SQL*Plus 11.2 (Instant Client) and
other OCI-based applications has necessarily changed since OS X El
Capitan broke DYLD_LIBRARY_PATH
. The updated instructions are
given on the Instant
Client Downloads for Mac OS X (Intel x86) page.
Here they are repeated. The steps also work on earlier versions of OS X:
Download the desired Instant Client ZIP files from OTN. All installations require the Basic or Basic Lite package.
Unzip the packages into a single directory such as "~/instantclient_11_2". For example, to use SQL*Plus:
cd ~ unzip instantclient-basic-macos.x64-11.2.0.4.0.zip unzip instantclient-sqlplus-macos.x64-11.2.0.4.0.zip
Create the appropriate libclntsh.dylib link for the version of Instant Client. For example:
cd ~/instantclient_11_2 ln -s libclntsh.dylib.11.1 libclntsh.dylib
Note: OCCI programs will additionally need:
ln -s libocci.dylib.11.1 libocci.dylib
Add links to "~/lib" for required Basic package libraries. For example, to use OCI programs (including SQL*Plus, Python's cx_Oracle, PHP's OCI8, Node.js's node-oracledb, and Ruby's ruby-oci8 driver):
mkdir ~/lib ln -s ~/instantclient_11_2/libclntsh.dylib.11.1 ~/lib/ ln -s ~/instantclient_11_2/{libnnz11.dylib,libociei.dylib} ~/lib/
To run SQL*Plus, add its libraries to "~/lib", and update PATH. For example:
ln -s ~/instantclient_11_2/{libsqlplus.dylib,libsqlplusic.dylib} ~/lib/ export PATH=~/instantclient_11_2:$PATH
Node-oracledb 1.8 has a streaming mode for queries (Node.js add-on for Oracle Database)
Node-oracledb 1.8.0, the Node.js add-on for Oracle Database, is onNPM.
Top new changes: New Query Result Streaming. Use DRCP connect strings only with a connection pool.
I want to start by saying thanks to all contributors past and current! It is the community that defines the product.
Query Result Streaming
Node Streams can now be used for queries after a pull request from Sagie Gur-Ari was merged. A new connection.queryStream() method returns a Readable Stream. Of course, if you prefer callbacks, the existing ResultSet feature can continue to be used.
The new query stream feature is implemented as a wrapper around the
ResultSet Class. In particular it uses resultset.getRows()
to fetch a subset of data, each
row of which will generate a data
event. The only reason
to understand this is that getRows()
takes a parameter to
specify how many rows to fetch. We had some (well, a lot of) debate
about to set this value and keep the API simple. For the moment, the
value of oracle.maxRows
is used. Note the value does not
affect how many rows are returned by streamQuery()
events
because getRows()
will be repeatedly called when more
rows are needed. Instead, this parameter is used to tune stream
performance. In the near future, when PR 361
is reviewed, we may introduce a specialized tuning parameter.
We also want to look at ways of interrupting the streams early.
But, in node-oracledb 1.8, make sure to read to the end of the query to
avoid leaking a cursor. The ResultSet close()
is
executed internally; you do not need to call it to release ResultSet
resources.
An example of query streaming is:
var stream = connection.queryStream('SELECT first_name, last_name FROM employees ORDER BY employee_id' ); stream.on('error', function (error) { console.error(error); return; }); stream.on('metadata', function (metadata) { console.log(metadata); }); stream.on('data', function (data) { console.log(data); }); stream.on(end, function () { connection.release( function(err) { if (err) { console.error(err.message); } }); });
There is a runnable example in examples/selectstream.js. Other useful examples are in the test file test/stream1.js.
Use DRCP Connect Strings Only With a Connection Pool
In node-oracledb 1.8 you must now use a connection pool if your connect string requests a DRCP connection. Previously this was just a best practice. Now it is enforced.
Connect strings that request DRCP connections look either like:
connectString : "mymachine/mydbservice:pooled"
or
connectString : "SALES"
where the SALES
connect identifier maps to atnsnames.ora
entry specifying SERVER=POOLED
,
for example:
SALES=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=mymachine) (PORT=1521))(CONNECT_DATA=(SERVICE_NAME=mydbservice) (SERVER=POOLED)))
If you try oracledb.getConnection(...)
you will get an
error ORA-56609: Usage not supported with DRCP
.
Instead use a connection pool, see node-oracledb Connection Pooling documentation:
oracledb.createPool ( { user : "hr" password : "welcome" connectString : "mymachine/mydbservice:pooled" }, function(err, pool) { pool.getConnection ( function(err, connection) { . . . // use connection }); });
In the unlikely case where the Node process is short-lived and you
really, really just want a single connection, create a pool with a
single session; the createPool()
option attributes can
be: poolMax: 1, poolMin: 1, poolIncrement: 0
Millisecond Precisions
A pull request from Antonio Bustos has helped make some tests more portable by removing some time ambiguity. The Oracle DATE data type does not contain milliseconds. If an application inserts a JavaScript date with milliseconds, the DATE tests will now only compare the non-millisecond date components to validate results.
Windows Debug Builds
Kubo Takehiro (who is the maintainer of the popular Ruby ruby-oci8 extension) spotted a hierarchy problem with node-oracledb Windows Debug build options. The binding.gyp entry has now been fixed.
Other Changes
The driver name is now set to "node-oracledb : 1.8.0". This is
visible to DBAs, for example in theV$SESSION_CONNECT_INFO
view. It lets DBAs see what apps,
and what versions, are connecting to the database.
The pool queue stats now show the start time of the pool. A couple of parameter check bugs were also fixed. See CHANGELOG for details.
Resources
Issues and questions about node-oracledb can be posted on GitHub. We value your input to help prioritize work on the add-on. Drop us a line!
node-oracledb installation instructions are here.
Node-oracledb documentation is here.
PHP OCI8 2.0.11 and 2.1.1 are available on PECL
I've released PHP OCI8 2.0.11 (for supported PHP 5.x versions) and 2.1.1 (for PHP 7) to PECL. Windows DLLs on PECL been built by the PHP release team. The updated OCI8 code has also been merged to the PHP source branches and should land in the future PHP 5.6.21 and PHP 7.0.7 source bundles, respectively.
PHP OCI8 2.1.1 fixes a bug triggered by usingoci_fetch_all()
with a query having more than eight
columns. To install on PHP 7 via PECL, use pecl install
oci8
PHP OCI8 2.0.11 has one fix for a bind regression with 32-bit PHP.
To install on PHP 5.x use pecl install oci8-2.0.11
My old Underground PHP and Oracle Manual still contains a lot of useful information about using PHP with Oracle Database. Check it out!
node-oracledb 1.9.0-Dev Branch with Promises is on GitHub
Top features: Promise support
node-oracledb 1.9.0-Development is now available only as a development-only branch on GitHub. It adds Promise support and some other goodies mentioned below. The plan is to incorporate any user feedback, stabilize the features, improve documentation, improve test covereage, and run stress tests. Once this is all done, then a production release to npm will be made. Personally I think this will take 2-4 weeks, but it is totally dependent on what is uncovered by you, the user.
Since this is a development branch, features are subject to change. Use GitHub Issue #410 to ask design questions and discuss the branch.
Install by setting OCI_LIB_DIR
and OCI_INC_DIR
as normal, and running npm install oracle/node-oracledb.git#dev-1.9
. Or install from GitHub by cloning the repository,
checking out the dev-1.9 branch, setting OCI_LIB_DIR
and OCI_INC_DIR
, and install with npm install
Anyone is welcome to report test results, contribute new tests or update documentation (or code!) to help us get a production release out faster. You do need to have your OCA accepted first before we can look at any pull requests.
As you can see, most of the doc is ready, and there are a solid number of tests for new functionality. You can help us by testing your own favorite Promise library, as we are only planning on testing the default Promise implementation in Node 0.12, 4 and 5. Also check out how connections are handled as you may like a different style - let us know.
In node-oracledb 1.9-dev:
Promise support was added. All asynchronous functions can now return promises. The default Promise library is used for Node 0.12, 4 and 5. It can be easily overridden if you wish to incorporate your own implementation.
The current implemention typically requires two promise chains. Let us know what you think. There are solutions that could be made. What do you want?
A new
toQueryStream()
method was added. It is for ResultSets. It lets REF CURSORS be transformed into Readable Streams. It can also be used to convert ResultSets from top-level queries to streams, however the existingconnection.queryStream()
method will probably be easier to use for these queries.An experimental query Stream
_close()
method was added. It allows query streams to be closed without needing to fetch all the data. It is marked experimental because there isn't good information about whether the current Node Streams implementation really allows interruptions.Open question: Should _close() invoke pause() internally?
Aliases
pool.close()
andconnection.close()
have been added forpool.terminate()
andconnection.release()
respectively. This should make it easier to remember which method to use for releasing a connection, terminating a connection pool, or closing a ResultSet: you can just useclose()
.Some method parameter validation checks, such as the number or types of parameters, will now throw errors synchronously instead of returning errors via the callback.
Removed an extra call to
getRows()
made byqueryStream()
at end-of-fetch.Some annoying, seemingly random crashes caused by connections being garbage collected while still in use should no longer occur. These were more common in smaller scripts that finished quickly, but could be seen in systems under load.
Resources
Issues and questions about node-oracledb can be posted on GitHub. We value your input to help prioritize work on the add-on. Drop us a line!
node-oracledb installation instructions are here.
Node-oracledb documentation is here.
Getting a C++11 compiler for Node 4, 5 and 6 on Oracle Linux 6
A newer compiler is needed on Oracle Linux 6 when you want to use add-ons like node-oracledb with Node 4 or later. This is because add-ons for those versions need to be built with a C++11 compatibile compiler. The default compiler on OL 6 doesn't have this support. OL 7 does have such a compiler, so these instructions are not needed for that version.
For OL 6 the easist way to get a new compiler is from the Software Collection Library (SCL). You enable the software
collection yum channel, run a yum install
command, and
then the compiler is immediately available to use. Detailed
installation SCL instructions are in the manual.
The steps below show how to install node-oracledb on Oracle Linux 6 for Node.js 4 or later.
Enabling the Software Collection Library
If you are using yum.oracle.com
(formerly known aspublic-yum.oracle.com
) then edit/etc/yum.repos.d/public-yum-ol6.repo
and enable theol6_software_collections
channel:
[ol6_software_collections] name=Software Collection Library release 1.2 packages for Oracle Linux 6 (x86_64) baseurl=http://yum.oracle.com/repo/OracleLinux/OL6/SoftwareCollections12/x86_64/ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle gpgcheck=1 enabled=1
If necessary, you can get the latest channel list fromhttp://yum.oracle.com/public-yum-ol6.repo
and merge any
updates from it into your existing/etc/yum.repos.d/public-yum-ol6.repo
file.
Alternatively, if your machine has a ULN support subscription, you can subscribe to the Oracle Software Collections 1.2 for Oracle Linux 6 channel in the Manage Subscription page on linux.oracle.com.
Installing the Updated Compiler
Once the channel is enabled, install the updated compiler with:
yum install scl-utils devtoolset-3
This will install a number of packages that comprise the complete, updated tool set.
Installing node-oracledb
Installing node-oracledb on Node 4 (or later) is the same as in install instuctions, but using the new compiler. The Oracle Linux manual chapter Using the Software Collection Version of a Command shows various ways to enable the dev toolset.
In summary, to install node-oracledb on Node 4 or later using Oracle Linux 6, first install an Oracle client such as Instant Client. If you have anything except the Instant Client RPM packages, tell the installer where the libraries and header files are located, for example:
export OCI_LIB_DIR=$HOME/instantclient export OCI_INC_DIR=$HOME/instantclient/sdk/include
If you are behind a firewall, set your proxy:
export http_proxy=http://my.proxy.example.com:80/
In my development environments I often find some cleanup helps:
which npm && rm -rf $(npm root)/oracledb $(npm root)/nan $HOME/.node-gyp $HOME/.npm \&& npm cache clean
Now node-oracledb can be installed using the newer compiler:
scl enable devtoolset-3 -- npm install oracledb
Using Node
Now you can use Node:
$ node version.js node.js version: v4.4.3 node-oracledb version: 10900 node-oracledb text format: 1.9.0 oracle client library version: 1201000200 oracle client library text format: 12.1.0.2.0 oracle database version: 1201000200 oracle database text format: 12.1.0.2.0 $ cat /etc/oracle-release oracle linux server release 6.7
Emoji? Look at the Oracle New Gen Developers
Forget emoji, look at the Oracle New Gen Developers!

Node-oracledb 1.9.1 with Promises and Node 6 Support is on NPM
Top features: Promise support. Node 6 support.
The new node-oracledb 1.9.1 release adds Promise support, it now supports the new Node 6 (as well as previous releases), and it has some welcome stability fixes. Other nice goodies are mentioned below. Thanks to everyone who gave feedback on our 1.9.0 development branch - we couldn't have done it without you.
node-oracledb 1.9.1 is now available on NPM. Installation instructions are here. Documentation is here.
The changes in node-oracledb 1.9.1 since 1.8
Promise support was added. All asynchronous functions can now optionally return Promises. When asynchronous functions are passed with a callback function parameter, the familiar callback flow is used. If the callback parameter is omitted, then a Promise is returned. There are some examples in the examples directory, see promises.js and webapppromises.js.
Node Promises allow a programming paradigm that many Node users find comfortable. Some users had implemented their own Promise wrappers for node-oracledb; a few had even been published on NPM. Now the official implementation makes Promises available to everyone.
The default Promise library is used for Node 0.12, 4, 5 and 6. It can be easily overridden if you wish to incorporate your own implementation. This is also useful for Node 0.10 where there is no native library.
A new
toQueryStream()
method was added for ResultSets. It lets REF CURSORS be fetched via Readable Streams. See the example refcursortoquerystream.jsIt can also be used with ResultSets from top-level queries, allowing them to be converted to streams. However the existing
connection.queryStream()
method will probably be easier to use in this scenario.Aliases
pool.close()
andconnection.close()
have been added forpool.terminate()
andconnection.release()
respectively. This should make it easier to remember which method to use for releasing a connection, terminating a connection pool, or closing a ResultSet: you can just useclose()
.An experimental query Stream
_close()
method was added. It allows query streams to be closed without needing to fetch all the data. It is marked experimental because there isn't good information about how safe interrupting the current Node Streams implementation is.Calling
_close()
invokespause()
, if necessary. On Node 0.10 you may get a pause event even if you had previously paused the stream. This is because Node 0.10 doesn't support theisPaused()
call.Upgraded to NAN 2.3 for Node 6. This removes the deprecation warnings that Node 6 was generating with the older NAN 2.2.
Older versions of Node can still be used, of course.
Mitigated some annoying, seemingly random crashes if JavaScript objects were garbage collected too early. While many well programmed apps naturally hold the relevant JavaScript objects until no longer required, other apps don't. Premature garbage collection could affect these latter scripts if they finished quickly or when under load.
A similar change was made to Lob buffers used during LOB insertion.
Memory 'improvements':
Fixed some memory leaks when using ResultSets.
Fixed a memory leak with the Pool queue timer map.
Fixed memory release logic when querying LOBs and an error occurs.
Removed an extra call to
getRows()
made byqueryStream()
at end-of-fetch.Error changes:
Some method parameter validation checks, such as the number or types of parameters, will now throw errors synchronously instead of returning errors via the callback.
Improved validation for
fetchInfo
usage.Increased the internal buffer size for Oracle Database error messages.
Altered some node-oracledb NJS-xyz error message text for consistency.
The test suite is no longer automatically installed when installing with
npm install oracledb
from NPM. The test suite was (and will be) getting bigger and bigger. It is not being used by most people, so installing it automatically is wasteful.You can still run the tests using a GitHub clone. The updated test README has instructions for this. To allow tests to be moved and run anywhere, we left the tests'
require('oracledb')
calls without a path prefix so you may need to setNODE_PATH
as described.Fixed a symbol name redefinition warning for
DATA_BLOB
when compiling on Windows.
Overall node-oracledb 1.9.1 is a significant milestone with the addition of Promise support, the support for Node 6, and the general resiliency changes. I'm very happy with this release and would encourage upgrading to it.
What's Next?
What's next? There are still lots of enhancements for node-oracledb on the wish list. Please let us know your priorities.
Issues and questions about node-oracledb can be posted on GitHub. Your input helps us schedule work on the add-on. Drop us a line!
Using Oracle on OS X? Instant Client 12.1 is here
Oracle Instant Client 12.1 for OS X was just released and is now available for free download from OTN for 32-bit and 64-bit applications.
Instant Client provides libraries and tools for connecting to Oracle Database. Among other uses, languages such as C, Python, PHP, Ruby, Perl and Node.js can use Instant Client for database connectivity.
In addition to having Oracle 12.1 client features like auto-tuning, new in this release is an ODBC driver.
The install instructions have been updated to reflect the resolution
of the linking issues caused by the OS X El Capitan changes with SIP
to ignore DYLD_LIBRARY_PATH
in sub processes. The~/lib
location required for Instant Client 11.2 on El
Capitan is no longer needed with Instant Client 12.1. Note if you are
creating your own apps, you should link with -rpath
.
This release of Instant Client supports Mavericks, Yosemite, and El Capitan. Applications can connect to Oracle Database 10.2 or more recent. You should continue using the older 11.2 client if you need to connect to Oracle Database 9.2.
Questions and comments can be posted to the OTN forum for whichever component or tool you are using. General questions about Instant Client are best posted to the OCI Forum.
If you are interested in running Oracle Database itself on OS X, see my earlier post The Easiest Way to Install Oracle Database on Mac OS X.
Node-oracledb 1.10 has Enhanced Metadata
Top feature: Enhanced Metadata
The changes in node-oracledb 1.10 are:
Enhanced query metadata thanks to a Pull Request from Leonardo. He kindly allowed us to take over and fine tune the implementation.
Additional metadata for query and REF CURSOR columns is available in the
metaData
object when the new booleanoracledb.extendedMetaData
attribute or correspondingexecute()
option attributeextendedMetaData
aretrue
.For example, if the
DEPARTMENTS
table is like:SQL> desc departments Name Null? Type ----------------------------------------- -------- ---------------------------- DEPARTMENT_ID NOT NULL NUMBER(4) DEPARTMENT_NAME NOT NULL VARCHAR2(30) MANAGER_ID NUMBER(6) LOCATION_ID NUMBER(4)
Then a query in node-oracledb would give extended metadata:
[ { name: 'DEPARTMENT_ID', fetchType: 2002, dbType: 2, precision: 4, scale: 0, nullable: false }, { name: 'DEPARTMENT_NAME', fetchType: 2001, dbType: 1, byteSize: 30, nullable: false }, { name: 'MANAGER_ID', fetchType: 2002, dbType: 2, precision: 6, scale: 0, nullable: true }, { name: 'LOCATION_ID', fetchType: 2002, dbType: 2, precision: 4, scale: 0, nullable: true } ]
You can see that the available attributes vary with the database type. The attributes are described in the metaData documentation.
The commonly used column name is always available in
metaData
regardless of the value ofextendedMetaData
. This is consistent with previous versions.The metadata
dbType
andfetchType
attributes numbers are described in newDB_TYPE_*
constants and the existing node-oracledb type constants, respectively. Your code should use these constants when checking metadata types.Why did we make the extra metadata optional and off by default? Why do the types use numbers instead of strings? We had a lot of debate about common use cases, out-of-box experience, performance etc. and this is the way the cookie crumbled.
I know this enhancement will make your applications easier to maintain and more powerful.
Fixed an issue preventing the garbage collector cleaning up when a query with LOBs is executed but LOB data isn't actually streamed.
Report an error earlier when a named bind object is used in a bind-by-position context. A new error NJS-044 is returned. Previously errors like ORA-06502 were given since the expected attributes were not found and bind settings ended up as defaults. You can still use unnamed objects for bind-by-position binds like:
var sql = "begin myproc(:1, :2, :3); end;"; var binds = [ id, name, { type: oracledb.STRING, dir: oracledb.BIND_OUT } ];
Here the third array element is an unnamed object.
Fixed a bug where an error event could have been emitted on a QueryStream instance prior to the underlying ResultSet having been closed. This would cause problems if the user tried to close the connection in the error event handler as the ResultSet could have prevented it.
Fixed a bug where the public close method was invoked on the ResultSet instance that underlies the QueryStream instance if an error occurred during a call to getRows. The public method would have thrown an error had the QueryStream instance been created from a ResultSet instance via the toQueryStream method. Now the call to the C layer close method is invoked directly.
Updated
Pool._logStats
to throw an error instead of printing to the console if the pool is not valid.Added GitHub Issue and Pull Request templates.
Updated installation instructions for OS X using the new Instant Client 12.1 release.
Added installation instructions for AIX and Solaris x64.
Some enhancements were made to the underlying DPI data access layer. These were developed in conjuction with a non- node-oracledb consumer of DPI, but a couple of changes lay groundwork for potential, user-visible, node-oracledb enhancements:
Allow
SYSDBA
connectionsAllow session tagging
Allow the character set and national character set to be specified via parameters to the DPI layer
Support heterogeneous pools (in addition to existing homogeneous pools)
To reiterate, these are not exposed to node-oracledb.
Resources
Issues and questions about node-oracledb can be posted on GitHub. Your input helps us schedule work on the add-on. Drop us a line!
node-oracledb installation instructions are here.
Node-oracledb documentation is here.
Node-oracledb 1.10.1 Released to NPM
We've pushed out a patch release of node-oracledb to GitHub and NPM. It has a bind fix that didn't land in time for 1.10.0. A memory leak regression with REF CURSORs was also fixed, as was a pre-existing memory leak in the unexpected case of a REF CURSOR failure.
The changes in node-oracledb 1.10.1 are:
Fixed a bug that prevented a null value being passed from JavaScript into an IN OUT bind.
Fixed a memory leak introduced in 1.10 with REF CURSORs.
Fixed an existing memory leak problem if an error happens when fetching REF CURSORs.
Added a mocha configuration file for the test suite. The test suite README has updated instructions on how to add tests.
As a side effect, the tests now run in numeric order.
A couple of other internal improvements are shown in the CHANGELOG.
Resources
Issues and questions about node-oracledb can be posted on GitHub. Your input helps us schedule work on the add-on. Drop us a line!
Node-oracledb installation instructions are here.
Node-oracledb API and user documentation is here.