my $url = shift @_ or return;
my ($old_parse, $new_parse,
$dbconn_part, $url_parts_hash, $table_name, $tparam_name, $tparam_value, $conn_param_string, $query_part);
# In case the whole URL is quoted (should we do this with double-quotes too ?)
if( $url=~/^'(.*)'$/ ) {
$url = $1;
}
if( $url=~/^\w+$/ ) {
$new_parse = {
'unambig_url' => ':///',
'query_params' => { 'object_type' => 'Analysis', 'logic_name' => $url, },
};
} else {
# Perform environment variable substitution separately with and without curly braces.
# Make sure expressions stay as they were if we were unable to substitute them.
#
$url =~ s/\$(?|\{(\w+)\}|(\w+))/defined($ENV{$1})?"$ENV{$1}":"\$$1"/eg;
if( ($dbconn_part, @$url_parts_hash{'driver', 'user', 'pass', 'host', 'port', 'dbname'}, $table_name, $tparam_name, $tparam_value, $conn_param_string) =
$url =~ m{^((\w*):
my ($dummy, %conn_params) = split(/[;=]/, $conn_param_string
my $query_params;
my $exception_from_OLD_format;
if($table_name) {
if($table_name eq 'analysis') {
$query_params->{'object_type'} = 'Analysis';
$query_params->{$tparam_name} = $tparam_value; # $tparam_name is 'logic_name' or 'dbID', $tparam_value is the analysis_name or dbID
} elsif($table_name eq 'accu') {
$query_params->{'object_type'} = 'Accumulator';
$query_params->{'accu_name'} = $tparam_name;
$query_params->{'accu_address'} = $tparam_value;
} elsif($table_name eq 'job') {
die "Jobs cannot yet be located by URLs, sorry";
} else {
$query_params->{'object_type'} = 'NakedTable';
$query_params->{'table_name'} = $table_name;
if($tparam_name) {
if( $tparam_name eq 'insertion_method' ) { # extra hint on the OLD format from the insertion_method
$query_params->{'insertion_method'} = $tparam_value;
} elsif( $tparam_name eq 'table_name' ) { # hinting this is NEW format with a bipartite dbpath
$exception_from_OLD_format = 1;
}
}
}
}
if($exception_from_OLD_format) {
warn "\nOLD URL parser thinks you are using the NEW URL syntax for a remote $query_params->{'object_type'}, so skipping it (it may be wrong!)\n";
} else {
$old_parse = {
'dbconn_part' => $dbconn_part,
%$url_parts_hash,
'conn_params' => \%conn_params,
'query_params' => $query_params,
'unambig_url' => $unambig_url,
};
}
} # /if OLD format
if( ($dbconn_part, @$url_parts_hash{'driver', 'user', 'pass', 'host', 'port', 'dbname'}, $query_part, $conn_param_string) =
$url =~ m{^((\w+):
my ($dummy, %conn_params) = split(/[;=]/, $conn_param_string
my $query_params = $query_part ? { split(/[&=]/, $query_part ) } : undef;
my $exception_from_NEW_format;
my ($driver, $dbname) = @$url_parts_hash{'driver', 'dbname'};
if(!$query_params and ($driver eq 'mysql' or $driver eq 'pgsql') and $dbname and $dbname=~m{/}) { # a special case of multipart dbpath hints at the OLD format (or none at all)
$query_params = { 'object_type' => 'NakedTable' };
$exception_from_NEW_format = 1;
} elsif($query_params and not (my $object_type = $query_params->{'object_type'})) { # do a bit of guesswork:
if($query_params->{'logic_name'}) {
$object_type = 'Analysis';
if($dbname and $dbname=~m{^([/~\w\-\.]*)/analysis$}) {
$exception_from_NEW_format = 1;
}
} elsif($query_params->{'job_id'}) {
$object_type = 'AnalysisJob';
} elsif($query_params->{'semaphore_id'}) {
$object_type = 'Semaphore';
} elsif($query_params->{'accu_name'}) { # we don't require $query_params->{'accu_address'} to support scalar accu
$object_type = 'Accumulator';
} elsif($query_params->{'table_name'}) { # NB: the order is important here, in case table_name is reset for non-NakedTables
$object_type = 'NakedTable';
} elsif($query_params->{'insertion_method'}) {
$object_type = 'NakedTable';
if($dbname and $dbname=~m{^([/~\w\-\.]*)/(\w+)$}) {
$exception_from_NEW_format = 1;
}
}
$query_params->{'object_type'} = $object_type;
}
if($exception_from_NEW_format) {
warn "\nNEW URL parser thinks you are using the OLD URL syntax for a remote $query_params->{'object_type'}, so skipping it (it may be wrong!)\n";
} else {
my $unambig_url = hash_to_unambig_url( $url_parts_hash );
$new_parse = {
'dbconn_part' => $dbconn_part,
%$url_parts_hash,
'conn_params' => \%conn_params,
'query_params' => $query_params,
'unambig_url' => $unambig_url,
};
}
} # /if NEW format
}
if($new_parse and $old_parse) {
if(stringify($old_parse) eq stringify($new_parse)) {
return $new_parse;
} else {
warn "\nThe URL '$url' can be parsed ambiguously:\n\t".stringify($old_parse)."\nvs\n\t".stringify($new_parse)."\n). Using the OLD parser at the moment.\nPlease change your URL to match the new format if you see weird behaviour\n\n";
return $old_parse;
}
} elsif($new_parse) {
return $new_parse;
} elsif($old_parse) {
warn "\nThe URL '$url' only works with the old parser, please start using the new syntax as the old parser will soon be deprecated\n\n";
return $old_parse;
} else {
warn "\nThe URL '$url' could not be parsed, please check it\n";
return;
}
}