From 86b0ce0cc1a35891eb80a0ffd60f2201dda681fa Mon Sep 17 00:00:00 2001 From: Igor Bubelov Date: Sun, 18 Aug 2024 18:06:43 +0700 Subject: [PATCH] Refactor area model --- Cargo.lock | 1 + Cargo.toml | 2 +- src/area/admin.rs | 28 +++-- src/area/model.rs | 181 ++++++++++++++------------------ src/area/service.rs | 28 ++--- src/area/v2.rs | 12 +-- src/area/v3.rs | 16 +-- src/command/add_area.rs | 4 +- src/command/fix_tags.rs | 2 +- src/command/generate_reports.rs | 2 +- src/command/import_countries.rs | 6 +- src/report/model.rs | 16 +-- src/report/v2.rs | 6 +- src/report/v3.rs | 6 +- src/vacuum/mod.rs | 4 +- 15 files changed, 148 insertions(+), 166 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a6afef..31ea531 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1517,6 +1517,7 @@ dependencies = [ "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", + "serde_json", "smallvec", "time", ] diff --git a/Cargo.toml b/Cargo.toml index 508c252..fa812a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ strip = "symbols" actix-web = { version = "4.9.0", default-features = false, features = ["macros", "compress-brotli"] } # https://github.com/rusqlite/rusqlite/releases -rusqlite = { version = "0.31.0", default-features = false, features = ["bundled", "time"] } +rusqlite = { version = "0.31.0", default-features = false, features = ["bundled", "time", "serde_json"] } # https://github.com/seanmonstar/reqwest/releases reqwest = { version = "0.12.5", default-features = false, features = ["rustls-tls", "json"] } diff --git a/src/area/admin.rs b/src/area/admin.rs index 4516be9..3e9a886 100644 --- a/src/area/admin.rs +++ b/src/area/admin.rs @@ -45,7 +45,7 @@ pub async fn post( let area = pool .get() .await? - .interact(move |conn| area::service::insert(&args.tags, conn)) + .interact(move |conn| area::service::insert(args.tags.clone(), conn)) .await??; let log_message = format!( "{} created a new area: https://api.btcmap.org/v3/areas/{}", @@ -70,8 +70,12 @@ pub async fn patch( pool: Data>, ) -> Result, Error> { let token = auth.check(&req).await?; - let area = Area::select_by_id_or_alias_async(&id_or_alias, &pool) + let cloned_id_or_alias = id_or_alias.clone(); + let area = pool + .get() .await? + .interact(move |conn| Area::select_by_id_or_alias(&cloned_id_or_alias, &conn)) + .await?? .ok_or(Error::HttpNotFound(format!( "There is no area with id or alias = {}", id_or_alias, @@ -79,7 +83,7 @@ pub async fn patch( let area = pool .get() .await? - .interact(move |conn| area::service::patch_tags(area.id, &args.tags, conn)) + .interact(move |conn| area::service::patch_tags(area.id, args.tags.clone(), conn)) .await??; let log_message = format!( "{} updated area https://api.btcmap.org/v3/areas/{}", @@ -98,8 +102,12 @@ pub async fn delete( pool: Data>, ) -> Result, Error> { let token = auth.check(&req).await?; - let area = Area::select_by_id_or_alias_async(&id_or_alias, &pool) + let cloned_id_or_alias = id_or_alias.clone(); + let area = pool + .get() .await? + .interact(move |conn| Area::select_by_id_or_alias(&cloned_id_or_alias, &conn)) + .await?? .ok_or(Error::HttpNotFound(format!( "There is no area with id or alias = {}", id_or_alias, @@ -197,7 +205,7 @@ mod test { #[test] async fn patch_should_return_401_if_unauthorized() -> Result<()> { let state = mock_state().await; - Area::insert(&Map::new(), &state.conn)?; + Area::insert(Map::new(), &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -221,7 +229,7 @@ mod test { let url_alias = "test"; let mut tags = Map::new(); tags.insert("url_alias".into(), Value::String(url_alias.into())); - Area::insert(&tags, &state.conn)?; + Area::insert(tags, &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -247,7 +255,7 @@ mod test { .to_request(); let res = test::call_service(&app, req).await; assert_eq!(res.status(), StatusCode::OK); - let area = Area::select_by_url_alias(&url_alias, &state.conn)?.unwrap(); + let area = Area::select_by_alias(&url_alias, &state.conn)?.unwrap(); assert!(area.tags["string"].is_string()); assert!(area.tags["unsigned"].is_u64()); assert!(area.tags["float"].is_f64()); @@ -261,7 +269,7 @@ mod test { let url_alias = "test"; let mut tags = Map::new(); tags.insert("url_alias".into(), Value::String(url_alias.into())); - Area::insert(&tags, &state.conn)?; + Area::insert(tags, &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -287,7 +295,7 @@ mod test { let mut tags = Map::new(); tags.insert("url_alias".into(), Value::String(url_alias.into())); tags.insert("geo_json".into(), phuket_geo_json()); - Area::insert(&tags, &state.conn)?; + Area::insert(tags, &state.conn)?; let area_element = state .element_repo @@ -327,7 +335,7 @@ mod test { let res = test::call_service(&app, req).await; assert_eq!(res.status(), StatusCode::OK); - let area: Option = Area::select_by_url_alias(&url_alias, &state.conn)?; + let area: Option = Area::select_by_alias(&url_alias, &state.conn)?; assert!(area.is_some()); assert!(area.unwrap().deleted_at.is_some()); diff --git a/src/area/model.rs b/src/area/model.rs index b5f9bad..28f9a41 100644 --- a/src/area/model.rs +++ b/src/area/model.rs @@ -1,13 +1,15 @@ use crate::{Error, Result}; -use deadpool_sqlite::Pool; use geojson::{GeoJson, Geometry}; use rusqlite::{named_params, Connection, OptionalExtension, Row}; use serde_json::{Map, Value}; -use std::time::Instant; +use std::{ + thread::sleep, + time::{Duration, Instant}, +}; use time::{format_description::well_known::Rfc3339, OffsetDateTime}; use tracing::{debug, error, info}; -#[derive(PartialEq, Debug, Clone)] +#[derive(Debug, Eq, PartialEq)] pub struct Area { pub id: i64, pub tags: Map, @@ -17,15 +19,16 @@ pub struct Area { } const TABLE: &str = "area"; -const ALL_COLUMNS: &str = "rowid, tags, created_at, updated_at, deleted_at"; -const COL_ROWID: &str = "rowid"; +const ALL_COLUMNS: &str = "id, tags, created_at, updated_at, deleted_at"; +const COL_ID: &str = "id"; const COL_TAGS: &str = "tags"; const _COL_CREATED_AT: &str = "created_at"; const COL_UPDATED_AT: &str = "updated_at"; const COL_DELETED_AT: &str = "deleted_at"; impl Area { - pub fn insert(tags: &Map, conn: &Connection) -> Result { + pub fn insert(tags: Map, conn: &Connection) -> Result { + sleep(Duration::from_millis(10)); let query = format!( r#" INSERT INTO {TABLE} ({COL_TAGS}) @@ -33,12 +36,8 @@ impl Area { "# ); debug!(query); - conn.execute( - &query, - named_params! { ":tags": serde_json::to_string(tags)? }, - )?; - Ok(Area::select_by_id(conn.last_insert_rowid(), conn)? - .ok_or(Error::Rusqlite(rusqlite::Error::QueryReturnedNoRows))?) + conn.execute(&query, named_params! { ":tags": Value::from(tags) })?; + Ok(Area::select_by_id(conn.last_insert_rowid(), conn)?.unwrap()) } pub fn select_all(limit: Option, conn: &Connection) -> Result> { @@ -47,7 +46,7 @@ impl Area { r#" SELECT {ALL_COLUMNS} FROM {TABLE} - ORDER BY {COL_UPDATED_AT}, {COL_ROWID} + ORDER BY {COL_UPDATED_AT}, {COL_ID} LIMIT :limit "# ); @@ -56,14 +55,14 @@ impl Area { .prepare(&query)? .query_map( named_params! { ":limit": limit.unwrap_or(i64::MAX) }, - Self::mapper(), + mapper(), )? .collect::, _>>()?; let time_ms = start.elapsed().as_millis(); info!( count = res.len(), time_ms, - "Loaded all areas ({}) in {} ms", + "Loaded {} areas in {} ms", res.len(), time_ms, ); @@ -75,43 +74,42 @@ impl Area { limit: Option, conn: &Connection, ) -> Result> { + let start = Instant::now(); let query = format!( r#" SELECT {ALL_COLUMNS} FROM {TABLE} WHERE {COL_UPDATED_AT} > :updated_since - ORDER BY {COL_UPDATED_AT}, {COL_ROWID} + ORDER BY {COL_UPDATED_AT}, {COL_ID} LIMIT :limit "# ); debug!(query); - Ok(conn + let res = conn .prepare(&query)? .query_map( named_params! { ":updated_since": updated_since.format(&Rfc3339)?, ":limit": limit.unwrap_or(i64::MAX), }, - Self::mapper(), + mapper(), )? - .collect::, _>>()?) - } - - pub async fn select_by_id_or_alias_async( - id_or_alias: &str, - pool: &Pool, - ) -> Result> { - let id_or_alias = id_or_alias.to_string(); - pool.get() - .await? - .interact(move |conn| Area::select_by_id_or_alias(&id_or_alias, conn)) - .await? + .collect::, _>>()?; + let time_ms = start.elapsed().as_millis(); + info!( + count = res.len(), + time_ms, + "Loaded {} areas in {} ms", + res.len(), + time_ms, + ); + Ok(res) } pub fn select_by_id_or_alias(id_or_alias: &str, conn: &Connection) -> Result> { match id_or_alias.parse::() { Ok(id) => Area::select_by_id(id, conn), - Err(_) => Area::select_by_url_alias(id_or_alias, conn), + Err(_) => Area::select_by_alias(id_or_alias, conn), } } @@ -120,43 +118,36 @@ impl Area { r#" SELECT {ALL_COLUMNS} FROM {TABLE} - WHERE {COL_ROWID} = :id + WHERE {COL_ID} = :id "# ); debug!(query); Ok(conn - .query_row(&query, named_params! { ":id": id }, Self::mapper()) + .query_row(&query, named_params! { ":id": id }, mapper()) .optional()?) } - pub fn select_by_url_alias(url_alias: &str, conn: &Connection) -> Result> { + pub fn select_by_alias(alias: &str, conn: &Connection) -> Result> { let query = format!( r#" SELECT {ALL_COLUMNS} FROM {TABLE} - WHERE json_extract({COL_TAGS}, '$.url_alias') = :url_alias + WHERE json_extract({COL_TAGS}, '$.url_alias') = :alias "# ); debug!(query); Ok(conn - .query_row( - &query, - named_params! { ":url_alias": url_alias }, - Self::mapper(), - ) + .query_row(&query, named_params! { ":alias": alias }, mapper()) .optional()?) } - pub fn patch_tags(&self, tags: &Map, conn: &Connection) -> Result { - Area::_patch_tags(self.id, tags, conn) - } - - pub fn _patch_tags(id: i64, tags: &Map, conn: &Connection) -> Result { + pub fn patch_tags(id: i64, tags: Map, conn: &Connection) -> Result { + sleep(Duration::from_millis(10)); let query = format!( r#" UPDATE {TABLE} - SET {COL_TAGS} = json_patch({COL_TAGS}, :tags) - WHERE {COL_ROWID} = :id + SET {COL_TAGS} = json_patch({COL_TAGS}, json(:tags)) + WHERE {COL_ID} = :id "# ); debug!(query); @@ -164,23 +155,20 @@ impl Area { &query, named_params! { ":id": id, - ":tags": serde_json::to_string(tags)?, + ":tags": Value::from(tags), }, )?; Ok(Area::select_by_id(id, &conn)? .ok_or(Error::Rusqlite(rusqlite::Error::QueryReturnedNoRows))?) } - pub fn remove_tag(&self, name: &str, conn: &Connection) -> Result { - Area::_remove_tag(self.id, name, conn) - } - - fn _remove_tag(id: i64, name: &str, conn: &Connection) -> Result { + pub fn remove_tag(id: i64, name: &str, conn: &Connection) -> Result { + sleep(Duration::from_millis(10)); let query = format!( r#" UPDATE {TABLE} SET {COL_TAGS} = json_remove({COL_TAGS}, :name) - WHERE {COL_ROWID} = :id + WHERE {COL_ID} = :id "# ); debug!(query); @@ -196,21 +184,13 @@ impl Area { } #[cfg(test)] - pub fn __set_updated_at(&self, updated_at: &OffsetDateTime, conn: &Connection) -> Result { - Area::_set_updated_at(self.id, updated_at, conn) - } - - #[cfg(test)] - pub fn _set_updated_at( - id: i64, - updated_at: &OffsetDateTime, - conn: &Connection, - ) -> Result { + pub fn set_updated_at(id: i64, updated_at: &OffsetDateTime, conn: &Connection) -> Result { + sleep(Duration::from_millis(10)); let query = format!( r#" UPDATE {TABLE} SET {COL_UPDATED_AT} = :updated_at - WHERE {COL_ROWID} = :id + WHERE {COL_ID} = :id "# ); debug!(query); @@ -226,25 +206,18 @@ impl Area { } pub fn set_deleted_at( - &self, - deleted_at: Option, - conn: &Connection, - ) -> Result { - Area::_set_deleted_at(self.id, deleted_at, conn) - } - - pub fn _set_deleted_at( id: i64, deleted_at: Option, conn: &Connection, ) -> Result { + sleep(Duration::from_millis(10)); match deleted_at { Some(deleted_at) => { let query = format!( r#" UPDATE {TABLE} SET {COL_DELETED_AT} = :deleted_at - WHERE {COL_ROWID} = :id + WHERE {COL_ID} = :id "# ); debug!(query); @@ -261,7 +234,7 @@ impl Area { r#" UPDATE {TABLE} SET {COL_DELETED_AT} = NULL - WHERE {COL_ROWID} = :id + WHERE {COL_ID} = :id "# ); debug!(query); @@ -335,18 +308,18 @@ impl Area { return geometries; } +} - const fn mapper() -> fn(&Row) -> rusqlite::Result { - |row: &Row| -> rusqlite::Result { - let tags: String = row.get(1)?; - Ok(Area { - id: row.get(0)?, - tags: serde_json::from_str(&tags).unwrap(), - created_at: row.get(2)?, - updated_at: row.get(3)?, - deleted_at: row.get(4)?, - }) - } +const fn mapper() -> fn(&Row) -> rusqlite::Result { + |row: &Row| -> rusqlite::Result { + let tags: String = row.get(1)?; + Ok(Area { + id: row.get(0)?, + tags: serde_json::from_str(&tags).unwrap(), + created_at: row.get(2)?, + updated_at: row.get(3)?, + deleted_at: row.get(4)?, + }) } } @@ -365,7 +338,7 @@ mod test { async fn insert() -> Result<()> { let state = mock_state().await; let tags = mock_tags(); - let res = Area::insert(&tags, &state.conn)?; + let res = Area::insert(tags.clone(), &state.conn)?; assert_eq!(tags, res.tags); assert_eq!(res, Area::select_by_id(res.id, &state.conn)?.unwrap()); Ok(()) @@ -376,9 +349,9 @@ mod test { let conn = mock_conn(); assert_eq!( vec![ - Area::insert(&Map::new(), &conn)?, - Area::insert(&Map::new(), &conn)?, - Area::insert(&Map::new(), &conn)?, + Area::insert(Map::new(), &conn)?, + Area::insert(Map::new(), &conn)?, + Area::insert(Map::new(), &conn)?, ], Area::select_all(None, &conn)?, ); @@ -388,15 +361,15 @@ mod test { #[test] async fn select_updated_since() -> Result<()> { let state = mock_state().await; - let _area_1 = Area::insert(&mock_tags(), &state.conn)?; + let _area_1 = Area::insert(mock_tags(), &state.conn)?; let _area_1 = - Area::_set_updated_at(_area_1.id, &datetime!(2020-01-01 00:00 UTC), &state.conn)?; - let area_2 = Area::insert(&mock_tags(), &state.conn)?; + Area::set_updated_at(_area_1.id, &datetime!(2020-01-01 00:00 UTC), &state.conn)?; + let area_2 = Area::insert(mock_tags(), &state.conn)?; let area_2 = - Area::_set_updated_at(area_2.id, &datetime!(2020-01-02 00:00 UTC), &state.conn)?; - let area_3 = Area::insert(&mock_tags(), &state.conn)?; + Area::set_updated_at(area_2.id, &datetime!(2020-01-02 00:00 UTC), &state.conn)?; + let area_3 = Area::insert(mock_tags(), &state.conn)?; let area_3 = - Area::_set_updated_at(area_3.id, &datetime!(2020-01-03 00:00 UTC), &state.conn)?; + Area::set_updated_at(area_3.id, &datetime!(2020-01-03 00:00 UTC), &state.conn)?; assert_eq!( vec![area_2, area_3], Area::select_updated_since(&datetime!(2020-01-01 00:00 UTC), None, &state.conn)?, @@ -407,7 +380,7 @@ mod test { #[test] async fn select_by_id() -> Result<()> { let conn = mock_conn(); - let area = Area::insert(&Map::new(), &conn)?; + let area = Area::insert(Map::new(), &conn)?; assert_eq!(area, Area::select_by_id(area.id, &conn)?.unwrap()); Ok(()) } @@ -418,8 +391,8 @@ mod test { let url_alias = json!("url_alias_value"); let mut tags = Map::new(); tags.insert("url_alias".into(), url_alias.clone()); - Area::insert(&tags, &conn)?; - let area = Area::select_by_url_alias(url_alias.as_str().unwrap(), &conn)?; + Area::insert(tags, &conn)?; + let area = Area::select_by_alias(url_alias.as_str().unwrap(), &conn)?; assert!(area.is_some()); let area = area.unwrap(); assert_eq!(url_alias, area.tags["url_alias"]); @@ -435,10 +408,10 @@ mod test { let tag_2_value = json!("tag_2_value"); let mut tags = Map::new(); tags.insert(tag_1_name.into(), tag_1_value.clone()); - let area = Area::insert(&tags, &conn)?; + let area = Area::insert(tags.clone(), &conn)?; assert_eq!(tag_1_value, area.tags[tag_1_name]); tags.insert(tag_2_name.into(), tag_2_value.clone()); - let area = Area::_patch_tags(area.id, &tags, &conn)?; + let area = Area::patch_tags(area.id, tags, &conn)?; assert_eq!(tag_1_value, area.tags[tag_1_name]); assert_eq!(tag_2_value, area.tags[tag_2_name]); Ok(()) @@ -447,10 +420,10 @@ mod test { #[test] async fn set_deleted_at() -> Result<()> { let conn = mock_conn(); - let area = Area::insert(&Map::new(), &conn)?; - let area = Area::_set_deleted_at(area.id, Some(OffsetDateTime::now_utc()), &conn)?; + let area = Area::insert(Map::new(), &conn)?; + let area = Area::set_deleted_at(area.id, Some(OffsetDateTime::now_utc()), &conn)?; assert!(area.deleted_at.is_some()); - let area = Area::_set_deleted_at(area.id, None, &conn)?; + let area = Area::set_deleted_at(area.id, None, &conn)?; assert!(area.deleted_at.is_none()); Ok(()) } diff --git a/src/area/service.rs b/src/area/service.rs index bf344e4..fc86bf4 100644 --- a/src/area/service.rs +++ b/src/area/service.rs @@ -8,7 +8,7 @@ use rusqlite::Connection; use serde_json::{Map, Value}; use time::OffsetDateTime; -pub fn insert(tags: &Map, conn: &mut Connection) -> Result { +pub fn insert(tags: Map, conn: &mut Connection) -> Result { let sp = conn.savepoint()?; let url_alias = tags .get("url_alias") @@ -32,24 +32,24 @@ pub fn insert(tags: &Map, conn: &mut Connection) -> Result if geo_json.is_err() { Err(Error::HttpConflict("Invalid geo_json".into()))? } - if Area::select_by_url_alias(url_alias, &sp)?.is_some() { + if Area::select_by_alias(url_alias, &sp)?.is_some() { Err(Error::HttpConflict( "This url_alias is already in use".into(), ))? } - let area = Area::insert(&tags, &sp)?; + let area = Area::insert(tags, &sp)?; let area_elements = element::service::find_in_area(&area, &sp)?; element::service::update_areas_tag(&area_elements, &sp)?; sp.commit()?; Ok(area) } -pub fn patch_tags(id: i64, tags: &Map, conn: &mut Connection) -> Result { +pub fn patch_tags(id: i64, tags: Map, conn: &mut Connection) -> Result { let sp = conn.savepoint()?; let area = Area::select_by_id(id, &sp)?.unwrap(); let area_elements = element::service::find_in_area(&area, &sp)?; element::service::update_areas_tag(&area_elements, &sp)?; - let area = Area::_patch_tags(id, tags, &sp)?; + let area = Area::patch_tags(id, tags, &sp)?; let area_elements = element::service::find_in_area(&area, &sp)?; element::service::update_areas_tag(&area_elements, &sp)?; sp.commit()?; @@ -60,7 +60,7 @@ pub fn soft_delete(id: i64, conn: &mut Connection) -> Result { let sp = conn.savepoint()?; let area = Area::select_by_id(id, &sp)?.unwrap(); let area_elements = element::service::find_in_area(&area, &sp)?; - let area = area.set_deleted_at(Some(OffsetDateTime::now_utc()), &sp)?; + let area = Area::set_deleted_at(area.id, Some(OffsetDateTime::now_utc()), &sp)?; element::service::update_areas_tag(&area_elements, &sp)?; sp.commit()?; Ok(area) @@ -82,7 +82,7 @@ mod test { let url_alias = json!("test"); tags.insert("url_alias".into(), url_alias.clone()); tags.insert("geo_json".into(), phuket_geo_json()); - let area = super::insert(&tags, &mut conn)?; + let area = super::insert(tags, &mut conn)?; let db_area = Area::select_by_id(area.id, &conn)?.unwrap(); assert_eq!(area, db_area); Ok(()) @@ -101,7 +101,7 @@ mod test { let url_alias = json!("test"); tags.insert("url_alias".into(), url_alias.clone()); tags.insert("geo_json".into(), phuket_geo_json()); - super::insert(&tags, &mut conn)?; + super::insert(tags, &mut conn)?; let db_area_element = Element::select_by_id(area_element.id, &conn)?.unwrap(); assert_eq!(1, db_area_element.tag("areas").as_array().unwrap().len()); Ok(()) @@ -114,14 +114,14 @@ mod test { let url_alias = json!("test"); tags.insert("url_alias".into(), url_alias.clone()); tags.insert("geo_json".into(), phuket_geo_json()); - let area = Area::insert(&tags, &mut conn)?; + let area = Area::insert(tags, &mut conn)?; let mut patch_tags = Map::new(); let new_tag_name = "foo"; let new_tag_value = json!("bar"); patch_tags.insert(new_tag_name.into(), new_tag_value.clone()); let new_alias = json!("test1"); patch_tags.insert("url_alias".into(), new_alias.clone()); - let area = super::patch_tags(area.id, &patch_tags, &mut conn)?; + let area = super::patch_tags(area.id, patch_tags, &mut conn)?; let db_area = Area::select_by_id(area.id, &conn)?.unwrap(); assert_eq!(area, db_area); assert_eq!(new_tag_value, db_area.tags[new_tag_name]); @@ -144,8 +144,8 @@ mod test { let url_alias = json!("test"); tags.insert("url_alias".into(), url_alias.clone()); tags.insert("geo_json".into(), phuket_geo_json()); - let area = Area::insert(&tags, &mut conn)?; - let area = super::patch_tags(area.id, &Map::new(), &mut conn)?; + let area = Area::insert(tags, &mut conn)?; + let area = super::patch_tags(area.id, Map::new(), &mut conn)?; let db_area = Area::select_by_id(area.id, &conn)?.unwrap(); assert_eq!(area, db_area); let db_area_element = Element::select_by_id(area_element.id, &conn)?.unwrap(); @@ -156,7 +156,7 @@ mod test { #[test] fn soft_delete() -> Result<()> { let mut conn = mock_conn(); - let area = Area::insert(&Map::new(), &conn)?; + let area = Area::insert(Map::new(), &conn)?; super::soft_delete(area.id, &mut conn)?; let db_area = Area::select_by_id(area.id, &conn)?.unwrap(); assert!(db_area.deleted_at.is_some()); @@ -177,7 +177,7 @@ mod test { let url_alias = json!("test"); tags.insert("url_alias".into(), url_alias.clone()); tags.insert("geo_json".into(), phuket_geo_json()); - let area = Area::insert(&tags, &mut conn)?; + let area = Area::insert(tags, &mut conn)?; super::soft_delete(area.id, &mut conn)?; let db_area = Area::select_by_id(area.id, &conn)?.unwrap(); assert!(db_area.deleted_at.is_some()); diff --git a/src/area/v2.rs b/src/area/v2.rs index 85d2728..40dd14b 100644 --- a/src/area/v2.rs +++ b/src/area/v2.rs @@ -89,7 +89,7 @@ pub async fn get_by_url_alias( let area = pool .get() .await? - .interact(move |conn| Area::select_by_url_alias(&cloned_url_alias, conn)) + .interact(move |conn| Area::select_by_alias(&cloned_url_alias, conn)) .await??; area.ok_or(Error::HttpNotFound(format!( "Area with url_alias = {url_alias} doesn't exist" @@ -126,7 +126,7 @@ mod tests { let state = mock_state().await; let mut tags = Map::new(); tags.insert("url_alias".into(), "test".into()); - Area::insert(&tags, &state.conn)?; + Area::insert(tags, &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -144,9 +144,9 @@ mod tests { let state = mock_state().await; let mut tags = Map::new(); tags.insert("url_alias".into(), "test".into()); - Area::insert(&tags, &state.conn)?; - Area::insert(&tags, &state.conn)?; - Area::insert(&tags, &state.conn)?; + Area::insert(tags.clone(), &state.conn)?; + Area::insert(tags.clone(), &state.conn)?; + Area::insert(tags, &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -165,7 +165,7 @@ mod tests { let area_url_alias = "test"; let mut tags = Map::new(); tags.insert("url_alias".into(), Value::String(area_url_alias.into())); - Area::insert(&tags, &state.conn)?; + Area::insert(tags, &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) diff --git a/src/area/v3.rs b/src/area/v3.rs index ffeb2a2..ab81952 100644 --- a/src/area/v3.rs +++ b/src/area/v3.rs @@ -148,7 +148,7 @@ mod test { #[test] async fn get_not_empty_array() -> Result<()> { let state = mock_state().await; - let area = Area::insert(&Map::new(), &state.conn)?; + let area = Area::insert(Map::new(), &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -166,9 +166,9 @@ mod test { #[test] async fn get_with_limit() -> Result<()> { let state = mock_state().await; - let area_1 = Area::insert(&Map::new(), &state.conn)?; - let area_2 = Area::insert(&Map::new(), &state.conn)?; - let _area_3 = Area::insert(&Map::new(), &state.conn)?; + let area_1 = Area::insert(Map::new(), &state.conn)?; + let area_2 = Area::insert(Map::new(), &state.conn)?; + let _area_3 = Area::insert(Map::new(), &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) @@ -186,11 +186,11 @@ mod test { #[test] async fn get_updated_since() -> Result<()> { let state = mock_state().await; - let area_1 = Area::insert(&Map::new(), &state.conn)?; - Area::_set_updated_at(area_1.id, &datetime!(2022-01-05 00:00 UTC), &state.conn)?; - let area_2 = Area::insert(&Map::new(), &state.conn)?; + let area_1 = Area::insert(Map::new(), &state.conn)?; + Area::set_updated_at(area_1.id, &datetime!(2022-01-05 00:00 UTC), &state.conn)?; + let area_2 = Area::insert(Map::new(), &state.conn)?; let area_2 = - Area::_set_updated_at(area_2.id, &datetime!(2022-02-05 00:00 UTC), &state.conn)?; + Area::set_updated_at(area_2.id, &datetime!(2022-02-05 00:00 UTC), &state.conn)?; let app = test::init_service( App::new() .app_data(Data::new(state.pool)) diff --git a/src/command/add_area.rs b/src/command/add_area.rs index a82e231..9ccdffa 100644 --- a/src/command/add_area.rs +++ b/src/command/add_area.rs @@ -91,11 +91,11 @@ pub async fn run(conn: &Connection) -> Result<()> { )), ); - match Area::select_by_url_alias(url_alias, conn)? { + match Area::select_by_alias(url_alias, conn)? { Some(_) => Err(Error::HttpConflict( "Area with this url_alias already exists".into(), ))?, - None => Area::insert(&tags, conn)?, + None => Area::insert(tags, conn)?, }; Ok(()) diff --git a/src/command/fix_tags.rs b/src/command/fix_tags.rs index f6123f9..8ade895 100644 --- a/src/command/fix_tags.rs +++ b/src/command/fix_tags.rs @@ -12,7 +12,7 @@ pub async fn run(conn: &Connection) -> Result<()> { let geo_json: Value = serde_json::from_str(&unescaped)?; let mut patch_set = Map::new(); patch_set.insert("geo_json".into(), geo_json); - area.patch_tags(&patch_set, &conn)?; + Area::patch_tags(area.id, patch_set, &conn)?; warn!(area.id, "Fixed geo_json tag"); } } diff --git a/src/command/generate_reports.rs b/src/command/generate_reports.rs index a726a90..3ad8a30 100644 --- a/src/command/generate_reports.rs +++ b/src/command/generate_reports.rs @@ -226,7 +226,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), json!("test")); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; for _ in 1..100 { state .report_repo diff --git a/src/command/import_countries.rs b/src/command/import_countries.rs index b01e9b1..ac0999f 100644 --- a/src/command/import_countries.rs +++ b/src/command/import_countries.rs @@ -47,13 +47,13 @@ pub async fn run(path: &str, conn: &mut Connection) -> Result<()> { let reader = BufReader::new(file); let json: CountryJson = serde_json::from_reader(reader)?; - match Area::select_by_url_alias(&json.id, &tx)? { + match Area::select_by_alias(&json.id, &tx)? { Some(area) => { - area.patch_tags(&json.tags, &tx)?; + Area::patch_tags(area.id, json.tags, &tx)?; info!(json.id, "Patched tags for an existing area"); } None => { - Area::insert(&json.tags, &tx)?; + Area::insert(json.tags, &tx)?; info!(json.id, "Inserted area"); } } diff --git a/src/report/model.rs b/src/report/model.rs index 55002f1..0e43f70 100644 --- a/src/report/model.rs +++ b/src/report/model.rs @@ -415,7 +415,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -433,7 +433,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -459,7 +459,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; let report_1 = state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -500,7 +500,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -514,7 +514,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - let area = Area::insert(&area_tags, &state.conn)?; + let area = Area::insert(area_tags, &state.conn)?; state .report_repo .insert( @@ -543,7 +543,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; let tag_1_name = "foo"; let tag_1_value = "bar"; let tag_2_name = "qwerty"; @@ -571,7 +571,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; let report = state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -599,7 +599,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; let report = state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) diff --git a/src/report/v2.rs b/src/report/v2.rs index 1a0f352..b89bee1 100644 --- a/src/report/v2.rs +++ b/src/report/v2.rs @@ -191,7 +191,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -213,7 +213,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; state .report_repo .insert(1, &date!(2023 - 05 - 06), &Map::new()) @@ -243,7 +243,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - Area::insert(&area_tags, &state.conn)?; + Area::insert(area_tags, &state.conn)?; let report_1 = state .report_repo .insert(1, &OffsetDateTime::now_utc().date(), &Map::new()) diff --git a/src/report/v3.rs b/src/report/v3.rs index 4876286..22df9a4 100644 --- a/src/report/v3.rs +++ b/src/report/v3.rs @@ -166,7 +166,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - let area = Area::insert(&area_tags, &state.conn)?; + let area = Area::insert(area_tags, &state.conn)?; let report = state .report_repo .insert(area.id, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -190,7 +190,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - let area = Area::insert(&area_tags, &state.conn)?; + let area = Area::insert(area_tags, &state.conn)?; let report_1 = state .report_repo .insert(area.id, &OffsetDateTime::now_utc().date(), &Map::new()) @@ -222,7 +222,7 @@ mod test { let state = mock_state().await; let mut area_tags = Map::new(); area_tags.insert("url_alias".into(), "test".into()); - let area = Area::insert(&area_tags, &state.conn)?; + let area = Area::insert(area_tags, &state.conn)?; let report_1 = state .report_repo diff --git a/src/vacuum/mod.rs b/src/vacuum/mod.rs index b5699f7..baa3934 100644 --- a/src/vacuum/mod.rs +++ b/src/vacuum/mod.rs @@ -35,7 +35,7 @@ fn vacuum_area(area: &Area, conn: &Connection) -> Result { if value.is_null() { warn!(area_id = area.id, key, "Area tag is null"); - Area::remove_tag(area, key, conn)?; + Area::remove_tag(area.id, key, conn)?; nulls_removed += 1; } @@ -44,7 +44,7 @@ fn vacuum_area(area: &Area, conn: &Connection) -> Result { if value == "" { warn!(area_id = area.id, key, value, "Area tag is useless string"); - Area::remove_tag(area, key, conn)?; + Area::remove_tag(area.id, key, conn)?; useless_strings_removed += 1; } }