Database-Async-Engine-PostgreSQL
view release on metacpan or search on metacpan
lib/Database/Async/Engine/PostgreSQL.pm view on Meta::CPAN
$log->tracef('URI for connection is %s', "$uri");
my $endpoint = join ':', $uri->host, $uri->port;
$log->tracef('Will connect to %s', $endpoint);
$self->{ssl} = do {
my $mode = $uri->query_param('sslmode') // 'prefer';
$Protocol::Database::PostgreSQL::Constants::SSL_NAME_MAP{$mode} // die 'unknown SSL mode ' . $mode;
};
# We're assuming TCP (either v4 or v6) here, but there's not really any reason we couldn't have
# UNIX sockets or other transport layers here other than lack of demand so far.
my @connect_params;
if ($uri->host and not $uri->host =~ m!^[/@]!) {
@connect_params = (
service => $uri->port,
host => $uri->host,
socktype => 'stream',
);
} elsif ($uri->host eq '') {
@connect_params = (
addr => {
family => 'unix',
socktype => 'stream',
path => '/var/run/postgresql/.s.PGSQL.'.$uri->port,
}
);
} else {
@connect_params = (
addr => {
family => 'unix',
socktype => 'stream',
path => $uri->host.'/.s.PGSQL.'.$uri->port,
}
);
}
my $sock = await $loop->connect(@connect_params);
if ($sock->sockdomain == Socket::PF_INET or $sock->sockdomain == Socket::PF_INET6) {
my $local = join ':', $sock->sockhost_service(1);
my $remote = join ':', $sock->peerhost_service(1);
$log->tracef('Connected to %s as %s from %s', $endpoint, $remote, $local);
} elsif ($sock->sockdomain == Socket::PF_UNIX) {
$log->tracef('Connected to %s as %s', $endpoint, $sock->peerpath);
}
# We start with a null handler for read, because our behaviour varies depending on
# whether we want to go through the SSL dance or not.
$self->add_child(
my $stream = IO::Async::Stream->new(
handle => $sock,
on_read => sub { 0 }
)
);
# SSL is conveniently simple: a prefix exchange before the real session starts,
# and the user can decide whether SSL is mandatory or optional.
$stream = await $self->negotiate_ssl(
stream => $stream,
);
Scalar::Util::weaken($self->{stream} = $stream);
$self->outgoing->each(sub {
$log->tracef('Write bytes [%v02x]', $_);
$self->ready_for_query->set_string('');
$self->stream->write("$_");
return;
});
$stream->configure(
on_read => $self->curry::weak::on_read,
read_len => $self->read_len,
write_len => $self->write_len,
autoflush => 0,
);
$log->tracef('Send initial request with user %s', $uri->user);
# This is where the extensible options for initial connection are applied:
# we have already handled SSL by this point, so we exclude this from the
# list and pass everything else directly to the startup packet.
my %qp = $uri->query_params;
delete $qp{sslmode};
$qp{application_name} //= $self->application_name;
$self->protocol->send_startup_request(
database => $self->database_name,
user => $self->database_user,
%qp
);
$connected->set_numeric(1);
return $stream;
}
=head2 service_conf_path
Return the expected location for the pg_service.conf file.
=cut
sub service_conf_path {
my ($class) = @_;
return $ENV{PGSERVICEFILE} if exists $ENV{PGSERVICEFILE};
return $ENV{PGSYSCONFDIR} . '/pg_service.conf' if exists $ENV{PGSYSCONFDIR};
my $path = File::HomeDir->my_home . '/.pg_service.conf';
return $path if -r $path;
return '/etc/pg_service.conf';
}
sub service_parse {
my ($class, $path) = @_;
return Config::Tiny->read($path, 'encoding(UTF-8)');
}
sub find_service {
my ($class, $srv) = @_;
my $data = $class->service_parse(
$class->service_conf_path
);
die 'service ' . $srv . ' not found in config' unless $data->{$srv};
return $data->{$srv};
}
( run in 2.133 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )