diff options
Diffstat (limited to 'lib/Travelynx/Model/Stations.pm')
-rw-r--r-- | lib/Travelynx/Model/Stations.pm | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/lib/Travelynx/Model/Stations.pm b/lib/Travelynx/Model/Stations.pm new file mode 100644 index 0000000..ac4019c --- /dev/null +++ b/lib/Travelynx/Model/Stations.pm @@ -0,0 +1,199 @@ +package Travelynx::Model::Stations; + +# Copyright (C) 2022 Birte Kristina Friesel +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +use strict; +use warnings; +use 5.020; + +sub new { + my ( $class, %opt ) = @_; + + return bless( \%opt, $class ); +} + +sub add_or_update { + my ( $self, %opt ) = @_; + my $stop = $opt{stop}; + my $loc = $stop->loc; + my $source = 1; + my $db = $opt{db} // $self->{pg}->db; + + if ( my $s = $self->get_by_eva( $loc->eva, db => $db ) ) { + if ( $source == 1 and $s->{source} == 0 and not $s->{archived} ) { + return; + } + $db->update( + 'stations', + { + name => $loc->name, + lat => $loc->lat, + lon => $loc->lon, + source => $source, + archived => 0 + }, + { eva => $loc->eva } + ); + return; + } + $db->insert( + 'stations', + { + eva => $loc->eva, + name => $loc->name, + lat => $loc->lat, + lon => $loc->lon, + source => $source, + archived => 0 + } + ); +} + +sub add_meta { + my ( $self, %opt ) = @_; + my $db = $opt{db} // $self->{pg}->db; + my $eva = $opt{eva}; + my @meta = @{ $opt{meta} }; + + for my $meta (@meta) { + if ( $meta != $eva ) { + $db->insert( + 'related_stations', + { + eva => $eva, + meta => $meta + }, + { on_conflict => undef } + ); + } + } +} + +sub get_db_iterator { + my ($self) = @_; + + return $self->{pg}->db->select( 'stations', '*' ); +} + +sub get_meta { + my ( $self, %opt ) = @_; + my $db = $opt{db} // $self->{pg}->db; + my $eva = $opt{eva}; + + my $res = $db->select( 'related_stations', ['meta'], { eva => $eva } ); + my @ret; + + while ( my $row = $res->hash ) { + push( @ret, $row->{meta} ); + } + + return @ret; +} + +sub get_for_autocomplete { + my ($self) = @_; + + my $res = $self->{pg}->db->select( 'stations', ['name'] ); + my %ret; + + while ( my $row = $res->hash ) { + $ret{ $row->{name} } = undef; + } + + return \%ret; +} + +# Fast +sub get_by_eva { + my ( $self, $eva, %opt ) = @_; + + if ( not $eva ) { + return; + } + + my $db = $opt{db} // $self->{pg}->db; + + return $db->select( 'stations', '*', { eva => $eva } )->hash; +} + +# Fast +sub get_by_evas { + my ( $self, @evas ) = @_; + + my @ret + = $self->{pg}->db->select( 'stations', '*', { eva => { '=', \@evas } } ) + ->hashes->each; + return @ret; +} + +# Slow +sub get_latlon_by_name { + my ( $self, %opt ) = @_; + + my $db = $opt{db} // $self->{pg}->db; + + my %location; + my $res = $db->select( 'stations', [ 'name', 'lat', 'lon' ] ); + while ( my $row = $res->hash ) { + $location{ $row->{name} } = [ $row->{lat}, $row->{lon} ]; + } + return \%location; +} + +# Slow +sub get_by_name { + my ( $self, $name, %opt ) = @_; + + my $db = $opt{db} // $self->{pg}->db; + + return $db->select( 'stations', '*', { name => $name }, { limit => 1 } ) + ->hash; +} + +# Slow +sub get_by_names { + my ( $self, @names ) = @_; + + my @ret + = $self->{pg}->db->select( 'stations', '*', { name => { '=', \@names } } ) + ->hashes->each; + return @ret; +} + +# Slow +sub get_by_ds100 { + my ( $self, $ds100, %opt ) = @_; + + my $db = $opt{db} // $self->{pg}->db; + + return $db->select( 'stations', '*', { ds100 => $ds100 }, { limit => 1 } ) + ->hash; +} + +# Can be slow +sub search { + my ( $self, $identifier, %opt ) = @_; + + if ( $identifier =~ m{ ^ \d+ $ }x ) { + return $self->get_by_eva( $identifier, %opt ) + // $self->get_by_ds100( $identifier, %opt ) + // $self->get_by_name( $identifier, %opt ); + } + + return $self->get_by_ds100( $identifier, %opt ) + // $self->get_by_name( $identifier, %opt ); +} + +# Slow +sub grep_unknown { + my ( $self, @stations ) = @_; + + my %station = map { $_->{name} => 1 } $self->get_by_names(@stations); + my @unknown_stations = grep { not $station{$_} } @stations; + + return @unknown_stations; +} + +1; |