Revision history for DBIO-Firebird
0.900004 2026-11-08
* Storage
- The text of an error names the type, the column, the constraint
and the table, never a value: the key of a PRIMARY KEY, UNIQUE
or FOREIGN KEY violation (Problematic key value is ("A" = ***,
"B" = ***)) and the string of a conversion error are masked,
also for short bound values and a value holding quotes, commas
or line breaks; the refusals for a boolean or numeric column
name the column only. $dbh->errstr stays raw.
- Three transports: DBD::Firebird (DBIO::Firebird::Storage),
DBD::InterBase (Storage::InterBase) and DBD::ODBC
(DBIO::Firebird::Storage::ODBC, ADR 0010); the ODBC storage is
declared as storage_type and untested against a Firebird ODBC
driver.
- SQL dialect 3 is forced on connect, also on a connection an
AccessBroker opens. Another ib_dialect in the DSN or as an
attribute is refused, naming the place, never the DSN or a
password.
- Dates and timestamps are read in the ISO formats by default
(ib_time_all 'ISO' on every native connection, not on
Storage::ODBC).
- Text is UTF8 on every native connection: ib_charset=UTF8 and
ib_enable_utf8 => 1 are added, also to every AccessBroker answer,
unless the connect info names its own. Text comes back as
characters and unflagged strings are flagged when bound.
- ib_ attributes from an AccessBroker connect over dbi:Firebird:
(not on Storage::ODBC). A HostBound view (Replicated) is bound
into the DSN as db=host[/port]:path, host= / hostname= with
port=, or a local database name; any other form is refused
naming the form.
- Reading and writing keeps working after DDL and after a rolled
back transaction with statement caching on; a statement handle the
DBD destroyed is prepared anew (ADR 0011).
- A commit or DDL statement the server refuses dies with the
server's error (a DBIO::Exception::Server) on the same
connection, and is not repeated after a reconnect.
- A BOOLEAN value is checked on both the single and the bulk path:
1, 0 and undef pass, 'true' and 'false' (any case) are
translated, '' is FALSE, anything else dies naming the column.
Not on the ODBC storage.
- A text or binary BLOB column can be searched by value; a value
too long to compare on Firebird is refused before the DBD,
naming table and column. The placeholders are found by core's
scanner, so a ? in a literal, quoted name or comment is left
alone.
- A value that is no number is refused for a numeric column
instead of being stored as 0. Not on Storage::ODBC.
- Boolean, numeric and UTF8 adjustments of bound values run
through core's _adjust_bind_values and leave the caller's bind
list alone.
- $rs->rand orders by RAND(), $rs->explain returns the plan
without running the statement (refused over ODBC), and
$rs->results_exist works. $rs->except, except_all, intersect
and intersect_all are refused: Firebird has only UNION
(ADR 0039).
- transactional_ddl is declared 0: a whole deploy batch is not
bracketed (see "Transactional DDL -- not claimed" in
DBIO::Firebird::Deploy).
* DDL
- install_ddl writes declared sizes (varchar, char, numeric,
decimal) and Firebird's type names: TIMESTAMP, BIGINT, SMALLINT,
DOUBLE PRECISION, BOOLEAN, and BLOB SUB_TYPE TEXT for an unsized
string and mediumtext/longtext.
- Every identifier is double-quoted, as the storage quotes it, so
the installed table is the table the ORM queries. A column
without is_nullable is NOT NULL.
- boolean is a BOOLEAN column (Firebird 3 is the minimum) with
DEFAULT TRUE / FALSE from 0, 1, 'true' or 'false'.
is_auto_increment is GENERATED BY DEFAULT AS IDENTITY; an
identity with a default or on a non-integer type dies.
- Foreign keys and unique constraints are written after all CREATE
TABLE statements, so table order and cycles do not matter;
on_delete and on_update come from the belongs_to or from the
has_many's cascade_delete and cascade_copy; is_deferrable is
refused.
- The canonical index declaration (idx, indices; core ADR 0061)
creates plain or unique indexes and refuses expression,
partial and descending ones. An index the primary key, a unique
constraint or a foreign key already provides is not built twice.
- A string default with an apostrophe is quoted correctly.
- Refused with a DBIO::Exception naming table and column: bit,
enum, time zone types, binary and varbinary below Firebird 4,
NUMERIC/DECIMAL above 18 digits (DBD::Firebird cannot bind or
read an INT128), and a table or view name with a dot.
* Diff
- Foreign keys, unique constraints and primary keys are part of
the diff (DBIO::Firebird::Diff::Constraint): new tables get them
after every CREATE TABLE, existing tables get DROP CONSTRAINT /
ADD CONSTRAINT, compared by what they say, not by name. The
order lets an index or key on a dropped column go first, and
DROP TABLE runs child before parent.
- Views are created, replaced and dropped from rdb$view_source; a
changed definition is dropped before the table changes and created
again after. A name that is a table on one side and a view on the
other is refused.
- A column change the server always refuses (narrowing CHAR,
character to non-character, no conversion, fewer digits, a type
change of a key column) is refused before the first statement.
Adding or removing IDENTITY on an existing column is refused.
- A name that differs from the schema's only in letter case is
refused, naming every pair, instead of DROP + CREATE (see "NAMES
THAT DIFFER ONLY IN CASE" in DBIO::Firebird::Diff).
- A default the declaration no longer has is dropped; the column
size is carried on ADD and ALTER ... TYPE.
* Deploy
- DBIO::Firebird::Deploy inherits apply and upgrade from
DBIO::Deploy::Base (ADR 0013): a diff that drops something or
changes a column lossily runs with allow_destructive => 1 and
stops before its first statement without it; dry_run returns the
diff and executes nothing. Widening pairs (smallint to integer,
date to timestamp, char to varchar, a larger size) are not lossy.
- apply also refuses, naming table and column, a NOT NULL column
without a default added to a table that holds rows and a column
that becomes NOT NULL over a NULL.
- diff, upgrade and install work on a schema connected through an
AccessBroker (a coderef or dbh_maker answer is refused). The
temporary database is created on the server also when the DSN
spells host and path as attributes; its errors do not quote the
password.
* Introspect
- The model reads columns, indexes, unique constraints, foreign keys
and primary key names from the rdb$ tables (see "THE INTROSPECTED
MODEL" in DBIO::Firebird::Introspect); field types follow the
server, including NUMERIC/DECIMAL, boolean, int128, decfloat and
time zone types.
- A foreign key names its constraint under constraint_name
(core ADR 0021); is_auto_increment is read from rdb$identity_type.
* Dependencies
- Requires DBIO 0.900004 and DBD::Firebird;
DateTime::Format::Strptime is recommended.
* Tests and documentation
- DBIO::Firebird::Test::Conformance answers core's DDL, Diff and
Bind case tables (ADR 0012), including conformance_upgrade and
the deploy cases.
- README states where the driver stands for async use.
0.900001 2026-07-12
* Diff
- Fix DROP INDEX / DROP TABLE collision in full-schema sync (karr #14,
from dbio core #77 / dbio-postgresql #32). When diff reconciled a
live schema containing a table absent from the target (removed from
the app's DBIO classes, or an unmanaged leftover), it emitted both
DROP TABLE <t> and a later standalone DROP INDEX for one of that
table's indexes; since Firebird's DROP TABLE already removes the
table's own indexes, the standalone DROP INDEX failed once the table
was gone and aborted apply()/upgrade(). DBIO::Firebird::Diff::Index
now receives the tables sections (via the aux-section wiring in
DBIO::Firebird::Diff) and suppresses a standalone DROP INDEX for any
index whose owning table is itself being dropped in the same pass.
Indexes of surviving tables are still dropped as before. The diff
signature stays backward compatible: absent table sections yield an
empty dropped set (old two-argument behaviour).
* Dependencies
- DBD::Firebird is now a hard "requires" instead of "recommends":
the driver is useless without it, and t/00-load.t failed (rather
than skipping) when it was absent
(codeberg #1, reported by Slaven Rezić / eserte)
- Requires core DBIO >= 0.900001 (family-wide version alignment)
* Project
- Added SECURITY.md (CPAN Security Group guidelines v1.5.0)
* Tests
- Add t/45-diff-drop-table-index-cascade.t and extend t/40-diff.t:
full-diff regression for the DROP INDEX / DROP TABLE collision
(karr #14) plus Diff::Index unit cases for the new tables-aware drop
suppression, including an over-suppression guard (a surviving table's
index is still dropped standalone)
- t/50-introspect-contract.t: make the generated-code table()
assertions quote-agnostic (['"]). DBIO::Generate renders all
literals through DBIO::Generate::Util::pl_str -> B::perlstring,
which always emits double quotes, so the old single-quoted
regexes failed 2/40 offline; matches Core's quote-agnostic
precedent in ../dbio/t/generate/*
0.900000 2026-06-23
First release. Firebird and InterBase database driver for DBIO.
* Storage
- DBD::Firebird storage (driver "Firebird") and DBD::InterBase
storage variant (driver "InterBase"), auto-detected from the DSN
- shared Firebird/InterBase storage base with generator-based
autoincrement, savepoint support, and server-version detection
- ODBC connection variant supported via the InterBase storage path
- softcommit and datetime connect-calls, SQL dialect 3 forcing
- quoted identifiers and INSERT ... RETURNING
* SQLMaker
- Firebird FIRST/SKIP limit dialect via apply_limit
* Schema component and shortcut
- DBIO::Firebird schema component pinning the storage type
- "use DBIO -fb" shortcut (DBIO::Shortcut::fb)
* Types and DateTime
- Firebird type-system mapping for introspection and DDL
- DateTime formatter for Firebird / InterBase
* Introspection
- native introspection via RDB$ system tables: tables, columns,
indexes, foreign keys, and unique constraints
* DDL and deploy
- native DDL generation from DBIO Result classes, deduping sources
that share a physical table, skipping subquery/view sources,
dereferencing literal table names, and emitting CREATE VIEW for
non-virtual views
- desired-state deploy and upgrade via test-deploy-and-compare
* Diff
- native model diff for tables, columns, and indexes
Keyboard Shortcuts
Global
s
Focus search bar
?
Bring up this help dialog
GitHub
gp
Go to pull requests
gi
Go to GitHub issues (only if GitHub is preferred repository)