Skip to content

Commit ea495b9

Browse files
committed
Add saved_places and saved_areas to user table
1 parent 4c7d8b1 commit ea495b9

6 files changed

Lines changed: 145 additions & 10 deletions

File tree

src/db/main/migrations/97.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
DROP TRIGGER admin_updated_at;
2+
DROP TRIGGER user_updated_at;
3+
ALTER TABLE user ADD COLUMN saved_places TEXT NOT NULL DEFAULT '';
4+
ALTER TABLE user ADD COLUMN saved_areas TEXT NOT NULL DEFAULT '';
5+
CREATE TRIGGER user_updated_at UPDATE OF name, password, roles, saved_places, saved_areas, created_at, deleted_at ON user
6+
BEGIN
7+
UPDATE user SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
8+
END;
9+
CREATE TRIGGER osm_user_updated_at UPDATE OF osm_data, tags, created_at, deleted_at ON osm_user
10+
BEGIN
11+
UPDATE osm_user SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
12+
END;

src/db/main/schema.sql

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ CREATE TABLE IF NOT EXISTS "user"(
101101
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ')),
102102
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ')),
103103
deleted_at TEXT
104-
) STRICT;
104+
, saved_places TEXT NOT NULL DEFAULT '', saved_areas TEXT NOT NULL DEFAULT '') STRICT;
105105
CREATE TABLE access_token(
106106
id INTEGER PRIMARY KEY NOT NULL,
107107
user_id INTEGER NOT NULL REFERENCES "user"(id),
@@ -139,10 +139,6 @@ CREATE TABLE place_submission(
139139
closed_at TEXT,
140140
deleted_at TEXT
141141
) STRICT;
142-
CREATE TRIGGER user_updated_at UPDATE OF osm_data, tags, created_at, deleted_at ON "osm_user"
143-
BEGIN
144-
UPDATE "osm_user" SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
145-
END;
146142
CREATE TRIGGER report_updated_at UPDATE OF area_id, date, tags, created_at, deleted_at ON report
147143
BEGIN
148144
UPDATE report SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
@@ -163,10 +159,6 @@ CREATE TRIGGER element_issue_updated_at UPDATE OF element_id, code, severity, cr
163159
BEGIN
164160
UPDATE element_issue SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
165161
END;
166-
CREATE TRIGGER admin_updated_at UPDATE OF name, password, roles, created_at, deleted_at ON "user"
167-
BEGIN
168-
UPDATE "user" SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
169-
END;
170162
CREATE TRIGGER acess_token_updated_at UPDATE OF user_id, name, secret, roles, created_at, deleted_at ON access_token
171163
BEGIN
172164
UPDATE access_token SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
@@ -191,6 +183,14 @@ CREATE TRIGGER element_updated_at UPDATE OF overpass_data, tags, lat, lon, creat
191183
BEGIN
192184
UPDATE element SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
193185
END;
186+
CREATE TRIGGER user_updated_at UPDATE OF name, password, roles, saved_places, saved_areas, created_at, deleted_at ON user
187+
BEGIN
188+
UPDATE user SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
189+
END;
190+
CREATE TRIGGER osm_user_updated_at UPDATE OF osm_data, tags, created_at, deleted_at ON osm_user
191+
BEGIN
192+
UPDATE osm_user SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ') WHERE id = old.id;
193+
END;
194194
CREATE INDEX idx_user_updated_at ON "osm_user"(updated_at);
195195
CREATE INDEX area_updated_at ON area(updated_at);
196196
CREATE INDEX report_updated_at ON report(updated_at);
@@ -211,7 +211,6 @@ CREATE INDEX admin_updated_at ON "user"(updated_at);
211211
CREATE INDEX access_token_secret ON access_token(secret);
212212
CREATE UNIQUE INDEX area_element_area_id_element_id ON area_element(area_id, element_id);
213213
CREATE INDEX element_event_updated_at ON element_event(updated_at);
214-
CREATE INDEX element_event_user_created_type ON element_event(user_id, created_at, type);
215214
CREATE INDEX idx_area_bbox_west ON area(bbox_west);
216215
CREATE INDEX idx_area_bbox_south ON area(bbox_south);
217216
CREATE INDEX idx_area_bbox_east ON area(bbox_east);
@@ -220,4 +219,6 @@ CREATE UNIQUE INDEX place_submission_origin_external_id ON place_submission(orig
220219
CREATE INDEX element_lat_lon ON element(lat, lon);
221220
CREATE INDEX place_submission_lat_lon ON place_submission(lat, lon);
222221
CREATE INDEX element_deleted_at ON element(deleted_at);
222+
CREATE INDEX element_event_user_created_type ON element_event(user_id, created_at, type);
223+
CREATE INDEX area_type ON area(json_extract(tags, '$.type'));
223224
COMMIT;

src/db/main/user/blocking_queries.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,52 @@ pub fn set_roles(admin_id: i64, roles: &[Role], conn: &Connection) -> Result<Use
9999
.map_err(Into::into)
100100
}
101101

102+
#[allow(dead_code)]
103+
pub fn set_saved_places(id: i64, saved_places: &[i64], conn: &Connection) -> Result<User> {
104+
let saved_places: String = saved_places
105+
.iter()
106+
.map(|id| id.to_string())
107+
.collect::<Vec<_>>()
108+
.join(",");
109+
conn.query_row(
110+
&format!(
111+
r#"
112+
UPDATE {TABLE}
113+
SET {SavedPlaces} = ?1
114+
WHERE {Id} = ?2
115+
RETURNING {projection}
116+
"#,
117+
projection = User::projection(),
118+
),
119+
params![saved_places, id],
120+
User::mapper(),
121+
)
122+
.map_err(Into::into)
123+
}
124+
125+
#[allow(dead_code)]
126+
pub fn set_saved_areas(id: i64, saved_areas: &[i64], conn: &Connection) -> Result<User> {
127+
let saved_areas: String = saved_areas
128+
.iter()
129+
.map(|id| id.to_string())
130+
.collect::<Vec<_>>()
131+
.join(",");
132+
conn.query_row(
133+
&format!(
134+
r#"
135+
UPDATE {TABLE}
136+
SET {SavedAreas} = ?1
137+
WHERE {Id} = ?2
138+
RETURNING {projection}
139+
"#,
140+
projection = User::projection(),
141+
),
142+
params![saved_areas, id],
143+
User::mapper(),
144+
)
145+
.map_err(Into::into)
146+
}
147+
102148
#[cfg(test)]
103149
mod test {
104150
use super::schema::Role;
@@ -158,4 +204,30 @@ mod test {
158204
assert_eq!(roles, super::select_by_id(admin_id, &conn)?.roles,);
159205
Ok(())
160206
}
207+
208+
#[test]
209+
fn set_saved_places() -> Result<()> {
210+
let conn = conn();
211+
let admin_id = super::insert("name", "pwd", &conn)?.id;
212+
let saved_places = vec![1, 2, 3];
213+
super::set_saved_places(admin_id, &saved_places, &conn)?;
214+
assert_eq!(
215+
saved_places,
216+
super::select_by_id(admin_id, &conn)?.saved_places
217+
);
218+
Ok(())
219+
}
220+
221+
#[test]
222+
fn set_saved_areas() -> Result<()> {
223+
let conn = conn();
224+
let admin_id = super::insert("name", "pwd", &conn)?.id;
225+
let saved_areas = vec![10, 20, 30];
226+
super::set_saved_areas(admin_id, &saved_areas, &conn)?;
227+
assert_eq!(
228+
saved_areas,
229+
super::select_by_id(admin_id, &conn)?.saved_areas
230+
);
231+
Ok(())
232+
}
161233
}

src/db/main/user/queries.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,21 @@ pub async fn set_roles(admin_id: i64, roles: &[Role], pool: &Pool) -> Result<Use
4545
.interact(move |conn| blocking_queries::set_roles(admin_id, &roles, conn))
4646
.await?
4747
}
48+
49+
#[allow(dead_code)]
50+
pub async fn set_saved_places(id: i64, saved_places: &[i64], pool: &Pool) -> Result<User> {
51+
let saved_places = saved_places.to_vec();
52+
pool.get()
53+
.await?
54+
.interact(move |conn| blocking_queries::set_saved_places(id, &saved_places, conn))
55+
.await?
56+
}
57+
58+
#[allow(dead_code)]
59+
pub async fn set_saved_areas(id: i64, saved_areas: &[i64], pool: &Pool) -> Result<User> {
60+
let saved_areas = saved_areas.to_vec();
61+
pool.get()
62+
.await?
63+
.interact(move |conn| blocking_queries::set_saved_areas(id, &saved_areas, conn))
64+
.await?
65+
}

src/db/main/user/schema.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub enum Columns {
1212
Name,
1313
Password,
1414
Roles,
15+
SavedPlaces,
16+
SavedAreas,
1517
CreatedAt,
1618
UpdatedAt,
1719
DeletedAt,
@@ -23,6 +25,8 @@ pub struct User {
2325
pub name: String,
2426
pub password: String,
2527
pub roles: Vec<Role>,
28+
pub saved_places: Vec<i64>,
29+
pub saved_areas: Vec<i64>,
2630
pub created_at: String,
2731
pub updated_at: String,
2832
pub deleted_at: Option<String>,
@@ -60,6 +64,8 @@ impl User {
6064
Columns::Name,
6165
Columns::Password,
6266
Columns::Roles,
67+
Columns::SavedPlaces,
68+
Columns::SavedAreas,
6369
Columns::CreatedAt,
6470
Columns::UpdatedAt,
6571
Columns::DeletedAt,
@@ -78,6 +84,8 @@ impl User {
7884
name: row.get(Columns::Name.as_ref())?,
7985
password: row.get(Columns::Password.as_ref())?,
8086
roles: Self::parse_roles(row.get(Columns::Roles.as_ref())?),
87+
saved_places: Self::parse_saved_items(row.get(Columns::SavedPlaces.as_ref())?),
88+
saved_areas: Self::parse_saved_items(row.get(Columns::SavedAreas.as_ref())?),
8189
created_at: row.get(Columns::CreatedAt.as_ref())?,
8290
updated_at: row.get(Columns::UpdatedAt.as_ref())?,
8391
deleted_at: row.get(Columns::DeletedAt.as_ref())?,
@@ -92,6 +100,20 @@ impl User {
92100
.filter_map(|s| Role::from_str(&s).ok())
93101
.collect()
94102
}
103+
104+
fn parse_saved_items(column_value: String) -> Vec<i64> {
105+
column_value
106+
.split(',')
107+
.filter_map(|s| {
108+
let s = s.trim();
109+
if s.is_empty() {
110+
None
111+
} else {
112+
s.parse().ok()
113+
}
114+
})
115+
.collect()
116+
}
95117
}
96118

97119
impl FromStr for Role {

src/rpc/auth/whoami.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ mod test {
3838
created_at: "2023-01-01T00:00:00Z".to_string(),
3939
updated_at: "2023-01-01T00:00:00Z".to_string(),
4040
deleted_at: None,
41+
saved_places: vec![],
42+
saved_areas: vec![],
4143
};
4244

4345
let result = super::run(&user).await.unwrap();
@@ -61,6 +63,8 @@ mod test {
6163
created_at: "2023-01-01T00:00:00Z".to_string(),
6264
updated_at: "2023-01-01T00:00:00Z".to_string(),
6365
deleted_at: None,
66+
saved_places: vec![],
67+
saved_areas: vec![],
6468
};
6569

6670
let result = super::run(&user).await.unwrap();
@@ -78,6 +82,8 @@ mod test {
7882
created_at: "2023-01-01T00:00:00Z".to_string(),
7983
updated_at: "2023-01-01T00:00:00Z".to_string(),
8084
deleted_at: None,
85+
saved_places: vec![],
86+
saved_areas: vec![],
8187
};
8288

8389
let result = super::run(&user).await.unwrap();
@@ -95,6 +101,8 @@ mod test {
95101
created_at: "not-a-timestamp".to_string(),
96102
updated_at: "2023-01-01T00:00:00Z".to_string(),
97103
deleted_at: None,
104+
saved_places: vec![],
105+
saved_areas: vec![],
98106
};
99107

100108
let result = super::run(&user).await;
@@ -113,6 +121,8 @@ mod test {
113121
created_at: future_date.format(&Rfc3339)?,
114122
updated_at: future_date.format(&Rfc3339)?,
115123
deleted_at: None,
124+
saved_places: vec![],
125+
saved_areas: vec![],
116126
};
117127

118128
let result = super::run(&user).await?;

0 commit comments

Comments
 (0)