DBIO-MySQL-EV

Async MySQL/MariaDB storage for DBIO using EV::MariaDB.

Bypasses DBI entirely - speaks MariaDB's C client library directly for maximum performance with pipeline mode support.

Features

Synopsis

# EV async is opt-in per connection (ADR 0030). Loading the MySQL::EV
# component is an inert marker; the { async => 'ev' } attribute on
# connect() is what activates the EV backend. The 'ev' mode is
# registered by DBIO::MySQL::Storage (the sync driver).
package MyApp::Schema;
use base 'DBIO::Schema';
__PACKAGE__->load_components(qw(MySQL MySQL::EV));

my $schema = MyApp::Schema->connect(
    'dbi:MariaDB:database=myapp;host=localhost',
    'myapp', 'secret',
    { async => 'ev' },
);

# Async queries return Futures
$schema->resultset('Artist')->all_async->then(sub {
    my @artists = @_;
    say $_->name for @artists;
});

# insert_async resolves with the returned-columns HASHREF (autoinc PK
# overlaid onto the insert data) -- MySQL has no RETURNING clause, the
# EV storage reads SELECT LAST_INSERT_ID() on the pinned connection.
$schema->storage->insert_async('artist', { name => 'Tom' })->then(sub {
    my $returned = shift;
    say "inserted, new id = $returned->{id}";
});

# Pipeline
$schema->storage->pipeline(sub {
    Future->needs_all(
        map { $schema->resultset('Artist')->create_async({ name => $_ }) }
        @names
    );
});

AccessBroker

use DBIO::AccessBroker::Static;

my $broker = DBIO::AccessBroker::Static->new(
    host     => 'localhost',
    database => 'myapp',
    user     => 'myapp',
    password => 'secret',
);

# AccessBroker works with { async => 'ev' } the same way as the sync
# driver: per-spawn credentials are re-fetched and normalised for the
# EV::MariaDB native conninfo shape.
my $brokered = MyApp::Schema->connect($broker, { async => 'ev' });

Async

The storage class returns Future objects for all query operations, enabling fully non-blocking database access. Per ADR 0031, the return shape of each *_async method is binding:

The Future returned by every method auto-wraps a plain (non-Future) return in a then callback into a resolved Future (ADR 0031 §4) -- this is the native Future.pm behaviour, so chained callbacks can simply return $value without wrapping.

Pipeline

Pipeline mode batches multiple queries into a single network round-trip. Up to 64 queries can be in-flight simultaneously.

Event Loop Compatibility

EV::MariaDB uses the EV event loop. This works with:

Testing

# Load tests (skip without EV::MariaDB)
prove -l t/00-load.t t/01-storage-api.t

# Integration tests (need MySQL/MariaDB + EV::MariaDB)
DBIO_TEST_MYSQL_DSN='dbi:MariaDB:database=testdb;host=localhost' \
DBIO_TEST_MYSQL_USER=root \
DBIO_TEST_MYSQL_PASS=secret \
  prove -lr t/

Requirements

Copyright (C) 2026 DBIO Authors

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.