NAME
Dancer2::Plugin::QuickORM - Adds QuickORM syntactic sugar to Dancer2
VERSION
version 1.0000
SYNOPSIS
package MyApp;
use Dancer2;
use Dancer2::Plugin::QuickORM;
set plugins => {
QuickORM => {
default => {
class => 'MyApp::ORM',
},
},
};
# 'widget' table -> singular/plural keywords widget()/widgets()
get '/widget/:id' => sub {
return widget( route_parameters->get('id') );
};
get '/widgets' => sub {
return [ widgets( { color => 'blue' } ) ];
};
# get at the raw ORM connection directly
get '/stats' => sub {
return { row_count => orm()->handle('widget')->all };
};
DESCRIPTION
Dancer2::Plugin::QuickORM looks at the ORM(s) you've configured with DBIx::QuickORM, walks every table in their schema(s), and generates a Dancer2 keyword (i.e. an importable function) for each one, so routes can query it without any boilerplate.
For each configured ORM name (see "CONFIGURATION AND ENVIRONMENT"), the plugin's BUILD step:
Loads the configured
classand calls$class->orm($name)to obtain a connection.Iterates
$orm->schema($name)->tablesand, for each table, derives a singular and a plural keyword name from the table name (splittingStudlyCaps/CamelCaseinto words and singularising/pluralising with Lingua::EN::Inflect::Phrase).Registers those keywords, plus schema-prefixed variants (
<name>_<singular>and<name>_<plural>), so a table is always reachable unambiguously even if more than one configured ORM exposes a table of the same name.
Generated keywords
If a table's singular and plural forms differ (the common case, e.g. widget/widgets), two keywords are generated:
singular($id)-
Fetches the single row with that primary key. Croaks if called with no argument, or with a hashref (which is a search, not a primary key).
plural($where)-
Runs a search. Called with no arguments, returns every row. Called with a hashref, runs it as search conditions against the table. Croaks if given anything other than a hashref.
If a table's singular and plural forms are identical (e.g. moose), a single "smart" keyword is generated instead, which inspects the shape of its argument to decide what you meant:
a hashref is treated as search conditions (like the plural form above);
undef(i.e. no argument) croaks, since there's no sensible default;anything else (a plain scalar, or an arrayref) is treated as a primary key value and looked up like the singular form above;
any other kind of reference (coderef, scalarref, etc.) croaks, since it's neither a valid search nor a valid primary key.
Keyword collisions
Two different kinds of collision are handled, and handled differently:
- Two configured ORMs derive the same bare keyword
-
The bare keyword (e.g.
widget) becomes ambiguous: calling it croaks, telling you to use the schema-prefixed form (e.g.default_widgetorsecond_widget) instead. The schema-prefixed forms always work. - A derived keyword collides with an existing keyword
-
If the bare keyword name is already in use (either because it's a core Dancer2 DSL keyword, e.g.
sessionorresponse_header, or because this plugin has already registered it itself - its ownormkeyword, see below), the bare form is silently skipped so the existing keyword keeps working. The schema-prefixed form is still registered and reachable.
SUBROUTINES/METHODS
orm
orm(); # the connection configured as 'default'
orm($name); # the connection configured under $name
Returns the raw ORM connection object for the given configured name (defaults to 'default' when no name is given). Croaks if $name was not configured.
This is the one keyword the plugin always registers itself (via plugin_keywords), regardless of what tables are configured; use it when you need something the generated per-table keywords don't cover.
BUILD
Runs once when the plugin is instantiated. Reads the plugin configuration, loads each configured ORM class, and generates the per-table keywords described in "DESCRIPTION". Not intended to be called directly.
ATTRIBUTES
This plugin exposes no public attributes of its own. All of its behaviour is driven by the plugins->QuickORM section of your Dancer2 configuration; see "CONFIGURATION AND ENVIRONMENT".
DIAGNOSTICS
ORM '%s' is missing 'class' in the configuration-
A configured ORM name has no
classkey. Every entry underplugins->QuickORMmust specify one. Failed to load ORM class '%s': %s-
The configured
classcould not berequired; the underlying error is appended. ORM '%s' is not defined in the configuration-
orm($name)was called with a name that wasn't configured. '%s' requires a primary key value-
A singular (or smart) keyword was called with no argument.
'%s' expects a single primary key value, not a hashref of search conditions-
A singular keyword was called with a hashref; use the plural (search) keyword instead.
'%s' expects a hashref of search conditions-
A plural keyword was called with a non-hashref, non-undef argument.
'%s' requires a primary key value or a hashref of search conditions-
A smart keyword (identical singular/plural table) was called with no argument.
'%s' does not accept a reference of type '%s'-
A smart keyword was called with a reference that's neither a hashref (search) nor usable as a primary key.
%s is ambiguous; use <schema>_%s instead!-
The bare keyword is generated by more than one configured ORM; call the schema-prefixed form instead.
CONFIGURATION AND ENVIRONMENT
Configure one or more named ORMs under plugins->QuickORM in your Dancer2 config:
plugins:
QuickORM:
default:
class: MyApp::ORM
dsn: "dbi:Pg:dbname=myapp"
reporting:
class: MyApp::ORM
dsn: "dbi:Pg:dbname=myapp_reporting"
Each key under QuickORM is an ORM name (default is used when orm() is called without an argument); each value is a hashref that must contain a class, plus whatever other keys your ORM class needs.
Every key/value pair in a given ORM's configuration (including class itself) is also copied into %ENV as QuickORM_<name>_<key>, and the name itself is set as QuickORM_<name>_name, so the ORM class's orm() constructor can pick up its configuration from the environment if it prefers that to being passed arguments directly.
The configured class must implement the following DBIx::QuickORM features:
$class->orm($name) # -> connection object
$orm->schema($name)->tables # -> list of table objects
$table->name # -> table name string
$orm->handle($table_name) # -> handle object
$handle->by_id($id) # -> single row (hashref) or undef
$handle->where($hashref)->all # -> list of matching rows
$handle->all # -> list of every row
DEPENDENCIES
BUGS AND LIMITATIONS
Table names that singularise/pluralise to the same word as a Dancer2 core DSL keyword or another already-registered keyword are only reachable via their schema-prefixed keyword; see "Keyword collisions".
For tables whose singular and plural forms are identical, an arrayref argument is treated as a primary key value (passed straight through to the backend) rather than being rejected outright, since it isn't a hashref and isn't some other clearly-invalid reference type; whether that's a meaningful primary key value is left to the configured ORM class.
Please report any bugs or feature requests through the issue tracker for this distribution.
SEE ALSO
Dancer2, Dancer2::Plugin, DBIx::QuickORM
AUTHOR
D Ruth Holloway <ruth@hiruthie.me>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by D Ruth Holloway.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 404:
You forgot a '=back' before '=head1'