line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DBIx::Array::Connect; |
2
|
3
|
|
|
3
|
|
166756
|
use strict; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
103
|
|
3
|
3
|
|
|
3
|
|
16
|
use warnings; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
81
|
|
4
|
3
|
|
|
3
|
|
15
|
use base qw{Package::New}; |
|
3
|
|
|
|
|
10
|
|
|
3
|
|
|
|
|
3015
|
|
5
|
3
|
|
|
3
|
|
4797
|
use Config::IniFiles qw{}; |
|
3
|
|
|
|
|
68345
|
|
|
3
|
|
|
|
|
80
|
|
6
|
3
|
|
|
3
|
|
829
|
use Path::Class qw{}; |
|
3
|
|
|
|
|
24938
|
|
|
3
|
|
|
|
|
3367
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION='0.05'; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 NAME |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
DBIx::Array::Connect - Database Connections from an INI Configuration File |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 SYNOPSIS |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use DBIx::Array::Connect; |
17
|
|
|
|
|
|
|
my $dbx=DBIx::Array::Connect->new->connect("mydatabase"); #isa DBIx::Array |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my $dac=DBIx::Array::Connect->new(file=>"./my.ini"); #isa DBIx::Array::Connect |
20
|
|
|
|
|
|
|
my $dbx=$dac->connect("mydatabase"); #isa DBIx::Array |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 DESCRIPTION |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
Provides an easy way to construct database objects and connect to databases while providing an easy way to centralize management of database connection strings. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
This package reads database connection information from an INI formatted configuration file and returns a connected database object. |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
This module is used to connect to both Oracle 10g and 11g using L on both Linux and Win32, MySQL 4 and 5 using L on Linux, and Microsoft SQL Server using L on Linux and using L on Win32 systems in a 24x7 production environment. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 USAGE |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
Create an INI configuration file with the following format. The default location for the INI file is /etc/database-connections-config.ini on Linux-like systems and C:\Windows\database-connections-config.ini on Windows-like systems. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
[mydatabase] |
35
|
|
|
|
|
|
|
connection=DBI:mysql:database=mydb;host=myhost.mydomain.tld |
36
|
|
|
|
|
|
|
user=myuser |
37
|
|
|
|
|
|
|
password=mypassword |
38
|
|
|
|
|
|
|
options=AutoCommit=>1, RaiseError=>1 |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Connect to the database. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
my $dbx=DBIx::Array::Connect->new->connect("mydatabase"); #isa DBIx::Array |
43
|
|
|
|
|
|
|
my $dbh=$dbx->dbh; #if you don't want to use DBIx::Array... |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Use the L object like you normally would. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head2 new |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my $dac=DBIx::Array::Connect->new; #Defaults |
52
|
|
|
|
|
|
|
my $dac=DBIx::Array::Connect->new(file=>"path/my.ini"); #Override the INI location |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head1 METHODS |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head2 connect |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Returns a database object for the database nickname which is an INI section name. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
my $dbx=$dac->connect($nickname); #isa DBIx::Array |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
my %overrides=( |
63
|
|
|
|
|
|
|
connection => $connection, |
64
|
|
|
|
|
|
|
user => $user, |
65
|
|
|
|
|
|
|
password => $password, |
66
|
|
|
|
|
|
|
options => {}, |
67
|
|
|
|
|
|
|
execute => [], |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
my $dbx=$dac->connect($nickname, \%overrides); #isa DBIx::Array |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=cut |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub connect { |
74
|
0
|
|
|
0
|
1
|
0
|
my $self=shift; |
75
|
0
|
0
|
|
|
|
0
|
my $nickname=shift or die("Error: connect method requires a database nickname parameter."); |
76
|
0
|
|
|
|
|
0
|
my $override=shift; |
77
|
0
|
0
|
|
|
|
0
|
$override={} unless ref($override) eq "HASH"; |
78
|
0
|
0
|
0
|
|
|
0
|
my $connection= $override->{"connection"} || $self->cfg->val($nickname, "connection") |
79
|
|
|
|
|
|
|
or die(qq{Error: connection not defined for nickname "$nickname"}); |
80
|
0
|
|
0
|
|
|
0
|
my $user = $override->{"user"} || $self->cfg->val($nickname, "user", ""); |
81
|
0
|
|
0
|
|
|
0
|
my $password = $override->{"password"} || $self->cfg->val($nickname, "password", ""); |
82
|
0
|
|
|
|
|
0
|
my %options=(); |
83
|
0
|
0
|
|
|
|
0
|
if (ref($override->{"options"}) eq "HASH") { |
84
|
0
|
|
|
|
|
0
|
%options=%{$override->{"options"}}; |
|
0
|
|
|
|
|
0
|
|
85
|
|
|
|
|
|
|
} else { |
86
|
0
|
|
|
|
|
0
|
my $options=$self->cfg->val($nickname, "options", ""); |
87
|
0
|
|
|
|
|
0
|
%options=map {s/^\s*//;s/\s*$//;$_} split(/[,=>]+/, $options); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
88
|
|
|
|
|
|
|
} |
89
|
0
|
|
|
|
|
0
|
my $class=$self->class; |
90
|
0
|
|
|
|
|
0
|
eval("use $class"); |
91
|
0
|
|
|
|
|
0
|
my $dbx=$class->new(name=>$nickname); |
92
|
0
|
|
|
|
|
0
|
$dbx->connect($connection, $user, $password, \%options); |
93
|
0
|
0
|
|
|
|
0
|
if ($dbx->can("execute")) { |
94
|
0
|
|
|
|
|
0
|
my @execute=(); |
95
|
0
|
0
|
|
|
|
0
|
if (ref($override->{"execute"}) eq "ARRAY") { |
96
|
0
|
|
|
|
|
0
|
@execute=@{$override->{"execute"}}; |
|
0
|
|
|
|
|
0
|
|
97
|
|
|
|
|
|
|
} else { |
98
|
0
|
0
|
|
|
|
0
|
@execute=grep {defined && length} $self->cfg->val($nickname, "execute"); |
|
0
|
|
|
|
|
0
|
|
99
|
|
|
|
|
|
|
} |
100
|
0
|
|
|
|
|
0
|
$dbx->execute($_) foreach @execute; |
101
|
|
|
|
|
|
|
} |
102
|
0
|
|
|
|
|
0
|
return $dbx; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=head2 sections |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Returns all of the "active" section names in the INI file with the given type. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
my $list=$dac->sections("db"); #[] |
110
|
|
|
|
|
|
|
my @list=$dac->sections("db"); #() |
111
|
|
|
|
|
|
|
my @list=$dac->sections; #All "active" sections in INI file |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Note: active=1 is assumed active=0 is inactive |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
Example: |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
my @dbx=map {$dac->connect($_)} $dac->sections("db"); #Connect to all active databases of type db |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=cut |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub sections { |
122
|
5
|
|
|
5
|
1
|
10457
|
my $self=shift; |
123
|
5
|
|
100
|
|
|
24
|
my $type=shift || ""; |
124
|
5
|
|
|
|
|
16
|
my @list=grep {$self->cfg->val($_, "active", "1")} $self->cfg->Sections; |
|
25
|
|
|
|
|
549
|
|
125
|
5
|
100
|
|
|
|
117
|
@list=grep {$self->cfg->val($_, "type", "") eq $type} @list if $type; |
|
16
|
|
|
|
|
263
|
|
126
|
5
|
50
|
|
|
|
92
|
return wantarray ? @list : \@list; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head2 class |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Returns the class in to which to bless objects. The "class" is assumed to be a base DBIx::Array object. This package MAY work with other objects that have a connect method that pass directly to DBI->connect. The object must have a similar execute method to support the package's execute on connect capability. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
my $class=$dac->class; #$ |
134
|
|
|
|
|
|
|
$dac->class("DBIx::Array::Export"); #If you want the exports features of DBIx::Array |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
Set on construction |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
my $dac=DBIx::Array::Connect->new(class=>"DBIx::Array::Export"); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=cut |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub class { |
143
|
0
|
|
|
0
|
1
|
0
|
my $self=shift; |
144
|
0
|
0
|
|
|
|
0
|
$self->{"class"}=shift if @_; |
145
|
0
|
0
|
|
|
|
0
|
$self->{"class"}="DBIx::Array" unless defined $self->{"class"}; |
146
|
0
|
|
|
|
|
0
|
return $self->{"class"}; |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=head2 file |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
Sets or returns the profile INI filename |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
my $file=$dac->file; |
154
|
|
|
|
|
|
|
my $file=$dac->file("./my.ini"); |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
Set on construction |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
my $dac=DBIx::Array::Connect->new(file=>"./my.ini"); |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=cut |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub file { |
163
|
48
|
|
|
48
|
1
|
55
|
my $self=shift; |
164
|
48
|
50
|
|
|
|
105
|
if (@_) { |
165
|
0
|
|
|
|
|
0
|
$self->{'file'}=shift; |
166
|
0
|
0
|
|
|
|
0
|
die(sprintf(qq{Error: Cannot read file "%s".}, $self->{'file'})) unless -r $self->{'file'}; |
167
|
|
|
|
|
|
|
} |
168
|
48
|
100
|
|
|
|
108
|
unless (defined $self->{'file'}) { |
169
|
1
|
50
|
|
|
|
4
|
die(sprintf(qq{Error: path method returned a "%s"; expecting an array reference.}, ref($self->path))) |
170
|
|
|
|
|
|
|
unless ref($self->path) eq "ARRAY"; |
171
|
1
|
|
|
|
|
2
|
foreach my $path (@{$self->path}) { |
|
1
|
|
|
|
|
2
|
|
172
|
1
|
|
|
|
|
3
|
$self->{"file"}=Path::Class::file($path, $self->basename); |
173
|
1
|
50
|
|
|
|
194
|
last if -r $self->{"file"}; |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
#We may not have a vaild file here? We'll let Config::IniFiles catch the error. |
177
|
48
|
|
|
|
|
257
|
return $self->{'file'}; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head2 path |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Sets and returns a list of search paths for the INI file. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
my $path=$dac->path; # [] |
185
|
|
|
|
|
|
|
my $path=$dac->path(".", ".."); # [] |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Default: ["/etc"] on Linux-like systems |
188
|
|
|
|
|
|
|
Default: ['C:\Windows'] on Windows-like systems |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
Overloading path is a good way to migrate from one location to another over time. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
package My::Connect; |
193
|
|
|
|
|
|
|
use base qw{DBIx::Array::Connect}; |
194
|
|
|
|
|
|
|
sub path {[".", "..", "/etc", "/home"]}; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Put INI file in the same folder as tnsnames.ora file. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
package My::Connect::Oracle; |
199
|
|
|
|
|
|
|
use base qw{DBIx::Array::Connect}; |
200
|
|
|
|
|
|
|
use Path::Class qw{}; |
201
|
|
|
|
|
|
|
sub path {[Path::Class::dir($ENV{"ORACLE_HOME"}, qw{network admin})]}; #not taint safe |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=cut |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
sub path { |
206
|
12
|
|
|
12
|
1
|
3126
|
my $self=shift; |
207
|
12
|
100
|
|
|
|
42
|
$self->{"path"}=[@_] if @_; |
208
|
12
|
100
|
|
|
|
42
|
unless (ref($self->{"path"}) eq "ARRAY") { |
209
|
1
|
|
|
|
|
2
|
my @path=(); |
210
|
1
|
50
|
|
|
|
7
|
if ($^O eq "MSWin32") { |
211
|
0
|
|
|
|
|
0
|
eval("use Win32"); |
212
|
0
|
|
|
|
|
0
|
push @path, eval("Win32::GetFolderPath(Win32::CSIDL_WINDOWS)"); |
213
|
|
|
|
|
|
|
} else { |
214
|
1
|
|
|
1
|
|
1132
|
eval("use Sys::Path"); |
|
1
|
|
|
|
|
56037
|
|
|
1
|
|
|
|
|
21
|
|
|
1
|
|
|
|
|
102
|
|
215
|
1
|
|
|
|
|
67
|
push @path, eval("Sys::Path->sysconfdir"); |
216
|
|
|
|
|
|
|
} |
217
|
1
|
|
|
|
|
21
|
$self->{"path"}=\@path; |
218
|
|
|
|
|
|
|
} |
219
|
12
|
|
|
|
|
62
|
return $self->{"path"}; |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=head2 basename |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
Returns the INI basename. |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
You may want to overload the basename property if you inherit this package. |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
package My::Connect; |
229
|
|
|
|
|
|
|
use base qw{DBIx::Array::Connect}; |
230
|
|
|
|
|
|
|
sub basename {"whatever.ini"}; |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
Default: database-connections-config.ini |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=cut |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
sub basename { |
237
|
5
|
|
|
5
|
1
|
687
|
my $self=shift; |
238
|
5
|
100
|
|
|
|
17
|
$self->{"basename"}=shift if @_; |
239
|
5
|
100
|
|
|
|
18
|
$self->{"basename"}="database-connections-config.ini" |
240
|
|
|
|
|
|
|
unless $self->{"basename"}; |
241
|
5
|
|
|
|
|
22
|
return $self->{"basename"}; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=head2 cfg |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
Returns the L object so that you can read additional information from the INI file. |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
my $cfg=$dac->cfg; #isa Config::IniFiles |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
Example |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
my $connection_string=$dac->cfg->val($database, "connection"); |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=cut |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
sub cfg { |
257
|
46
|
|
|
46
|
1
|
62
|
my $self=shift; |
258
|
46
|
|
|
|
|
77
|
my $file=$self->file; #support for objects that can stringify paths. |
259
|
46
|
100
|
|
|
|
119
|
$self->{'cfg'}=Config::IniFiles->new(-file=>"$file") |
260
|
|
|
|
|
|
|
unless ref($self->{'cfg'}) eq "Config::IniFiles"; |
261
|
46
|
|
|
|
|
9728
|
return $self->{'cfg'}; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=head1 INI File Format |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 Section |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
The INI section is the value that needs to be passed in the connect method which is the database nickname. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
[section] |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
my $dbx=DBIx::Array::Connect->new->connect("section"); |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=head2 connection |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
The string passed to DBI to connect to the database. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Examples: |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
connection=DBI:CSV:f_dir=. |
281
|
|
|
|
|
|
|
connection=DBI:mysql:database=mydb;host=myhost.mydomain.tld |
282
|
|
|
|
|
|
|
connection=DBI:Sybase:server=mssqlserver.mydomain.tld;datasbase=mydb |
283
|
|
|
|
|
|
|
connection=DBI:Oracle:MYTNSNAME |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=head2 user |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
The string passed to DBI as the user. Default is "" for user-less drivers. |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=head2 password |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
The string passed to DBI as the password. Default is "" for password-less drivers. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=head2 options |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
Split and passed as a hash reference to DBI->connect. |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
options=AutoCommit=>1, RaiseError=>1, ReadOnly=>1 |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=head2 execute |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
Connection settings that you want to execute every time you connect |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
execute=ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY HH24:MI:SS' |
304
|
|
|
|
|
|
|
execute=INSERT INTO mylog (mycol) VALUES ('Me') |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=head2 type |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Allows grouping database connections in groups. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
type=group |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=head2 active |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
This option is used by the sections method to filter out databases that may be temporarily down. |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
active=1 |
317
|
|
|
|
|
|
|
active=0 |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Default: 1 |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head1 LIMITATIONS |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
Once the file method has cached a filename, basename and path are ignored. Once the Config::IniFiles is constructed the file method is ignored. If you want to use two different INI files, you should construct two different objects. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
The file, path and basename methods are common exports from other packages. Be wary! |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=head1 BUGS |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
Send email to author and log on RT. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head1 SUPPORT |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
DavisNetworks.com supports all Perl applications including this package. |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head1 AUTHOR |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
Michael R. Davis |
338
|
|
|
|
|
|
|
CPAN ID: MRDVT |
339
|
|
|
|
|
|
|
Satellite Tracking of People, LLC |
340
|
|
|
|
|
|
|
mdavis@stopllc.com |
341
|
|
|
|
|
|
|
http://www.stopllc.com/ |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=head1 COPYRIGHT |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
This program is free software licensed under the... |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
The General Public License (GPL) |
348
|
|
|
|
|
|
|
Version 2, June 1991 |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
The full text of the license can be found in the LICENSE file included with this module. |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head1 SEE ALSO |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=head2 The Building Blocks |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
L, L, L |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=head2 The Competition |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
L uses a CSV file to store data. The constructor is wrapper around DBI->connect. |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
my $dbh = DBIx::MyPassword->connect("user"); |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
L uses an INI file to store data. It uses encrypted passwords and the constructor returns array reference to feed into DBI->connect. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
my $dbh = DBI->connect(@{DBIx::PasswordIniFile->new(%arg)->getDBIConnectParams}) |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
L uses and internal hash reference to store data. The constructor is wrapper around DBI->connect. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
my $dbh = DBIx::Password->connect("user"); |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head2 The Comparison |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
L uses an INI file to store data. The constructor returns a L object which is a wrapper around DBI. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
my $dbx = DBIx::Array::Connect->new->connect("nickname"); |
377
|
|
|
|
|
|
|
my $dbh = $dbx->dbh; #if you don't want to use DBIx::Array... |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=cut |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
1; |