/usr/lib/perl5/DBD/File/HowTo.pod is in libdbi-perl 1.616-1build2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | =head1 NAME
DBD::File::HowTo - Guide to create DBD::File based driver
=head1 SYNOPSIS
perldoc DBD::File::HowTo
perldoc DBI
perldoc DBI::DBD
perldoc DBD::File::Developers
perldoc DBI::DBD::SqlEngine::Developers
perldoc DBI::DBD::SqlEngine
perldoc SQL::Eval
perldoc DBI::DBD::SqlEngine::HowTo
perldoc SQL::Statement::Embed
perldoc DBD::File
perldoc DBD::File::HowTo
perldoc DBD::File::Developers
=head1 DESCRIPTION
This document provides a step-by-step guide, how to create a new
C<DBD::File> based DBD. It expects that you carefully read the L<DBI>
documentation and that you're familiar with L<DBI::DBD> and had read and
understood L<DBD::ExampleP>.
This document addresses experienced developers who are really sure that
they need to invest time when writing a new DBI Driver. Writing a DBI
Driver is neither a weekend project nor an easy job for hobby coders
after work. Expect one or two man-month of time for the first start.
Those who are still reading, should be able to sing the rules of
L<DBI::DBD/CREATING A NEW DRIVER>.
Of course, DBD::File is a DBI::DBD::SqlEngine and you surely read
L<DBI::DBD::SqlEngine::HowTo> before continuing here.
=head1 CREATING DRIVER CLASSES
Do you have an entry in DBI's DBD registry? For this guide, a prefix of
C<foo_> is assumed.
=head2 Sample Skeleton
package DBD::Foo;
use strict;
use warnings;
use vars qw(@ISA $VERSION);
use base qw(DBD::File);
use DBI ();
$VERSION = "0.001";
package DBD::Foo::dr;
use vars qw(@ISA $imp_data_size);
@ISA = qw(DBD::File::dr);
$imp_data_size = 0;
package DBD::Foo::db;
use vars qw(@ISA $imp_data_size);
@ISA = qw(DBD::File::db);
$imp_data_size = 0;
package DBD::Foo::st;
use vars qw(@ISA $imp_data_size);
@ISA = qw(DBD::File::st);
$imp_data_size = 0;
package DBD::Foo::Statement;
use vars qw(@ISA);
@ISA = qw(DBD::File::Statement);
package DBD::Foo::Table;
use vars qw(@ISA);
@ISA = qw(DBD::File::Table);
1;
Tiny, eh? And all you have now is a DBD named foo which will is able to
deal with temporary tables, as long as you use L<SQL::Statement>. In
L<DBI::SQL::Nano> environments, this DBD can do nothing.
=head2 Start over
Based on L<DBI::DBD::SqlEngine::HowTo>, we're now having a driver which
could do basic things. Of course, it should now derive from DBD::File
instead of DBI::DBD::SqlEngine, shouldn't it?
DBD::File extends DBI::DBD::SqlEngine to deal with any kind of files.
In principle, the only extensions required are to the table class:
package DBD::Foo::Table;
sub bootstrap_table_meta
{
my ( $self, $dbh, $meta, $table ) = @_;
# initialize all $meta attributes which might be relevant for
# file2table
return $self->SUPER::bootstrap_table_meta($dbh, $meta, $table);
}
sub init_table_meta
{
my ( $self, $dbh, $meta, $table ) = @_;
# called after $meta contains the results from file2table
# initialize all missing $meta attributes
$self->SUPER::init_table_meta( $dbh, $meta, $table );
}
In case C<DBD::File::Table::open_file> doesn't open the files as the driver
needs that, override it!
sub open_file
{
my ( $self, $meta, $attrs, $flags ) = @_;
# ensure that $meta->{f_dontopen} is set
$self->SUPER::open_file( $meta, $attrs, $flags );
# now do what ever needs to be done
}
Combined with the methods implemented using the L<SQL::Statement::Embed>
guide, the table is full working and you could try a start over.
=head2 User comfort
C<DBD::File> since C<0.39> consolidates all persistent meta data of a table
into a single structure stored in C<< $dbh->{f_meta} >>. While DBD::File
provides only readonly access to this structure, modifications are still
allowed.
Primarily DBD::File provides access via setters C<get_file_meta>,
C<set_file_meta> and C<clear_file_meta>. Those methods are easily
accessible by the users via the C<< $dbh->func () >> interface provided
by DBI. Well, many users don't feel comfortize when calling
# don't require extension for tables cars
$dbh->func ("cars", "f_ext", ".csv", "set_file_meta");
DBD::File will inject a method into your driver to increase the user
comfort to allow:
# don't require extension for tables cars
$dbh->foo_set_meta ("cars", "f_ext", ".csv");
Better, but here and there users likes to do:
# don't require extension for tables cars
$dbh->{foo_tables}->{cars}->{f_ext} = ".csv";
This interface is provided when derived DBD's define following in
C<init_valid_attributes> (please compare carefully with the example in
DBI::DBD::SqlEngine::HowTo):
sub init_valid_attributes
{
my $dbh = $_[0];
$dbh->SUPER::init_valid_attributes ();
$dbh->{foo_valid_attrs} = {
foo_version => 1, # contains version of this driver
foo_valid_attrs => 1, # contains the valid attributes of foo drivers
foo_readonly_attrs => 1, # contains immutable attributes of foo drivers
foo_bar => 1, # contains the bar attribute
foo_baz => 1, # contains the baz attribute
foo_manager => 1, # contains the manager of the driver instance
foo_manager_type => 1, # contains the manager class of the driver instance
foo_meta => 1, # contains the public interface to modify table meta attributes
};
$dbh->{foo_readonly_attrs} = {
foo_version => 1, # ensure no-one modifies the driver version
foo_valid_attrs => 1, # do not permit to add more valid attributes ...
foo_readonly_attrs => 1, # ... or make the immutable mutable
foo_manager => 1, # manager is set internally only
foo_meta => 1, # ensure public interface to modify table meta attributes are immutable
};
$dbh->{foo_meta} = "foo_tables";
return $dbh;
}
This provides a tied hash in C<< $dbh->{foo_tables} >> and a tied hash for
each table's meta data in C<< $dbh->{foo_tables}->{$table_name} >>.
Modifications on the table meta attributes are done using the table
methods:
sub get_table_meta_attr { ... }
sub set_table_meta_attr { ... }
Both methods can adjust the attribute name for compatibility reasons, e.g.
when former versions of the DBD allowed different names to be used for the
same flag:
my %compat_map = (
abc => 'foo_abc',
xyz => 'foo_xyz',
);
__PACKAGE__->register_compat_map( \%compat_map );
If any user modification on a meta attribute needs reinitialization of
the meta structure (in case of C<DBD::File> these are the attributes
C<f_file>, C<f_dir>, C<f_ext> and C<f_lockfile>), inform DBD::File by
doing
my %reset_on_modify = (
foo_xyz => "foo_bar",
foo_abc => "foo_bar",
);
__PACKAGE__->register_reset_on_modify( \%reset_on_modify );
The next access to the table meta data will force DBD::File to re-do the
entire meta initialization process.
Any further action which needs to be taken can handled in
C<table_meta_attr_changed>:
sub table_meta_attr_changed
{
my ($class, $meta, $attrib, $value) = @_;
...
$class->SUPER::table_meta_attr_changed ($meta, $attrib, $value);
}
This is done before the new value is set in C<$meta>, so the attribute
changed handler can act depending on the old value.
=head2 Testing
Now you should have your own DBD::File based driver. Was easy, wasn't it?
But does it work well? Prove it by writing tests and remember to use
dbd_edit_mm_attribs from L<DBI::DBD> to ensure testing even rare cases.
=head1 AUTHOR
This guide is written by Jens Rehsack. DBD::File is written by Jochen
Wiedmann and Jeff Zucker.
The module DBD::File is currently maintained by
H.Merijn Brand < h.m.brand at xs4all.nl > and
Jens Rehsack < rehsack at googlemail.com >
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2010 by H.Merijn Brand & Jens Rehsack
All rights reserved.
You may freely distribute and/or modify this module under the terms of
either the GNU General Public License (GPL) or the Artistic License, as
specified in the Perl README file.
=cut
|