Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Add types to Database modules #666

Merged
merged 6 commits into from Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/database/attempt.ex
Expand Up @@ -9,6 +9,9 @@ defmodule BorsNG.Database.Attempt do
use BorsNG.Database.Model
alias BorsNG.Database.AttemptState

@type t :: %__MODULE__{}
@type id :: pos_integer

schema "attempts" do
belongs_to :patch, Patch
field :into_branch, :string
Expand All @@ -20,6 +23,7 @@ defmodule BorsNG.Database.Attempt do
timestamps()
end

@spec new(Patch.t, String.t) :: t
def new(%Patch{} = patch, arguments) do
%Attempt{
patch_id: patch.id,
Expand All @@ -32,6 +36,7 @@ defmodule BorsNG.Database.Attempt do
}
end

@spec all(AttemptState.t | :incomplete) :: Ecto.Queryable.t
def all(:incomplete) do
from b in Attempt,
where: b.state == 0 or b.state == 1
Expand All @@ -42,17 +47,20 @@ defmodule BorsNG.Database.Attempt do
where: b.state == ^state
end

@spec all_for_project(Project.id, AttemptState.t | :incomplete) :: Ecto.Queryable.t
def all_for_project(project_id, state) do
from b in all(state),
join: p in Patch, on: p.id == b.patch_id,
where: p.project_id == ^project_id
end

@spec all_for_patch(Patch.id) :: Ecto.Queryable.t
def all_for_patch(patch_id) do
from b in Attempt,
where: b.patch_id == ^patch_id
end

@spec all_for_patch(Patch.id, AttemptState.t | :complete | :incomplete | nil) :: Ecto.Queryable.t
def all_for_patch(patch_id, nil), do: all_for_patch(patch_id)

def all_for_patch(patch_id, :incomplete) do
Expand All @@ -70,31 +78,37 @@ defmodule BorsNG.Database.Attempt do
where: b.state == ^state
end

@spec get_by_commit(Project.id, String.t, AttemptState.t | :incomplete) :: Ecto.Queryable.t
def get_by_commit(project_id, commit, state) do
from b in all(state),
join: p in Patch, on: p.id == b.patch_id,
where: b.commit == ^commit and p.project_id == ^project_id
end

@spec next_poll_is_past(t, Project.t) :: boolean
def next_poll_is_past(attempt, project) do
now = DateTime.to_unix(DateTime.utc_now(), :second)
next_poll_is_past(attempt, project, now)
end

@spec next_poll_is_past(t, Project.t, pos_integer) :: boolean
def next_poll_is_past(attempt, project, now_utc_sec) do
next = get_next_poll_unix_sec(attempt, project)
next < now_utc_sec
end

@spec timeout_is_past(t) :: boolean
def timeout_is_past(%Attempt{timeout_at: timeout_at}) do
now = DateTime.to_unix(DateTime.utc_now(), :second)
now > timeout_at
end

@spec get_next_poll_unix_sec(t, Project.t) :: non_neg_integer
def get_next_poll_unix_sec(attempt, project) do
attempt.last_polled + project.batch_poll_period_sec
end

@spec changeset(t | Ecto.Changeset.t, map) :: Ecto.Changeset.t
@doc """
Builds a changeset based on the `struct` and `params`.
"""
Expand All @@ -103,6 +117,7 @@ defmodule BorsNG.Database.Attempt do
|> cast(params, [:patch_id, :commit, :state, :last_polled, :timeout_at])
end

@spec changeset_state(t | Ecto.Changeset.t, map) :: Ecto.Changeset.t
@doc """
Builds a changeset based on the `struct` and `params`.
"""
Expand Down
6 changes: 6 additions & 0 deletions lib/database/attempt_state.ex
Expand Up @@ -4,9 +4,13 @@ defmodule BorsNG.Database.AttemptState do
A type to represent the attmept state.
"""

@type t :: :waiting | :running | :ok | :error | :canceled
@typep internal :: 0..4

# Underlying storage is an integer.
def type, do: :integer

@spec cast(t | internal) :: {:ok, t}
# Accept the integer state values for easier translation of existing code.
def cast(state) when is_integer(state) do
case state do
Expand All @@ -32,10 +36,12 @@ defmodule BorsNG.Database.AttemptState do

def cast(_), do: :error

@spec load(internal) :: {:ok, t}
def load(int) when is_integer(int) do
cast(int)
end

@spec dump(t | internal) :: {:ok, internal}
def dump(term) when is_atom(term) do
case term do
:waiting -> {:ok, 0}
Expand Down
6 changes: 6 additions & 0 deletions lib/database/attempt_status.ex
Expand Up @@ -11,6 +11,8 @@ defmodule BorsNG.Database.AttemptStatus do
use BorsNG.Database.Model
alias BorsNG.Database.AttemptStatusState

@type t :: %__MODULE__{}

schema "attempt_statuses" do
belongs_to :attempt, Attempt
field :identifier, :string
Expand All @@ -19,21 +21,25 @@ defmodule BorsNG.Database.AttemptStatus do
timestamps()
end

@spec changeset(t | Ecto.Changeset.t, map) :: Ecto.Changeset.t
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:attempt_id, :identifier, :url, :state])
end

@spec get_for_attempt(Attempt.id, String.t) :: Ecto.Queryable.t
def get_for_attempt(attempt_id, identifier) do
from s in AttemptStatus,
where: s.attempt_id == ^attempt_id,
where: fragment("? LIKE ?", ^identifier, s.identifier)
end

@spec all_for_attempt(Attempt.id) :: Ecto.Queryable.t
def all_for_attempt(attempt_id) do
from s in AttemptStatus, where: s.attempt_id == ^attempt_id
end

@spec all_for_attempt(Attempt.id, AttemptStatusState.t | :incomplete) :: Ecto.Queryable.t
def all_for_attempt(attempt_id, :incomplete) do
from s in AttemptStatus,
where: s.attempt_id == ^attempt_id,
Expand Down
6 changes: 6 additions & 0 deletions lib/database/attempt_status_state.ex
Expand Up @@ -4,9 +4,13 @@ defmodule BorsNG.Database.AttemptStatusState do
A type to represent the status state.
"""

@type t :: :waiting | :running | :ok | :error
@typep internal :: 0..3

# Underlying storage is an integer.
def type, do: :integer

@spec cast(internal | t) :: {:ok, t}
# Accept the integer state values for easier translation of existing code.
def cast(state) when is_integer(state) do
case state do
Expand All @@ -30,10 +34,12 @@ defmodule BorsNG.Database.AttemptStatusState do

def cast(_), do: :error

@spec load(internal) :: {:ok, t}
def load(int) when is_integer(int) do
cast(int)
end

@spec dump(t | internal) :: {:ok, internal}
def dump(term) when is_atom(term) do
case term do
:waiting -> {:ok, 0}
Expand Down
23 changes: 18 additions & 5 deletions lib/database/batch.ex
Expand Up @@ -6,6 +6,8 @@ defmodule BorsNG.Database.Batch do
"""

@type t :: %__MODULE__{}
@type id :: pos_integer()
@type state :: :waiting | :running | :ok | :error | :conflict | :canceled

use BorsNG.Database.Model
alias BorsNG.Database.BatchState
Expand All @@ -22,6 +24,7 @@ defmodule BorsNG.Database.Batch do
timestamps()
end

@spec new(Project.id, String.t, non_neg_integer) :: t
def new(project_id, into_branch, priority \\ 0) do
%Batch{
into_branch: into_branch,
Expand All @@ -33,19 +36,22 @@ defmodule BorsNG.Database.Batch do
}
end

@spec is_empty(id, module) :: boolean
def is_empty(batch_id, repo) do
links = LinkPatchBatch
LinkPatchBatch
|> where([l], l.batch_id == ^batch_id)
|> repo.all()
links == []
|> Enum.empty?
end

@spec all_for_project(Project.id) :: Ecto.Queryable.t
def all_for_project(project_id) do
from b in Batch,
where: b.project_id == ^project_id,
order_by: [desc: b.state]
end

@spec all_for_project(Project.id, state | :complete | :incomplete | nil) :: Ecto.Queryable.t
def all_for_project(project_id, nil), do: all_for_project(project_id)

def all_for_project(project_id, :incomplete) do
Expand All @@ -65,18 +71,21 @@ defmodule BorsNG.Database.Batch do
where: b.state == ^state
end

@spec all_for_patch(Patch.id, :complete | :incomplete | nil) :: Ecto.Queryable.t
def all_for_patch(patch_id, state \\ nil) do
from b in all_assoc(state),
join: l in LinkPatchBatch, on: l.batch_id == b.id,
where: l.patch_id == ^patch_id
end

@spec all_assoc() :: Ecto.Queryable.t
def all_assoc do
from b in Batch,
join: p in assoc(b, :project),
preload: [project: p]
end

@spec all_assoc(:complete | :incomplete | nil) :: Ecto.Queryable.t
def all_assoc(nil), do: all_assoc()

def all_assoc(:incomplete) do
Expand All @@ -91,26 +100,31 @@ defmodule BorsNG.Database.Batch do
or b.state == ^(:canceled)
end

@spec get_assoc_by_commit(Project.id, String.t, :complete | :incomplete | nil) :: Ecto.Queryable.t
def get_assoc_by_commit(project_id, commit, state \\ nil) do
from b in all_assoc(state),
where: b.commit == ^commit and b.project_id == ^project_id
end

@spec next_poll_is_past(t) :: boolean
def next_poll_is_past(batch) do
now = DateTime.to_unix(DateTime.utc_now(), :second)
next_poll_is_past(batch, now)
end

@spec next_poll_is_past(t, pos_integer()) :: boolean
def next_poll_is_past(batch, now_utc_sec) do
next = get_next_poll_unix_sec(batch)
next < now_utc_sec
end

@spec timeout_is_past(t) :: boolean
def timeout_is_past(%Batch{timeout_at: timeout_at}) do
now = DateTime.to_unix(DateTime.utc_now(), :second)
now > timeout_at
end

@spec get_next_poll_unix_sec(t) :: integer
def get_next_poll_unix_sec(batch) do
period = if batch.state == :waiting do
batch.project.batch_delay_sec
Expand All @@ -120,9 +134,7 @@ defmodule BorsNG.Database.Batch do
batch.last_polled + period
end

@doc """
Builds a changeset based on the `struct` and `params`.
"""
@spec changeset(t | Ecto.Changeset.t, map) :: Ecto.Changeset.t
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [
Expand All @@ -135,6 +147,7 @@ defmodule BorsNG.Database.Batch do
])
end

@spec changeset_raise_priority(t | Ecto.Changeset.t, map) :: Ecto.Changeset.t
def changeset_raise_priority(struct, params \\ %{}) do
struct
|> cast(params, [
Expand Down
10 changes: 8 additions & 2 deletions lib/database/crash.ex
@@ -1,11 +1,14 @@
defmodule BorsNG.Database.Crash do
@moduledoc """
Crash dumps.
A Crash Dump from a Bors Agent.

Allows an admin to see that a crash happened for a certain build thus
allowing it to be reacted upon.
"""

use BorsNG.Database.Model

@type t :: %Crash{}
@type t :: %__MODULE__{}

schema "crashes" do
belongs_to :project, Project
Expand All @@ -14,6 +17,7 @@ defmodule BorsNG.Database.Crash do
timestamps()
end

@spec changeset(t | Ecto.Changeset.t, map) :: Ecto.Changeset.t
@doc """
Builds a changeset based on the `struct` and `params`.
"""
Expand All @@ -22,11 +26,13 @@ defmodule BorsNG.Database.Crash do
|> cast(params, [:crash, :component])
end

@spec all_for_project(Project.id) :: Ecto.Queryable.t
def all_for_project(project_id) do
from c in Crash,
where: c.project_id == ^project_id
end

@spec days(integer) :: Ecto.Queryable.t
def days(d) do
ds = d * 60 * 60 * 24
start = NaiveDateTime.utc_now() |> NaiveDateTime.add(-ds, :second)
Expand Down
2 changes: 2 additions & 0 deletions lib/database/installation.ex
Expand Up @@ -7,6 +7,8 @@ defmodule BorsNG.Database.Installation do

use BorsNG.Database.Model

@type xref :: integer

schema "installations" do
field :installation_xref, :integer

Expand Down