From 47f76da4f8cc31146d2834dfdf9731d330288c9d Mon Sep 17 00:00:00 2001 From: Birte Kristina Friesel Date: Fri, 26 Jul 2024 18:55:58 +0200 Subject: Multi-backend support Squashed commit of the following: commit 92518024ba295456358618c0e8180bd8e996fdf1 Author: Birte Kristina Friesel Date: Fri Jul 26 18:39:46 2024 +0200 add_or_update station: remove superfluos 'new backend id := old backend id' commit df21c20c6e4c86454f8a9ac69121404415217f2a Author: Birte Kristina Friesel Date: Fri Jul 26 18:35:51 2024 +0200 revert connection targets min_count to 3 commit be335cef07d0b42874f5fc1de4a1d13396e8e807 Author: Birte Kristina Friesel Date: Fri Jul 26 18:20:05 2024 +0200 mention backend selection in API documentation commit 9f41828fb4f18fd707e0087def3032e8d4c8d7d8 Author: Birte Kristina Friesel Date: Thu Jul 25 20:19:23 2024 +0200 use_history: not all backends provide route data in departure monitor commit 09714b4d89684b8331d0e96f564a4c7432318f70 Author: Birte Kristina Friesel Date: Thu Jul 25 20:11:44 2024 +0200 disambiguation: pass correct hafas parameter commit 8cdf1120fc32155dc6525be64601b7c10a9c7f52 Author: Birte Kristina Friesel Date: Thu Jul 25 20:11:28 2024 +0200 _checked_in: hide Zuglauf link for non-db checkins commit 7455653f541198e0e0a6d11aed421487ffdb6285 Author: Birte Kristina Friesel Date: Thu Jul 25 20:01:47 2024 +0200 debug output commit b9cda07f85601a58ea32dbdacdd5399f302db52b Author: Birte Kristina Friesel Date: Thu Jul 25 19:09:07 2024 +0200 fix remaining get_connection_targets / get_connecting_trains_p invocations commit 2759d7258c37c7498905cfe19f6b4c4f6d16bd21 Author: Birte Kristina Friesel Date: Wed Jul 24 20:50:12 2024 +0200 support non-DB HAFAS backends (WiP) --- lib/Travelynx/Model/Stations.pm | 203 +++++++++++++++++++++++++++++++++------- 1 file changed, 170 insertions(+), 33 deletions(-) (limited to 'lib/Travelynx/Model/Stations.pm') diff --git a/lib/Travelynx/Model/Stations.pm b/lib/Travelynx/Model/Stations.pm index ad219e0..7215aa5 100644 --- a/lib/Travelynx/Model/Stations.pm +++ b/lib/Travelynx/Model/Stations.pm @@ -14,38 +14,125 @@ sub new { return bless( \%opt, $class ); } -sub add_or_update { +sub get_backend_id { 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; + + if ( $opt{iris} ) { + + # special case + return 0; + } + if ( $opt{hafas} and $self->{backend_id}{hafas}{ $opt{hafas} } ) { + return $self->{backend_id}{hafas}{ $opt{hafas} }; + } + + my $db = $opt{db} // $self->{pg}->db; + my $backend_id = 0; + + if ( $opt{hafas} ) { + $backend_id = $db->select( + 'backends', + ['id'], + { + hafas => 1, + name => $opt{hafas} + } + )->hash->{id}; + $self->{backend_id}{hafas}{ $opt{hafas} } = $backend_id; + } + + return $backend_id; +} + +sub get_hafas_name { + my ( $self, %opt ) = @_; + + if ( exists $self->{hafas_name}{ $opt{backend_id} } ) { + return $self->{hafas_name}{ $opt{backend_id} }; + } + + my $db = $opt{db} // $self->{pg}->db; + my $hafas_name; + my $ret = $db->select( + 'backends', + ['name'], + { + hafas => 1, + id => $opt{backend_id}, } - $db->update( + )->hash; + + if ($ret) { + $hafas_name = $ret->{name}; + } + + $self->{hafas_name}{ $opt{backend_id} } = $hafas_name; + + return $hafas_name; +} + +sub get_backends { + my ( $self, %opt ) = @_; + + $opt{db} //= $self->{pg}->db; + + my $res = $opt{db}->select( 'backends', [ 'id', 'name', 'iris', 'hafas' ] ); + my @ret; + + while ( my $row = $res->hash ) { + push( + @ret, + { + id => $row->{id}, + name => $row->{name}, + iris => $row->{iris}, + hafas => $row->{hafas}, + } + ); + } + + return @ret; +} + +sub add_or_update { + my ( $self, %opt ) = @_; + my $stop = $opt{stop}; + my $loc = $stop->loc; + $opt{db} //= $self->{pg}->db; + + $opt{backend_id} //= $self->get_backend_id(%opt); + + if ( + my $s = $self->get_by_eva( + $loc->eva, + db => $opt{db}, + backend_id => $opt{backend_id} + ) + ) + { + $opt{db}->update( 'stations', { name => $loc->name, lat => $loc->lat, lon => $loc->lon, - source => $source, archived => 0 }, - { eva => $loc->eva } + { + eva => $loc->eva, + source => $opt{backend_id} + } ); return; } - $db->insert( + $opt{db}->insert( 'stations', { eva => $loc->eva, name => $loc->name, lat => $loc->lat, lon => $loc->lon, - source => $source, + source => $opt{backend_id}, archived => 0 } ); @@ -53,17 +140,20 @@ sub add_or_update { sub add_meta { my ( $self, %opt ) = @_; - my $db = $opt{db} // $self->{pg}->db; my $eva = $opt{eva}; my @meta = @{ $opt{meta} }; + $opt{db} //= $self->{pg}->db; + $opt{backend_id} //= $self->get_backend_id(%opt); + for my $meta (@meta) { if ( $meta != $eva ) { - $db->insert( + $opt{db}->insert( 'related_stations', { - eva => $eva, - meta => $meta + eva => $eva, + meta => $meta, + backend_id => $opt{backend_id}, }, { on_conflict => undef } ); @@ -82,7 +172,16 @@ sub get_meta { my $db = $opt{db} // $self->{pg}->db; my $eva = $opt{eva}; - my $res = $db->select( 'related_stations', ['meta'], { eva => $eva } ); + $opt{backend_id} //= $self->get_backend_id( %opt, db => $db ); + + my $res = $db->select( + 'related_stations', + ['meta'], + { + eva => $eva, + backend_id => $opt{backend_id} + } + ); my @ret; while ( my $row = $res->hash ) { @@ -93,9 +192,12 @@ sub get_meta { } sub get_for_autocomplete { - my ($self) = @_; + my ( $self, %opt ) = @_; + + $opt{backend_id} //= $self->get_backend_id(%opt); - my $res = $self->{pg}->db->select( 'stations', ['name'] ); + my $res = $self->{pg} + ->db->select( 'stations', ['name'], { source => $opt{backend_id} } ); my %ret; while ( my $row = $res->hash ) { @@ -113,18 +215,34 @@ sub get_by_eva { return; } - my $db = $opt{db} // $self->{pg}->db; + $opt{db} //= $self->{pg}->db; + $opt{backend_id} //= $self->get_backend_id(%opt); - return $db->select( 'stations', '*', { eva => $eva } )->hash; + return $opt{db}->select( + 'stations', + '*', + { + eva => $eva, + source => $opt{backend_id} + } + )->hash; } # Fast sub get_by_evas { - my ( $self, @evas ) = @_; + my ( $self, %opt ) = @_; - my @ret - = $self->{pg}->db->select( 'stations', '*', { eva => { '=', \@evas } } ) - ->hashes->each; + $opt{db} //= $self->{pg}->db; + $opt{backend_id} //= $self->get_backend_id(%opt); + + my @ret = $self->{pg}->db->select( + 'stations', + '*', + { + eva => { '=', $opt{evas} }, + source => $opt{backend_id} + } + )->hashes->each; return @ret; } @@ -132,10 +250,18 @@ sub get_by_evas { sub get_by_name { my ( $self, $name, %opt ) = @_; - my $db = $opt{db} // $self->{pg}->db; + $opt{db} //= $self->{pg}->db; + $opt{backend_id} //= $self->get_backend_id(%opt); - return $db->select( 'stations', '*', { name => $name }, { limit => 1 } ) - ->hash; + return $opt{db}->select( + 'stations', + '*', + { + name => $name, + source => $opt{backend_id} + }, + { limit => 1 } + )->hash; } # Slow @@ -152,16 +278,27 @@ sub get_by_names { sub get_by_ds100 { my ( $self, $ds100, %opt ) = @_; - my $db = $opt{db} // $self->{pg}->db; + $opt{db} //= $self->{pg}->db; + $opt{backend_id} //= $self->get_backend_id(%opt); - return $db->select( 'stations', '*', { ds100 => $ds100 }, { limit => 1 } ) - ->hash; + return $opt{db}->select( + 'stations', + '*', + { + ds100 => $ds100, + source => $opt{backend_id} + }, + { limit => 1 } + )->hash; } # Can be slow sub search { my ( $self, $identifier, %opt ) = @_; + $opt{db} //= $self->{pg}->db; + $opt{backend_id} //= $self->get_backend_id(%opt); + if ( $identifier =~ m{ ^ \d+ $ }x ) { return $self->get_by_eva( $identifier, %opt ) // $self->get_by_ds100( $identifier, %opt ) -- cgit v1.2.3