Tie::Array::DBD(3)
okay bestie, welcome to Tie::Array::DBD(3) β literally the page for tying a plain array to a database table. Itβs giving βarray but make it SQLβ energy. π
β¨ NAME β¨
Tie::Array::DBD β tie a plain array to a database table. Thatβs the whole assignment, and yes it ate. π«Ά
πΈ SYNOPSIS πΈ
use DBI;
use Tie::Array::DBD;
my $dbh = DBI->connect ("dbi:Pg:", ...);
tie my @array, "Tie::Array::DBD", "dbi:SQLite:dbname=db.tie";
tie my @array, "Tie::Array::DBD", $dbh;
tie my @array, "Tie::Array::DBD", $dbh, {
tbl => "t_tie_analysis",
key => "h_key",
fld => "h_value",
str => "Storable",
};
$array[42] = $value; # INSERT
$array[42] = 3; # UPDATE
delete $array[42]; # DELETE
$value = $array[42]; # SELECT
@array = (); # CLEAR
@array = (1..42);
$array[-2] = 42;
$_ = pop @array;
push @array, $_;
$_ = shift @array;
unshift @array, $_;
@a = splice @array, 2, -2, 5..9;
@k = keys @array; # $] >= 5.011
@v = values @array; # $] >= 5.011
π DESCRIPTION π
This module ties an array to a database table using only an βindexβ and a βvalueβ field. If no tables specification is passed, this will create a temporary table with h_key for the key field and a h_value for the value field.
I think it would make sense to merge the functionality that this module provides into Tie::DBI.
π§ tie π§
The tie call accepts two arguments:
π Database π
The first argument is the connection specifier. This is either an open database handle or a DBI_DSN string.
If this argument is a valid handle, this module does not open a database all by itself, but uses the connection provided in the handle.
If the first argument is a scalar, it is used as DSN for DBI->connect ().
Supported DBD drivers include DBD::Pg, DBD::SQLite, DBD::CSV, DBD::MariaDB, DBD::mysql, DBD::Oracle, DBD::Unify, and DBD::Firebird. Note that due to limitations they wonβt all perform equally well. Firebird is not tested anymore.
DBD::Pg and DBD::SQLite have an unexpected great performance when server is the local system. DBD::SQLite is even almost as fast as DB_File.
The current implementation appears to be extremely slow for CSV, as expected, mariadb/mysql, and Unify. For Unify and mariadb/mysql that is because these do not allow indexing on the key field so they cannot be set to be primary key.
When using DBD::CSV with Text::CSV_XS version 1.02 or newer, it might be wise to disable utf8 encoding (only supported as of DBD::CSV-0.48):
"dbi:CSV:f_ext=.csv/r;csv_null=1;csv_decode_utf8=0"
π Options π
The second argument is optional and should β if passed β be a hashref to options. The following options are recognized:
tblβ Defines the name of the table to be used. If none is passed, a new table is created with a unique name liket_tie_dbda_42253_1. When possible, the table is created as temporary. After the session, this table will be dropped.
If a table name is provided, it will be checked for existence. If found, it will be used with the specified key and fld. Otherwise it will be created with key and fld, but it will not be dropped at the end of the session.
keyβ Defines the name of the key field in the database table. The default ish_key.fldβ Defines the name of the value field in the database table. The default ish_value.vtpβ Defines the type of the fld field in the database table. The default is depending on the underlying database and most likely some kind of BLOB.strβ Defines the required persistence module. Currently supports the use ofStorable,Sereal,JSON,JSON::Syck,YAML,YAML::SyckandXML::Dumper.
The default is undefined.
Passing any other value will cause a croak.
If you want to preserve Encoding on the hash values, you should use this feature. (except where PV8 has a - in the support list below)
Hereβs the data-type tea, bestie, for a data structure like this:
my %deep = (
UND => undef,
IV => 1,
NV => 3.14159265358979,
PV => "string",
PV8 => "ab\ncd\x{20ac}\t",
PVM => $!,
RV => \$DBD,
AR => [ 1..2 ],
HR => { key => "value" },
OBJ => ( bless { auto_diag => 1 }, "Text::CSV_XS" ),
RX => qr{^re[gG]e?x},
FMT => *{$::{STDOUT}}{FORMAT},
CR => sub { "code"; },
GLB => *STDERR,
IO => *{$::{STDERR}}{IO},
);
Type order is exactly this: UND, IV, NV, PV, PV8, PVM, RV, AR, HR, OBJ, RX, FMT, CR, GLB, IO. In the list below, x means supported and - means not supported β no guessing, just the exact tea. π
No streamerβUNDx;IVx;NVx;PVx;PV8x;PVMx;RVx;ARx;HRx;OBJx;RX-;FMT-;CR-;GLB-;IO-StorableβUNDx;IVx;NVx;PVx;PV8x;PVMx;RVx;ARx;HRx;OBJx;RX-;FMT-;CR-;GLB-;IO-SerealβUNDx;IVx;NVx;PVx;PV8x;PVMx;RVx;ARx;HRx;OBJx;RXx;FMTx;CR-;GLB-;IO-JSONβUNDx;IVx;NVx;PVx;PV8x;PVMx;RV-;ARx;HRx;OBJ-;RX-;FMT-;CR-;GLB-;IO-JSON::SyckβUNDx;IVx;NVx;PVx;PV8-;PVMx;RV-;ARx;HRx;OBJx;RX-;FMTx;CR-;GLB-;IO-YAMLβUNDx;IVx;NVx;PVx;PV8-;PVMx;RVx;ARx;HRx;OBJx;RXx;FMTx;CR-;GLB-;IO-YAML::SyckβUNDx;IVx;NVx;PVx;PV8-;PVMx;RVx;ARx;HRx;OBJx;RX-;FMTx;CR-;GLB-;IO-XML::DumperβUNDx;IVx;NVx;PVx;PV8x;PVMx;RVx;ARx;HRx;OBJx;RX-;FMTx;CR-;GLB-;IO-FreezeThawβUNDx;IVx;NVx;PVx;PV8-;PVMx;RVx;ARx;HRx;OBJx;RX-;FMTx;CR-;GLBx;IO-BencodeβUND-;IVx;NVx;PVx;PV8-;PVMx;RV-;ARx;HRx;OBJ-;RX-;FMT-;CR-;GLBx;IO-
So, Storable does not support persistence of types CODE, REGEXP, FORMAT, IO, and GLOB. Be sure to test if all of your data types are supported by the serializer you choose. YMMV.
No streamer might work inside the current process if reference values are stored, but it is highly unlikely they are persistent.
Also note that this module does not yet support dynamic deep structures. See Nesting and deep structures.
π Encoding π
Tie::Array::DBD stores values as binary data. This means that all Encoding and magic is lost when the data is stored, and thus is also not available when the data is restored, hence all internal information about the data is also lost, which includes the UTF8 flag.
If you want to preserve the UTF8 flag you will need to store internal flags and use the streamer option:
tie my @array, "Tie::Array::DBD", { str => "Storable" };
If you do not want the performance impact of Storable just to be able to store and retrieve UTF-8 values, there are two ways to do so:
# Use utf-8 from database
tie my @array, "Tie::Array::DBD", "dbi:Pg:", { vtp => "text" };
$array[2] = "The teddybear costs \x{20ac} 45.95";
# use Encode
tie my @array, "Tie::Array::DBD", "dbi:Pg:";
$array[2] = encode "UTF-8", "The teddybear costs \x{20ac} 45.95";
Note that using Encode will allow other binary data too where using the database encoding does not:
$array[2] = pack "L>A*", time, encode "UTF-8", "Price: \x{20ac} 45.95";
π§Έ Nesting and deep structures π§Έ
Tie::Array::DBD stores values as binary data. This means that all structure is lost when the data is stored and not available when the data is restored. To maintain deep structures, use the streamer option:
tie my @array, "Tie::Array::DBD", { str => "Storable" };
Note that changes inside deep structures do not work. See TODO.
π οΈ METHODS π οΈ
ποΈ drop () ποΈ
If a table was used with persistence, the table will not be dropped when the untie is called. Dropping can be forced using the drop method at any moment while the array is tied:
(tied @array)->drop;
π PREREQUISITES π
The only real prerequisite is DBI but of course that uses the DBD driver of your choice. Some drivers are (very) actively maintained. Be sure to use recent Modules. DBD::SQLite for example seems to require version 1.29 or up.
π RESTRICTIONS and LIMITATIONS π
DBD::Oraclelimits the size of BLOB-reads to 4kb by default, which is too small for reasonable data structures.Tie::Array::DBDlocally raises this value to 4Mb, which is still an arbitrary limit.Storabledoes not support persistence of perl typesIO,REGEXP,CODE,FORMAT, andGLOB. Future extensions might implement some alternative streaming modules, likeData::Dump::Streameror use mixin approaches that enable you to fit in your own.- Note that neither
DBD::CSVnorDBD::UnifysupportAutoCommit. - For now, Firebird does not support
TEXT(orCLOB) inDBD::Firebirdat a level required byTie::Array::DBD.
Firebird support is stalled.
π TODO π
Update on deep changes
Currently, nested structures do not get updated when it is an change in a deeper part.
tie my @array, "Tie::Array::DBD", $dbh, { str => "Storable" };
@array = (
[ 1, "foo" ],
[ 2, "bar" ],
);
$array[1][0]++; # No effect :(
Documentation
Better document what the implications are of storing data content in a database and restoring that. It will not be fool proof.
Mixins
Maybe: implement a feature that would enable plugins or mixins to do the streaming or preservation of other data attributes.
π¦ AUTHOR π¦
H.Merijn Brand <h.m.brand@xs4all.nl>
π COPYRIGHT AND LICENSE π
Copyright (C) 2010-2023 H.Merijn Brand
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
π SEE ALSO π
DBI, Tie::DBI, Tie::Array, Tie::Hash::DBD, DBM::Deep, Storable, Sereal, JSON, JSON::Syck, YAML, YAML::Syck, XML::Dumper, Bencode, FreezeThaw
This iconic little page is from perl v5.42.0, dated 2023-01-07, and yes bestie β itβs Tie::Array::DBD(3). Mwah. πβ¨
π¦ where this page comes from
- opensuse-leap 16.0: perl-Tie-Hash-DBD 0.24-bp160.1.11 Β· Artistic-1.0 OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms