NAME
DBIO::Manual::Heritage - Everything that changed from DBIx::Class to DBIO
VERSION
version 0.900004
OVERVIEW
DBIO is a fork of DBIx::Class. It retains the relational-mapping model and most of the API surface, but replaces, extends, and integrates a significant number of components. This document is the definitive reference for everyone migrating from DBIx::Class, or anyone who needs to understand what DBIO is relative to its ancestor.
Naming
DBIO stands for DBI Objects. The namespace DBIO:: replaces DBIx::Class:: throughout. Every module, every test, every tool has been renamed accordingly.
DBIO is a clean break - there is no runtime DBIx::Class compatibility shim. Existing code is migrated by mechanical rename (DBIx::Class::* to DBIO::*) plus the targeted API updates listed in DBIO::Manual::Migration.
FUNDAMENTAL ARCHITECTURE CHANGES
DBIO::Base - the new meta-infrastructure base
DBIx::Class distributed its meta-level machinery across several internal packages. DBIO consolidates it into DBIO::Base, which every internal class uses as its root:
use mro 'c3'- MRO forced to C3 for the entire inheritance tree- DBIO::Componentised - the
load_components()machinery - Class::Accessor::Grouped -
mk_group_accessors() - Perl subroutine attributes via
MODIFY_CODE_ATTRIBUTES _skip_namespace_framesfor clean stack traces
Do not use DBIO::Base directly in application code. It is the machinery that everything else stands on. For your Result classes use DBIO::Core; for ResultSet classes use DBIO::ResultSet; for schema classes use DBIO::Schema.
SQL::Abstract replaces SQL::Abstract::Classic
DBIx::Class depended on SQL::Abstract::Classic, an older fork. DBIO uses the canonical SQL::Abstract (>= 2.000001) instead. The query API is compatible; the internal extensions required small adjustments in the SQLMaker layer.
apply_limit replaces limit_dialect
DBIx::Class used a sql_limit_dialect string and an emulate_limit() dispatch table inside the storage layer. DBIO removes both. The SQLMaker's apply_limit($sql, $rs_attrs, $rows, $offset) method renders the limit instead. The default implementation emits LIMIT ? OFFSET ?; a driver whose database needs another syntax overrides it in its SQLMaker subclass.
If you had custom emulate_limit() overrides, override apply_limit on your SQLMaker subclass.
Driver distributions split out of core
All database-specific storage classes have been removed from the DBIO core distribution and moved into dedicated CPAN distributions:
DBIO-PostgreSQL DBIO::PostgreSQL (most advanced: pg_catalog introspect,
enums, schemas, RLS, indexes)
DBIO-MySQL DBIO::MySQL
DBIO-SQLite DBIO::SQLite
DBIO-DuckDB DBIO::DuckDB (embedded analytical; UUID, Arrow,
Appender, quack RPC)
DBIO-DB2 DBIO::DB2
DBIO-Firebird DBIO::Firebird
DBIO-Informix DBIO::Informix
DBIO-MSSQL DBIO::MSSQL
DBIO-Oracle DBIO::Oracle
DBIO-Sybase DBIO::Sybase
Install only the driver you need. Every driver ships its own native introspection, diff, and deploy modules (the test-and-compare strategy) and does not require SQL::Translator.
Async is an explicit, per-connection mode whose queries return Future objects; each mode's transport is its own distribution. There is also a GraphQL projection layer:
DBIO-Forked DBIO::Forked (mode 'forked': fork per
query, any driver, no loop)
DBIO-Async DBIO::Async (mode 'future_io': the
driver's own async DBD
binding via Future::IO)
DBIO-PostgreSQL-EV DBIO::PostgreSQL::EV (mode 'ev': libpq via EV::Pg)
DBIO-MySQL-EV DBIO::MySQL::EV (mode 'ev': MariaDB via
EV::MariaDB)
DBIO-GraphQL DBIO::GraphQL (Result classes -> GraphQL)
Replicated storage is now in core
DBIx::Class::Replicated was an external distribution. DBIO::Replicated ships in the core distribution. Load it as a Schema component; it forces +DBIO::Replicated::Storage and coordinates a master backend plus optional replicants:
package MyApp::Schema;
use DBIO 'Schema', -pg;
__PACKAGE__->load_components('Replicated');
my $schema = MyApp::Schema->connect($dsn, $user, $pass, {
balancer_type => 'DBIO::Replicated::Balancer::First',
});
$schema->storage->connect_replicants([ $replica_dsn, $user, $pass ]);
Writes, transactions and deploy go through the master; reads are delegated to the balancer (default DBIO::Replicated::Balancer::First). The internals live in DBIO::Replicated::Pool, DBIO::Replicated::Backend, and DBIO::Replicated::Balancer.
SQL::Translator is optional
Every driver ships its own native Deploy, Introspect, and Diff modules. DBIO::Schema->deploy() checks the active storage class for a dbio_deploy_class() method; if present it routes to the native class, which deploys by introspecting both the live database and the desired schema and diffing the two models (test-and-compare). If a storage declares no native class, deploy() does not silently translate the schema for you: it falls through to deployment_statements(), which reads a pre-existing DDL file and throws if none is present. Core's deploy path never calls SQL::Translator, so SQL::Translator is an optional dependency rather than a required one.
RESULT CLASS STYLES
DBIx::Class had one way to write a Result class: the explicit __PACKAGE__->method() style. DBIO keeps that (called Vanilla) and adds two sugar layers.
Vanilla (classic, unchanged API)
package MyApp::Schema::Result::Artist;
use base 'DBIO::Core';
__PACKAGE__->table('artist');
__PACKAGE__->add_columns(
artistid => { data_type => 'integer', is_auto_increment => 1 },
name => { data_type => 'varchar', size => 100 },
);
__PACKAGE__->set_primary_key('artistid');
__PACKAGE__->has_many(cds => 'MyApp::Schema::Result::CD', 'artistid');
1;
See DBIO::Core and DBIO::Manual::ResultClass.
Candy (import-sugar, method renaming)
DBIO::Candy removes the __PACKAGE__-> boilerplate and exports short aliases. It also infers the table name from the package name.
package MyApp::Schema::Result::Artist;
use DBIO::Candy;
column artistid => { data_type => 'integer', is_auto_increment => 1 };
column name => { data_type => 'varchar', size => 100 };
primary_key 'artistid';
has_many cds => 'MyApp::Schema::Result::CD', 'artistid';
1;
Key aliases exported by Candy:
column -> add_columns
primary_key -> set_primary_key
unique_constraint -> add_unique_constraint
relationship -> add_relationship
Candy is derived from DBIx::Class::Candy, which has been integrated into the core distribution.
Cake (DDL-like DSL - most concise)
DBIO::Cake reads like schema DDL. Type functions (integer, varchar, serial, uuid, json, jsonb, text, boolean, ...) replace the verbose column-info hashref.
package MyApp::Schema::Result::Artist;
use DBIO::Cake;
col artistid => serial, auto_inc;
col name => varchar(100);
primary_key 'artistid';
has_many cds => 'MyApp::Schema::Result::CD', 'artistid';
1;
Cake modifiers:
null auto_inc fk($target)
default unsigned on_create on_update
Driver shortcuts activate driver-specific column types and components in one import flag:
use DBIO::Cake -Pg; # PostgreSQL defaults (uuid, jsonb, ...)
use DBIO::Cake -MySQL;
use DBIO::Cake -SQLite;
Other import flags:
-inflate_datetime load InflateColumn::DateTime automatically
-inflate_json inflate json columns to hashrefs
-inflate_jsonb inflate jsonb columns (PostgreSQL)
-retrieve_defaults fetch server-side defaults after insert
The type registry on the active Storage class (cake_defaults(), type_info($name)) drives driver-aware column type resolution.
INTEGRATED COMPONENTS
The following features were previously separate CPAN distributions or required load_components. In DBIO they are part of core and need no explicit loading unless noted.
DBIO::Timestamp (was DBIx::Class::TimeStamp)
Automatic created_at / updated_at timestamps. Configure per column:
col created_at => timestamp, on_create;
col updated_at => timestamp, on_update;
Or use the helpers available in all three styles:
col_created 'created_at'; # set on insert
col_updated 'updated_at'; # set on insert and update
cols_updated_created(); # both with default names
Available via DBIO::Timestamp. No load_components needed in Cake or Candy; Vanilla code can still load it explicitly.
Row helpers (was DBIx::Class::Helpers)
The following helpers from DBIx::Class::Helpers are integrated directly into DBIO::Row and require no load_components call:
- "TO_JSON" in DBIO::Row - serializable hashref, excludes blob/text columns
- "serializable_columns" in DBIO::Row - list of serializable column names
- "self_rs" in DBIO::Row - a ResultSet scoped to this row
- "get_storage_value" in DBIO::Row - original DB value before in-memory changes
- "before_column_change" in DBIO::Row - fire a callback before a column is modified
- "after_column_change" in DBIO::Row - fire a callback after a column is modified
- "around_column_change" in DBIO::Row - wrap a column update with an around-style hook
- "proxy_resultset_method" in DBIO::Row - expose a ResultSet
with_*method as a row accessor
These come from DBIx::Class::Helper::Row::StorageValues, DBIx::Class::Helper::Row::OnColumnChange, and DBIx::Class::Helper::ResultSet::ProxyResultSetMethod.
ResultSet helpers (was DBIx::Class::Helpers)
The DBIx::Class::Helper::ResultSet::* family is integrated into DBIO::ResultSet and likewise needs no load_components. Upstream these are components loaded per ResultSet class; in DBIO they are core API.
Attribute shortcuts, each of them a chainable ->search(undef, {...}):
- "order_by" in DBIO::ResultSet -
!colmeans DESC,-desc => 'col'too - "columns" in DBIO::ResultSet, "add_columns" in DBIO::ResultSet, "remove_columns" in DBIO::ResultSet, "no_columns" in DBIO::ResultSet
- "distinct" in DBIO::ResultSet, "group_by" in DBIO::ResultSet, "prefetch" in DBIO::ResultSet, "hri" in DBIO::ResultSet
- "rows" in DBIO::ResultSet, "limit" in DBIO::ResultSet, "limited_page" in DBIO::ResultSet, "has_rows" in DBIO::ResultSet
Search shortcuts. A leading dot qualifies the column with the current source alias, so ->null('.title') means me.title:
- "null" in DBIO::ResultSet, "not_null" in DBIO::ResultSet, "like" in DBIO::ResultSet, "not_like" in DBIO::ResultSet
- "search_or" in DBIO::ResultSet - OR together several ResultSets
- "me" in DBIO::ResultSet - the current source alias with a dot appended
Set operations, existence and the rest:
- "union" in DBIO::ResultSet, "union_all" in DBIO::ResultSet, "intersect" in DBIO::ResultSet, "intersect_all" in DBIO::ResultSet, "except" in DBIO::ResultSet, "except_all" in DBIO::ResultSet
- "results_exist" in DBIO::ResultSet, "results_exist_as_query" in DBIO::ResultSet - cheaper than
count - "one_row" in DBIO::ResultSet, "bare" in DBIO::ResultSet, "rand" in DBIO::ResultSet, "explain" in DBIO::ResultSet
Two divergences worth knowing. rand and explain are built on the storage hooks _random_function and _explain_query rather than upstream's DBIx::Introspector, so a driver declares its own dialect. And page is not the upstream shortcut - DBIO kept the DBIx::Class core method, which builds its ResultSet directly instead of routing through search.
DBIx::Class::Helper::ResultSet::IgnoreWantarray was deliberately not taken over; DBIO removes search's context-dependent return type outright instead. Also not integrated: DateMethods1, Errors, AutoRemoveColumns, ResultClassDWIM, and the upstream-deprecated VirtualView and Union. The reasoning for each is recorded in ADR 0011.
IntrospectableM2M (was DBIx::Class::IntrospectableM2M)
Many-to-many introspection is integrated into DBIO::Relationship::ManyToMany. The _m2m_metadata structure is populated automatically when you declare a many_to_many relationship. No load_components needed.
Accessible fields: accessor, relation, foreign_relation, rs_method, add_method, set_method, remove_method.
DBIO::UUIDColumns (was DBIx::Class::UUIDColumns)
Auto-generate UUID values on insert. Load the component and flag the columns with uuid_on_create:
__PACKAGE__->load_components('UUIDColumns');
__PACKAGE__->add_columns(
id => { data_type => 'varchar', size => 36, uuid_on_create => 1 },
);
Cake's uuid type function is a column type only (data_type => 'uuid'); it does not generate a value.
The default generator makes random version 4 UUIDs from Crypt::URandom. uuid_class() selects Data::UUID or UUID explicitly.
See DBIO::UUIDColumns.
DBIO::EncodedColumn
One-way encoding of column values (passwords with Bcrypt or Argon2, tokens with Digest). Unlike the other components in this chapter it must be loaded:
__PACKAGE__->load_components('EncodedColumn');
Then mark a column:
__PACKAGE__->add_columns(
password => {
data_type => 'varchar',
size => 100,
encode_column => 1,
encode_check_method => 'check_password',
},
);
The column is encoded transparently on write. The check_password (or whatever name you give encode_check_method) method is generated automatically on the Result class.
The default encode_class is Bcrypt (cost 12, stored as $2b$...); Argon2 stores $argon2id$...; Digest (SHA-256, SHA-384, SHA-512 or SHA3-*) stores dbio$<algo>$<salt_b64>$<digest_b64>. An unknown encode_class, an unknown encode_args key of the class or a Digest algorithm outside that list is refused when the class is loaded. A stored value without hash format matches only with accept_unencoded => 1 in encode_args.
See DBIO::EncodedColumn.
DBIO::HashAccessor
Accessor generation for serialized hash columns (JSON, YAML, MessagePack):
__PACKAGE__->add_hash_accessor('metadata', 'metadata_col');
Generates: metadata(), metadata_hash(), metadata_hash_delete(), metadata_push(), metadata_shift().
See DBIO::HashAccessor.
InflateColumn::Serializer (JSON, YAML, MessagePack)
Serialize complex Perl structures to a text/blob column. Available via load_components('InflateColumn::Serializer'). Serializer options: JSON, YAML, MessagePack.
PopulateMore (was DBIx::Class::Schema::PopulateMore)
DBIO::PopulateMore adds populate_more(), which fills several sources in one call and lets a row refer to one created earlier in the same call. Load it on the schema class:
__PACKAGE__->load_components('PopulateMore');
$schema->populate_more([
{ Gender => {
fields => 'label',
data => { male => 'male', female => 'female' },
} },
{ Person => {
fields => [ 'name', 'gender' ],
data => { john => [ 'john', '!Index:Gender.male' ] },
} },
]);
Values starting with ! are inflated: !Index:Source.key is the row created under that key, !Env:NAME a value from %ENV, and !Find:Source.[key=val] an existing row. $schema->populate is the plain per-source "populate" in DBIO::Schema.
NEW CONCEPTS
These features did not exist in DBIx::Class in any form.
DBIO::ChangeLog - audit trail per Result class
Automatic row-level change tracking. Add to a Result class:
__PACKAGE__->load_components('ChangeLog');
and to the schema class:
__PACKAGE__->load_components('ChangeLog::Schema');
The schema component registers a companion source <Source>_ChangeLog (table <table>_changelog) for every tracked source; $schema->deploy_changelog deploys those tables. By default every column change is recorded (INSERT, UPDATE, DELETE). Exclude sensitive columns with the changelog column flag:
__PACKAGE__->add_columns(
password_hash => { data_type => 'varchar', size => 255, changelog => 0 },
);
Changes are stored as JSON. Methods on a row of a tracked Result class:
$row->changelog; # ResultSet of this row's log entries
$row->changelog_serialize_changes($hashref);
$row->changelog_deserialize_changes($json_str);
The changes column is text. A driver or application component can override changelog_column_definitions to use a native type (e.g. jsonb on PostgreSQL). The DBIx::Class::Schema::Versioned-style standalone versioning (DBIO::Version) was dropped in favour of DBIO::DeploymentHandler; there is no dbio_schema_versions table. The DBIO::DeploymentHandler version table was renamed from its upstream name dbix_class_deploymenthandler_versions to dbio_deploymenthandler_versions (fork-rename); databases deployed with an older DBIO must be migrated manually (see "COMPATIBILITY: VERSION TABLE RENAME" in DBIO::DeploymentHandler).
See DBIO::ChangeLog and DBIO::ChangeLog::Schema.
DBIO::AccessBroker - credential source interface
A storage-agnostic interface for credential lifecycle management. A broker is a CredentialSource: it supplies the connect info for one backend identity. It does not route and does not own a host list - read/write routing and the master/replicant topology belong to DBIO::Replicated. Pass a broker to connect() in place of a DSN; the storage detects it and attaches it:
my $schema = MyApp::Schema->connect(
DBIO::AccessBroker::Static->new(
host => $host,
dbname => $dbname,
username => $user,
password => $pass,
)
);
The storage calls connect_info_for_storage($storage) on the broker before each connection. Static answers connection parameters, not a DSN: the storage builds the DSN for its driver, so the schema must load its driver component. One credential can serve many servers: the application builds a $broker->for_host($host) view per server and hands each to the connection on that host (DBIO::Replicated passes the views through).
Built-in broker classes:
- DBIO::AccessBroker::Static - one fixed set of connection parameters
- DBIO::AccessBroker::Vault - rotating credentials with TTL
- DBIO::AccessBroker::HostBound - one credential identity pinned to one host
Build a custom broker by subclassing DBIO::AccessBroker and implementing connect_info_for_storage, needs_refresh, and refresh.
DBIO::Moo and DBIO::Moose - OO framework bridges
Use Moo or Moose attributes alongside DBIO column accessors in the same Result, ResultSet, or Schema class.
package MyApp::Schema::Result::Artist;
use DBIO::Moo;
use DBIO::Cake;
col artistid => serial, auto_inc;
col name => varchar(100);
primary_key 'artistid';
has display_name => (is => 'lazy');
sub _build_display_name { 'Artist: ' . $_[0]->name }
1;
DBIO::Moo and DBIO::Moose wire the framework constructor (FOREIGNBUILDARGS for Moo, BUILDARGS for Moose) into DBIO's new() so that DBIO column data is routed correctly and Moo/Moose attributes are filtered from DBIO's column constructor.
Combinations with Cake and Candy are fully supported. Use DBIO::Cake with use DBIO::Moo in the same file.
See DBIO::Moo and DBIO::Moose.
Async storage interface
DBIO::Storage::Async defines a storage-agnostic async interface (Phase 1 + 2). Queries return Future objects. Async is an explicit, per-connection mode -- connect($dsn, $user, $pass, { async => 'forked' | 'future_io' | 'ev' | 'immediate' }) -- and the ev mode bypasses DBI entirely through a per-driver native client:
DBIO::PostgreSQL::EV(DBIO-PostgreSQL-EV) -libpqviaEV::Pg; adds COPY IN/OUT and request pipelining.DBIO::MySQL::EV(DBIO-MySQL-EV) - the MariaDB client viaEV::MariaDB, which pipelines consecutive queries automatically at the wire level.
The core async interface is in DBIO::Storage::Async. It includes transaction pinning: txn_do_async takes one connection from the pool and runs the whole transaction on it, and every pooled transport inherits that -- future_io and both ev backends alike. It also includes LISTEN/NOTIFY (ADR 0056): core owns the self-healing listen machinery, and PostgreSQL carries it on both the future_io and the ev transport. Application code that targets multiple backends should program against that interface; the modes and their transports are described in DBIO::Manual::AsyncStorage.
Type registry on Storage
Each driver's Storage class exposes:
$schema->storage->cake_defaults() # hashref of driver-preferred options
$schema->storage->type_info($type_name) # { components => [...], cake_options => {...} }
The Cake DSL reads this registry when resolving column types so that, for example, col data => jsonb on a PostgreSQL storage automatically activates InflateColumn::JSONB.
DBIO::Storage::DateTimeFormat - shared driver datetime base
DBIx::Class drivers each hand-rolled a private DateTime::Format::* wrapper package inside their storage class, typically require-ing DateTime::Format::Strptime at runtime. DBIO replaces these with a shared base, DBIO::Storage::DateTimeFormat. A driver's datetime format class declares its strptime patterns as class data and may name a preferred CPAN DateTime::Format::* class:
package DBIO::DriverName::DateTime::Format;
use base 'DBIO::Storage::DateTimeFormat';
__PACKAGE__->preferred_format_class('DateTime::Format::DriverName'); # optional
__PACKAGE__->datetime_parse_pattern('%Y-%m-%d %H:%M:%S');
__PACKAGE__->datetime_format_pattern('%Y-%m-%d %H:%M:%S');
When the preferred class is installed it handles parsing and formatting; otherwise the declared patterns are used via DateTime::Format::Strptime (a hard dependency of core, so drivers declare nothing extra). The pattern fallback round-trips identically to the preferred class.
UTILITY CHANGES
DBIO::Util replaces DBIx::Class::_ENV_
The internal DBIx::Class::_ENV_ pseudo-package has been removed. All runtime constants and utility functions are now in DBIO::Util:
use DBIO::Util qw( is_windows help_url scope_guard ... );
Exported functions include:
is_windows is_dev_release old_mro has_ithreads
dbiotest peepeeness shuffle_unordered_resultsets
help_url iv_size os_name
sigwarn_silencer modver_gt_or_eq assert_no_list_context
refdesc refcount hrefaddr scope_guard
quote_sub qsub perlstring serialize dump_value
UNRESOLVABLE_CONDITION
dir_path file_path parent_dir slurp_file write_file
mkpath rmtree class_path
firstidx uniq apply array_eq
is_plain_value is_literal_value
Path::Class is no longer a dependency; use the DBIO::Util path helpers instead.
DBIOx namespace
The DBIOx:: namespace is reserved for official DBIO extensions that are not part of the core distribution - analogous to DBIx:: but scoped to the DBIO ecosystem.
REMOVED FEATURES
Class::DBI compatibility (CDBICompat)
The DBIx::Class::CDBICompat layer and the legacy DB.pm shim have been removed entirely. There is no replacement. If you depend on Class::DBI compatibility, stay on DBIx::Class or port your code.
Hide-from-PAUSE package trick
Internal packages no longer use the package # hide from PAUSE\nFoo::Bar; trick. Meta::NoIndex in the distribution's META.yml handles PAUSE exclusion instead.
Removed external dependencies
SQL::Abstract::Classic- replaced bySQL::AbstractPath::Class- replaced by helpers in DBIO::UtilSub::Name- no longer usedSQL::Abstract::Util- merged into SQL::Abstract core
TESTING INFRASTRUCTURE
DBIO::Test - database-free unit testing
Core tests must not use a real database. DBIO::Test provides a mock storage back-end:
use DBIO::Test;
my $schema = DBIO::Test->init_schema(); # fake storage, no DBI
my $storage = $schema->storage;
$storage->mock(qr/SELECT .* FROM artist/, [
{ artistid => 1, name => 'Tori Amos' },
]);
Driver-specific tests (real SQL, real DBI) belong in the driver distributions.
Shared test schemas
The test schema shared across the core and driver distributions is DBIO::Test::Schema under dbio/lib/, with its result classes in DBIO::Test::Schema::*:
DBIO::Test::Schema::Artist
DBIO::Test::Schema::CD
DBIO::Test::Schema::Track
...
The optional OO-framework demo schemas are standalone schema classes and live as siblings of (not under) DBIO::Test::Schema. Keeping them out of the DBIO::Test::Schema::* namespace is deliberate: a no-arg load_classes sweep of that namespace would otherwise try to load them and die on any box lacking the optional dependency (Moose / MooseX::NonMoose / Moo). Tests that use them guard with eval { require ... }.
DBIO::Test::MooSchema # Moo result classes
DBIO::Test::MooseSchema # Moose result classes
DBIO::Test::MooCakeSchema # Moo + Cake DDL
DBIO::Test::MooseSugarSchema # Moose + Cake DDL
Load driver-specific result classes with the hashref form:
DBIO::Test::Schema->load_classes({
'DBIO::PostgreSQL::Test' => ['SequenceTest'],
});
Never redefine a shared schema class inline inside a driver test.
Environment variables renamed
All test environment variables were renamed from DBICTEST_* to DBIO_TEST_*:
DBIO_TEST_PG_DSN PostgreSQL DSN
DBIO_TEST_MYSQL_DSN MySQL/MariaDB DSN
There is no SQLite equivalent. SQLite needs no connection configuration, so DBIO defines no DBIO_TEST_SQLITE_DSN and nothing reads one: in DBIO::Optional::Dependencies every server engine's live-test group is gated on its own DBIO_TEST_*_DSN, while SQLite carries a plain rdbms_sqlite group with no gate at all.
MIGRATION QUICK-REFERENCE
DBIx::Class concept DBIO equivalent
---------------------------------------------------------------------
DBIx::Class::* DBIO::*
use base 'DBIx::Class::Core' use base 'DBIO::Core' (Vanilla)
use DBIO::Candy; (Candy)
use DBIO::Cake; (Cake)
sql_limit_dialect / emulate_limit apply_limit on SQLMaker subclass
SQL::Abstract::Classic SQL::Abstract (>= 2.000001)
DBIx::Class::TimeStamp DBIO::Timestamp (integrated)
DBIx::Class::Helpers DBIO::Row + DBIO::ResultSet helpers
(integrated)
DBIx::Class::IntrospectableM2M ManyToMany (integrated)
DBIx::Class::UUIDColumns DBIO::UUIDColumns (integrated)
DBIx::Class::Replicated DBIO::Replicated (in core)
DBIx::Class::CDBICompat removed (no replacement)
DBICTest::* DBIO::Test::*
DBICTEST_* env vars DBIO_TEST_* env vars
dbix_class_schema_versions removed (Schema::Versioned dropped;
use DBIO::DeploymentHandler)
dbix_class_deploymenthandler_versions
dbio_deploymenthandler_versions
(fork-rename; migrate old DBs manually)
SQL::Translator (DDL/deploy) native Deploy per driver (SQLT dropped)
SEE ALSO
- DBIO::Manual - documentation overview
- DBIO::Manual::DocMap - full documentation map
- DBIO::Manual::Migration - step-by-step DBIx::Class to DBIO conversion
- DBIO::Base - meta-infrastructure base class
- DBIO::Candy - import-sugar layer
- DBIO::Cake - DDL-like DSL layer
- DBIO::Timestamp - automatic timestamp columns
- DBIO::UUIDColumns - automatic UUID columns
- DBIO::EncodedColumn - one-way column encoding
- DBIO::ChangeLog - row-level audit trail
- DBIO::AccessBroker - credential source interface
- DBIO::Moo - Moo attribute bridge
- DBIO::Moose - Moose attribute bridge
- DBIO::Replicated - replicated storage
- DBIO::Test - database-free test infrastructure
- DBIO::Util - utility functions
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.