Revision history for DBIx-Fast
0.17 20/08/26
- DSN parsing is more accepting (strictly additive - no DSN that
worked before changes): the native "dbi:..." prefix is
case-insensitive; "dbi:SQLite::memory:" and other DSNs whose
driver-specific part contains colons are no longer rejected;
and a credential-less URI ("mariadb://localhost/db", socket /
peer auth) is accepted. Verified byte-identical output for every
previously-valid DSN.
- The vestigial "quote" constructor option no longer runs a dead
$dbh->quote() no-op on connect; it is still accepted (and stored
in args) for backward compatibility but has no effect - identifier
quoting is automatic and driver-aware.
- Security: the CRUD operator whitelist now covers non-hash WHERE
specs. update()/delete() accept SQL::Abstract's arrayref
(OR-of-conditions) and scalarref (literal SQL) WHERE shapes;
_safe_columns bailed out silently on anything that was not a
hash, letting an injected operator or literal SQL through when
the WHERE was built as an arrayref/scalarref from untrusted
input. Now validated recursively; scalarref WHERE is rejected.
Regression test in t/security.t.
- Fix: read methods (all/flat/hash/val/array/count) use the 3-arg
prepare_cached form, so a live query() iterator on the same SQL
is no longer finished out from under the caller (silent
truncation, a 0.17 regression).
- Fix: execute() with no bind argument clears any $p left from a
previous query instead of binding it to the new statement.
- Fix: qualified table names ("schema.table") work in count(),
upsert(), insert_many(), upsert_many() and Schema introspection
(were quoted as one identifier via _quote_id; now per-segment
via _quote_ident_path, matching insert/update/delete).
- Fix: Schema tables cache is a hashref when the database has no
tables (tn => 1 on an empty DB gave a misleading crash).
- Fix: cache => 0 (or '') no longer switches caching on; the guard
is truthiness, not defined-ness.
- Fix: a transaction clears its savepoints on successful commit
too, so a later rollback_to() cannot fire on a stale name.
- Fix: t/security.t guards its LRU::Cache require (was bare, would
fail on smokers without the optional backend); Result.pm POD
link to query() points at DBIx::Fast::SQL; META repository url
is a valid https URI (an SSH spec was silently dropped).
0.17 18/08/26
[ New ]
- DBIx::Fast::Connector: fork-safe lazy connections, throttled
ping, automatic reconnect (replaces DBIx::Connector).
- query() row-by-row iterator via DBIx::Fast::Result.
- Query cache (DBIx::Fast::Cache / Cached): TTL, tag invalidation,
LRU or CHI backends, CRUD auto-invalidation.
- upsert() / insert_many() / upsert_many(), driver-aware.
- txn(isolation => ...), whitelist-validated and restored on exit.
- DBIx::Fast::Profile::Pg: native PostgreSQL diagnostics.
- DBIx::Fast::Profile::mysql: native MySQL diagnostics (inherits
the MariaDB profile; overrides EXPLAIN, removed-in-8.0 EXTENDED).
- DBIx::Fast::Output: unified profiler output - text (default),
JSON lines or callback; profile_output / $obj->output(...).
- now_utc(); examples/profiler-pg.pl.
[ Security ]
- SQL injection hardening: operator whitelists for all CRUD
WHERE/SET specs; identifiers validated AND quoted everywhere.
- Credentials never echoed: connect/DSN errors redacted;
errors_redact also scrubs backticks.
- Fork safety: AutoInactiveDestroy + pid-guarded disconnect.
- Cache keys include method + connection identity.
- Deadlock retry gated on driver error codes, not message text;
isolation-restore failure closes the connection (fail closed).
- EXPLAIN allowlists (MariaDB/Pg) resist literal-quoting tricks,
file access and DoS functions; terminal escapes stripped.
[ Fixes ]
- Transaction retry/rollback state, savepoint sequencing, memory
leak (weakened back-refs), val() first-column contract.
- DSN parsing: host/port, ':' in passwords, postgres:// schemes,
driver-correct utf8 flags; Pg isolation and last_insert_id.
- Cache: bounded tag index, TTL pushed down to CHI, honest stats.
- Profiler text output degrades gracefully on bare installs:
Cpanel::JSON::XS / Term::ANSIColor are recommends, so print_query
falls back to core JSON::PP and colorless output when absent.
- Profile::MariaDB information_schema queries carry explicit
lowercase aliases (MySQL 8 uppercases unaliased columns) and
get_processes no longer uses the MariaDB-only time_ms column.
- Exceptions: Exception() honors errors_redact, attaches last_error
only when recent, POD documents the real always-croak contract;
a failed transaction records its error once, not three times.
[ Performance ]
- fetchall_arrayref C-loop fetches, prepare_cached everywhere,
lazy SQL::Abstract, cheaper profiler/cache internals.
[ Packaging ]
- Query/CRUD methods live in the DBIx::Fast::SQL role, composed
into DBIx::Fast - identical API, the main module is half the
size and each file documents its own methods.
- Test suite coherence pass: the committed fixture t/db/test.db is
read-only (writing suites use tempdirs; regenerated from
t/db/schema.sql, 455KB of stale rows dropped), duplicate suites
merged (02-schema/dbix-fast/driver MariaDB.t), live tests skip
cleanly when the server is down, tables are per-file prefixed
and cleaned up, and the whole suite passes under prove -j.
TableName() format-validates unconditionally (insert/update had
accepted names count/upsert rejected).
- Optional deps as recommends; whole distro on Object::Pad; full
POD with coverage tests; 500+ tests on SQLite/MariaDB/Pg/MySQL
(CI service containers); LICENSE, SECURITY.md, README.md.
0.161 21/03/26
- Connection mode: ping → fixup (eliminates ping overhead per query)
0.16 20/03/26
- Migration from Moo to Object::Pad (requires Perl v5.38+)
- New: tracker() - query profiling across all methods (all/hash/val/flat/array/exec/insert/update/delete)
- New: Profile::Base, Profile::MariaDB, Profile::SQLite (driver-specific diagnostics)
- New: Transaction module with nested support, savepoints, deadlock retry
- Removed: up2() (unused), Query.pm (unused), execute_prepare2 (duplicate), make_sen old (buggy)
- Renamed: make_senN → make_sen (correct implementation)
- Performance: statement caching (prepare_cached), inlined query methods, _make_where with join
- Bug fixes: Schema typos, HandleError return 0, Time::HiRes import, `rows` keyword MariaDB 11+
- Bug fixes: Profile::MariaDB init (execute→exec), session stats columns, getrusage optional
- Tests: 147 SQLite + 34 MariaDB + 14 profiler
- Updated CI: Perl 5.38/5.40, bookworm, Object::Pad
- Full POD documentation on all 8 modules
- Added examples/profiler-mariadb.pl
0.15 06/09/24
- args : SQLite
0.14 03/09/24
- POD
0.13 01/09/24
- t/exception.t
- Clean
0.12 01/09/24
- Test
- DSN / URI
- _check_dsn / _make_dsn_dbi
0.11 01/09/24
- SQL::Abstract
0.10 01/09/24
- _make_dsn
- _check_dsn
- driver && dbd
- t/functions.t
0.09 01/01/20
0.08 26/01/16
- Force UTF8
0.07 24/01/16
0.06 23/03/15
0.05 mié mar 18 03:30:38 CET 2015
- More test
- Method : array
0.04 mié mar 18 00:59:19 CET 2015
- Test
0.03 mar mar 17 00:50:31 CET 2015
- New methods : value & count
- Dereference hash reference for using 'keys'
0.02 mar mar 17 00:20:48 CET 2015
- extra_args -> time NOW()
0.01 -