NAME

DBIO::Candy - Sugar syntax for defining DBIO result classes

VERSION

version 0.900000

SYNOPSIS

package MyApp::Schema::Result::Artist;
use DBIO::Candy;

table 'artists';

primary_column id => {
    data_type => 'integer',
    is_auto_increment => 1,
};

column name => {
    data_type => 'varchar',
    size => 100,
};

column bio => {
    data_type => 'text',
    is_nullable => 1,
};

column created_at => {
    data_type => 'timestamp',
    set_on_create => 1,
};

column updated_at => {
    data_type => 'timestamp',
    set_on_create => 1,
    set_on_update => 1,
};

unique_constraint [qw(name)];
has_many cds => 'MyApp::Schema::Result::CD', 'artist_id';

1;

PostgreSQL-specific example:

package MyApp::Schema::Result::User;
use DBIO::Candy -components => ['InflateColumn::DateTime'];

table 'users';

primary_column id => {
    data_type => 'uuid',
    retrieve_on_insert => 1,
};

column name => {
    data_type => 'varchar',
    size => 100,
};

column role => {
    data_type => 'enum',
    extra => { list => [qw( admin moderator user guest )] },
    is_nullable => 1,
};

column metadata => {
    data_type => 'jsonb',
    default_value => '{}',
    serializer_class => 'JSON',
};

column embedding => {
    data_type => 'vector',
    size => 1536,
};

column tags => {
    data_type => 'text[]',
    is_nullable => 1,
};

column created_at => {
    data_type => 'timestamp',
    set_on_create => 1,
};

column updated_at => {
    data_type => 'timestamp',
    set_on_create => 1,
    set_on_update => 1,
};

column deleted_at => {
    data_type => 'timestamp',
    is_nullable => 1,
};

1;

DESCRIPTION

DBIO::Candy sits between vanilla DBIO::Core and DBIO::Cake. It keeps the familiar method-based API, but imports shorter helper names so result classes read more cleanly.

By default it:

  • turns on strict and warnings

  • sets your parent class to DBIO::Core

  • exports package methods used to define results as simple subroutines

  • aliases some method names for clarity

  • cleans the namespace after export via namespace::clean

IMPORT OPTIONS

Candy is a good fit when you want lighter syntax but still prefer explicit column hashrefs over Cake's DDL-style declarations.

-base

use DBIO::Candy -base => 'MyApp::Schema::Result';

Set the parent class. Defaults to DBIO::Core.

-autotable

use DBIO::Candy -autotable => v1;

Automatically generate the table name from the class name. Version v1 pluralizes (Cat becomes cats), 'singular' does not.

-components

use DBIO::Candy -components => ['InflateColumn::DateTime'];

Load components at import time so they can register their own sugar via DBIO::Candy::Exports.

-perl5

use DBIO::Candy -perl5 => v10;

Enable Perl feature flags (equivalent to use feature ':5.10').

-experimental

use DBIO::Candy -experimental => ['signatures'];

Enable experimental features.

IMPORTED SUBROUTINES

The following are exported with the same name and arguments as their __PACKAGE__->method equivalents:

belongs_to
has_many
has_one
inflate_column
many_to_many
might_have
remove_column
remove_columns
resultset_attributes
resultset_class
sequence
source_name
table

IMPORTED ALIASES

Shorter or clearer names for common methods:

column            => 'add_columns'
primary_key       => 'set_primary_key'
unique_constraint => 'add_unique_constraint'
relationship      => 'add_relationship'

TRANSFORMER FUNCTIONS

has_column

has_column foo => (
  data_type => 'varchar',
  size => 25,
);

Like add_columns but takes a flat list of key/value pairs (Moose-style) and wraps them into a hashref.

primary_column

primary_column id => {
  data_type => 'int',
  is_auto_increment => 1,
};

Defines a column and adds it to the primary key in a single call.

unique_column

unique_column name => {
  data_type => 'varchar',
  size => 30,
};

Defines a column and adds a unique constraint on it in a single call.

indices

indices(
  name_idx       => 'name',
  name_email_idx => ['name', 'email'],
);

Declares one or more secondary indexes on the table. Field lists may be a single column name or an arrayref of column names. Equivalent to the DBICx::Indexing component on DBIx::Class. The indexes are picked up by both the SQL::Translator deploy path (via sqlt_deploy_hook) and the native PostgreSQL deploy path (via pg_indexes), so they end up in the generated DDL regardless of which deploy method is in use.

SETTING DEFAULT IMPORT OPTIONS

Create a subclass to avoid repeating import options:

package MyApp::Schema::Candy;
use base 'DBIO::Candy';

sub base { $_[1] || 'MyApp::Schema::Result' }
sub perl_version { 12 }
sub autotable { 1 }
sub experimental { ['signatures'] }

Then in your result classes:

use MyApp::Schema::Candy;

AUTOTABLE VERSIONS

v1

Extracts the part after ::Result::, removes ::, decamelizes, and pluralizes:

MyApp::Schema::Result::Cat           -> cats
MyApp::Schema::Result::LonelyPerson  -> lonely_people

'singular'

Same as v1 but without pluralization:

MyApp::Schema::Result::Cat           -> cat
MyApp::Schema::Result::LonelyPerson  -> lonely_person

TIMESTAMP HELPERS

These are proxy methods for DBIO::Timestamp (loaded automatically):

col_created

col_created;               # creates 'created_at' column
col_created 'born_at';     # custom column name

col_updated

col_updated;               # creates 'updated_at' column
col_updated 'modified_at'; # custom column name

cols_updated_created

cols_updated_created;      # creates both at once

The most common pattern -- one line for both timestamp columns.

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.