NAME

DBIO::Storage::DBI::Capabilities - Two-tier capability probing for DBI storage drivers

VERSION

version 0.900001

DESCRIPTION

Capability detection for DBIO::Storage::DBI. Uses a two-tier accessor system:

A driver or user may define _use_X, which blindly without any checks says "(do not) use this capability" (use_dbms_capability is an inherited-type accessor).

If _use_X is undef, _supports_X is queried. This is a simple-style accessor which calls _determine_supports_X and stores the return in a slot on the storage object that is wiped on every $dbh reconnection (reconnection is not guaranteed to land on the same RDBMS version). _determine_supports_X does not need to exist on a driver — the runtime ->can-checks for it before calling.

The default capability list is below; drivers add their own with __PACKAGE__->mk_group_accessors(dbms_capability => '_supports_X').

CONTRACT VERSION

This class exposes an independent compatibility version, distinct from $VERSION (the dist version injected by Dist::Zilla's VersionFromMainModule):

my $v = $class->contract_version;

$CONTRACT_VERSION bumps when the capability-probing interface (the _supports_* / _use_* accessors, the default capability list, or the contract surface that drivers extend with new entries) changes. The dist $VERSION bumps on every release, but two core releases at the same contract version remain wire-compatible. Out-of-tree drivers should record the contract version they were last tested against and compare it against core's at load time, warning (or strict-failing under DBIO_STRICT_CONTRACT) when the shapes have drifted. See docs/adr/ for the contract-version policy.

CAPABILITY LIST

The default capability set is the following. Drivers add their own with __PACKAGE__->mk_group_accessors(dbms_capability => '_supports_X').

insert_returning / insert_returning_bound

INSERT ... RETURNING support.

multicolumn_in

Multi-column IN list optimisation.

placeholders / typeless_placeholders

Driver placeholder style.

join_optimizer

Join-order hinting. On by default; not strictly a capability.

transactional_ddl -- F02 / F10

True iff the engine runs DDL inside a normal transaction (i.e. txn_do { do_ddl() } is atomic). False if the engine forces an implicit COMMIT on DDL (MySQL, Oracle, DB2, Sybase, Informix) or depends on AutoCommit=on for in-place rebuilds (SQLite). DBIO::Deploy::Base uses this to decide whether to wrap a multi-statement DDL loop in $storage->txn_do; DBIO::DeploymentHandler uses it to decide whether the whole upgrade can run atomically. Drivers register their engine value via __PACKAGE__->_use_transactional_ddl(0|1) (in the driver's storage class) or by defining _determine_supports_transactional_ddl.

supports_if_exists -- F12

True iff the engine / diff emitter can use IF [NOT] EXISTS in DDL (CREATE TABLE IF NOT EXISTS, DROP TABLE IF EXISTS, ALTER TABLE ... ADD COLUMN IF NOT EXISTS). False on engines that do not parse the syntax (older MySQL / MariaDB before 10.0.2, some SQLite builds, others). DBIO::Diff::Op::should_emit_if_exists probes this to decide whether to emit guarded DDL. Drivers register their engine value via __PACKAGE__->_use_supports_if_exists(0|1) or by defining _determine_supports_supports_if_exists.

AUTHOR

DBIO & DBIx::Class Authors

COPYRIGHT AND LICENSE

Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.