From 223af265806cf90bfcbff92eb7cea6a81bf9c42c Mon Sep 17 00:00:00 2001 From: Connor Rigby Date: Mon, 18 Sep 2017 17:23:10 -0700 Subject: [PATCH] begin migration to sqlite3 --- .gitignore | 3 + config/config.exs | 7 +- config/target/dev.exs | 11 +- lib/farmbot.ex | 1 + lib/farmbot/bootstrap/configurator.ex | 4 +- lib/farmbot/database/record_storage.ex | 226 ------------------ lib/farmbot/database/selectors.ex | 60 ----- lib/farmbot/database/selectors/error.ex | 8 - lib/farmbot/database/syncable.ex | 159 ------------ lib/farmbot/database/syncable/device.ex | 16 -- lib/farmbot/database/syncable/farm_event.ex | 16 -- lib/farmbot/database/syncable/peripheral.ex | 32 --- lib/farmbot/database/syncable/point.ex | 31 --- lib/farmbot/database/syncable/regimen.ex | 12 - lib/farmbot/database/syncable/sequence.ex | 15 -- lib/farmbot/database/syncable/tool.ex | 12 - lib/farmbot/database/syncable_error.ex | 4 - lib/farmbot/repo.ex | 5 + lib/farmbot/system.ex | 3 +- mix.exs | 13 +- mix.lock.host | 9 + mix.lock.qemu_arm | 51 ++++ mix.lock.rpi0 | 14 ++ .../{host => }/farmbot/host/system_tasks.ex | 0 nerves/farmbot/target/ecto.ex | 35 +++ nerves/farmbot/target/network.ex | 9 + nerves/farmbot/target/system_tasks.ex | 15 ++ .../farmbot/host/firmware_handler_stub.ex | 9 - .../migrations/20170915182355_add_thing.exs | 7 + test/farmbot/database/record_storage_test.exs | 71 ------ test/farmbot/database/selectors_test.exs | 140 ----------- test/farmbot/database/syncable/point_test.exs | 58 ----- 32 files changed, 174 insertions(+), 882 deletions(-) delete mode 100644 lib/farmbot/database/record_storage.ex delete mode 100644 lib/farmbot/database/selectors.ex delete mode 100644 lib/farmbot/database/selectors/error.ex delete mode 100644 lib/farmbot/database/syncable.ex delete mode 100644 lib/farmbot/database/syncable/device.ex delete mode 100644 lib/farmbot/database/syncable/farm_event.ex delete mode 100644 lib/farmbot/database/syncable/peripheral.ex delete mode 100644 lib/farmbot/database/syncable/point.ex delete mode 100644 lib/farmbot/database/syncable/regimen.ex delete mode 100644 lib/farmbot/database/syncable/sequence.ex delete mode 100644 lib/farmbot/database/syncable/tool.ex delete mode 100644 lib/farmbot/database/syncable_error.ex create mode 100644 lib/farmbot/repo.ex create mode 100644 mix.lock.qemu_arm rename nerves/{host => }/farmbot/host/system_tasks.ex (100%) create mode 100644 nerves/farmbot/target/ecto.ex create mode 100644 nerves/farmbot/target/network.ex create mode 100644 nerves/farmbot/target/system_tasks.ex delete mode 100644 nerves/host/farmbot/host/firmware_handler_stub.ex create mode 100644 priv/repo/migrations/20170915182355_add_thing.exs delete mode 100644 test/farmbot/database/record_storage_test.exs delete mode 100644 test/farmbot/database/selectors_test.exs delete mode 100644 test/farmbot/database/syncable/point_test.exs diff --git a/.gitignore b/.gitignore index 6d3e8234..67cbfc06 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,6 @@ auth_secret_test.exs flash_fw.sh tmp +*.sqlite3 +*.img +run-qemu.sh diff --git a/config/config.exs b/config/config.exs index 88bf7a46..c7418068 100644 --- a/config/config.exs +++ b/config/config.exs @@ -33,13 +33,18 @@ config :farmbot, :init, [] # See Farmbot.BotState.Transport for details. config :farmbot, :transport, [] - # Configure Farmbot Behaviours. config :farmbot, :behaviour, [ authorization: Farmbot.Bootstrap.Authorization, firmware_handler: Farmbot.Firmware.StubHandler, ] +config :farmbot, Farmbot.Repo, + adapter: Sqlite.Ecto2, + database: "#{env}.sqlite3" + +config :farmbot, ecto_repos: [Farmbot.Repo] + case target do "host" -> import_config("host/#{env}.exs") _ -> diff --git a/config/target/dev.exs b/config/target/dev.exs index ec462d74..84ff41f1 100644 --- a/config/target/dev.exs +++ b/config/target/dev.exs @@ -1,16 +1,23 @@ use Mix.Config -config :farmbot, data_path: "/state" +config :farmbot, Farmbot.Repo, + adapter: Sqlite.Ecto2, + database: "/root/#{Mix.env()}.sqlite3" + +config :farmbot, data_path: "/root" # Configure your our system. # Default implementation needs no special stuff. config :farmbot, :init, [ + # Run migrations and whatnot. + Farmbot.Target.Ecto, + # initialize the configuration. # This bring up a captive portal if needed. Farmbot.Bootstrap.Configurator, # Start up Network - Farmbot.System.Network + Farmbot.Target.Network ] # Transports. diff --git a/lib/farmbot.ex b/lib/farmbot.ex index a9927e24..aef7a6a8 100644 --- a/lib/farmbot.ex +++ b/lib/farmbot.ex @@ -50,6 +50,7 @@ defmodule Farmbot do def init(args) do children = [ + supervisor(Farmbot.Repo, []), supervisor(Farmbot.System.Supervisor, [args, [name: Farmbot.System.Supervisor ]]), supervisor(Farmbot.Bootstrap.Supervisor, [args, [name: Farmbot.Bootstrap.Supervisor ]]), # supervisor(Farmbot.FarmEvent.Supervisor, [args, [name: Farmbot.FarmEvent.Supervisor ]]), diff --git a/lib/farmbot/bootstrap/configurator.ex b/lib/farmbot/bootstrap/configurator.ex index 61241178..b0ab1040 100644 --- a/lib/farmbot/bootstrap/configurator.ex +++ b/lib/farmbot/bootstrap/configurator.ex @@ -21,7 +21,7 @@ defmodule Farmbot.Bootstrap.Configurator do """ def start_link(_, opts) do Logger.info "Configuring Farmbot." - sup = Supervisor.start_link(__MODULE__, [self()], opts) + supervisor = Supervisor.start_link(__MODULE__, [self()], opts) # case supervisor do # {:ok, pid} -> # receive do @@ -51,7 +51,7 @@ defmodule Farmbot.Bootstrap.Configurator do end end - defp stop(supervisor, status) do + def stop(supervisor, status) do Supervisor.stop(supervisor, :normal) status end diff --git a/lib/farmbot/database/record_storage.ex b/lib/farmbot/database/record_storage.ex deleted file mode 100644 index c63c0899..00000000 --- a/lib/farmbot/database/record_storage.ex +++ /dev/null @@ -1,226 +0,0 @@ -defmodule Farmbot.Database.RecordStorage do - @moduledoc """ - This module is only responsible for storage of information. - """ - - alias Farmbot.Database.Syncable - use Farmbot.DebugLog, color: :LIGHT_PURPLE - require Logger - use GenServer - - @typedoc """ - The module name of the object you want to access. - """ - @type syncable :: atom - - @typedoc """ - The incremental id givin to resources. - """ - @type local_id :: integer - - @typedoc """ - The (API) Database id given to resources. - """ - @type db_id :: integer - - @typedoc """ - Identifies a resource by its `syncable` (kind), `local_id`, and `db_id` - """ - @type ref_id :: {syncable, local_id, db_id} - - @typedoc """ - Held in `refs`. - """ - @type resource_map :: Syncable.t - - @typedoc false - @type record_storage :: GenServer.server - - @typedoc false - @type syncable_object :: map - - @doc """ - Commits a list of records to the db. - """ - @spec commit_records([map] | map, record_storage) :: :ok | {:error, term} - def commit_records(list_or_single_record, record_storage) - - def commit_records([record | rest], record_storage) do - :ok = commit_records(record, record_storage) - commit_records(rest, record_storage) - end - - def commit_records([], _record_storage) do - :ok - end - - def commit_records(record, record_storage) when is_map(record) do - :ok = GenServer.call(record_storage, {:update_or_create, record}) - end - - @doc "Clear all records." - def flush(record_storage), do: GenServer.call(record_storage, :flush) - - @doc "Flush a syncable." - def flush(record_storage, syncable), do: GenServer.call(record_storage, {:flush, syncable}) - - @doc """ - Get a resource by its kind and id. - """ - @spec get_by_id(record_storage, syncable, db_id) :: resource_map | nil - def get_by_id(record_storage, kind, id), - do: GenServer.call(record_storage, {:get_by, kind, id}) - - @doc """ - Get all resources of this kind. - """ - @spec get_all(record_storage, syncable) :: [resource_map] - def get_all(record_storage, kind), - do: GenServer.call(record_storage, {:get_all, kind}) - - ## GenServer - - defmodule State do - @moduledoc false - - defimpl Inspect, for: __MODULE__ do - def inspect(thing, _) do - "#DatabaseState<#{inspect thing.all}>" - end - end - - defstruct [ - :by_kind_and_id, - :awaiting, - :by_kind, - :refs, - :all - ] - end - - @typep state :: State.t - - @doc """ - Start the Database - """ - def start_link(opts), - do: GenServer.start_link(__MODULE__, [], opts) - - def init([]) do - initial_by_kind_and_id = %{} - initial_by_kind = %{} - initial_refs = %{} - initial_all = [] - - state = %State{ - by_kind_and_id: initial_by_kind_and_id, - by_kind: initial_by_kind, - refs: initial_refs, - all: initial_all, - } - {:ok, state} - end - - def handle_call(:flush, _, _old_state) do - {:ok, new_state} = init([]) - {:reply, :ok, new_state} - end - - def handle_call({:flush, syncable}, _, old_state) do - {:reply, :ok, remove_all_syncable(old_state, syncable)} - end - - def handle_call({:get_by, kind, id}, _, state) do - r = get_by_kind_and_id(state, kind, id) - {:reply, r, state} - end - - def handle_call({:get_all, syncable}, _, state) do - {:reply, get_all_by_kind(state, syncable), state} - end - - def handle_call({:update_or_create, record}, _, state) do - {:reply, :ok, reindex(state, record)} - end - - @spec remove_all_syncable(state, syncable) :: state - defp remove_all_syncable(state, syncable) do - new_all = Enum.reject(state.all, fn({s, _, _}) -> s == syncable end) - - new_by_kind_and_id = state.by_kind_and_id - |> Enum.reject(fn({{s, _}, _}) -> s == syncable end) - |> Map.new - - new_refs = state.refs - |> Enum.reject(fn({{s, _, _}, _}) -> s == syncable end) - |> Map.new() - - %{ - state | - by_kind_and_id: new_by_kind_and_id, - by_kind: Map.put(state.by_kind, syncable, []), - refs: new_refs, - all: new_all - } - end - - # returns all the references of syncable - @spec get_all_by_kind(state, syncable) :: [resource_map] - defp get_all_by_kind(state, syncable) do - all = state.by_kind[syncable] || [] - Enum.map(all, fn(ref) -> state.refs[ref] end) - end - - @spec get_by_kind_and_id(state, syncable, integer) :: resource_map | nil - defp get_by_kind_and_id(state, kind, id) do - case state.by_kind_and_id[{kind, id}] do - {_kind, _local_id, db_id} = ref when id == db_id -> - state.refs[ref] - _ -> nil - end - end - - @spec new_ref_id(map) :: ref_id - defp new_ref_id(%{__struct__: syncable, id: id}) do - # TODO(Connor) One day, we will need a local id. - {syncable, -1, id} - end - - defp reindex(state, record) do - # get some info - kind = Map.fetch!(record, :__struct__) - id = Map.fetch!(record, :id) || raise "No id for record: #{inspect record}" - - # Do we have it already? - maybe_old = get_by_kind_and_id(state, kind, id) - if maybe_old do - debug_log("updating old record") - already_exists = maybe_old - # if it existed, update it. - # set the ref from the old one. - new = %{already_exists | body: record} - new_refs = %{state.refs | new.ref_id => new} - %{state | refs: new_refs} - else - debug_log("inputting new record") - # if not, just add it. - rid = new_ref_id(record) - - new_syncable = %Syncable{ - body: record, - ref_id: rid - } - - all = [rid | state.all] - by_kind = Map.put(state.by_kind, kind, [rid | state.by_kind[kind] || []]) - new_refs = Map.put(state.refs, rid, new_syncable) - by_kind_and_id = Map.put(state.by_kind_and_id, {kind, id}, rid) - - %{ state | - refs: new_refs, - all: all, - by_kind: by_kind, - by_kind_and_id: by_kind_and_id } - end - end -end diff --git a/lib/farmbot/database/selectors.ex b/lib/farmbot/database/selectors.ex deleted file mode 100644 index 168dc600..00000000 --- a/lib/farmbot/database/selectors.ex +++ /dev/null @@ -1,60 +0,0 @@ -defmodule Farmbot.Database.Selectors do - @moduledoc """ - Instead of litering the codebase with map/reduce/filter functions, - consider putting database query functions into this module. - """ - alias Farmbot.{Database, DebugLog} - alias Database.RecordStorage - alias Database.Syncable - alias __MODULE__.Error, as: SelectorError - alias Syncable.{Point, Device} - use DebugLog - - @doc """ - Find a Point with a particular type. - * "Plant" - * "ToolSlot" - * "GenericPointer" - """ - @spec find_point(GenServer.server(), binary, integer) :: Syncable.t | no_return - def find_point(record_storage, "Plant" = pt, id), - do: do_find_point(record_storage, pt, id) - - def find_point(record_storage, "ToolSlot" = pt, id), - do: do_find_point(record_storage, pt, id) - - def find_point(record_storage, "GenericPointer" = pt, id), - do: do_find_point(record_storage, pt, id) - - @spec do_find_point(GenServer.server(), binary, integer) :: Point.t - defp do_find_point(record_storage, point_t, point_id) do - result = RecordStorage.get_by_id(record_storage, Point, point_id) || raise SelectorError, [ - syncable: Point, syncable_id: point_id, message: "does not exist." - ] - - case result.body.pointer_type do - type when type == point_t -> result - _ -> raise SelectorError, [ - syncable: Point, syncable_id: point_id, message: "does not match type: #{point_t}" - ] - end - end - - @doc """ - Get this device. Raises. - """ - @spec get_device(GenServer.server()) :: Syncable.body | no_return - def get_device(record_storage) do - case RecordStorage.get_all(record_storage, Device) do - [device] -> device.body - [_device | _] -> - raise SelectorError, [ - syncable: Device, syncable_id: nil, message: "Too many devices." - ] - [] -> - raise SelectorError, [ - syncable: Device, syncable_id: nil, message: "No device." - ] - end - end -end diff --git a/lib/farmbot/database/selectors/error.ex b/lib/farmbot/database/selectors/error.ex deleted file mode 100644 index 1cb27262..00000000 --- a/lib/farmbot/database/selectors/error.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule Farmbot.Database.Selectors.Error do - @moduledoc "Error message for selectors." - defexception [ - :syncable_id, - :syncable, - :message, - ] -end diff --git a/lib/farmbot/database/syncable.ex b/lib/farmbot/database/syncable.ex deleted file mode 100644 index 9ceea542..00000000 --- a/lib/farmbot/database/syncable.ex +++ /dev/null @@ -1,159 +0,0 @@ -defmodule Farmbot.Database.Syncable do - @moduledoc """ - Glue between HTTP and Database. - """ - - @enforce_keys [:ref_id, :body] - defstruct [:ref_id, :body] - - @typedoc """ - Module structs. - """ - @type body :: map - - @type ref_id :: Farmbot.Database.ref_id - @type t :: %__MODULE__{ref_id: ref_id, body: body} - import Farmbot.HTTP.Helpers - alias __MODULE__.Error - - @doc """ - Pipe a HTTP request thru this. Trust me :tm: - """ - def parse_resp({:error, message}, _module), do: {:error, message} - def parse_resp({:ok, %{status_code: code, body: resp_body}}, module) - when is_2xx(code) do - parsed = resp_body |> String.trim() |> Poison.decode |> handle_json_output(resp_body) - cond do - is_list(parsed) -> Enum.map(parsed, fn(i) -> module.to_struct(i) end) - is_map(parsed) -> module.to_struct(parsed) - true -> raise Error, - message: "Don't know how to handle: #{inspect parsed}" - end - end - - def parse_resp({:ok, bad_response}, _module), do: {:error, bad_response} - - defp handle_json_output(res, resp_body) do - case res do - {:ok, body} -> body - {:error, :invalid, _pos} -> - spawn(fn() -> - IO.puts "INVALID JSON \r\n\r\n #{inspect resp_body} \r\n\r\n" - end) - - raise Error, message: "Bad json" - end - end - - @doc ~s""" - Builds common functionality for all Syncable Resources. `args` takes two keywords. - * `model` - a definition of the struct. - * `endpoint` - a tuple shaped like: {"/single_url", "/plural_url"} - - Heres what it _WILL_ provide: - * For HTTP access we have: - * `sindular_url/0` - The single url endpoint - * `plural_url/0` - The plural url endpoint - * `fetch/1` and `fetch/2` - * `fetch/1` - takes a callback of either an anon function, or a tuple - shaped: {module, function, args} where the first arg is the result - described below. - * `fetch/2` - takes an id and a callback described above. - - * For Data manipulation - * `to_struct/1` - takes a stringed map and _safely_ turns it into a stuct. - - Heres what it _WILL NOT_ provide: - * local database access - * extensibility - """ - defmacro __using__(args) do - model = Keyword.get(args, :model) || raise "You need a model!" - {singular, plural} = Keyword.get(args, :endpoint) || raise Error, - message: "Syncable requires a endpoint: {singular_url, plural_url}" - quote do - alias Farmbot.HTTP - import Farmbot.Database.Syncable, only: [parse_resp: 2] - defstruct unquote(model) ++ [:id] - - defimpl Inspect, for: __MODULE__ do - def inspect(syncable, _) do - "#Syncable<#{List.last(Module.split(__MODULE__))} #{syncable.id}>" - end - end - - @doc "Find an item by id from the database." - def get_by_id(record_storage, id) do - Farmbot.Database.RecordStorage.get_by_id(record_storage, __MODULE__, id) - end - - @doc "Get all items." - def get_all(record_storage) do - Farmbot.Database.RecordStorage.get_all(record_storage, __MODULE__) - end - - @doc "Flush all items." - def flush(record_storage) do - Farmbot.Database.RecordStorage.flush(record_storage, __MODULE__) - end - - @doc """ - The Singular api endpoing url. - """ - def singular_url, do: unquote(singular) - - @doc """ - The plural api endpoint. - """ - def plural_url, do: unquote(plural) - - @doc """ - Fetches all `#{__MODULE__}` objects from the API. - """ - def fetch(http, then) do - url = "/api" <> plural_url() - result = http |> HTTP.get(url) |> parse_resp(__MODULE__) - - if function_exported?(__MODULE__, :on_fetch, 2) do - apply __MODULE__, :on_fetch, [result] - end - - case then do - {module, fun, args} -> apply(module, fun, [result | args]) - anon when is_function(anon) -> anon.(result) - end - end - - @doc """ - Fetches a specific `#{__MODULE__}` from the API, by it's id. - """ - def fetch(http, id, then) do - url = "/api" <> unquote(singular) <> "/#{id}" - result = http |> HTTP.get(url) |> parse_resp(__MODULE__) - - if function_exported?(__MODULE__, :on_fetch, 2) do - apply __MODULE__, :on_fetch, [result] - end - - case then do - {module, fun, args} -> apply(module, fun, [result | args]) - anon when is_function(anon) -> anon.(result) - end - end - - @doc """ - Changes a string map, to a struct - """ - def to_struct(item) do - module = __MODULE__ - sym_keys = Map.keys(%__MODULE__{}) - str_keys = Enum.map(sym_keys, fn(key) -> Atom.to_string(key) end) - - next = Map.take(item, str_keys) - new = Map.new(next, fn({key, val}) -> {String.to_atom(key), val} end) - struct(module, new) - end - - end - end -end diff --git a/lib/farmbot/database/syncable/device.ex b/lib/farmbot/database/syncable/device.ex deleted file mode 100644 index 9d2d8069..00000000 --- a/lib/farmbot/database/syncable/device.ex +++ /dev/null @@ -1,16 +0,0 @@ -defmodule Farmbot.Database.Syncable.Device do - @moduledoc """ - A Device from the Farmbot API. - """ - - alias Farmbot.Database - alias Database.Syncable - use Syncable, model: [ - :name, - :timezone - ], endpoint: {"/device", "/device"} - - # def on_fetch(%Context{} = context, %__MODULE__{timezone: tz}) do - # true = Farmbot.BotState.update_config(context, "timezone", tz) - # end -end diff --git a/lib/farmbot/database/syncable/farm_event.ex b/lib/farmbot/database/syncable/farm_event.ex deleted file mode 100644 index 84165a80..00000000 --- a/lib/farmbot/database/syncable/farm_event.ex +++ /dev/null @@ -1,16 +0,0 @@ -defmodule Farmbot.Database.Syncable.FarmEvent do - @moduledoc """ - A FarmEvent from the Farmbot API. - """ - - alias Farmbot.Database.Syncable - use Syncable, model: [ - :start_time, - :end_time, - :repeat, - :time_unit, - :executable_id, - :executable_type, - :calendar - ], endpoint: {"/farm_events", "/farm_events"} -end diff --git a/lib/farmbot/database/syncable/peripheral.ex b/lib/farmbot/database/syncable/peripheral.ex deleted file mode 100644 index 19176963..00000000 --- a/lib/farmbot/database/syncable/peripheral.ex +++ /dev/null @@ -1,32 +0,0 @@ -defmodule Farmbot.Database.Syncable.Peripheral do - @moduledoc """ - A Peripheral from the Farmbot API. - """ - - alias Farmbot.Database - alias Database.Syncable - use Syncable, model: [ - :pin, - :mode, - :label - ], endpoint: {"/peripherals", "/peripherals"} - - # def on_fetch(context, object_or_list) - # - # def on_fetch(%Context{} = _, []), do: :ok - # - # def on_fetch(%Context{} = context, [%__MODULE__{} = first | rest]) do - # on_fetch(context, first) - # on_fetch(context, rest) - # end - # - # def on_fetch(%Context{} = context, %__MODULE__{pin: pin, mode: mode, label: label}) do - # :ok = Farmbot.BotState.set_pin_mode(context, pin, mode) - # ast = %Ast{ - # kind: "read_pin", - # args: %{pin_number: pin, pin_mode: mode, label: label}, - # body: [] - # } - # Command.do_command(ast, context) - # end -end diff --git a/lib/farmbot/database/syncable/point.ex b/lib/farmbot/database/syncable/point.ex deleted file mode 100644 index a2a7bebb..00000000 --- a/lib/farmbot/database/syncable/point.ex +++ /dev/null @@ -1,31 +0,0 @@ -defmodule Farmbot.Database.Syncable.Point do - @moduledoc """ - A Point from the Farmbot API. - """ - - alias Farmbot.Database - alias Database.{Syncable, Selectors} - alias Selectors.Error, as: SelectorError - use Syncable, model: [ - :pointer_type, - :created_at, - :tool_id, - :radius, - :name, - :meta, - :x, - :y, - :z, - ], endpoint: {"/points", "/points"} - - @doc """ - Turn a tool into a Point. - """ - def get_tool(record_storage, tool_id) do - record_storage - |> Database.RecordStorage.get_all(__MODULE__) - |> Enum.find(fn(%{body: point}) -> point.tool_id == tool_id end) || - raise SelectorError, syncable: __MODULE__, syncable_id: tool_id, - message: "Could not find tool_slot with tool_id: #{tool_id}" - end -end diff --git a/lib/farmbot/database/syncable/regimen.ex b/lib/farmbot/database/syncable/regimen.ex deleted file mode 100644 index ec3a9436..00000000 --- a/lib/farmbot/database/syncable/regimen.ex +++ /dev/null @@ -1,12 +0,0 @@ -defmodule Farmbot.Database.Syncable.Regimen do - @moduledoc """ - A Regimen from the Farmbot API. - """ - - alias Farmbot.Database - alias Database.Syncable - use Syncable, model: [ - :name, - :regimen_items - ], endpoint: {"/regimens", "/regimens"} -end diff --git a/lib/farmbot/database/syncable/sequence.ex b/lib/farmbot/database/syncable/sequence.ex deleted file mode 100644 index d13a3f17..00000000 --- a/lib/farmbot/database/syncable/sequence.ex +++ /dev/null @@ -1,15 +0,0 @@ -defmodule Farmbot.Database.Syncable.Sequence do - @moduledoc """ - A Sequence from the Farmbot API. - """ - - alias Farmbot.Database - alias Database.Syncable - use Syncable, model: [ - :version, - :body, - :args, - :kind, - :name - ], endpoint: {"/sequences", "/sequences"} -end diff --git a/lib/farmbot/database/syncable/tool.ex b/lib/farmbot/database/syncable/tool.ex deleted file mode 100644 index 2fd030f5..00000000 --- a/lib/farmbot/database/syncable/tool.ex +++ /dev/null @@ -1,12 +0,0 @@ -defmodule Farmbot.Database.Syncable.Tool do - @moduledoc """ - A Tool from the Farmbot API. - """ - - alias Farmbot.Database - alias Database.Syncable - use Syncable, model: [ - :name, - :status - ], endpoint: {"/tools", "/tools"} -end diff --git a/lib/farmbot/database/syncable_error.ex b/lib/farmbot/database/syncable_error.ex deleted file mode 100644 index 55d0b6af..00000000 --- a/lib/farmbot/database/syncable_error.ex +++ /dev/null @@ -1,4 +0,0 @@ -defmodule Farmbot.Database.Syncable.Error do - @moduledoc "Syncable error" - defexception [:message] -end diff --git a/lib/farmbot/repo.ex b/lib/farmbot/repo.ex new file mode 100644 index 00000000..464da359 --- /dev/null +++ b/lib/farmbot/repo.ex @@ -0,0 +1,5 @@ +defmodule Farmbot.Repo do + use Ecto.Repo, + otp_app: :farmbot, + adapter: Sqlite.Ecto2 +end diff --git a/lib/farmbot/system.ex b/lib/farmbot/system.ex index a3e3000a..e56dd5fb 100644 --- a/lib/farmbot/system.ex +++ b/lib/farmbot/system.ex @@ -19,7 +19,6 @@ defmodule Farmbot.System do Should remove all persistant data. this includes: * network config * credentials - * database """ @callback factory_reset(reason) :: no_return @@ -49,5 +48,5 @@ defmodule Farmbot.System do @spec shutdown(unparsed_reason) :: no_return def shutdown(reason) do @system_tasks.shutdown(reason) - end + end end diff --git a/mix.exs b/mix.exs index e0dbb7e2..ac72e61c 100644 --- a/mix.exs +++ b/mix.exs @@ -86,6 +86,8 @@ defmodule Farmbot.Mixfile do {:cowboy, "~> 1.0.0"}, {:plug, "~> 1.0"}, + {:ecto, "~> 2.2.2"}, + {:sqlite_ecto2, "~> 2.2.1"} ] end @@ -107,6 +109,7 @@ defmodule Farmbot.Mixfile do end defp system("rpi0"), do: {:nerves_system_rpi0, ">= 0.0.0", runtime: false} + defp system("qemu_arm"), do: {:nerves_system_qemu_arm, ">= 0.0.0", runtime: false} defp package do [ @@ -117,20 +120,18 @@ defmodule Farmbot.Mixfile do end defp elixirc_paths(:test, "host") do - ["./lib", "./nerves/host", "./test/support"] + ["./lib", "./nerves/farmbot/host", "./test/support"] end defp elixirc_paths(_env, target) do - ["./lib", "./nerves/#{target}"] + ["./lib", "./nerves/farmbot/target"] end defp aliases("host"), do: [] defp aliases(_system) do ["deps.precompile": ["nerves.precompile", "deps.precompile"], - "deps.loadpaths": ["deps.loadpaths", "nerves.loadpaths"], - "firmware.upload": ["farmbot.upload"], - "firmware.sign": ["farmbot.sign"] - ] + "deps.loadpaths": ["deps.loadpaths", "nerves.loadpaths"] + ] end end diff --git a/mix.lock.host b/mix.lock.host index 11cf27cb..49cf6337 100644 --- a/mix.lock.host +++ b/mix.lock.host @@ -1,12 +1,17 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [], [], "hexpm"}, "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [], [], "hexpm"}, "cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [], [{:cowlib, "~> 1.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"}, "credo": {:hex, :credo, "0.8.6", "335f723772d35da499b5ebfdaf6b426bfb73590b6fcbc8908d476b75f8cbca3f", [], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [], [], "hexpm"}, "distillery": {:hex, :distillery, "1.5.1", "7ad7354214959c0f65f57ddd49478c81c3b2733ca2e5ccfb9eb55351108466aa", [], [], "hexpm"}, "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [], [], "hexpm"}, + "ecto": {:hex, :ecto, "2.2.3", "b1896b129db30d54073bedd5f3ba8a99dd6d64ebae3cf59057ae287060b46905", [], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"}, + "esqlite": {:hex, :esqlite, "0.2.3", "1a8b60877fdd3d50a8a84b342db04032c0231cc27ecff4ddd0d934485d4c0cd5", [], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.16.3", "cd2a4cfe5d26e37502d3ec776702c72efa1adfa24ed9ce723bb565f4c30bd31a", [], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, "ex_json_schema": {:hex, :ex_json_schema, "0.5.5", "d8d4c3f47b86c9e634e124d518b290dda82a8b94dcc314e45af10042fc369361", [], [], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, @@ -27,8 +32,12 @@ "nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"}, "ranch": {:hex, :ranch, "1.4.0", "10272f95da79340fa7e8774ba7930b901713d272905d0012b06ca6d994f8826b", [], [], "hexpm"}, "rsa": {:hex, :rsa, "0.0.1", "a63069f88ce342ffdf8448b7cdef4b39ba7dee3c1510644a39385c7e63ba246f", [], [], "hexpm"}, + "sbroker": {:hex, :sbroker, "1.0.0", "28ff1b5e58887c5098539f236307b36fe1d3edaa2acff9d6a3d17c2dcafebbd0", [], [], "hexpm"}, + "sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.1", "6447456ef4264177d16e489b88f7abc63463e9eddc1fef4358b3f73562b7a2d8", [], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"}, + "sqlitex": {:hex, :sqlitex, "1.3.3", "3aac5fd702be346f71d9de6e01702c9954484cd0971aa443490bb3bde045d919", [], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, "timex": {:hex, :timex, "3.1.24", "d198ae9783ac807721cca0c5535384ebdf99da4976be8cefb9665a9262a1e9e3", [], [{:combine, "~> 0.7", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "0.1.201605", "0c4184819b9d6adedcc02107b68321c45d8e853def7a32629b7961b9f2e95f33", [], [], "hexpm"}, diff --git a/mix.lock.qemu_arm b/mix.lock.qemu_arm new file mode 100644 index 00000000..c722ca29 --- /dev/null +++ b/mix.lock.qemu_arm @@ -0,0 +1,51 @@ +%{"bootloader": {:hex, :bootloader, "0.1.2", "835ddcf50b796714658f342061d5d48ebc34cbd0d81cdbd5a5a8ae00705d72b1", [], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"}, + "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"}, + "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [], [], "hexpm"}, + "cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [], [{:cowlib, "~> 1.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [], [], "hexpm"}, + "distillery": {:hex, :distillery, "1.5.1", "7ad7354214959c0f65f57ddd49478c81c3b2733ca2e5ccfb9eb55351108466aa", [], [], "hexpm"}, + "dns": {:hex, :dns, "1.0.1", "1d88187fdf564d937cee202949141090707fd0c9d7fcae903a6878ef24ef5d1e", [], [{:socket, "~> 0.3.12", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"}, + "ecto": {:hex, :ecto, "2.2.3", "b1896b129db30d54073bedd5f3ba8a99dd6d64ebae3cf59057ae287060b46905", [], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"}, + "esqlite": {:hex, :esqlite, "0.2.3", "1a8b60877fdd3d50a8a84b342db04032c0231cc27ecff4ddd0d934485d4c0cd5", [], [], "hexpm"}, + "ex_json_schema": {:hex, :ex_json_schema, "0.5.5", "d8d4c3f47b86c9e634e124d518b290dda82a8b94dcc314e45af10042fc369361", [], [], "hexpm"}, + "gen_mqtt": {:hex, :gen_mqtt, "0.3.1", "6ce6af7c2bcb125d5b4125c67c5ab1f29bcec2638236509bcc6abf510a6661ed", [], [{:vmq_commons, "1.0.0", [hex: :vmq_commons, repo: "hexpm", optional: false]}], "hexpm"}, + "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "mdns": {:hex, :mdns, "0.1.6", "b51b902b15b50e0e1522483c6a5fb073413e3d3d6ef52a44b93a541460b47d29", [], [{:dns, "~> 1.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, + "nerves": {:hex, :nerves, "0.7.5", "3aa6a336b2ad6c1c9589cc2b577511b3c4c375c1ba6c533ab9f88adb8c21f0c3", [], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.2.2", "a876f4e44ccc02606b923d7097b64dc7793384d716583cfca756b7f0dff9d441", [], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_init_gadget": {:hex, :nerves_init_gadget, "0.2.1", "20f36dd062fb00e2be8817ddff1b9ced9762877cfe23f6ec1d5936a37e3fc2c8", [], [{:mdns, "~> 0.1", [hex: :mdns, repo: "hexpm", optional: false]}, {:nerves_firmware_ssh, "~> 0.2", [hex: :nerves_firmware_ssh, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.3", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_network": {:hex, :nerves_network, "0.3.4", "c50a36b8263cda2bee18f408287d0f4474f8367702d170864325abbd5d424e4d", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_network_interface": {:hex, :nerves_network_interface, "0.4.2", "7a3663a07803f2f9f1e37146714d24ccec1e9349268586e4ed8c41f38641d837", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_runtime": {:hex, :nerves_runtime, "0.4.4", "26034bc7d13dbd46aab2f429f988656621a4d91872ccf5fa748c16630bd65016", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.5", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_system_br": {:hex, :nerves_system_br, "0.13.7", "85399547717c0386a4f2039e3467c14a23c3b77f66a4b97c2a67e48734dab2bb", [], [], "hexpm"}, + "nerves_system_qemu_arm": {:hex, :nerves_system_qemu_arm, "0.12.2", "9b90ad998ed75e93edd96fc79c8c8e0c872926ddde05ad56031ad81a903dc4d5", [], [{:nerves, "~> 0.7", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "~> 0.13.7", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "~> 0.11.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "0.11.0", "8d7606275a2d19de26ae238cd59475f4c06679aa9222b8987518d7c8a7beae51", [], [{:nerves, "~> 0.7", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.1", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "1.1.0", "0f03e4a3f3beef5fe271de0148b9f106c417e57f303f635c21c74b4bd6eb68ee", [], [], "hexpm"}, + "nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, + "nerves_wpa_supplicant": {:hex, :nerves_wpa_supplicant, "0.3.2", "19dc7e1248336e7f542b11b2b857ceb5b088d3eb41a6ca75b7b76628dcf67aad", [], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, + "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"}, + "ranch": {:hex, :ranch, "1.4.0", "10272f95da79340fa7e8774ba7930b901713d272905d0012b06ca6d994f8826b", [], [], "hexpm"}, + "rsa": {:hex, :rsa, "0.0.1", "a63069f88ce342ffdf8448b7cdef4b39ba7dee3c1510644a39385c7e63ba246f", [], [], "hexpm"}, + "sbroker": {:hex, :sbroker, "1.0.0", "28ff1b5e58887c5098539f236307b36fe1d3edaa2acff9d6a3d17c2dcafebbd0", [], [], "hexpm"}, + "socket": {:hex, :socket, "0.3.12", "4a6543815136503fee67eff0932da1742fad83f84c49130c854114153cc549a6", [], [], "hexpm"}, + "sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.1", "6447456ef4264177d16e489b88f7abc63463e9eddc1fef4358b3f73562b7a2d8", [], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"}, + "sqlitex": {:hex, :sqlitex, "1.3.3", "3aac5fd702be346f71d9de6e01702c9954484cd0971aa443490bb3bde045d919", [], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, + "system_registry": {:hex, :system_registry, "0.6.0", "31642177e6002d3cff2ada3553ed4e9c0a6ca015797d62d7d17c0ab8696185fc", [], [], "hexpm"}, + "timex": {:hex, :timex, "3.1.24", "d198ae9783ac807721cca0c5535384ebdf99da4976be8cefb9665a9262a1e9e3", [], [{:combine, "~> 0.7", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, + "tzdata": {:hex, :tzdata, "0.1.201605", "0c4184819b9d6adedcc02107b68321c45d8e853def7a32629b7961b9f2e95f33", [], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [], [], "hexpm"}, + "uuid": {:hex, :uuid, "1.1.7", "007afd58273bc0bc7f849c3bdc763e2f8124e83b957e515368c498b641f7ab69", [], [], "hexpm"}, + "vmq_commons": {:hex, :vmq_commons, "1.0.0", "5f5005c12db33f92f40e818a3617fb148972d59adcf99298c9d3808ef3582e34", [], [], "hexpm"}} diff --git a/mix.lock.rpi0 b/mix.lock.rpi0 index b21a4721..50c2446c 100644 --- a/mix.lock.rpi0 +++ b/mix.lock.rpi0 @@ -1,9 +1,16 @@ %{"bootloader": {:hex, :bootloader, "0.1.2", "835ddcf50b796714658f342061d5d48ebc34cbd0d81cdbd5a5a8ae00705d72b1", [], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"}, "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [], [], "hexpm"}, + "cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [], [{:cowlib, "~> 1.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.4.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [], [], "hexpm"}, "distillery": {:hex, :distillery, "1.5.1", "7ad7354214959c0f65f57ddd49478c81c3b2733ca2e5ccfb9eb55351108466aa", [], [], "hexpm"}, "dns": {:hex, :dns, "1.0.1", "1d88187fdf564d937cee202949141090707fd0c9d7fcae903a6878ef24ef5d1e", [], [{:socket, "~> 0.3.12", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"}, + "ecto": {:hex, :ecto, "2.2.3", "b1896b129db30d54073bedd5f3ba8a99dd6d64ebae3cf59057ae287060b46905", [], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"}, + "esqlite": {:hex, :esqlite, "0.2.3", "1a8b60877fdd3d50a8a84b342db04032c0231cc27ecff4ddd0d934485d4c0cd5", [], [], "hexpm"}, "ex_json_schema": {:hex, :ex_json_schema, "0.5.5", "d8d4c3f47b86c9e634e124d518b290dda82a8b94dcc314e45af10042fc369361", [], [], "hexpm"}, "ex_syslogger": {:git, "https://github.com/slashmili/ex_syslogger.git", "7e2ddccb90b69d1b593d24b71f46c682c0300c00", []}, "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], [], "hexpm"}, @@ -14,6 +21,7 @@ "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "mdns": {:hex, :mdns, "0.1.6", "b51b902b15b50e0e1522483c6a5fb073413e3d3d6ef52a44b93a541460b47d29", [], [{:dns, "~> 1.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, "nerves": {:hex, :nerves, "0.7.5", "3aa6a336b2ad6c1c9589cc2b577511b3c4c375c1ba6c533ab9f88adb8c21f0c3", [], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"}, "nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.2.2", "a876f4e44ccc02606b923d7097b64dc7793384d716583cfca756b7f0dff9d441", [], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"}, @@ -28,9 +36,15 @@ "nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, "nerves_wpa_supplicant": {:hex, :nerves_wpa_supplicant, "0.3.2", "19dc7e1248336e7f542b11b2b857ceb5b088d3eb41a6ca75b7b76628dcf67aad", [], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, "neves_init_gadget": {:git, "https://github.com/fhunleth/nerves_init_gadget.git", "801b0e2ec96b6b50585b8bf86e605608502e41b6", []}, + "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"}, + "ranch": {:hex, :ranch, "1.4.0", "10272f95da79340fa7e8774ba7930b901713d272905d0012b06ca6d994f8826b", [], [], "hexpm"}, "rsa": {:hex, :rsa, "0.0.1", "a63069f88ce342ffdf8448b7cdef4b39ba7dee3c1510644a39385c7e63ba246f", [], [], "hexpm"}, + "sbroker": {:hex, :sbroker, "1.0.0", "28ff1b5e58887c5098539f236307b36fe1d3edaa2acff9d6a3d17c2dcafebbd0", [], [], "hexpm"}, "socket": {:hex, :socket, "0.3.12", "4a6543815136503fee67eff0932da1742fad83f84c49130c854114153cc549a6", [], [], "hexpm"}, + "sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.1", "6447456ef4264177d16e489b88f7abc63463e9eddc1fef4358b3f73562b7a2d8", [], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"}, + "sqlitex": {:hex, :sqlitex, "1.3.3", "3aac5fd702be346f71d9de6e01702c9954484cd0971aa443490bb3bde045d919", [], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, "syslog": {:git, "https://github.com/Vagabond/erlang-syslog.git", "4a6c6f2c996483e86c1320e9553f91d337bcb6aa", [tag: "1.0.5"]}, "system_registry": {:hex, :system_registry, "0.6.0", "31642177e6002d3cff2ada3553ed4e9c0a6ca015797d62d7d17c0ab8696185fc", [], [], "hexpm"}, diff --git a/nerves/host/farmbot/host/system_tasks.ex b/nerves/farmbot/host/system_tasks.ex similarity index 100% rename from nerves/host/farmbot/host/system_tasks.ex rename to nerves/farmbot/host/system_tasks.ex diff --git a/nerves/farmbot/target/ecto.ex b/nerves/farmbot/target/ecto.ex new file mode 100644 index 00000000..c8a701b0 --- /dev/null +++ b/nerves/farmbot/target/ecto.ex @@ -0,0 +1,35 @@ +defmodule Farmbot.Target.Ecto do + @moduledoc "Setup the Database." + + @behaviour Farmbot.System.Init + require Logger + + def start_link(_, _opts) do + [repo] = Application.get_env(:farmbot, :ecto_repos) + + Logger.info "Dropping DB." + repo.__adapter__.storage_down(repo.config) + + Logger.info "Creating DB." + repo.__adapter__.storage_up(repo.config) + + Logger.info "Migrating DB." + opts = [all: true] + {:ok, pid, apps} = Mix.Ecto.ensure_started(repo, opts) + + migrator = &Ecto.Migrator.run/4 + pool = repo.config[:pool] + migrations_path = Path.join((:code.priv_dir(:farmbot) |> to_string), "repo") + migrated = + if function_exported?(pool, :unboxed_run, 2) do + pool.unboxed_run(repo, fn -> migrator.(repo, migrations_path, :up, opts) end) + else + migrator.(repo, migrations_path, :up, opts) + end + + pid && repo.stop(pid) + Mix.Ecto.restart_apps_if_migrated(apps, migrated) + :ignore + end + +end diff --git a/nerves/farmbot/target/network.ex b/nerves/farmbot/target/network.ex new file mode 100644 index 00000000..7839f99c --- /dev/null +++ b/nerves/farmbot/target/network.ex @@ -0,0 +1,9 @@ +defmodule Farmbot.Target.Network do + @moduledoc "Bring up network." + + @behaviour Farmbot.System.Init + + def start_link(_, _opts) do + :ignore + end +end diff --git a/nerves/farmbot/target/system_tasks.ex b/nerves/farmbot/target/system_tasks.ex new file mode 100644 index 00000000..4eebd634 --- /dev/null +++ b/nerves/farmbot/target/system_tasks.ex @@ -0,0 +1,15 @@ +defmodule Farmbot.Target.SystemTasks do + @moduledoc "Target implementation for System Tasks." + + @behaviour Farmbot.System + + def factory_reset(_reason) do + end + + def reboot(_reason) do + end + + def shutdown(_reason) do + + end +end diff --git a/nerves/host/farmbot/host/firmware_handler_stub.ex b/nerves/host/farmbot/host/firmware_handler_stub.ex deleted file mode 100644 index 0ea6d010..00000000 --- a/nerves/host/farmbot/host/firmware_handler_stub.ex +++ /dev/null @@ -1,9 +0,0 @@ -defmodule Farmbot.Host.FirmwareHandlerStub do - @moduledoc "Stubs out firmware functionality when you don't have an arduino." - use GenServer - - @doc "Start the firmware handler stub." - def start_link(firmware, opts) do - GenServer.start_link(__MODULE__, firmware, opts) - end -end diff --git a/priv/repo/migrations/20170915182355_add_thing.exs b/priv/repo/migrations/20170915182355_add_thing.exs new file mode 100644 index 00000000..d153becc --- /dev/null +++ b/priv/repo/migrations/20170915182355_add_thing.exs @@ -0,0 +1,7 @@ +defmodule Farmbot.Repo.Migrations.AddThing do + use Ecto.Migration + + def change do + + end +end diff --git a/test/farmbot/database/record_storage_test.exs b/test/farmbot/database/record_storage_test.exs deleted file mode 100644 index 22e5215f..00000000 --- a/test/farmbot/database/record_storage_test.exs +++ /dev/null @@ -1,71 +0,0 @@ -defmodule Farmbot.Database.RecordStorageTest do - @moduledoc "Test storage implementation." - - use ExUnit.Case - alias Farmbot.Database.RecordStorage, as: RS - alias Farmbot.Database.Syncable - - defmodule SomeSyncable do - use Farmbot.Database.Syncable, model: [:foo, :bar], endpoint: {"fake", "nope"} - end - - defmodule SomeOtherSyncable do - use Farmbot.Database.Syncable, model: [:foo, :baz], endpoint: {"fake", "nope"} - end - - setup do - {:ok, rs} = RS.start_link([]) - [rs: rs] - end - - test "Commits a single new record.", ctx do - record = %SomeSyncable{foo: 1, bar: 1, id: 123} - :ok = RS.commit_records(record, ctx.rs) - assert RS.get_all(ctx.rs, SomeSyncable) == [%Syncable{body: record, ref_id: {SomeSyncable, -1, 123}}] - end - - test "Commits a list of new records.", ctx do - records = Enum.map(0..10, fn(id) -> %SomeSyncable{foo: "hello", bar: "world", id: id} end) - :ok = RS.commit_records(records, ctx.rs) - assert Enum.all?(0..10, fn(id) -> - assert RS.get_by_id(ctx.rs, SomeSyncable, id) == %Syncable{body: %SomeSyncable{foo: "hello", bar: "world", id: id}, ref_id: {SomeSyncable, -1, id}} - end) - end - - test "updates a record", ctx do - record_a = %SomeSyncable{foo: 1, bar: 1, id: 123} - :ok = RS.commit_records(record_a, ctx.rs) - - record_b = %{record_a | foo: 123, bar: 123} - RS.commit_records(record_b, ctx.rs) - r = RS.get_by_id(ctx.rs, SomeSyncable, 123) - assert r == %Syncable{body: %SomeSyncable{bar: 123, foo: 123, id: 123}, ref_id: {SomeSyncable, -1, 123}} - - refute Enum.count(RS.get_all(ctx.rs, SomeSyncable)) > 2 - end - - test "Inspects the state reasonably.", ctx do - record = %SomeSyncable{foo: 1, bar: 1, id: 123} - :ok = RS.commit_records(record, ctx.rs) - assert inspect( :sys.get_state(ctx.rs)) == "#DatabaseState<[{Farmbot.Database.RecordStorageTest.SomeSyncable, -1, 123}]>" - end - - test "flushes all records.", ctx do - record = %SomeSyncable{foo: 1, bar: 1, id: 123} - :ok = RS.commit_records(record, ctx.rs) - RS.flush(ctx.rs) - assert RS.get_all(ctx.rs, SomeSyncable) == [] - - assert inspect( :sys.get_state(ctx.rs)) == "#DatabaseState<[]>" - end - - test "flushes records of one syncable.", ctx do - record1 = %SomeSyncable{foo: 1, bar: 2, id: 22} - record2 = %SomeOtherSyncable{foo: 12, baz: 33, id: 123 } - :ok = RS.commit_records([record1, record2], ctx.rs) - RS.flush(ctx.rs, SomeSyncable) - assert RS.get_all(ctx.rs, SomeSyncable) == [] - assert match?([_syncable], RS.get_all(ctx.rs, SomeOtherSyncable)) - end - -end diff --git a/test/farmbot/database/selectors_test.exs b/test/farmbot/database/selectors_test.exs deleted file mode 100644 index 15ce8151..00000000 --- a/test/farmbot/database/selectors_test.exs +++ /dev/null @@ -1,140 +0,0 @@ -defmodule Farmbot.Database.SelectorsTest do - @moduledoc "Tests selectors." - - use ExUnit.Case - alias Farmbot.Database.RecordStorage, as: RS - alias Farmbot.Database.Syncable - alias Syncable.Point - alias Syncable.Tool - alias Farmbot.Database.Selectors - alias Selectors.Error, as: SelectorError - - setup do - {:ok, rs} = RS.start_link([]) - [ - %Point{ - pointer_type: "Plant", - created_at: nil, - tool_id: nil, - radius: 5, - name: "Cabbage", - meta: nil, - x: 0, - y: 1, - z: 2, - id: 1 - }, - - %Tool{ - name: "Laser Beam", - status: "idle", - id: 9000 - }, - - %Point{ - pointer_type: "ToolSlot", - created_at: nil, - tool_id: 9000, - radius: 5, - name: "Laser Beam holder", - meta: nil, - x: 0, - y: 10, - z: 10, - id: 2 - }, - - %Point{ - pointer_type: "GenericPointer", - created_at: nil, - tool_id: nil, - radius: 5, - name: "Hole in the bed", - meta: nil, - x: 123, - y: 222, - z: 0, - id: 3 - }, - - ] |> RS.commit_records(rs) - [rs: rs] - end - - test "finds a plant", ctx do - r = Selectors.find_point(ctx.rs, "Plant", 1) - assert r == %Syncable{body: %Point{ - pointer_type: "Plant", - created_at: nil, - tool_id: nil, - radius: 5, - name: "Cabbage", - meta: nil, - x: 0, - y: 1, - z: 2, - id: 1 - }, ref_id: {Point, -1, 1}} - end - - test "finds a toolslot", ctx do - r = Selectors.find_point(ctx.rs, "GenericPointer", 3) - assert r == %Syncable{body: %Point{ - pointer_type: "GenericPointer", - created_at: nil, - tool_id: nil, - radius: 5, - name: "Hole in the bed", - meta: nil, - x: 123, - y: 222, - z: 0, - id: 3 - }, ref_id: {Point, -1, 3}} - end - - test "finds an uncatagorized pointer.", ctx do - r = Selectors.find_point(ctx.rs, "ToolSlot", 2) - assert r == %Syncable{body: %Point{ - pointer_type: "ToolSlot", - created_at: nil, - tool_id: 9000, - radius: 5, - name: "Laser Beam holder", - meta: nil, - x: 0, - y: 10, - z: 10, - id: 2 - }, ref_id: {Point, -1, 2}} - end - - test "raises when requesting the wrong type", ctx do - assert_raise SelectorError, "does not match type: ToolSlot", fn() -> - Selectors.find_point(ctx.rs, "ToolSlot", 1) - end - end - - alias Syncable.Device - test "Gets the db entry for this device.", ctx do - device_record = %Device{name: "farmbot_negative_one", timezone: nil, id: 1} - RS.commit_records(device_record, ctx.rs) - device = Selectors.get_device(ctx.rs) - assert device.name == "farmbot_negative_one" - end - - test "raises if there is more than one device", ctx do - device_record_1 = %Device{name: "farmbot_negative_one", timezone: nil, id: 1} - device_record_2 = %Device{name: "farmbot_negative_two", timezone: nil, id: 2} - RS.commit_records([device_record_1, device_record_2], ctx.rs) - assert_raise SelectorError, "Too many devices.", fn() -> - IO.inspect Selectors.get_device(ctx.rs) - end - end - - test "raises if there is no device", ctx do - assert_raise SelectorError, "No device.", fn() -> - Selectors.get_device(ctx.rs) - end - end -end diff --git a/test/farmbot/database/syncable/point_test.exs b/test/farmbot/database/syncable/point_test.exs deleted file mode 100644 index c78e16eb..00000000 --- a/test/farmbot/database/syncable/point_test.exs +++ /dev/null @@ -1,58 +0,0 @@ -defmodule Farmbot.Database.Syncable.PointTest do - @moduledoc "Tests point funs." - - alias Farmbot.Database.{Syncable, Selectors} - alias Selectors.Error, as: SelectorError - alias Syncable.{Point, Tool} - alias Farmbot.Database.RecordStorage, as: RS - - use ExUnit.Case - - setup do - {:ok, rs} = RS.start_link([]) - [rs: rs] - end - - test "gets a tool by id", ctx do - [ - %Tool{ - name: "Laser Beam", - status: "idle", - id: 9000 - }, - - %Point{ - pointer_type: "ToolSlot", - created_at: nil, - tool_id: 9000, - radius: 5, - name: "Laser Beam holder", - meta: nil, - x: 0, - y: 10, - z: 10, - id: 2 - }, - ] |> RS.commit_records(ctx.rs) - assert Point.get_tool(ctx.rs, 9000) == %Syncable{body: %Point{ - pointer_type: "ToolSlot", - created_at: nil, - tool_id: 9000, - radius: 5, - name: "Laser Beam holder", - meta: nil, - x: 0, - y: 10, - z: 10, - id: 2 - }, ref_id: {Point, -1, 2}} - end - - test "Raises when a tool doesn't exist", ctx do - assert_raise SelectorError, "Could not find tool_slot with tool_id: 1234", - fn() -> - Point.get_tool(ctx.rs, 1234) - end - end - -end