NAME
DBD::Spanner - Perl DBI Driver for Google Cloud Spanner with Non-Blocking Async Support
SYNOPSIS
use DBI;
# Standard Connection (gRPC default transport)
my $dbh = DBI->connect(
'dbi:Spanner:projects/my-project/instances/my-instance/databases/my-database',
'', '', { RaiseError => 1, AutoCommit => 1 }
);
# REST Transport Connection
my $dbh_rest = DBI->connect(
'dbi:Spanner:projects/my-project/instances/my-instance/databases/my-database;transport=rest',
'', ''
);
# Connection Health Check
$dbh->ping();
# Asynchronous Non-Blocking Query
my $sth = $dbh->prepare('SELECT id, display_name FROM users WHERE active = ?', { Async => 1 });
my $rv = $sth->execute(1);
if ($rv eq '0E0') {
# Event loop integration via socket / file descriptor fileno
my $fd = $sth->fileno();
while ($sth->FETCH('AsyncWantRead')) {
if ($sth->async_read_ready()) {
my $row = $sth->fetch_async_row();
last if !defined $row;
print "User ID: $row->[0], Name: $row->[1]\n";
}
}
}
# Transaction Management
$dbh->begin_work();
$dbh->do('INSERT INTO users (id, display_name) VALUES (101, "Alice")');
$dbh->commit();
# Bulk Tuple Batch Execution
my $sth_batch = $dbh->prepare('INSERT INTO logs (id, event) VALUES (?, ?)');
$sth_batch->bind_param_array(1, [1, 2, 3]);
$sth_batch->bind_param_array(2, ['click', 'view', 'purchase']);
my $tuples = $sth_batch->execute_array({ ArrayTupleStatus => [] });
DESCRIPTION
DBD::Spanner provides a full-featured Perl DBI driver for Google Cloud Spanner. It supports synchronous and non-blocking asynchronous queries, gRPC and REST transports, transaction boundaries, bulk batch tuple execution, and Information Schema catalog metadata queries.
CONNECTING
DSN Syntax
dbi:Spanner:projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID
dbi:Spanner:project=PROJECT_ID;instance=INSTANCE_ID;database=DATABASE_ID
Transport Options
Cloud Spanner supports both gRPC (HTTP/2) and REST (HTTP/1.1) protocols.
gRPC (Default): High-performance streaming transport via Google gRPC.
dbi:Spanner:projects/P/instances/I/databases/D;transport=grpcREST: Standard HTTP REST transport via JSON APIs.
dbi:Spanner:projects/P/instances/I/databases/D;transport=rest
Environment Variables
SPANNER_DATABASE_PATH: Default database path if omitted from DSN.SPANNER_TRANSPORT: Transport override (grpcorrest).GOOGLE_APPLICATION_CREDENTIALS: Path to service account JSON key file.
BLOCKING VS NON-BLOCKING OPERATIONS
DBD::Spanner supports both standard synchronous (blocking) operations and non-blocking asynchronous operations.
1. Synchronous (Blocking) Operations (Default)
By default, calls to execute() block execution until the database query completes and initial results arrive from Cloud Spanner:
my $sth = $dbh->prepare('SELECT id, display_name FROM users WHERE active = ?');
$sth->execute(1); # Blocks until query completes!
while (my $row = $sth->fetchrow_arrayref()) {
print "User ID: $row->[0], Name: $row->[1]\n";
}
2. Asynchronous (Non-Blocking) Operations
To execute queries without blocking the Perl main thread or event loop, pass { Async = 1 }> to prepare(). execute() returns immediately with status '0E0' without blocking:
my $sth = $dbh->prepare('SELECT id, display_name FROM users WHERE active = ?', { Async => 1 });
my $rv = $sth->execute(1); # Returns '0E0' immediately without blocking!
if ($rv eq '0E0') {
# File descriptor for IO::Select / EV event loops
my $fd = $sth->fileno();
# Poll non-blocking handle
while ($sth->FETCH('AsyncWantRead')) {
if ($sth->async_read_ready()) {
my $row = $sth->fetch_async_row();
last if !defined $row;
print "User ID: $row->[0], Name: $row->[1]\n";
}
}
}
ASYNCHRONOUS NON-BLOCKING OPERATIONS
DBD::Spanner supports non-blocking execution via DBI's Async attribute.
Handle Methods
$sth-fileno()>: Returns the socket/channel file descriptor for IO::Select / EV event loops.$sth-FETCH('AsyncWantRead')>: Returns true while waiting for server response bytes.$sth-async_read_ready()>: Polls non-blocking socket state.$sth-fetch_async_row()>: Non-blocking fetch of the next result tuple.
METADATA & CATALOG METHODS
$dbh-table_info($catalog, $schema, $table, $type)>$dbh-column_info($catalog, $schema, $table, $column)>$dbh-primary_key_info($catalog, $schema, $table)>