DBIx::Class::Async - Oracle Database

4 min read
← Back to Blogs
DBIx::Class::Async - Oracle Database

DISCLAIMER: Image is generated using ChatGPT.



It has been a long time since I shared an update regarding DBIx::Class::Async. The reason is simple: no known critical issues have been reported. While DBIx::Class::Async v0.65 is officially still experimental, it is quite stable. I am not in a rush to declare it production ready just yet.

However, yesterday, I received an email regarding the project…

Email Notice

To be honest, as of v0.65, I haven’t done any testing against an Oracle database. I wasn’t entirely sure how to reply to the email, but my first thought was to add basic tests for Oracle database interaction.

There was just one big issue: I didn’t have a working Oracle database to begin with, and setting one up from scratch isn’t something I’m willing to do right now.

So, what other options did I have then? My good old friend, the Docker container.

Before doing anything else, I needed to create an Oracle account by visiting this page. Once that was done, I had to create an auth token to use with the container. You can find the page to generate the token here.

With that settled, we are now ready to spin up a Docker container for the Oracle database.

$ docker run -d \
             --name oracle-test \
             -p 1521:1521 \
             -e ORACLE_PWD=testpass \
             container-registry.oracle.com/database/free:latest

Please give couple of minutes to let the database engine to a healthy state.

$ dps
Container ID: 1bc24c6e0738
Image: container-registry.oracle.com/database/free:latest
Command: "/bin/bash -c $ORACL…"
Created: 2026-04-30 23:51:00 +0100 BST
Status: Up 2 minutes (healthy)
Ports: 0.0.0.0:1521->1521/tcp, [::]:1521->1521/tcp
Names: oracle-test

Let’s create test user in the docker container.

$ docker exec -it oracle-test sqlplus sys/testpass@FREEPDB1 as sysdba

SQL*Plus: Release 23.26.1.0.0 - Production on Thu Apr 30 23:53:47 2026
Version 23.26.1.0.0

Copyright (c) 1982, 2025, Oracle.  All rights reserved.


Connected to:
Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free
Version 23.26.1.0.0

SQL> CREATE USER dbictest IDENTIFIED BY dbictest123;

User created.

SQL> GRANT CONNECT, RESOURCE, UNLIMITED TABLESPACE TO dbictest;

Grant succeeded.

SQL> exit
Disconnected from Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free
Version 23.26.1.0.0

Time to setup Oracle client now.

$ mkdir -p ~/oracle/instantclient
$ docker cp oracle-test:/opt/oracle/product/26ai/dbhomeFree ~/oracle/instantclient
$ export ORACLE_HOME=~/oracle/instantclient/dbhomeFree
$ export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

In my local setup, I had to install few missing libraries and create softlink.

$ sudo apt-get install -y libaio1t64 libaio-dev
$ sudo ln -s /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/x86_64-linux-gnu/libaio.so.1
$ cpanm -vS DBD::Oracle
$ cpanm -vS Math::Base36

Let’s test the connection.

$ perl -e '
use DBI;
my $dbh = DBI->connect(
    "dbi:Oracle:host=localhost;port=1521;service_name=FREEPDB1",
    "dbictest", "dbictest123",
    { RaiseError => 1, AutoCommit => 1 }
);
print "Connected OK!\n";
$dbh->disconnect;
'

I see a, Connected OK! message, all good so far.

Now it’s time to create a unit test that covers basic operations with the Oracle database.

I decided to add the unit test, 001-oracle.t, to the xt/ subfolder to keep it separate from the standard test suite.

You can find the complete source code for the unit test here.

Now let’s prove the test.

$ export DBIC_ASYNC_ORACLE_DSN='dbi:Oracle:host=localhost;port=1521;service_name=FREEPDB1'
$ export DBIC_ASYNC_ORACLE_USER='dbictest'
$ export DBIC_ASYNC_ORACLE_PASS='dbictest123'
$ prove -lv xt/001-oracle.t
xt/001-oracle.t ..
ok 1 - 'Schema connected to Oracle' isa 'DBIx::Class::Async::Schema'
# Subtest: Basic CRUD — User
    ok 1 - An object of class 'DBIx::Class::Async::ResultSet' isa 'DBIx::Class::Async::ResultSet'
    ok 2 - 'create() returns a Row' isa 'DBIx::Class::Async::Row'
    ok 3 - name is correct
    ok 4 - email is correct
    ok 5 - id was assigned by Oracle sequence
    ok 6 - 'find() returns a Row' isa 'DBIx::Class::Async::Row'
    ok 7 - find() name matches
    ok 8 - update() name correct
    ok 9 - update() active correct
    ok 10 - Row is gone after delete()
    1..10
ok 2 - Basic CRUD — User
# Subtest: Search and count
    ok 1 - count() increased by 3 after creates
    ok 2 - 'search()->all() returns arrayref' isa 'ARRAY'
    ok 3 - At least 2 active users found
    ok 4 - search()->count() works on Oracle
    1..4
ok 3 - Search and count
# Subtest: Relationships — belongs_to and has_many
    ok 1 - 'order created' isa 'DBIx::Class::Async::Row'
    ok 2 - amount is correct
    ok 3 - FK user_id correct
    ok 4 - 'belongs_to returns Row' isa 'DBIx::Class::Async::Row'
    ok 5 - belongs_to correct user
    ok 6 - has_many returns 1 order
    ok 7 - has_many correct order
    1..7
ok 4 - Relationships — belongs_to and has_many
# Subtest: Transactions — txn_do
    ok 1 - txn_do committed both rows
    1..1
ok 5 - Transactions — txn_do
# Subtest: Concurrent async queries
    ok 1 - Concurrent count() returned a result
    ok 2 - 'Concurrent search()->all() returned arrayref' isa 'ARRAY'
    1..2
ok 6 - Concurrent async queries
1..6
ok
All tests successful.
Files=1, Tests=6,  1 wallclock secs ( 0.01 usr  0.00 sys +  0.18 cusr  0.09 csys =  0.28 CPU)
Result: PASS

Now it’s time to bundle the changes and upload them to CPAN.

Before, I do that, I want to switch to v-string versioning. Consequently, the next version will be v1.0.0.

The updated distribution is now available in the GitHub repository.


Happy Hacking !!!