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	-