-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1964 from get10101/feat/in-app-polls
feat(mobile): show in app survey
- Loading branch information
Showing
24 changed files
with
940 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
coordinator/migrations/2024-02-02-075927_add_polls_table/down.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
-- This file should undo anything in `up.sql` | ||
drop table answers; | ||
drop table choices; | ||
drop table polls; | ||
DROP TYPE IF EXISTS "Poll_Type_Type"; |
37 changes: 37 additions & 0 deletions
37
coordinator/migrations/2024-02-02-075927_add_polls_table/up.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
-- Your SQL goes here | ||
|
||
CREATE TYPE "Poll_Type_Type" AS ENUM ('SingleChoice'); | ||
|
||
CREATE TABLE polls | ||
( | ||
id SERIAL PRIMARY KEY NOT NULL, | ||
poll_type "Poll_Type_Type" NOT NULL, | ||
question TEXT NOT NULL, | ||
active BOOLEAN NOT NULL, | ||
creation_timestamp timestamp WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
CREATE TABLE choices | ||
( | ||
id SERIAL PRIMARY KEY NOT NULL, | ||
poll_id SERIAL REFERENCES polls (id), | ||
value TEXT NOT NULL | ||
); | ||
|
||
CREATE TABLE answers | ||
( | ||
id SERIAL PRIMARY KEY NOT NULL, | ||
choice_id SERIAL REFERENCES choices (id), | ||
trader_pubkey TEXT NOT NULL REFERENCES users (pubkey), | ||
value TEXT NOT NULL, | ||
creation_timestamp timestamp WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
INSERT INTO polls (poll_type, question, active) | ||
VALUES ('SingleChoice', 'Where did you hear about us?', true); | ||
|
||
INSERT INTO choices (poll_id, value) | ||
VALUES (1, 'Social media (X.com, Nostr)'), | ||
(1, 'Search engine (Google, Duckduckgo)'), | ||
(1, 'Friends'), | ||
(1, 'other'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
use crate::schema::answers; | ||
use crate::schema::choices; | ||
use crate::schema::polls; | ||
use crate::schema::sql_types::PollTypeType; | ||
use anyhow::bail; | ||
use anyhow::Result; | ||
use diesel::query_builder::QueryId; | ||
use diesel::AsExpression; | ||
use diesel::FromSqlRow; | ||
use diesel::Identifiable; | ||
use diesel::Insertable; | ||
use diesel::PgConnection; | ||
use diesel::QueryDsl; | ||
use diesel::QueryResult; | ||
use diesel::Queryable; | ||
use diesel::RunQueryDsl; | ||
use diesel::Selectable; | ||
use diesel::SelectableHelper; | ||
use std::any::TypeId; | ||
use std::collections::HashMap; | ||
use time::OffsetDateTime; | ||
|
||
#[derive(Debug, Clone, Copy, PartialEq, FromSqlRow, AsExpression, Eq, Hash)] | ||
#[diesel(sql_type = PollTypeType)] | ||
pub enum PollType { | ||
SingleChoice, | ||
} | ||
|
||
impl QueryId for PollTypeType { | ||
type QueryId = PollTypeType; | ||
const HAS_STATIC_QUERY_ID: bool = false; | ||
|
||
fn query_id() -> Option<TypeId> { | ||
None | ||
} | ||
} | ||
|
||
#[derive(Insertable, Queryable, Identifiable, Selectable, Debug, Clone, Eq, PartialEq, Hash)] | ||
#[diesel(table_name = polls)] | ||
#[diesel(primary_key(id))] | ||
pub struct Poll { | ||
pub id: i32, | ||
pub poll_type: PollType, | ||
pub question: String, | ||
pub active: bool, | ||
pub creation_timestamp: OffsetDateTime, | ||
} | ||
|
||
#[derive(Insertable, Queryable, Identifiable, Selectable, Debug, Clone, Eq, PartialEq)] | ||
#[diesel(belongs_to(Poll))] | ||
#[diesel(table_name = choices)] | ||
#[diesel(primary_key(id))] | ||
pub struct Choice { | ||
pub id: i32, | ||
pub poll_id: i32, | ||
pub value: String, | ||
} | ||
#[derive(Insertable, Queryable, Identifiable, Debug, Clone)] | ||
#[diesel(primary_key(id))] | ||
pub struct Answer { | ||
pub id: Option<i32>, | ||
pub choice_id: i32, | ||
pub trader_pubkey: String, | ||
pub value: String, | ||
pub creation_timestamp: OffsetDateTime, | ||
} | ||
|
||
pub fn active(conn: &mut PgConnection) -> QueryResult<Vec<commons::Poll>> { | ||
let _polls: Vec<Poll> = polls::table.load(conn)?; | ||
let _choices: Vec<Choice> = choices::table.load(conn)?; | ||
|
||
let results = polls::table | ||
.left_join(choices::table) | ||
.select(<(Poll, Option<Choice>)>::as_select()) | ||
.load::<(Poll, Option<Choice>)>(conn)?; | ||
|
||
let mut polls_with_choices = HashMap::new(); | ||
for (poll, choice) in results { | ||
let entry = polls_with_choices.entry(poll).or_insert_with(Vec::new); | ||
if let Some(choice) = choice { | ||
entry.push(choice); | ||
} | ||
} | ||
|
||
let polls = polls_with_choices | ||
.into_iter() | ||
.map(|(poll, choice_vec)| commons::Poll { | ||
id: poll.id, | ||
poll_type: poll.poll_type.into(), | ||
question: poll.question, | ||
choices: choice_vec | ||
.into_iter() | ||
.map(|choice| commons::Choice { | ||
id: choice.id, | ||
value: choice.value, | ||
}) | ||
.collect(), | ||
}) | ||
.collect(); | ||
Ok(polls) | ||
} | ||
|
||
impl From<PollType> for commons::PollType { | ||
fn from(value: PollType) -> Self { | ||
match value { | ||
PollType::SingleChoice => commons::PollType::SingleChoice, | ||
} | ||
} | ||
} | ||
|
||
pub fn add_answer(conn: &mut PgConnection, answers: commons::PollAnswers) -> Result<()> { | ||
let mut affected_rows = 0; | ||
for answer in answers.answers { | ||
affected_rows += diesel::insert_into(answers::table) | ||
.values(Answer { | ||
id: None, | ||
choice_id: answer.choice_id, | ||
trader_pubkey: answers.trader_pk.to_string(), | ||
value: answer.value, | ||
creation_timestamp: OffsetDateTime::now_utc(), | ||
}) | ||
.execute(conn)?; | ||
} | ||
|
||
if affected_rows == 0 { | ||
bail!( | ||
"Could not insert answers by user {}.", | ||
answers.trader_pk.to_string() | ||
); | ||
} else { | ||
tracing::trace!(%affected_rows, trade_pk = answers.trader_pk.to_string(), | ||
"Added new answers to a poll."); | ||
} | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.