—package
MySQL::Config;
use
strict;
$VERSION
=
sprintf
"%d.%02d"
,
q$Revision: 1.2 $
=~ /(\d+)\.(\d+)/;
$GLOBAL_CNF
=
"/etc/%s.cnf"
unless
defined
$GLOBAL_CNF
;
@EXPORT
=
qw(load_defaults)
;
@EXPORT_OK
=
qw(parse_defaults)
;
# ======================================================================
# --- Public Functions ---
# ======================================================================
sub
load_defaults {
my
(
$conf_file
,
$groups
,
$argc
,
$argv
) =
@_
;
my
(
$user_cnf
,
$ini
,
$field
);
$ini
= { };
# ------------------------------------------------------------------
# Sanity checking:
# # $conf_file should be a string, defaults to "my"
# * $groups should be a ref to an array
# * $argc should be a ref to a scalar
# * $argv should be a ref to an array
# ------------------------------------------------------------------
# This silliness is undocumented; please don't rely on it!
unless
(
@_
== 4) {
$argv
=
$argc
;
$argc
=
$groups
;
$groups
=
$conf_file
;
$conf_file
=
"my"
;
}
$groups
= [
$groups
]
unless
ref
$groups
eq
'ARRAY'
;
if
(
defined
$argc
) {
$argc
= \
$argc
unless
ref
$argc
eq
'SCALAR'
;
}
else
{
$argc
= \(
my
$i
= 0);
}
$argv
= [
$argv
]
unless
ref
$argv
eq
'ARRAY'
;
$user_cnf
=
"$ENV{HOME}/.$conf_file.cnf"
;
# ------------------------------------------------------------------
# Parse the global config and user's config
# ------------------------------------------------------------------
_parse(
$ini
,
sprintf
$GLOBAL_CNF
,
$conf_file
);
_parse(
$ini
,
$user_cnf
);
# ------------------------------------------------------------------
# Pull out the appropriate pieces, based on @$groups
# ------------------------------------------------------------------
@$groups
=
keys
%$ini
unless
@$groups
;
for
$field
(
@$groups
) {
my
@keys
=
reverse
keys
%{
$ini
->{
$field
} };
for
(
@keys
) {
unshift
@$argv
,
sprintf
"--%s=%s"
,
$_
,
$ini
->{
$field
}->{
$_
};
$$argc
++;
}
}
1;
}
sub
parse_defaults {
my
(
$conf_file
,
$groups
) =
@_
;
my
(
$count
,
$argv
,
%ini
);
$argv
= [ ];
unless
(
@_
== 2) {
$groups
=
$conf_file
;
$conf_file
=
"my"
;
}
load_defaults(
$conf_file
,
$groups
, \
$count
,
$argv
);
for
(
@$argv
) {
/^--(.*)=(.*)$/
and
$ini
{ $1 } = $2;
}
return
wantarray
?
%ini
: \
%ini
;
}
# ======================================================================
# --- Private Functions ---
# ======================================================================
# ----------------------------------------------------------------------
# _parse($file)
#
# Parses an ini-style file
# ----------------------------------------------------------------------
sub
_parse {
my
$ini
=
shift
;
my
$file
=
shift
;
my
$current
;
local
(
$_
,
*INI
);
return
{ }
unless
-f
$file
&& -r _;
$ini
||= { };
unless
(
open
INI,
$file
) {
carp
"Couldn't oprn $file: $!"
;
return
{ };
}
while
(<INI>) {
s/[;
#].*$//;
s/^\s*//;
s/\s*$//;
next
unless
length
;
/^\s*\[(.*)\]\s*$/
and
$current
= $1,
next
;
my
(
$n
,
$v
) =
split
/\s*=\s*/;
$v
=
qq("$v")
if
$v
=~ /\s/;
$ini
->{
$current
}->{
$n
} =
$v
;
}
unless
(
close
INI) {
carp
"Couldn't close $file: $!"
;
}
return
$ini
;
}
1;
__END__
=head1 NAME
MySQL::Config - Parse and utilize MySQL's /etc/my.cnf and ~/.my.cnf files
=head1 SYNOPSIS
use MySQL::Config;
my @groups = qw(client myclient);
my $argc = 0;
my @argv = ();
load_defaults "my", @groups, $argc, @argv;
=head1 DESCRIPTION
MySQL::Config emulates the load_defaults() function from mysqlclient.
Just like load_defaults(), it returns a list primed to be passed to
getopt_long(), a.k.a. Getopt::Long. load_defaults takes 4 arguments:
a string denoting the name of the config file (which should generally
be "my"); an array of groups which should be returned; a scalar that
will hold the total number of parsed elements; and an array that will
hold the final versions of the extracted name, value pairs. This
final array will be in a format suitable for processing with
Getopt::Long:
--user=username
--password=password
and so on.
load_defaults() has an un-Perlish interface, mostly because it is
exactly the same signature as the version from the C API. There is
also a function, not exported by default, called parse_defaults(),
which returns a hash of parsed (name, value) pairs (or a hashref
in scalar context):
use MySQL::Config qw(parse_defaults);
my %cfg = parse_defaults("my", [ qw(client myclient) ]);
%cfg looks like:
%cfg = (
"user" => "username",
"password" => "password",
)
and so on. This might be a more natural interface for some programs;
however, load_defaults() is more true to the original.
=head1 USING SOMETHING OTHER THAN "my" AS THE FIRST STRING
This string controls the name of the configuration file; the names
work out to, basically:
~/.${cfg_name}.cnf
and
/etc/${cnf_name}.cnf
If you are using this module for mysql clients, then this should
probably remain my. Otherwise, you are free to mangle this however
you choose.
$ini = parse_defaults("your", [ "foo" ]);
=head1 BUGS / KNOWN ISSUES
The C version of load_defaults() returns elements in the order in
which they are defined in the file; this version returns them in hash
order, with duplicates removed.
=head1 VERSION
$Revision: 1.2 $
=head1 AUTHOR
darren chamberlain E<lt>darren@cpan.orgE<gt>