NAME

DBIO::Deploy::Base::TempDatabase - Deploy base for drivers that diff against a temporary database

VERSION

version 0.900004

DESCRIPTION

A DBIO::Deploy::Base specialization for drivers whose diff builds the target model by deploying the desired schema into a freshly created temporary database and introspecting it -- PostgreSQL and MySQL. (Drivers that use an in-memory database, such as DuckDB and SQLite, do not need this: they override "_build_target_model" in DBIO::Deploy::Base with a :memory: connection.)

It provides the shared temp-database orchestration:

  • "_build_target_model" -- create a temp db, deploy + introspect into it, then always try to drop it (even if the deploy or introspection dies), and re-raise any error of the deploy afterwards. A drop that fails is warned about, naming the database that is still on the server.

  • "_deploy_and_introspect_temp" -- connect to the temp db, run the install DDL, introspect, disconnect.

  • "_temp_connect_info" -- derive the temp-db connection info from the live storage's connect info by rewriting the database name in the DSN.

A subclass supplies only the genuinely engine-specific seam: "_create_temp_db" and "_drop_temp_db" (the CREATE DATABASE / DROP DATABASE dialect, and any transaction handling), plus the three class-name hooks from DBIO::Deploy::Base.

METHODS

_create_temp_db

my $name = $self->_create_temp_db($dbh);

Create a uniquely-named temporary database and return its name. Abstract -- the CREATE DATABASE statement and quoting/transaction handling are engine-specific.

The $dbh it is handed has AutoCommit on and holds no transaction of the caller's. The method ends no transaction itself -- no COMMIT, no local $dbh->{AutoCommit} = 1, which commits the open one inside DBI -- and leaves the handle's AutoCommit as it found it.

_drop_temp_db

$self->_drop_temp_db($dbh, $name);

Drop the temporary database named $name. Abstract.

The $dbh is the one "_create_temp_db" was handed: AutoCommit on, no transaction of the caller's. The method ends no transaction itself and leaves the handle's AutoCommit as it found it.

temp_db_prefix

Prefix for generated temp-database names. Defaults to _dbio_tmp_. A subclass's "_create_temp_db" typically builds the full name as prefix . $$ . '_' . time().

_build_target_model

Reads the temp connection info once ("_temp_connect_info") before anything is created: a storage it cannot be derived from dies here, with no temp database made. Then creates a temp database, deploys + introspects the desired schema into it via "_deploy_and_introspect_temp", and drops the temp database. The drop runs unconditionally (wrapped in its own eval), so a failed deploy or introspection does not by itself leak a temp database; the original error is then re-raised.

A drop that fails does not change the outcome: the model is returned, or the error of the deploy re-raised, as if it had worked. But the database is then still on the server, so the failure is warned about, by the name of the database and with the error of the drop -- passwords in it shown as *** -- for it to be dropped by hand. Every database left behind gets its own warning.

_admin_dbh

The handle CREATE DATABASE and DROP DATABASE run on, handed to "_create_temp_db" and "_drop_temp_db". It has AutoCommit on, and a driver ends no transaction on it, so the transaction of the caller stays as it is. Whenever the storage holds a transaction, or the live handle has AutoCommit off -- also one the storage does not know of, from begin_work on the raw handle or AutoCommit => 0 in the connect info -- the statements run on a connection of their own to the live database, AutoCommit on, closed again when the build is done. Otherwise the live handle is used.

_deploy_and_introspect_temp

my $model = $self->_deploy_and_introspect_temp($temp_db);

Connects to $temp_db (via "_temp_connect_info"), runs the install DDL, introspects the result, disconnects, and returns the model. Errors during deploy or introspection are re-raised after the connection is closed, and are what is raised when closing it fails as well; an error of the disconnect is raised when it is the only one. A connection that cannot be opened dies with DBI's error, the password in it shown as ***.

_temp_connect_info

my ($dsn, $user, $pass) = $self->_temp_connect_info($temp_db);

Derives connection info for the temp database from the live storage's normalised _dbi_connect_info ([ $dsn, $user, $password, \%attrs ]), rewriting the dbname= / database= component of the DSN to $temp_db (appending it when absent). The storage is read as it is at the moment of the call, with or without an AccessBroker (then the broker's current answer), and nothing of it is kept. The DSN has to be a plain, non-empty string: a coderef DSN (also a broker answer that is a dbh_maker), a missing, an empty or a non-scalar DSN dies.

_temp_dsn

my $temp_dsn = $self->_temp_dsn($dsn, $temp_db);

Given the live storage's $dsn and the temp-database name $temp_db, return the DSN string used to connect to the temp database. The default rewrites the database= / dbname= component of $dsn to $temp_db (appending ;dbname=$temp_db when absent) -- the standard form for engines whose DSN names the database with a dbname= key (PostgreSQL, MySQL).

This is the single overridable seam for the temp-db DSN form: a driver whose DSN shape differs (e.g. Firebird's dbi:Firebird:localhost:$db) overrides only this method and inherits the rest of "_temp_connect_info" (the connect-info shape handling, user/password extraction, coderef-DSN guard).

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.