NAME

DBIx::QuickORM::Manual::QuickStart - A friendly first tour of DBIx::QuickORM.

DESCRIPTION

This is the first page to read if you are new to DBIx::QuickORM. It walks you from an empty script to fetching rows, inserting rows, following relations, and running a transaction - all using the quick() interface, which needs no schema definition at all.

The idea: point quick() at a database, and DBIx::QuickORM introspects all the table and column metadata directly from the live database. You get back a ready-to-use connection and start treating rows as objects immediately.

When you want more control (defining your own schema, custom row classes, joins, and so on) follow the links at the end of this page. For the bigger picture and the full set of guides, see DBIx::QuickORM::Manual.

CONNECT

Use the quick() class method. Provide exactly one of credentials or connect. The SQL dialect is detected automatically from the DSN (or the dbd), so you usually do not need to think about it.

use DBIx::QuickORM;

my $con = DBIx::QuickORM->quick(
    credentials => {
        dsn   => $dsn,        # e.g. "dbi:Pg:dbname=myapp;host=..."
        user  => $user,
        pass  => $pass,
    },

    # Type classes (under DBIx::QuickORM::Type unless fully qualified)
    # used to auto inflate/deflate matching columns.
    auto_types => ['JSON', 'UUID'],
);

If you would rather hand DBIx::QuickORM a callback that produces a fresh DBI handle, use connect instead of credentials:

my $con = DBIx::QuickORM->quick(
    connect => sub { DBI->connect($dsn, $user, $pass) },
);

$con is a DBIx::QuickORM::Connection. It self-heals: it can reconnect in place and retry work, preserving its row cache. That is the only object you need to keep around.

OPTIONS

quick() accepts a few optional affordances:

auto_types => \@type_classes

Type classes (under DBIx::QuickORM::Type unless fully qualified) used to auto inflate/deflate matching columns. See DBIx::QuickORM::Manual::Types.

dialect => $name

Force a specific dialect instead of detecting it from the DSN/driver.

autorow => 0 | 1 | $prefix

Whether to generate a row class per table (with named field and relation accessors). Defaults to 0 (off - you get generic DBIx::QuickORM::Row objects). Pass 1 to enable it under a generated namespace, or pass a namespace prefix string (e.g. 'My::Row') to generate classes like My::Row::Users. See DBIx::QuickORM::Manual::Schema.

row_manager => $class_or_instance

The row manager that provides per-connection row caching/identity. Defaults to 'DBIx::QuickORM::RowManager::Cached'. See DBIx::QuickORM::Manual::Caching.

FETCH ROWS

A handle is the interface for talking to a table. Get one with $con->handle('table_name'), then ask it for rows.

# Every row in the 'users' table, as Row objects:
my @users = $con->handle('users')->all;

# Narrow it down with a where clause, then fetch:
my @smiths = $con->handle('users')->where({surname => 'smith'})->all;

# Exactly one matching row (dies if more than one matches):
my $user = $con->handle('users')->where({email => $email})->one;

When you want a row by primary key, by_id is the shortcut:

my $user = $con->by_id(users => 5);

For convenience the connection proxies the common handle methods directly, so the simple cases need no explicit handle:

my @users = $con->all('users');
my $user  = $con->one(users => {email => $email});
my $count = $con->count('users');

Read a column off a row with field:

print $user->field('name'), "\n";

If you connected with an autorow base class (see DBIx::QuickORM and DBIx::QuickORM::Manual::Schema), each column also gets a named accessor, so you can write $user->name instead of $user->field('name').

For everything handles can do - ordering, limiting, iterators, and more - see DBIx::QuickORM::Manual::Querying.

INSERT ROWS

Insert with a hashref of column values. You get back the new row object, populated with anything the database filled in (auto-increment ids, defaults, and so on).

my $bob = $con->insert(users => {name => 'bob', email => 'bob@example.com'});

print "new id: ", $bob->field('id'), "\n";

You can also go through a handle, which is handy once you have a handle around:

my $bob = $con->handle('users')->insert({name => 'bob'});

See DBIx::QuickORM::Manual::Querying for create, update, and delete in depth.

WORKING WITH ROWS

A row is a DBIx::QuickORM::Row. Reading a column gives you its inflated value - typed columns come back as Perl values (a JSON column as a ref, a UUID as its object, and so on):

my $name = $user->field('name');

MODIFY NOW, SAVE LATER

Setting a field with the two-argument form stages the change as pending; nothing is written until you save. This lets you make several changes and persist them together:

$user->field(name  => 'robert');     # staged, not written yet
$user->field(email => 'r@example.com');
$user->save;                          # write all pending changes at once

$user->has_pending;                   # true while changes are unsaved
$user->discard;                       # throw away pending changes instead

To set and save in a single step, use update:

$user->update({name => 'robert'});    # stage these changes and save

INFLATED vs RAW vs ORIGINAL VALUES

A row tracks the values it last read from the database (the "stored" values) separately from any pending changes, and can give you each in inflated or raw (database) form:

$user->field('meta');          # inflated value (e.g. a JSON ref)
$user->raw_field('meta');      # raw value as stored in the db (a string)

$user->field(name => 'robert');
$user->field('name');          # 'robert'  - the pending value
$user->stored_field('name');   # 'bob'     - the original, from the db
$user->raw_stored_field('name'); # original, in raw db form

Grab them all at once as a hashref with fields (inflated) or raw_fields (raw).

REFRESH AND DELETE

Re-read the row's stored values from the database, or remove the row:

$user->refresh;
$user->delete;

If you refresh a row that still has unsaved changes the two can disagree; the row is then "desynced" until you discard the changes or call force_sync. See DBIx::QuickORM::Row for the full row interface.

FOLLOW RELATIONS

If the database has foreign keys, DBIx::QuickORM picks them up during introspection, and you can walk from one row to its related rows by the link name.

Use obtain for a link that points at a single row, and follow for a link that points at many. follow returns a handle, so you can refine it before fetching:

# A link to one row (e.g. the author of a post):
my $author = $post->obtain('author');

# A link to many rows (e.g. all posts by a user):
my @posts = $user->follow('posts')->all;

# follow gives you a handle, so you can keep narrowing:
my @recent = $user->follow('posts')->where({year => 2026})->all;

With an autorow base class these also become named accessors on the row, matching the link name, so you can write $post->author or $user->posts->all directly.

For defining links yourself, naming them, and joining across them, see DBIx::QuickORM::Manual::Relations.

RUN A TRANSACTION

Wrap related work in txn. Hand it a callback: if the callback returns normally the transaction commits; if it throws, the transaction rolls back.

$con->txn(sub {
    my $txn = shift;

    my $user = $con->insert(users => {name => 'carol'});
    $con->insert(posts => {user_id => $user->field('id'), title => 'Hello'});

    # Returning normally commits. You can also commit or roll back
    # explicitly, which exits the callback immediately:
    #   $txn->commit;
    #   $txn->rollback;
});

Transactions nest using savepoints, and DBIx::QuickORM can retry a transaction automatically when the database reports a transient conflict. For all of that, see DBIx::QuickORM::Manual::Transactions.

WHERE TO NEXT

You now know enough to be productive. From here:

DBIx::QuickORM::Manual::Concepts

The key ideas (dialects, schema, affinity) that make everything else easier.

DBIx::QuickORM::Manual::Schema

Define your own schema, tables, columns, and custom row classes instead of introspecting everything.

DBIx::QuickORM::Manual::Querying

The full handle interface: where clauses, ordering, limiting, iterators, create, update, and delete.

DBIx::QuickORM::Manual::Relations

Define links (foreign keys), follow them, and join across them.

DBIx::QuickORM::Manual::Transactions

Nested transactions, savepoints, callbacks, and automatic retry.

DBIx::QuickORM::Manual

The documentation hub, linking every tutorial, guide, and reference.

SOURCE

The source code repository for DBIx-QuickORM can be found at https://github.com/exodist/DBIx-QuickORM/.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright Chad Granum <exodist7@gmail.com>.

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

See https://dev.perl.org/licenses/