NAME
    DBIx::Fast - DBI fast & easy

SYNOPSIS
        use DBIx::Fast;

        # Connect via DSN
        my $db = DBIx::Fast->new(
            dsn      => 'dbi:MariaDB:database=mydb:localhost',
            user     => 'root',
            password => 'secret',
        );

        # Connect via URI
        my $db = DBIx::Fast->new( dsn => 'mariadb://root:secret@localhost:3306/mydb' );

        # SQLite shortcut
        my $db = DBIx::Fast->new( SQLite => '/path/to/db.sqlite' );

        # Dependency injection
        my $db = DBIx::Fast->new( db => $connector, driver => 'SQLite' );

        # Queries
        $db->all('SELECT * FROM users WHERE active = ?', 1);
        my $rows = $db->results;

        my $user = $db->hash('SELECT * FROM users WHERE id = ?', $id);
        my $name = $db->val('SELECT name FROM users WHERE id = ?', $id);
        my @ids  = $db->flat('SELECT id FROM users');
        my $total = $db->count('users', { active => 1 });

        # CRUD
        $db->insert('users', { name => 'Alice', status => 1 }, time => 'created_at');
        $db->up('users', { name => 'Bob' }, { id => 1 });
        $db->up('users', { name => 'Bob' }, { id => 1 }, 'updated_at');
        $db->delete('users', { id => 1 });

        # Transactions
        $db->txn(sub {
            $db->insert('orders', { total => 100 });
            $db->insert('order_items', { order_id => $db->last_id, product => 'Widget' });
        });

        # Named parameters
        $db->execute('SELECT * FROM users WHERE name = :name', { name => 'Alice' });

DESCRIPTION
    DBIx::Fast is a lightweight database abstraction layer built on top of
    DBI, DBIx::Connector, and SQL::Abstract. It provides fast, simple access
    to SQLite, PostgreSQL, MariaDB, and MySQL databases with Object::Pad.

    Requires Perl v5.38 or later.

CONSTRUCTOR
  new
        my $db = DBIx::Fast->new(%args);

    Accepted parameters:

    "dsn" - DBI DSN string or URI ("mariadb://user:pass@host:port/db")
    "SQLite" - Path to SQLite database file (shortcut)
    "db" - Database name string or pre-built DBIx::Connector object
    "driver" - Database driver: SQLite, Pg, MariaDB, mysql
    "user", "password", "host" - Connection credentials
    "RaiseError", "PrintError", "AutoCommit" - DBI attributes (defaults: 1,
    0, 1)
    "tn" - Enable table name validation (default: 0)
    "abstract" - Enable SQL::Abstract (default: 1)
    "trace", "profile" - DBI tracing/profiling options

ACCESSORS
  db
    DBIx::Connector instance (read/write).

  dbd
    Database driver name: SQLite, Pg, MariaDB, or mysql (read-only).

  dsn
    Processed DSN string (read-only).

  Q
    SQL::Abstract instance (read/write).

  sql
    Current SQL statement (read/write).

  last_sql
    Last executed SQL statement (read/write).

  p
    Current bind parameters arrayref (read/write).

  results
    Last query result (read/write).

  last_id
    Last insert ID (read/write).

  errors
    All errors as arrayref (read-only).

  last_error
    Last error message string (read-only).

  args
    Processed constructor configuration hashref (read-only).

QUERY METHODS
  all
        $db->all('SELECT * FROM users WHERE id > ?', 10);
        my $rows = $db->results;  # arrayref of hashrefs

    Executes SQL and stores all rows in "results".

  hash
        $db->hash('SELECT * FROM users WHERE id = ?', 1);
        my $row = $db->results;  # hashref

    Executes SQL and stores a single row in "results".

  val
        my $name = $db->val('SELECT name FROM users WHERE id = ?', 1);

    Executes SQL and returns a single scalar value.

  flat
        my @names = $db->flat('SELECT name FROM users');

    Executes SQL and returns a flat list of values.

  array
        $db->array('SELECT name FROM users');
        my $names = $db->results;  # arrayref

    Executes SQL and stores a single column as arrayref in "results".

  count
        my $total = $db->count('users');
        my $active = $db->count('users', { status => 1 });

    Returns row count, optionally filtered by WHERE conditions.

  exec
        my $sth = $db->exec('CREATE TABLE foo (id INT)');
        my $sth = $db->exec('INSERT INTO foo VALUES (?)', 42);

    Executes raw SQL with optional bind parameters. Records query in
    profiler if initialized. Returns the statement handle.

  execute
        $db->execute('SELECT * FROM users WHERE name = :name', { name => 'Alice' });
        $db->execute('SELECT * FROM users WHERE id = :id', { id => 1 }, 'hash');

    Executes SQL with named parameter substitution (":name" syntax). Third
    argument selects result type: "arrayref" (default) or "hash".

CRUD METHODS
  insert
        $db->insert('users', { name => 'Alice', status => 1 });
        $db->insert('users', { name => 'Alice' }, time => 'created_at');
        my $id = $db->last_id;

    Inserts a row using SQL::Abstract. Sets "last_id" automatically based on
    the database driver.

  update
        $db->update('users', {
            sen   => { name => 'Bob', status => 1 },
            where => { id => 1 },
        });
        $db->update('users', {
            sen   => { name => 'Bob' },
            where => { id => 1 },
        }, time => 'updated_at');

    Updates rows using SQL::Abstract. Pass "time => 'column_name'" to
    auto-set a timestamp column to now().

  up
        $db->up('users', { name => 'Bob' }, { id => 1 });
        $db->up('users', { name => 'Bob' }, { id => 1 }, 'updated_at');

    Shortcut for "update". Arguments: table, data hashref, where hashref,
    optional time column name (positional).

  delete
        $db->delete('users', { id => 1 });

    Deletes rows using SQL::Abstract.

SUBSYSTEMS
  schema
        my $schema = $db->schema;

    Returns the DBIx::Fast::Schema instance (lazy-loaded) for table
    introspection.

  transaction
        my $tx = $db->transaction;

    Returns the DBIx::Fast::Transaction instance (lazy-loaded).

  txn
        $db->txn(sub { ... });
        $db->txn(sub { ... }, { max_retries => 5 });

    Shortcut for "$db->transaction->do(...)". Executes a code block inside a
    transaction with automatic commit/rollback and deadlock retry.

  profiler
        my $profiler = $db->profiler;

    Returns the driver-specific profile instance
    (DBIx::Fast::Profile::MariaDB, DBIx::Fast::Profile::SQLite, etc.) for
    native database diagnostics. Lazy-loaded on first access.

  tracker
        my $tracker = $db->tracker;

    Returns the DBIx::Fast::Profiler instance for query tracking. Once
    activated, all queries executed through "all", "hash", "val", "flat",
    "array", "exec", "insert", "update", "up", and "delete" are recorded
    with timing information.

        # Activate tracking
        $db->tracker;

        # Run some queries
        $db->all('SELECT * FROM users');
        $db->insert('logs', { action => 'login' });
        $db->up('users', { last_login => $db->now }, { id => 1 });

        # Get statistics
        my $stats = $db->tracker->get_stats;
        printf "Queries: %d, Total: %.4fs, Avg: %.4fs\n",
            $stats->{total_queries}, $stats->{total_time}, $stats->{avg_time};

        # Slow queries
        my $slow = $db->tracker->get_slow_queries(5);
        for my $q (@$slow) {
            printf "%.4fs - %s\n", $q->{duration}, $q->{sql};
        }

        # Stats by type (SELECT, INSERT, UPDATE, DELETE)
        my $by_type = $db->tracker->get_detailed_stats;

        # Print formatted report
        $db->tracker->print_stats;

        # Clear recorded queries
        $db->tracker->clear;

  load_extension
        my $ext = $db->load_extension('Schema');

    Dynamically loads and caches a "DBIx::Fast::*" extension module.

UTILITY METHODS
  now
    Returns the current timestamp in MySQL format ("YYYY-MM-DD HH:MM:SS").

  set_error
        $db->set_error($code, $message);

    Appends an error to the "errors" array and updates "last_error".

  make_sen
        $db->sql('SELECT * FROM users WHERE name = :name AND age = :age');
        $db->make_sen({ name => 'Alice', age => 30 });
        # $db->sql is now 'SELECT * FROM users WHERE name = ? AND age = ?'
        # $db->p is ['Alice', 30]

    Replaces named placeholders (":name") with "?" in order of appearance in
    the SQL string. Supports duplicate placeholders.

  q
        $db->q('SELECT * FROM users WHERE id = ?', 1);

    Sets "sql" and "p" (bind parameters) for subsequent use.

  execute_prepare
        $db->sql('INSERT INTO users (name) VALUES (?)');
        $db->execute_prepare('Alice');

    Prepares and executes the current "sql" with bind parameters.

  TableName
        my $table = $db->TableName('users');

    Validates a table name. When "tn => 1" is set, checks that the table
    exists in the schema cache.

  Exception
        $db->Exception("Something went wrong");

    Throws an exception via "croak", respecting "RaiseError" and
    "PrintError" settings.

SEE ALSO
    DBI, DBIx::Connector, SQL::Abstract, Object::Pad

AUTHOR
    Harun Delgado <hdp@nurmol.com>

LICENSE AND COPYRIGHT
    This is free software under the Artistic License 2.0.
    <http://www.perlfoundation.org/artistic_license_2_0>

