Skip to content

Commit 4d1b9e2

Browse files
committed
Add timezone to place
1 parent f4613fa commit 4d1b9e2

File tree

9 files changed

+190
-3
lines changed

9 files changed

+190
-3
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2018"
99
[dependencies]
1010
base64 = "0.13"
1111
chrono = { version = "0.4", features = ["serde"] }
12-
chrono-tz = "0.5"
12+
chrono-tz = { version = "0.5", features = ["serde"] }
1313
clap = "3.0.0-beta"
1414
custom_error = "1.9"
1515
diesel = { version = "1.4", features = ["postgres", "chrono", "r2d2", "serde_json", "uuidv07"] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
DROP TABLE "public"."opening_hour_day";
2+
3+
4+
DROP TABLE "public"."opening_hour_date";
5+
6+
7+
DROP TABLE "public"."opening_hour_computed";
8+
9+
10+
ALTER TABLE "public"."place"
11+
DROP COLUMN "timezone";
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
CREATE TABLE "public"."opening_hour_day" (
2+
"id" uuid NOT NULL DEFAULT gen_random_uuid(),
3+
"place_id" uuid NOT NULL,
4+
"day" int2 NOT NULL,
5+
"opening_time" time NOT NULL,
6+
"closure_time" time NOT NULL,
7+
"evacuation_time" time NOT NULL,
8+
"created_at" timestamptz NOT NULL DEFAULT NOW(),
9+
"updated_at" timestamptz NOT NULL DEFAULT NOW(),
10+
PRIMARY KEY ("id")
11+
);
12+
13+
CREATE INDEX "opening_hour_day_place_id_index" ON "public"."opening_hour_day" USING BTREE ("place_id");
14+
15+
ALTER TABLE "public"."opening_hour_day" ADD FOREIGN KEY ("place_id") REFERENCES "public"."place" ("id") ON DELETE CASCADE;
16+
17+
CREATE TABLE "public"."opening_hour_date" (
18+
"id" uuid NOT NULL DEFAULT gen_random_uuid(),
19+
"place_id" uuid NOT NULL,
20+
"date" date NOT NULL,
21+
"opening_time" time,
22+
"closure_time" time,
23+
"evacuation_time" time,
24+
"closed" bool NOT NULL,
25+
"created_at" timestamptz NOT NULL DEFAULT NOW(),
26+
"updated_at" timestamptz NOT NULL DEFAULT NOW(),
27+
PRIMARY KEY ("id")
28+
);
29+
30+
CREATE INDEX "opening_hour_date_place_id_index" ON "public"."opening_hour_date" USING BTREE ("place_id");
31+
32+
ALTER TABLE "public"."opening_hour_date" ADD FOREIGN KEY ("place_id") REFERENCES "public"."place" ("id") ON DELETE CASCADE;
33+
34+
CREATE TABLE "public"."opening_hour_computed" (
35+
"id" uuid NOT NULL DEFAULT gen_random_uuid(),
36+
"place_id" uuid NOT NULL,
37+
"opening_timestamp" timestamptz NOT NULL,
38+
"closing_timestamp" timestamptz NOT NULL,
39+
"evacuation_timestamp" timestamptz NOT NULL,
40+
"created_at" timestamptz NOT NULL DEFAULT NOW(),
41+
"updated_at" timestamptz NOT NULL DEFAULT NOW(),
42+
PRIMARY KEY ("id")
43+
);
44+
45+
CREATE INDEX "opening_hour_computed_place_id_index" ON "public"."opening_hour_computed" USING BTREE ("place_id");
46+
47+
ALTER TABLE "public"."opening_hour_computed" ADD FOREIGN KEY ("place_id") REFERENCES "public"."place" ("id") ON DELETE CASCADE;
48+
49+
SELECT diesel_manage_updated_at('opening_hour_day');
50+
SELECT diesel_manage_updated_at('opening_hour_date');
51+
SELECT diesel_manage_updated_at('opening_hour_computed');
52+
53+
ALTER TABLE "public"."place" ADD COLUMN "timezone" text NOT NULL DEFAULT 'Europe/Paris';

src/model/place/common.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::model::organization::Organization;
22

33
use super::super::schema::place;
4-
use super::super::types::{GaugeLevel, Gauge_level};
4+
use super::super::types::{GaugeLevel, Gauge_level, Timezone};
55
use chrono::{DateTime, Utc};
66
use postgis::ewkb::Point;
77

@@ -26,6 +26,7 @@ pub struct Place {
2626
pub location: Option<PointC<Point>>,
2727
pub current_gauge_level: GaugeLevel,
2828
pub current_gauge_percent: Option<i64>,
29+
pub timezone: Timezone,
2930
}
3031

3132
pub struct PlaceSearchResult {
@@ -45,6 +46,7 @@ pub struct PlaceInsert {
4546
pub address: Option<String>,
4647
pub maximum_duration: i64,
4748
pub location: Option<PointC<Point>>,
49+
pub timezone: Timezone,
4850
}
4951

5052
#[derive(AsChangeset)]
@@ -58,6 +60,7 @@ pub struct PlaceUpdate {
5860
pub address: Option<String>,
5961
pub maximum_duration: i64,
6062
pub location: Option<PointC<Point>>,
63+
pub timezone: Timezone,
6164
}
6265

6366
#[derive(QueryableByName)]
@@ -93,6 +96,8 @@ pub struct PlaceSearchRow {
9396
pub current_gauge_level: GaugeLevel,
9497
#[sql_type = "Nullable<Int8>"]
9598
pub current_gauge_percent: Option<i64>,
99+
#[sql_type = "Text"]
100+
pub timezone: Timezone,
96101

97102
// organization table
98103
#[sql_type = "Uuid"]
@@ -135,6 +140,7 @@ impl From<PlaceSearchRow> for PlaceSearchResult {
135140
location: place_row.location,
136141
current_gauge_level: place_row.current_gauge_level,
137142
current_gauge_percent: place_row.current_gauge_percent,
143+
timezone: place_row.timezone,
138144
},
139145
organization: Organization {
140146
id: place_row.org_id,

src/model/schema.rs

+66-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,57 @@ table! {
3737
}
3838
}
3939

40+
table! {
41+
use diesel::sql_types::*;
42+
use postgis_diesel::sql_types::*;
43+
use crate::model::types::*;
44+
45+
opening_hour_computed (id) {
46+
id -> Uuid,
47+
place_id -> Uuid,
48+
opening_timestamp -> Timestamptz,
49+
closing_timestamp -> Timestamptz,
50+
evacuation_timestamp -> Timestamptz,
51+
created_at -> Timestamptz,
52+
updated_at -> Timestamptz,
53+
}
54+
}
55+
56+
table! {
57+
use diesel::sql_types::*;
58+
use postgis_diesel::sql_types::*;
59+
use crate::model::types::*;
60+
61+
opening_hour_date (id) {
62+
id -> Uuid,
63+
place_id -> Uuid,
64+
date -> Date,
65+
opening_time -> Nullable<Time>,
66+
closure_time -> Nullable<Time>,
67+
evacuation_time -> Nullable<Time>,
68+
closed -> Bool,
69+
created_at -> Timestamptz,
70+
updated_at -> Timestamptz,
71+
}
72+
}
73+
74+
table! {
75+
use diesel::sql_types::*;
76+
use postgis_diesel::sql_types::*;
77+
use crate::model::types::*;
78+
79+
opening_hour_day (id) {
80+
id -> Uuid,
81+
place_id -> Uuid,
82+
day -> Int2,
83+
opening_time -> Time,
84+
closure_time -> Time,
85+
evacuation_time -> Time,
86+
created_at -> Timestamptz,
87+
updated_at -> Timestamptz,
88+
}
89+
}
90+
4091
table! {
4192
use diesel::sql_types::*;
4293
use postgis_diesel::sql_types::*;
@@ -74,6 +125,7 @@ table! {
74125
location -> Nullable<Geometry>,
75126
current_gauge_level -> Gauge_level,
76127
current_gauge_percent -> Nullable<Int8>,
128+
timezone -> Text,
77129
}
78130
}
79131

@@ -116,8 +168,21 @@ joinable!(checkin -> place (place_id));
116168
joinable!(checkin -> session (session_id));
117169
joinable!(checkin -> user (user_id));
118170
joinable!(infection -> organization (organization_id));
171+
joinable!(opening_hour_computed -> place (place_id));
172+
joinable!(opening_hour_date -> place (place_id));
173+
joinable!(opening_hour_day -> place (place_id));
119174
joinable!(organization -> user (user_id));
120175
joinable!(place -> organization (organization_id));
121176
joinable!(session -> user (user_id));
122177

123-
allow_tables_to_appear_in_same_query!(checkin, infection, organization, place, session, user,);
178+
allow_tables_to_appear_in_same_query!(
179+
checkin,
180+
infection,
181+
opening_hour_computed,
182+
opening_hour_date,
183+
opening_hour_day,
184+
organization,
185+
place,
186+
session,
187+
user,
188+
);

src/model/types.rs

+42
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
use std::fmt;
2+
use std::io::Write;
3+
4+
use chrono_tz::Tz;
5+
use diesel::backend::Backend;
6+
use diesel::deserialize;
7+
use diesel::serialize::{self, Output, ToSql};
8+
use diesel::sql_types::Text;
9+
use diesel::types::FromSql;
210

311
#[derive(Debug, PartialEq, diesel_derive_enum::DbEnum)]
412
#[DieselType = "Gauge_level"]
@@ -28,3 +36,37 @@ pub fn join_gauge_levels(gauge_levels: Vec<GaugeLevel>) -> String {
2836
.collect::<Vec<String>>()
2937
.join(",")
3038
}
39+
40+
#[derive(Debug, PartialEq, FromSqlRow, AsExpression)]
41+
#[sql_type = "Text"]
42+
pub struct Timezone {
43+
pub tz: Tz,
44+
}
45+
46+
impl From<Tz> for Timezone {
47+
fn from(tz: Tz) -> Self {
48+
Timezone { tz }
49+
}
50+
}
51+
52+
impl<DB> ToSql<Text, DB> for Timezone
53+
where
54+
DB: Backend,
55+
String: ToSql<Text, DB>,
56+
{
57+
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
58+
self.tz.to_string().to_sql(out)
59+
}
60+
}
61+
62+
impl<DB> FromSql<Text, DB> for Timezone
63+
where
64+
DB: Backend,
65+
String: FromSql<Text, DB>,
66+
{
67+
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
68+
let tz_str = String::from_sql(bytes)?;
69+
let tz = tz_str.parse::<Tz>()?;
70+
Ok(Timezone { tz })
71+
}
72+
}

src/serve/controller/place.rs

+2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ async fn create(
168168
address: data.address,
169169
maximum_duration: data.maximum_duration,
170170
location: data.location.map(|location| location.into()),
171+
timezone: data.timezone.into(),
171172
},
172173
)?;
173174

@@ -205,6 +206,7 @@ async fn update(
205206
address: data.address,
206207
maximum_duration: data.maximum_duration,
207208
location: data.location.map(|location| location.into()),
209+
timezone: data.timezone.into(),
208210
},
209211
)?;
210212

src/serve/types/place.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::model::organization::Organization as OrganizationModel;
33
use crate::model::place::{Place as PlaceModel, PlaceSearchResult as PlaceSearchResultModel};
44
use crate::model::types::GaugeLevel as GaugeLevelModel;
55
use crate::types::{Location, Pagination, PaginationQuery};
6+
use chrono_tz::Tz;
67
use serde::{Deserialize, Serialize};
78
use uuid::Uuid;
89

@@ -18,6 +19,7 @@ pub struct Place {
1819
pub address: Option<String>,
1920
pub location: Option<Location>,
2021
pub current_gauge_level: GaugeLevel,
22+
pub timezone: Tz,
2123
}
2224

2325
#[derive(Serialize)]
@@ -36,6 +38,7 @@ pub struct OwnedPlace {
3638
pub current_gauge: i64,
3739
pub current_gauge_percent: Option<i64>,
3840
pub current_gauge_level: GaugeLevel,
41+
pub timezone: Tz,
3942
}
4043

4144
#[derive(Deserialize, Serialize)]
@@ -88,6 +91,7 @@ pub struct PlaceForm {
8891
pub location: Option<Location>,
8992
#[validate(range(min = 1, max = 1440))]
9093
pub maximum_duration: i64,
94+
pub timezone: Tz,
9195
}
9296

9397
impl From<(PlaceModel, OrganizationModel)> for Place {
@@ -101,6 +105,7 @@ impl From<(PlaceModel, OrganizationModel)> for Place {
101105
address: place.address,
102106
location: place.location.map(|point| point.into()),
103107
current_gauge_level: place.current_gauge_level.into(),
108+
timezone: place.timezone.tz,
104109
}
105110
}
106111
}
@@ -131,6 +136,7 @@ impl From<(PlaceModel, OrganizationModel)> for OwnedPlace {
131136
current_gauge: place.current_gauge,
132137
current_gauge_percent: place.current_gauge_percent,
133138
current_gauge_level: place.current_gauge_level.into(),
139+
timezone: place.timezone.tz,
134140
}
135141
}
136142
}

0 commit comments

Comments
 (0)