Skip to content

feat(DBI): driver-architecture + pure-Perl DBD support#544

Closed
fglock wants to merge 1 commit intofix/dbi-verifier-fallbackfrom
fix/dbi-install-driver
Closed

feat(DBI): driver-architecture + pure-Perl DBD support#544
fglock wants to merge 1 commit intofix/dbi-verifier-fallbackfrom
fix/dbi-install-driver

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 22, 2026

Summary

Previously use DBI; DBI->install_driver("NullP") died with Undefined subroutine &DBI::install_driver. The bundled DBI.pm talked to the Java DBI backend only, bypassing the DBI driver architecture (DBD::<name>::driver factories, DBI::_new_drh / _new_dbh / _new_sth, DBD::_::common / dr / db / st base classes). That path covers JDBC drivers (SQLite, H2, ...) but not the pure-Perl DBDs bundled with upstream DBI — DBD::NullP, DBD::ExampleP, DBD::Sponge, DBD::Mem, DBD::File, DBD::DBM — which the DBI self-tests rely on extensively.

This PR adds the minimum driver-architecture pieces needed by those DBDs, in a new file src/main/perl/lib/DBI/_Handles.pm:

  • DBI->install_driver / installed_drivers / data_sources / available_drivers / setup_driver;
  • DBI::_new_drh / _new_dbh / _new_sth (handle factories, returning plain blessed hashrefs — no tie magic);
  • DBI::_get_imp_data (stub);
  • DBD::_::common / dr / db / st base classes with FETCH, STORE, err, errstr, state, set_err, trace, trace_msg, parse_trace_flag(s), func, dump_handle, visit_child_handles, default connect / connect_cached, quote, quote_identifier, data_sources, disconnect, commit, rollback, ping, finish, fetchrow_array, fetchrow_hashref, rows, bind_col(s), bind_param(_array), execute_array, _set_fbav;
  • Stub DBI::dr / DBI::db / DBI::st packages so isa('DBI::dr') succeeds; DBD::_::<suffix> inherits from DBI::<suffix>.

DBI.pm's connect wrapper now detects a pure-Perl DBD (has driver() but no _dsn_to_jdbc) and routes through install_driver($name)->connect(...) instead of the JDBC backend.

Lives in a separate .pm for the same per-method bytecode-size reason as DBI/_Utils.pm from #540.

Effect on jcpan -t DBI (stacked on #542)

Files Subtests Passing Failing
before 200 946 676 270
after 200 1600 1240 360

+564 subtests now pass, +654 more are reached. 10 fewer test files fail overall. The remaining failures are real DBI-level issues (DBI::PurePerl, DBD::File / DBM / Gofer, a handful of handle-tracking edge cases) tracked as Phase 3 in dev/modules/dbi_test_parity.md.

Depends on

Test plan

  • make (full unit tests) passes.
  • ./jperl -e 'use DBI; my $drh = DBI->install_driver("NullP"); my $dbh = DBI->connect("dbi:NullP:", "", ""); my $sth = $dbh->prepare("SELECT 1"); $sth->execute' now works.
  • ./jperl ~/.cpan/build/DBI-1.647-5/t/02dbidrv.t runs 37+ subtests (previously: died on line 155 with Can't locate object method install_driver).
  • jcpan -t DBI baseline matches the table above.

Generated with Devin

Previously `use DBI; DBI->install_driver("NullP")` died with
"Undefined subroutine &DBI::install_driver". The bundled DBI.pm
talked to the Java DBI backend only, bypassing the DBI driver
architecture (DBD::<name>::driver factories, DBI::_new_drh/dbh/sth,
DBD::_::common / dr / db / st base classes). That path covers JDBC
drivers (SQLite, H2, ...) but not the pure-Perl DBDs bundled with
upstream DBI — DBD::NullP, DBD::ExampleP, DBD::Sponge, DBD::Mem,
DBD::File, DBD::DBM — which the DBI self-tests rely on extensively.

This change adds the minimum driver-architecture pieces needed by
those DBDs, in a new file src/main/perl/lib/DBI/_Handles.pm:

  * DBI->install_driver / installed_drivers / data_sources /
    available_drivers / setup_driver;
  * DBI::_new_drh / _new_dbh / _new_sth (handle factories,
    returning plain blessed hashrefs — no tie magic);
  * DBI::_get_imp_data (stub);
  * DBD::_::common / dr / db / st base classes with FETCH, STORE,
    err, errstr, state, set_err, trace, trace_msg,
    parse_trace_flag(s), func, dump_handle, visit_child_handles,
    default connect / connect_cached, quote, quote_identifier,
    data_sources, disconnect, commit, rollback, ping, finish,
    fetchrow_array, fetchrow_hashref, rows, bind_col(s),
    bind_param(_array), execute_array, _set_fbav;
  * Stub DBI::dr / DBI::db / DBI::st packages so `isa('DBI::dr')`
    succeeds; DBD::_::<suffix> inherits from DBI::<suffix>.

DBI.pm's connect wrapper now detects a pure-Perl DBD (has `driver()`
but no `_dsn_to_jdbc`) and routes through
`install_driver($name)->connect(...)` instead of the JDBC backend.

Lives in a separate .pm for the same per-method bytecode-size
reason as DBI/_Utils.pm from PR #540.

Effect on `jcpan -t DBI` (stacked on PR #542):
  before: 200 files, 946 subtests, 676 passing, 270 failing
  after:  200 files, 1600 subtests, 1240 passing, 360 failing
  => +564 subtests now pass (+654 newly executed). 10 fewer test
     files fail overall; the remaining failures are real DBI-level
     issues (DBI::PurePerl, DBD::File/DBM/Gofer, a handful of
     handle-tracking edge cases) tracked as Phase 3 in the plan.

See dev/modules/dbi_test_parity.md.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock
Copy link
Copy Markdown
Owner Author

fglock commented Apr 22, 2026

Superseded by unified PR (see new PR). All four commits rebased into a single branch targeting master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant