@@ -124,10 +124,38 @@ defmodule EpochtalkServer.Models.Poll do
124124 if poll_answers_len > 0 , do: poll_cs , else: add_error ( poll_cs , :answers , "can't be blank" )
125125 end
126126
127+ @ doc """
128+ Update changeset for `Poll` model
129+ """
130+ @ spec update_changeset (
131+ poll :: t ( ) ,
132+ attrs :: map ( ) | nil
133+ ) :: Ecto.Changeset . t ( )
134+ def update_changeset ( poll , attrs \\ % { } ) do
135+ poll_answers_len = length ( poll . poll_answers || [ ] )
136+
137+ poll
138+ |> cast ( attrs , [
139+ :max_answers ,
140+ :expiration ,
141+ :change_vote ,
142+ :display_mode
143+ ] )
144+ |> validate_required ( [
145+ :max_answers ,
146+ :change_vote ,
147+ :display_mode
148+ ] )
149+ |> validate_naivedatetime ( :expiration , after: :utc_now )
150+ |> validate_number ( :max_answers , greater_than: 0 , less_than_or_equal_to: poll_answers_len )
151+ |> validate_length ( :question , min: 1 , max: 255 )
152+ |> validate_display_mode ( )
153+ end
154+
127155 @ doc """
128156 Creates a new `Poll` in the database
129157 """
130- @ spec create ( post_attrs :: map ( ) ) :: { :ok , post :: t ( ) } | { :error , Ecto.Changeset . t ( ) }
158+ @ spec create ( poll_attrs :: map ( ) ) :: { :ok , poll :: t ( ) } | { :error , Ecto.Changeset . t ( ) }
131159 def create ( poll_attrs ) do
132160 Repo . transaction ( fn ->
133161 post_cs = create_changeset ( % Poll { } , poll_attrs )
@@ -148,6 +176,19 @@ defmodule EpochtalkServer.Models.Poll do
148176 end )
149177 end
150178
179+ @ doc """
180+ Updates an existing `Poll` in the database
181+ """
182+ @ spec update ( poll_attrs :: map ( ) ) ::
183+ { :ok , poll :: t ( ) } | { :error , Ecto.Changeset . t ( ) }
184+ def update ( attrs ) do
185+ Poll
186+ |> Repo . get_by ( thread_id: attrs [ "thread_id" ] )
187+ |> Repo . preload ( [ :poll_answers ] )
188+ |> update_changeset ( attrs )
189+ |> Repo . update ( )
190+ end
191+
151192 @ doc """
152193 Returns boolean indicating if the specified `User` has voted on the specified `Thread`
153194 """
@@ -167,6 +208,96 @@ defmodule EpochtalkServer.Models.Poll do
167208 Repo . exists? ( query )
168209 end
169210
211+ @ doc """
212+ Returns boolean indicating if the specified `User` has not voted on the specified `Thread`
213+ """
214+ @ spec has_not_voted ( thread_id :: integer , user_id :: integer ) :: boolean
215+ def has_not_voted ( thread_id , user_id ) , do: ! has_voted ( thread_id , user_id )
216+
217+ @ doc """
218+ Returns boolean indicating if the specified `Poll` exists given a `Thread` id
219+ """
220+ @ spec exists ( thread_id :: integer ) :: boolean
221+ def exists ( thread_id ) do
222+ query =
223+ from p in Poll ,
224+ where: p . thread_id == ^ thread_id ,
225+ select: p . id
226+
227+ Repo . exists? ( query )
228+ end
229+
230+ @ doc """
231+ Returns integer indicating the max number of answers for the `Poll` given a `Thread` id
232+ """
233+ @ spec max_answers ( thread_id :: integer ) :: non_neg_integer
234+ def max_answers ( thread_id ) do
235+ query =
236+ from p in Poll ,
237+ where: p . thread_id == ^ thread_id ,
238+ select: p . max_answers
239+
240+ Repo . one ( query )
241+ end
242+
243+ @ doc """
244+ Sets boolean indicating if the specified `Poll` is locked given a `Thread` id
245+ """
246+ @ spec set_locked ( thread_id :: integer , locked :: boolean ) :: { non_neg_integer , nil | [ term ( ) ] }
247+ def set_locked ( thread_id , locked ) when is_integer ( thread_id ) and is_boolean ( locked ) do
248+ query = from p in Poll , where: p . thread_id == ^ thread_id
249+ Repo . update_all ( query , set: [ locked: locked ] )
250+ end
251+
252+ @ doc """
253+ Returns boolean indicating if the specified `Poll` is locked given a `Thread` id
254+ """
255+ @ spec locked ( thread_id :: integer ) :: boolean
256+ def locked ( thread_id ) do
257+ query =
258+ from p in Poll ,
259+ where: p . thread_id == ^ thread_id ,
260+ select: p . locked
261+
262+ Repo . one ( query )
263+ end
264+
265+ @ doc """
266+ Returns boolean indicating if the specified `Poll` is unlocked given a `Thread` id
267+ """
268+ @ spec unlocked ( thread_id :: integer ) :: boolean
269+ def unlocked ( thread_id ) , do: ! locked ( thread_id )
270+
271+ @ doc """
272+ Returns boolean indicating if the specified `Poll` allows votes to be changed given a `Thread` id
273+ """
274+ @ spec allow_change_vote ( thread_id :: integer ) :: boolean
275+ def allow_change_vote ( thread_id ) do
276+ query =
277+ from p in Poll ,
278+ where: p . thread_id == ^ thread_id ,
279+ select: p . change_vote
280+
281+ Repo . one ( query )
282+ end
283+
284+ @ doc """
285+ Returns boolean indicating if the specified `Poll` is currently running given a `Thread` id
286+ """
287+ @ spec running ( thread_id :: integer ) :: boolean
288+ def running ( thread_id ) do
289+ query =
290+ from p in Poll ,
291+ where: p . thread_id == ^ thread_id ,
292+ select: p . expiration
293+
294+ expiration = Repo . one ( query )
295+
296+ if expiration == nil ,
297+ do: true ,
298+ else: NaiveDateTime . compare ( expiration , NaiveDateTime . utc_now ( ) ) == :gt
299+ end
300+
170301 @ doc """
171302 Queries `Poll` Data by thread
172303 """
@@ -180,6 +311,8 @@ defmodule EpochtalkServer.Models.Poll do
180311 Repo . one ( query )
181312 end
182313
314+ # var q = 'UPDATE polls SET (max_answers, change_vote, expiration, display_mode) = ($1, $2, $3, $4) WHERE id = $5';
315+
183316 # === Private Helper Functions ===
184317
185318 defp validate_display_mode ( changeset ) do
0 commit comments