DBIx::C...Storage(3)

✨ DBIx::Class::Storage β€” Generic Storage Handler ✨

okay bestie, so this is DBIx::Class::Storage(3) from the User Contributed Perl Documentation, and honestly? it's giving foundation energy. like it's the base class that all the other storage classes are built on top of. main character vibes but make it infrastructure πŸ’…


🌸 DESCRIPTION 🌸

A base implementation of the common Storage methods, no cap. If you want the specific deets about DBI-based storage, go peek at DBIx::Class::Storage::DBI instead β€” that's the version with all the extra lore πŸ¦‹


πŸŽ€ METHODS πŸŽ€

🌈 new

Arguments: $schema

Instantiates the Storage object. literally just makes one. that's it. that's the whole vibe ✨

🌈 set_schema

Resets the schema class or object that owns this storage object. you'd use this during "clone" in DBIx::Class::Schema β€” like when the storage needs to be re-homed to a different schema owner 🫢

🌈 connected

Returns true if we've got an open storage connection going on, and false if it's not (yet) open. a little vibe check for your connection 😌

🌈 disconnect

Closes any open storage connection. unconditionally. no questions asked, no goodbyes, it's just over πŸ’€

🌈 ensure_connected

Kicks off a connection to the storage if one isn't already open. like "hey are you connected? no? okay connecting now" 🧚

🌈 throw_exception

Throws an exception β€” it croaks. dramatic but necessary πŸ”₯

🌈 txn_do

Arguments: $coderef, @coderef_args? Return Value: The return value of $coderef

Executes $coderef with (optional) arguments @coderef_args atomically, and returns its result (if any). If an exception gets caught, a rollback is issued and then the exception is rethrown. and if the rollback itself fails (i.e. it throws an exception), you get an exception thrown that includes a "Rollback failed" message. messy but honest 😭

For example:

my $author_rs = $schema->resultset('Author')->find(1);
my @titles = qw/Night Day It/;

my $coderef = sub {
  # If any one of these fails, the entire transaction fails
  $author_rs->create_related('books', {
    title => $_
  }) foreach (@titles);

  return $author->books;
};

my $rs;
try {
  $rs = $schema->txn_do($coderef);
} catch {
  my $error = shift;
  # Transaction failed
  die "something terrible has happened!"
    if ($error =~ /Rollback failed/);          # Rollback failed

  deal_with_failed_transaction();
};

In a nested transaction (like, calling txn_do() from inside a txn_do() coderef), only the outermost transaction will issue a "txn_commit". and txn_do() can be called in void, scalar and list context and it'll behave as expected. iconic, honestly πŸ‘‘

⚠️ bestie pls read this one: all of the code in your coderef β€” including non-DBIx::Class code β€” is part of the transaction. This transaction may fail out halfway, or it may get partially double-executed (in the case that our DB connection failed halfway through the transaction, in which case we reconnect and restart the txn). So it's best that any side-effects in your coderef are idempotent (that is, can be re-executed multiple times and get the same result), and that you check up on your side-effects in the case of transaction failure. no cap, this matters πŸ™ˆ

🌈 txn_begin

Starts a transaction. simple as that.

but lowkey, go see the preferred "txn_do" method instead β€” it lets a whole entire code block be executed transactionally, which is usually what you actually want πŸ’–

🌈 txn_commit

Issues a commit of the current transaction.

Important: it does not perform an actual storage commit unless there's a DBIx::Class transaction currently in effect (i.e. you called "txn_begin"). so like, don't expect magic if you never started anything ✨

🌈 txn_rollback

Issues a rollback of the current transaction. A nested rollback will throw a DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION exception, which lets the rollback propagate all the way up to the outermost transaction. teamwork 🫢

🌈 svp_begin

Arguments: $savepoint_name?

Creates a new savepoint using the name you pass in as the argument. If you don't provide a name, a random one gets used. surprise savepoint πŸŽ€

🌈 svp_release

Arguments: $savepoint_name?

Releases the savepoint you gave as the argument. If none is provided, it releases the savepoint created most recently. This will implicitly release all savepoints created after the one explicitly released as well β€” so yes, it's a whole cascade situation 🌊

🌈 svp_rollback

Arguments: $savepoint_name?

Rolls back to the savepoint you passed as the argument. If none is provided, it rolls back to the savepoint created most recently. This will implicitly release all savepoints created after the savepoint we rollback to. bye bye to the later ones πŸ’…

🌈 txn_scope_guard

An alternative way of transaction handling, based on DBIx::Class::Storage::TxnScopeGuard:

my $txn_guard = $storage->txn_scope_guard;

$result->col1("val1");
$result->update;

$txn_guard->commit;

If an exception occurs, or the guard object otherwise leaves the scope before "$txn_guard->commit" is called, the transaction will be rolled back by an explicit "txn_rollback" call. In essence this is basically a "txn_begin"/"txn_commit" pair, minus the stress of having to call "txn_rollback" in all the right places 😌

⚠️ but heads up: since there's no defined code closure, there will be no retries and other magic upon database disconnection. If you need that functionality, see "txn_do" instead πŸ¦‹

🌈 sql_maker

Returns a "sql_maker" object β€” normally an object of class "DBIx::Class::SQLMaker". your little SQL factory 🌸

🌈 debug

Causes trace information to be emitted on the "debugobj" object. (or "STDERR" if "debugobj" hasn't specifically been set).

This is the equivalent to setting "DBIC_TRACE" in your shell environment. same energy, different doorway ✨

🌈 debugfh

An opportunistic proxy to ->debugobj->debugfh(@_).

If the currently set "debugobj" doesn't have a "debugfh" method, calling this is a no-op. it just… doesn't do anything. no drama πŸ’€

🌈 debugobj

Sets or retrieves the object used for metric collection. Defaults to an instance of DBIx::Class::Storage::Statistics that is compatible with the original method of using a coderef as a callback. See the aforementioned Statistics class for more information πŸ‘‘

🌈 debugcb

Sets a callback to be executed each time a statement is run; takes a sub reference. The callback is executed as $sub->($op, $info) where $op is SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.

but ngl, see "debugobj" for a better way 😌

🌈 cursor_class

The cursor class for this Storage object. that's the whole thing πŸŽ€

🌈 deploy

Deploys the tables to storage (CREATE TABLE and friends in a SQL-based Storage class). This would normally be called through "deploy" in DBIx::Class::Schema. it's giving "build the whole empire" energy 🏰

🌈 connect_info

The arguments of "connect_info" are always a single array reference, and they're Storage-handler specific.

This is normally accessed via "connection" in DBIx::Class::Schema, which encapsulates its argument list in an arrayref before calling "connect_info" here. so it wraps it up all cute before handing it over 🎁

🌈 select

Handles a select statement.

🌈 insert

Handles an insert statement.

🌈 update

Handles an update statement.

🌈 delete

Handles a delete statement. yes all four of these are just one-liners, they're the classic quartet 🎢

🌈 select_single

Performs a select, fetch and return of data β€” handles a single row only. one row and one row only, bestie βœ‹

🌈 columns_info_for

Returns metadata for the given source's columns. This is deprecated, and will be removed before 1.0. You should be specifying the metadata yourself if you need it. like, it's on its way out, don't get attached πŸ’€


πŸ¦‹ ENVIRONMENT VARIABLES πŸ¦‹

πŸ’œ DBIC_TRACE

If "DBIC_TRACE" is set then trace information is produced (as when the "debug" method is set).

If the value is of the form 1=/path/name then the trace output is written to the file /path/name. fancy 🌟

⚠️ This environment variable is checked when the storage object is first created (when you call connect on your schema). So, run-time changes to this environment variable will not take effect unless you also re-connect on your schema. so like… set it before, not during πŸ™ˆ

πŸ’œ DBIC_TRACE_PROFILE

If "DBIC_TRACE_PROFILE" is set, DBIx::Class::Storage::Debug::PrettyTrace will be used to format the output from "DBIC_TRACE". The value it is set to is the "profile" that will be used. If the value is a filename, the file is read with Config::Any and the results are used as the configuration for tracing. See "new" in SQL::Abstract::Tree for what that structure should look like ✨

πŸ’œ DBIX_CLASS_STORAGE_DBI_DEBUG

Old name for DBIC_TRACE. a little throwback, retro vibes πŸ•°οΈ


🌈 SEE ALSO 🌈

  • DBIx::Class::Storage::DBI β€” reference storage implementation using DBI and a subclass of SQL::Abstract::Classic ( or similar )

πŸ’– FURTHER QUESTIONS? πŸ’–

Check the list of additional DBIC resources. they've got you 🫢


This module is free software copyright by the DBIx::Class (DBIC) authors. You can redistribute it and/or modify it under the same terms as the DBIx::Class library. slay, free software πŸ’…


and that's the whole page bestie β€” brought to you by perl v5.42.0, dated 2025-01-22, signed off with love from the User Contributed Perl Documentation girlies πŸŒΈβœ¨πŸ¦‹

πŸ“¦ where this page comes from