NAME

DBIO::Manual::Component - Developing DBIO Components

VERSION

version 0.900004

WHAT IS A COMPONENT

A component is a module that can be added to your DBIO classes to provide extra functionality. A good example is DBIO::InflateColumn, which automatically inflates and deflates column values to and from Perl objects.

DBIO distinguishes between core infrastructure -- the classes every result class transitively inherits from, whether you ask for them or not -- and optional components that you opt into via load_components.

USING

Optional components are loaded with load_components() on your result class:

package My::Schema::Result::Thing;
use base qw( DBIO::Core );
__PACKAGE__->load_components(qw/InflateColumn::DateTime/);

You usually omit the DBIO:: prefix; load_components looks under DBIO:: by default. To load a component outside that namespace, prefix the name with +:

__PACKAGE__->load_components(qw/ +My::Component /);

The order in which components are loaded matters -- it determines the order they appear in the C3 inheritance chain. If a component overrides a method also overridden by another component, the one loaded first wins. When in doubt, read the docs of the components you are using.

CREATING COMPONENTS

A component is a class inheriting from DBIO::Base:

package DBIO::MyComp;
use base qw(DBIO::Base);
# Add methods, accessors, load other components, etc.
1;

When loaded, the component is injected into the result class' inheritance chain via Class::C3. A component can provide new methods, override methods provided by other components, or hook into lifecycle methods on DBIO::Row:

sub insert {
  my $self = shift;
  # Do stuff with $self before insert.
  return $self->next::method(@_);
}

sub delete {
  my $self = shift;
  # Do stuff with $self before delete.
  return $self->next::method(@_);
}

Work that has to happen before the row is written -- setting a column, generating a key, taking a key out of the update hashref -- does not belong in insert / update / delete. DBIO::Row has a hook for each, prepare_insert, prepare_update($upd) and prepare_delete, which do nothing in DBIO::Row and which both the synchronous methods and insert_async / update_async / delete_async call, once, before they read the columns:

sub prepare_insert {
  my $self = shift;
  $self->slug(lc $self->title) unless defined $self->slug;
  return $self->next::method(@_);
}

sub prepare_update {
  my ($self, $upd) = @_;
  # $upd is the hashref given to update(), or undef; take keys out of it
  # in place to set them another way
  $self->touched_at(time);
  return $self->next::method($upd);
}

An override of insert, update or delete is not on the way of the *_async methods, which send their statement through the storage backend. A class that has one without a *_async sibling in the same package has it run: the *_async method goes through the full synchronous method, which on a row bound to an async context ("with_context" in DBIO::Row) is refused, naming the class and the method. Override insert and friends for work that surrounds the write -- further statements after it, siblings, a transaction (DBIO::Ordered, DBIO::ChangeLog) -- and add a *_async beside it if that work can be done asynchronously. DBIO::Timestamp, DBIO::UUIDColumns and DBIO::FilterColumn use the hooks.

Components loaded earlier sit closer to the front of the @ISA chain. If you override insert() but DBIO::Row appears in the chain before your component, your override is shadowed. To inspect the actual resolution order:

print join ', ', mro::get_linear_isa('YourClass::Name');

CORE INFRASTRUCTURE

These classes are the substrate for every result class. They are loaded implicitly by DBIO::Core and you do not list them in load_components.

DBIO::Core -- The standard component bundle that user-facing result classes inherit from. Loads the rest of the core infrastructure.

DBIO::Row -- Per-row state, accessors, insert/update/delete, the lifecycle hook surface every other component cooperates with.

DBIO::PK -- Primary key handling.

DBIO::ResultSourceProxy -- Provides __PACKAGE__->table(...) and proxies result-source methods onto the result class.

DBIO::Relationship -- Inter-table relationships (belongs_to, has_many, might_have, many_to_many).

DBIO::InflateColumn -- Per-column inflate/deflate hook used by both core and optional components.

DBIO::Timestamp -- set_on_create / set_on_update column flags for automatic timestamp maintenance.

BUILT-IN OPTIONAL COMPONENTS

These ship in the DBIO core distribution and are loaded explicitly via load_components.

DBIO::InflateColumn::DateTime -- Inflate date/time columns to DateTime objects.

DBIO::InflateColumn::Serializer -- Serialise complex Perl structures into a single column (JSON, YAML, MessagePack).

DBIO::FilterColumn -- Bidirectional filter callbacks between in-memory and storage representations.

DBIO::EncodedColumn -- One-way encode columns such as passwords.

DBIO::UUIDColumns -- uuid_on_create column flag for automatic UUID generation on insert.

DBIO::Ordered -- position / grouping column flags to maintain a position column over an ordered list of rows.

DBIO::HashAccessor -- Generate get/set/exists/delete/push helpers for serialised hash columns.

DBIO::ChangeLog -- Record per-column change history into companion ChangeLog tables. Per-column changelog => 0 flag to exclude sensitive fields.

SEE ALSO

DBIO::Manual::Cookbook

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.