diff --git a/stationapi/src/infrastructure/line_repository.rs b/stationapi/src/infrastructure/line_repository.rs index 1884b230..048337be 100644 --- a/stationapi/src/infrastructure/line_repository.rs +++ b/stationapi/src/infrastructure/line_repository.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use async_trait::async_trait; use sqlx::{MySql, MySqlConnection, Pool}; @@ -134,7 +136,8 @@ impl InternalLineRepository { async fn find_by_id(id: u32, conn: &mut MySqlConnection) -> Result, DomainError> { let rows: Option = sqlx::query_as!( LineRow, - "SELECT DISTINCT l.line_cd, + "SELECT + l.line_cd, l.company_cd, l.line_type, l.line_symbol_primary, @@ -184,7 +187,8 @@ impl InternalLineRepository { ) -> Result, DomainError> { let rows: Option = sqlx::query_as!( LineRow, - "SELECT DISTINCT l.line_cd, + "SELECT + l.line_cd, l.company_cd, l.line_type, l.line_symbol_primary, @@ -209,12 +213,13 @@ impl InternalLineRepository { COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, COALESCE(a.line_color_c, l.line_color_c) AS line_color_c - FROM `lines` AS l - JOIN `stations` AS s ON s.station_cd = ? - JOIN `station_station_types` AS sst ON sst.station_cd = s.station_cd - LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd - LEFT JOIN `aliases` AS a ON la.alias_cd = a.id - WHERE l.line_cd = s.line_cd", + FROM `lines` AS l + JOIN `stations` AS s ON s.station_cd = ? + JOIN `station_station_types` AS sst ON sst.station_cd = s.station_cd + LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd + LEFT JOIN `aliases` AS a ON la.alias_cd = a.id + WHERE l.line_cd = s.line_cd + ORDER BY l.line_cd", station_id, ) .fetch_optional(conn) @@ -236,6 +241,8 @@ impl InternalLineRepository { return Ok(vec![]); } + let ids: HashSet = ids.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(ids.len() - 1)); let query_str = format!( "SELECT * FROM `lines` WHERE line_cd IN ( {} ) AND e_status = 0", @@ -259,7 +266,8 @@ impl InternalLineRepository { ) -> Result, DomainError> { let rows: Vec = sqlx::query_as!( LineRow, - "SELECT DISTINCT l.line_cd, + "SELECT DISTINCT + l.line_cd, l.company_cd, l.line_type, l.line_symbol_primary, @@ -284,14 +292,15 @@ impl InternalLineRepository { sst.line_group_cd, s.station_cd, s.station_g_cd - FROM `lines` AS l - JOIN `stations` AS s ON s.station_g_cd = ? - AND s.e_status = 0 - JOIN `station_station_types` AS sst ON sst.station_cd = s.station_cd - LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd - LEFT JOIN `aliases` AS a ON la.alias_cd = a.id - WHERE l.line_cd = s.line_cd - AND l.e_status = 0", + FROM `lines` AS l + JOIN `stations` AS s ON s.station_g_cd = ? + AND s.e_status = 0 + JOIN `station_station_types` AS sst ON sst.station_cd = s.station_cd + LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd + LEFT JOIN `aliases` AS a ON la.alias_cd = a.id + WHERE l.line_cd = s.line_cd + AND l.e_status = 0 + ORDER BY l.line_cd", station_group_id ) .fetch_all(conn) @@ -309,29 +318,44 @@ impl InternalLineRepository { return Ok(vec![]); } + let station_group_id_vec: HashSet = station_group_id_vec.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(station_group_id_vec.len() - 1)); let query_str = format!( - "SELECT - l.*, - s.station_cd, - s.station_g_cd, - sst.line_group_cd, - COALESCE(a.line_name, l.line_name) AS line_name, - COALESCE(a.line_name_k, l.line_name_k) AS line_name_k, - COALESCE(a.line_name_h, l.line_name_h) AS line_name_h, - COALESCE(a.line_name_r, l.line_name_r) AS line_name_r, - COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, - COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, - COALESCE(a.line_color_c, l.line_color_c) AS line_color_c + "SELECT DISTINCT + l.line_cd, + l.company_cd, + l.line_type, + l.line_symbol_primary, + l.line_symbol_secondary, + l.line_symbol_extra, + l.line_symbol_primary_color, + l.line_symbol_secondary_color, + l.line_symbol_extra_color, + l.line_symbol_primary_shape, + l.line_symbol_secondary_shape, + l.line_symbol_extra_shape, + l.e_status, + l.e_sort, + l.average_distance, + s.station_cd, + s.station_g_cd, + COALESCE(a.line_name, l.line_name) AS line_name, + COALESCE(a.line_name_k, l.line_name_k) AS line_name_k, + COALESCE(a.line_name_h, l.line_name_h) AS line_name_h, + COALESCE(a.line_name_r, l.line_name_r) AS line_name_r, + COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, + COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, + COALESCE(a.line_color_c, l.line_color_c) AS line_color_c FROM `lines` AS l - JOIN `stations` AS s ON s.station_g_cd IN ( {} ) AND s.e_status = 0 - LEFT JOIN `station_station_types` AS sst ON sst.station_cd = s.station_cd + JOIN `stations` AS s ON s.station_g_cd IN ( {} ) LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd LEFT JOIN `aliases` AS a ON la.alias_cd = a.id WHERE l.line_cd = s.line_cd AND l.e_status = 0 - GROUP BY s.station_cd", + AND s.e_status = 0 + ORDER BY l.line_cd", params ); @@ -352,7 +376,8 @@ impl InternalLineRepository { ) -> Result, DomainError> { let rows: Vec = sqlx::query_as!( LineRow, - "SELECT DISTINCT l.line_cd, + "SELECT DISTINCT + l.line_cd, l.company_cd, l.line_type, l.line_symbol_primary, @@ -377,15 +402,14 @@ impl InternalLineRepository { COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, COALESCE(a.line_color_c, l.line_color_c) AS line_color_c - FROM `lines` AS l - JOIN `station_station_types` AS sst ON sst.line_group_cd = ? - JOIN `stations` AS s ON s.station_cd = sst.station_cd - AND s.e_status = 0 - LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd - LEFT JOIN `aliases` AS a ON la.alias_cd = a.id - WHERE l.line_cd = s.line_cd - AND l.e_status = 0 - GROUP BY l.line_cd", + FROM `lines` AS l + JOIN `station_station_types` AS sst ON sst.line_group_cd = ? + JOIN `stations` AS s ON s.station_cd = sst.station_cd + LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd + LEFT JOIN `aliases` AS a ON la.alias_cd = a.id + WHERE l.line_cd = s.line_cd + AND l.e_status = 0 + ORDER BY l.line_cd", line_group_id ) .fetch_all(conn) @@ -402,29 +426,45 @@ impl InternalLineRepository { return Ok(vec![]); } + let line_group_id_vec: HashSet = line_group_id_vec.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(line_group_id_vec.len() - 1)); let query_str = format!( "SELECT DISTINCT - l.*, - sst.line_group_cd, - COALESCE(a.line_name, l.line_name) AS line_name, - COALESCE(a.line_name_k, l.line_name_k) AS line_name_k, - COALESCE(a.line_name_h, l.line_name_h) AS line_name_h, - COALESCE(a.line_name_r, l.line_name_r) AS line_name_r, - COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, - COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, - COALESCE(a.line_color_c, l.line_color_c) AS line_color_c, - s.station_cd, - s.station_g_cd + l.line_cd, + l.company_cd, + l.line_type, + l.line_symbol_primary, + l.line_symbol_secondary, + l.line_symbol_extra, + l.line_symbol_primary_color, + l.line_symbol_secondary_color, + l.line_symbol_extra_color, + l.line_symbol_primary_shape, + l.line_symbol_secondary_shape, + l.line_symbol_extra_shape, + l.e_status, + l.e_sort, + l.average_distance, + sst.line_group_cd, + COALESCE(a.line_name, l.line_name) AS line_name, + COALESCE(a.line_name_k, l.line_name_k) AS line_name_k, + COALESCE(a.line_name_h, l.line_name_h) AS line_name_h, + COALESCE(a.line_name_r, l.line_name_r) AS line_name_r, + COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, + COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, + COALESCE(a.line_color_c, l.line_color_c) AS line_color_c, + s.station_cd, + s.station_g_cd FROM `lines` AS l JOIN `station_station_types` AS sst ON sst.line_group_cd IN ( {} ) - JOIN `stations` AS s ON s.station_cd = sst.station_cd AND s.e_status = 0 + JOIN `stations` AS s ON s.station_cd = sst.station_cd LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd LEFT JOIN `aliases` AS a ON la.alias_cd = a.id WHERE l.line_cd = s.line_cd AND l.e_status = 0 - GROUP BY sst.line_group_cd, l.line_cd", + ORDER BY l.line_cd", params ); @@ -446,29 +486,45 @@ impl InternalLineRepository { return Ok(vec![]); } + let line_group_id_vec: HashSet = line_group_id_vec.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(line_group_id_vec.len() - 1)); let query_str = format!( "SELECT DISTINCT - l.*, - sst.line_group_cd, - COALESCE(a.line_name, l.line_name) AS line_name, - COALESCE(a.line_name_k, l.line_name_k) AS line_name_k, - COALESCE(a.line_name_h, l.line_name_h) AS line_name_h, - COALESCE(a.line_name_r, l.line_name_r) AS line_name_r, - COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, - COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, - COALESCE(a.line_color_c, l.line_color_c) AS line_color_c, - s.station_cd, - s.station_g_cd + l.line_cd, + l.company_cd, + l.line_type, + l.line_symbol_primary, + l.line_symbol_secondary, + l.line_symbol_extra, + l.line_symbol_primary_color, + l.line_symbol_secondary_color, + l.line_symbol_extra_color, + l.line_symbol_primary_shape, + l.line_symbol_secondary_shape, + l.line_symbol_extra_shape, + l.e_status, + l.e_sort, + l.average_distance, + sst.line_group_cd, + COALESCE(a.line_name, l.line_name) AS line_name, + COALESCE(a.line_name_k, l.line_name_k) AS line_name_k, + COALESCE(a.line_name_h, l.line_name_h) AS line_name_h, + COALESCE(a.line_name_r, l.line_name_r) AS line_name_r, + COALESCE(a.line_name_zh, l.line_name_zh) AS line_name_zh, + COALESCE(a.line_name_ko, l.line_name_ko) AS line_name_ko, + COALESCE(a.line_color_c, l.line_color_c) AS line_color_c, + s.station_cd, + s.station_g_cd FROM `lines` AS l LEFT JOIN `station_station_types` AS sst ON sst.line_group_cd IN ( {} ) - LEFT JOIN `stations` AS s ON s.station_cd = sst.station_cd AND s.e_status = 0 + LEFT JOIN `stations` AS s ON s.station_cd = sst.station_cd LEFT JOIN `line_aliases` AS la ON la.station_cd = s.station_cd LEFT JOIN `aliases` AS a ON la.alias_cd = a.id WHERE l.line_cd = s.line_cd AND l.e_status = 0 - GROUP BY l.line_cd", + ORDER BY l.line_cd", params ); diff --git a/stationapi/src/infrastructure/train_type_repository.rs b/stationapi/src/infrastructure/train_type_repository.rs index 3130cfa6..edbc99a5 100644 --- a/stationapi/src/infrastructure/train_type_repository.rs +++ b/stationapi/src/infrastructure/train_type_repository.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use crate::domain::{ entity::train_type::TrainType, error::DomainError, repository::train_type_repository::TrainTypeRepository, @@ -141,7 +143,9 @@ impl InternalTrainTypeRepository { ) -> Result, DomainError> { let rows: Vec = sqlx::query_as!( TrainTypeRow, - "SELECT + "SELECT DISTINCT + sst.id, + t.type_cd, t.type_name, t.type_name_k, t.type_name_r, @@ -150,12 +154,14 @@ impl InternalTrainTypeRepository { t.color, t.direction, t.kind, - sst.* + sst.station_cd, + sst.line_group_cd, + sst.pass FROM types as t JOIN `station_station_types` AS sst ON sst.line_group_cd = ? WHERE t.type_cd = sst.type_cd - ORDER BY t.kind, sst.id", + ORDER BY sst.id", line_group_id ) .fetch_all(conn) @@ -169,7 +175,9 @@ impl InternalTrainTypeRepository { conn: &mut MySqlConnection, ) -> Result, DomainError> { let rows: Vec = sqlx::query_as!(TrainTypeRow, - "SELECT + "SELECT DISTINCT + sst.id, + t.type_cd, t.type_name, t.type_name_k, t.type_name_r, @@ -178,7 +186,9 @@ impl InternalTrainTypeRepository { t.color, t.direction, t.kind, - sst.* + sst.station_cd, + sst.line_group_cd, + sst.pass FROM `types` AS t JOIN `stations` AS s ON s.station_cd = ? AND s.e_status = 0 JOIN `station_station_types` AS sst ON sst.station_cd = s.station_cd AND sst.type_cd = t.type_cd AND sst.pass <> 1 @@ -197,9 +207,20 @@ impl InternalTrainTypeRepository { conn: &mut MySqlConnection, ) -> Result, DomainError> { let rows: Option = sqlx::query_as( - "SELECT - t.*, - sst.* + "SELECT DISTINCT + sst.id, + t.type_cd, + t.type_name, + t.type_name_k, + t.type_name_r, + t.type_name_zh, + t.type_name_ko, + t.color, + t.direction, + t.kind, + sst.station_cd, + sst.line_group_cd, + sst.pass FROM `types` as t JOIN `station_station_types` AS sst ON sst.line_group_cd = ? WHERE @@ -238,11 +259,24 @@ impl InternalTrainTypeRepository { return Ok(vec![]); } + let station_id_vec: HashSet = station_id_vec.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(station_id_vec.len() - 1)); let query_str = format!( - "SELECT - t.*, - sst.* + "SELECT DISTINCT + sst.id, + t.type_cd, + t.type_name, + t.type_name_k, + t.type_name_r, + t.type_name_zh, + t.type_name_ko, + t.color, + t.direction, + t.kind, + sst.station_cd, + sst.line_group_cd, + sst.pass FROM types as t JOIN `stations` AS s ON s.station_cd IN ( {} ) AND s.e_status = 0 @@ -272,12 +306,25 @@ impl InternalTrainTypeRepository { return Ok(vec![]); } + let station_id_vec: HashSet = station_id_vec.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(station_id_vec.len() - 1)); let query_str = format!( - "SELECT - t.*, - sst.* - FROM + "SELECT DISTINCT + sst.id, + t.type_cd, + t.type_name, + t.type_name_k, + t.type_name_r, + t.type_name_zh, + t.type_name_ko, + t.color, + t.direction, + t.kind, + sst.station_cd, + sst.line_group_cd, + sst.pass + FROM station_station_types as sst, stations as s, types as t @@ -295,7 +342,7 @@ impl InternalTrainTypeRepository { AND s.e_status = 0 AND sst.line_group_cd = ? AND sst.pass <> 1 - ORDER BY t.kind, sst.id", + ORDER BY sst.id", params ); @@ -318,12 +365,24 @@ impl InternalTrainTypeRepository { return Ok(vec![]); } + let line_group_id_vec: HashSet = line_group_id_vec.into_iter().collect(); + let params = format!("?{}", ", ?".repeat(line_group_id_vec.len() - 1)); let query_str = format!( - "SELECT - t.*, - s.*, - sst.* + "SELECT DISTINCT + sst.id, + t.type_cd, + t.type_name, + t.type_name_k, + t.type_name_r, + t.type_name_zh, + t.type_name_ko, + t.color, + t.direction, + t.kind, + sst.station_cd, + sst.line_group_cd, + sst.pass FROM types as t JOIN `station_station_types` AS sst ON sst.line_group_cd IN ( {} ) AND sst.pass <> 1 AND sst.type_cd = t.type_cd diff --git a/stationapi/src/use_case/interactor/query.rs b/stationapi/src/use_case/interactor/query.rs index 270885ca..12acdcfb 100644 --- a/stationapi/src/use_case/interactor/query.rs +++ b/stationapi/src/use_case/interactor/query.rs @@ -1,7 +1,4 @@ -use std::{ - collections::BTreeMap, - sync::{Arc, Mutex}, -}; +use std::{collections::BTreeMap, sync::Arc}; use async_trait::async_trait; @@ -528,42 +525,22 @@ where .await?; let rows = Arc::new(rows); - let line_group_id_vec = Arc::clone(&rows) - .iter() - .filter_map(|row| row.line_group_cd) - .collect::>(); - let line_group_id_vec = Arc::new(line_group_id_vec); - let tt_lines = self - .line_repository - .get_by_line_group_id_vec_for_routes(Arc::clone(&line_group_id_vec).to_vec()) - .await?; - let tt_lines = Arc::new(Mutex::new(tt_lines)); - - let train_types = self - .train_type_repository - .get_by_line_group_id_vec(Arc::clone(&line_group_id_vec).to_vec()) - .await?; - let train_types = Arc::new(train_types); - let station_group_id_vec: Vec = rows.clone().iter().map(|row| row.station_g_cd).collect(); - let transfer_stations = self + let transfer_stations = &mut self .station_repository .get_by_station_group_id_vec(station_group_id_vec.clone()) .await?; - let transfer_stations = Arc::new(Mutex::new(transfer_stations)); let rows_lines = self .line_repository - .get_by_station_group_id_vec(station_group_id_vec) + .get_by_line_group_id_vec_for_routes(station_group_id_vec) .await?; let rows_lines: Vec = rows_lines .into_iter() .map(|mut line| { line.line_symbols = self.get_line_symbols(&line); - let transfer_stations = Arc::clone(&transfer_stations); - let mut transfer_stations = transfer_stations.lock().unwrap(); let station = transfer_stations .iter_mut() .find(|row| row.line_cd == line.line_cd) @@ -590,77 +567,36 @@ where }, ); - let mut routes = Vec::with_capacity(route_row_tree_map.len()); - - for (id, stops) in route_row_tree_map { - let stops_with_line: Vec = stops - .iter() - .map(|row: &Station| { - let mut stop = - std::convert::Into::::into( - row.clone(), - ); - - let extracted_line = Arc::new(self.extract_line_from_station(&stop)); - stop.line = Some(Box::new(Arc::clone(&extracted_line).as_ref().clone())); - stop.lines = rows_lines - .clone() - .iter() - .filter(|l| l.station_cd == stop.station_cd) - .cloned() - .collect(); - stop.station_numbers = self.get_station_numbers(&stop); - - let locked_tt_lines = tt_lines.lock().unwrap(); - - if stop.has_train_types { - stop.train_type = Some(Box::new(TrainType { - id: row.type_id.unwrap(), - station_cd: row.station_cd, - type_cd: row.type_cd.unwrap(), - line_group_cd: row.line_group_cd.unwrap(), - pass: row.pass.unwrap(), - type_name: row.type_name.clone().unwrap(), - type_name_k: row.type_name_k.clone().unwrap(), - type_name_r: row.type_name_r.clone(), - type_name_zh: row.type_name_zh.clone(), - type_name_ko: row.type_name_ko.clone(), - color: row.color.clone().unwrap(), - direction: row.direction.unwrap(), - kind: row.kind.unwrap(), - line: Some(Box::new( - locked_tt_lines - .clone() - .iter() - .find(|line| line.line_cd == row.line_cd) - .unwrap() - .clone(), - )), - lines: locked_tt_lines - .clone() - .iter_mut() - .map(|l| { - l.train_type = Arc::clone(&train_types) - .iter() - .filter(|tt| { - tt.line_group_cd == stop.line_group_cd.unwrap() - }) - .find(|tt| tt.station_cd == l.station_cd) - .cloned(); - l.to_owned() - }) - .collect(), - })); - } - stop.into() - }) - .collect(); - let var_name = Route { - id, - stops: stops_with_line, - }; - routes.push(var_name); - } + let routes = route_row_tree_map + .iter() + .map(|(id, stops)| { + let stops_with_line: Vec = stops + .iter() + .map(|row: &Station| { + let mut stop = + std::convert::Into::::into( + row.clone(), + ); + + let extracted_line = Arc::new(self.extract_line_from_station(&stop)); + stop.line = Some(Box::new(Arc::clone(&extracted_line).as_ref().clone())); + stop.lines = rows_lines + .clone() + .iter() + .filter(|l| l.station_cd == stop.station_cd) + .cloned() + .collect(); + stop.station_numbers = self.get_station_numbers(&stop); + + stop.into() + }) + .collect(); + Route { + id: *id, + stops: stops_with_line, + } + }) + .collect(); Ok(routes) } }