use
vars
qw($OBDA_SPEC_VERSION $OBDA_SEARCH_PATH
$HOME $PRIVATE_DIR $PUBLIC_DIR $REGISTRY
$FALLBACK_REGISTRY)
;
BEGIN {
$OBDA_SPEC_VERSION
= 1.0;
$HOME
=
$ENV
{HOME}
if
(
defined
$ENV
{HOME});
if
(
defined
$ENV
{OBDA_SEARCH_PATH}) {
$OBDA_SEARCH_PATH
=
$ENV
{OBDA_SEARCH_PATH} ||
''
;
}
}
my
%implement
= (
'flat'
=>
'Bio::DB::Flat'
,
'biosql'
=>
'Bio::DB::BioSQL::OBDA'
,
'biofetch'
=>
'Bio::DB::BioFetch'
);
$PRIVATE_DIR
=
'.bioinformatics'
;
$PUBLIC_DIR
=
'/etc/bioinformatics'
;
$REGISTRY
=
'seqdatabase.ini'
;
sub
new {
my
(
$class
,
@args
) =
shift
;
my
$self
=
$class
->SUPER::new(
@args
);
$self
->{
'_dbs'
} = {};
$self
->_load_registry();
return
$self
;
}
sub
_load_registry {
my
$self
=
shift
;
eval
{
$HOME
= (
getpwuid
($>))[7]; }
unless
$HOME
;
if
($@) {
$self
->
warn
(
"This Perl doesn't implement function getpwuid(), no $HOME"
);
}
my
@ini_files
=
$self
->_get_ini_files();
@ini_files
=
$self
->_make_private_registry()
unless
(
@ini_files
);
my
(
$db
,
$hash
) = ();
for
my
$file
(
@ini_files
) {
open
my
$FH
,
"$file"
;
while
( <
$FH
> ) {
if
(/^VERSION=([\d\.]+)/) {
if
($1 >
$OBDA_SPEC_VERSION
or !$1) {
$self
->throw(
"Do not know about this version [$1] > $OBDA_SPEC_VERSION"
);
last
;
}
next
;
}
next
if
( /^
next
if
( /^\s/ );
if
( /^\[(\S+)\]/ ) {
$db
= $1;
next
;
}
my
(
$tag
,
$value
) =
split
(
'='
,
$_
);
$value
=~ s/\s//g;
$tag
=~ s/\s//g;
$hash
->{
$db
}->{
"\L$tag"
} =
$value
;
}
}
for
my
$db
(
keys
%{
$hash
} ) {
if
( !
exists
$self
->{
'_dbs'
}->{
$db
} ) {
my
$failover
= Bio::DB::Failover->new();
$self
->{
'_dbs'
}->{
$db
} =
$failover
;
}
my
$class
;
if
(
defined
$implement
{
$hash
->{
$db
}->{
'protocol'
}}) {
$class
=
$implement
{
$hash
->{
$db
}->{
'protocol'
}};
}
else
{
$self
->
warn
(
"Registry does not support protocol "
.
$hash
->{
$db
}->{
'protocol'
});
next
;
}
eval
"require $class"
;
if
($@) {
$self
->
warn
(
"Couldn't load $class"
);
next
;
}
else
{
eval
{
my
$randi
=
$class
->new_from_registry( %{
$hash
->{
$db
}} );
$self
->{
'_dbs'
}->{
$db
}->add_database(
$randi
);
};
if
($@) {
$self
->
warn
(
"Couldn't call new_from_registry() on [$class]\n$@"
);
}
}
}
}
sub
get_database {
my
(
$self
,
$dbname
) =
@_
;
$dbname
=
lc
$dbname
;
if
( !
defined
$dbname
) {
$self
->
warn
(
"must get_database with a database name"
);
return
;
}
if
( !
exists
$self
->{
'_dbs'
}->{
$dbname
} ) {
$self
->
warn
(
"No database with name $dbname in Registry"
);
return
;
}
return
$self
->{
'_dbs'
}->{
$dbname
};
}
sub
services {
my
(
$self
) =
@_
;
return
()
unless
(
defined
$self
->{
'_dbs'
} &&
ref
(
$self
->{
'_dbs'
} ) =~ /HASH/i);
return
keys
%{
$self
->{
'_dbs'
}};
}
sub
_get_ini_files {
my
$self
=
shift
;
my
@ini_files
= ();
if
(
$OBDA_SEARCH_PATH
) {
foreach
my
$dir
(
split
/;/,
$OBDA_SEARCH_PATH
) {
my
$file
=
$dir
.
"/"
.
$REGISTRY
;
next
unless
-e
$file
;
push
@ini_files
,
$file
;
}
}
push
@ini_files
,
"$HOME/$PRIVATE_DIR/$REGISTRY"
if
(
$HOME
&& -e
"$HOME/$PRIVATE_DIR/$REGISTRY"
);
push
@ini_files
,
"$PUBLIC_DIR/$REGISTRY"
if
( -e
"$PUBLIC_DIR/$REGISTRY"
);
@ini_files
;
}
sub
_make_private_registry {
my
$self
=
shift
;
my
@ini_file
;
my
$nor_in
=
$OBDA_SEARCH_PATH
?
"nor in directory specified by\n$OBDA_SEARCH_PATH"
:
"and environment variable OBDA_SEARCH_PATH wasn't set"
;
$self
->
warn
(
"No $REGISTRY file found in $HOME/$PRIVATE_DIR/\n"
.
"nor in $PUBLIC_DIR $nor_in.\n"
.
"Using web to get registry from\n$FALLBACK_REGISTRY"
);
my
$f
= Bio::Root::HTTPget::getFH(
$FALLBACK_REGISTRY
);
eval
{
mkdir
"$HOME/$PRIVATE_DIR"
unless
-e
"$HOME/$PRIVATE_DIR"
;
};
$self
->throw(
"Could not make directory $HOME/$PRIVATE_DIR, "
.
"no $REGISTRY file available"
)
if
$@;
open
(
my
$F
,
">$HOME/$PRIVATE_DIR/$REGISTRY"
);
print
$F
while
(<
$F
>);
close
$F
;
$self
->
warn
(
"Stored $REGISTRY file in $HOME/$PRIVATE_DIR"
);
push
@ini_file
,
"$HOME/$PRIVATE_DIR/$REGISTRY"
;
@ini_file
;
}
1;