diff --git a/lib/ecto_gss/repo.ex b/lib/ecto_gss/repo.ex index 6807f1e..9b36893 100644 --- a/lib/ecto_gss/repo.ex +++ b/lib/ecto_gss/repo.ex @@ -60,21 +60,21 @@ defmodule EctoGSS.Repo do * by range of rows: `start_id` and `end_id` options; * by exact list of rows: `rows` option. """ - @spec all(Ecto.Queryable.t(), Keyword.t()) :: [Ecto.Schema.t()] - def all(schema, opts \\ []) do + @spec all(Ecto.Queryable.t(), Keyword.t()) :: [Ecto.Schema.t()] | no_return + def all(schema, opts \\ []) when is_atom(schema) do with {:ok, pid} <- get_spreadsheet_pid(schema), index when index > 0 <- last_column_index(schema), {response_format, {:ok, data}} <- rows_by_params(pid, index, opts) do response_values_by_opts(response_format, schema, data, opts) else - :error -> - raise EctoGSS.NoSpreadsheetPid, message: "no pid" - :invalid_record -> raise EctoGSS.NotSchema, message: "not a schema in first param" + :error -> + raise EctoGSS.NoSpreadsheetPid, message: "no pid" + _ -> - nil + [] end end @@ -82,18 +82,18 @@ defmodule EctoGSS.Repo do Get a record by row id, raise if not found. """ @spec get(Ecto.Queryable.t(), integer()) :: Ecto.Schema.t() | nil | no_return - def get(schema, id) do + def get(schema, id) when is_atom(schema) do with {:ok, pid} <- get_spreadsheet_pid(schema), index when index > 0 <- last_column_index(schema), {:ok, data} <- GSS.Spreadsheet.read_row(pid, id, column_to: index) do from_spreadsheet_row_values(schema, data, id) else - :error -> - raise EctoGSS.NoSpreadsheetPid, message: "no pid" - :invalid_record -> raise EctoGSS.NotSchema, message: "not a schema in first param" + :error -> + raise EctoGSS.NoSpreadsheetPid, message: "no pid" + _ -> nil end @@ -102,10 +102,10 @@ defmodule EctoGSS.Repo do @doc """ Get a record by row, raise if not found. """ - @spec get!(Ecto.Queryable.t(), integer()) :: Ecto.Schema.t() | no_return - def get!(_schema, nil), do: raise(%Ecto.NoResultsError{message: "no results found"}) + @spec get!(Ecto.Queryable.t(), integer() | nil) :: Ecto.Schema.t() | no_return + def get!(_schema, nil), do: raise Ecto.NoResultsError, message: "no results found" - def get!(schema, id) do + def get!(schema, id) when is_atom(schema) do raise_if_no_results(schema, get(schema, id)) end @@ -118,6 +118,7 @@ defmodule EctoGSS.Repo do object = apply_changes(changeset), row_values = spreadsheet_row_values(object), id = get_inc_row(pid), + IO.inspect(row_values), :ok <- GSS.Spreadsheet.append_row(pid, id, row_values) do {:ok, Map.put(object, :id, id)} else @@ -137,7 +138,7 @@ defmodule EctoGSS.Repo do def insert(%{__struct__: _model} = object) do object |> change(%{}) - |> insert + |> insert() end @doc """ @@ -145,7 +146,9 @@ defmodule EctoGSS.Repo do """ @spec insert!(ecto_object) :: Ecto.Schema.t() | no_return def insert!(changeset) do - raise_if_changeset_errors(insert(changeset), "insert") + changeset + |> insert() + |> raise_if_changeset_errors("insert") end @doc """ @@ -177,7 +180,9 @@ defmodule EctoGSS.Repo do """ @spec update!(Ecto.Changeset.t()) :: Ecto.Schema.t() | no_return def update!(%Ecto.Changeset{} = changeset) do - raise_if_changeset_errors(update(changeset), "update") + changeset + |> update() + |> raise_if_changeset_errors("update") end @doc """ @@ -202,7 +207,9 @@ defmodule EctoGSS.Repo do """ @spec insert_or_update!(Ecto.Changeset.t()) :: Ecto.Schema.t() | no_return def insert_or_update!(changeset) do - raise_if_changeset_errors(insert_or_update(changeset), "upsert") + changeset + |> insert_or_update() + |> raise_if_changeset_errors("upsert") end @doc """ @@ -232,9 +239,11 @@ defmodule EctoGSS.Repo do @doc """ Delete an existing record, raise in case of error. """ - @spec delete!(ecto_object) :: result | no_return + @spec delete!(ecto_object) :: Ecto.Schema.t | no_return def delete!(record) do - raise_if_changeset_errors(delete(record), "delete") + record + |> delete() + |> raise_if_changeset_errors("delete") end @spec response_values_by_opts(:rows | :range, module(), [map()], Keyword.t()) :: [ @@ -263,7 +272,7 @@ defmodule EctoGSS.Repo do end end - @spec from_spreadsheet_row_values(module(), [String.t()], String.t()) :: Ecto.Schema.t() | nil + @spec from_spreadsheet_row_values(module(), [String.t()], String.t() | integer()) :: Ecto.Schema.t() | nil defp from_spreadsheet_row_values(schema, [head | _] = values, id) do if Enum.join(values) == "" or head == "!!" do nil @@ -360,12 +369,12 @@ defmodule EctoGSS.Repo do index + 1 end - @spec get_spreadsheet_pid(Ecto.Changeset.t()) :: {:ok, pid()} | :error | :invalid_record + @spec get_spreadsheet_pid(Ecto.Changeset.t() | module()) :: {:ok, pid()} | :error | :invalid_record defp get_spreadsheet_pid(%Ecto.Changeset{} = record) do get_spreadsheet_pid(spreadsheet(record), list(record)) end - defp get_spreadsheet_pid(schema) do + defp get_spreadsheet_pid(schema) when is_atom(schema) do if is_gss_schema_module?(schema) do get_spreadsheet_pid(schema.spreadsheet(), schema.list()) else @@ -436,7 +445,7 @@ defmodule EctoGSS.Repo do end # Raise Ecto.NoResultsError if there is no results - @spec raise_if_no_results(module(), Ecto.Schema.t()) :: Ecto.Schema.t() | no_return + @spec raise_if_no_results(module(), Ecto.Schema.t() | nil) :: Ecto.Schema.t() | no_return defp raise_if_no_results(schema, result) do case result do nil -> raise Ecto.NoResultsError.exception(queryable: schema) @@ -458,14 +467,11 @@ defmodule EctoGSS.Repo do end) raise Ecto.InvalidChangesetError, action: action, changeset: changeset - - _ -> - raise Ecto.InvalidChangesetError, action: action end end # Convert all changeset errors into a single string value. - @spec changeset_errors_to_string(Ecto.Changeset.t()) :: String.t() + @spec changeset_errors_to_string(Ecto.Changeset.t()) :: map() defp changeset_errors_to_string(changeset) do Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} -> Enum.reduce(opts, msg, fn {key, value}, _acc -> diff --git a/mix.exs b/mix.exs index 3dc4a45..08c0ff6 100644 --- a/mix.exs +++ b/mix.exs @@ -4,8 +4,8 @@ defmodule EctoGss.Mixfile do def project do [ app: :ecto_gss, - version: "0.2.0", - elixir: "~> 1.4", + version: "0.2.1", + elixir: "~> 1.6", description: "Use Google Spreadsheets as storage for Ecto objects.", docs: [extras: ["README.md"]], build_embedded: Mix.env() == :prod, @@ -36,7 +36,7 @@ defmodule EctoGss.Mixfile do defp deps do [ - {:elixir_google_spreadsheets, "~> 0.1.10"}, + {:elixir_google_spreadsheets, "~> 0.1.14"}, {:ecto, "~> 3.0"}, {:earmark, ">= 0.0.0", only: :dev}, {:ex_doc, ">= 0.0.0", only: :dev} diff --git a/mix.lock b/mix.lock index c469a2f..8ba5d47 100644 --- a/mix.lock +++ b/mix.lock @@ -1,24 +1,28 @@ %{ - "certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, optional: false]}]}, - "decimal": {:hex, :decimal, "1.6.0", "bfd84d90ff966e1f5d4370bdd3943432d8f65f07d3bab48001aebd7030590dcc", [:mix], []}, + "base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"}, + "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.8.0", "ca462e0d885f09a1c5a342dbd7c1dcf27ea63548c65a65e67334f4b61803822e", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], []}, "ecto": {:hex, :ecto, "3.0.6", "d33ab5b3f7553a41507d4b0ad5bf192d533119c4ad08f3a5d63d85aa12117dc9", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, optional: false]}, {:jason, "~> 1.0", [hex: :jason, optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: true]}]}, - "elixir_google_spreadsheets": {:hex, :elixir_google_spreadsheets, "0.1.10", "60a6ef13598a092ed1e13e1aeb7a2cc444abaf13624115b5413f909d644f08e6", [:mix], [{:gen_stage, ">= 0.12.0", [hex: :gen_stage, optional: false]}, {:goth, "~> 0.5.0", [hex: :goth, optional: false]}, {:httpoison, "~> 0.12", [hex: :httpoison, optional: false]}, {:poison, "~> 3.1", [hex: :poison, optional: false]}]}, + "elixir_google_spreadsheets": {:hex, :elixir_google_spreadsheets, "0.1.14", "f5610767dc0591ce9fedfd858c3184bdb7e0777920e77e05b955610e7499c8bd", [:mix], [{:gen_stage, "~> 0.14", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:goth, "~> 1.0", [hex: :goth, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.4", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.19.2", "6f4081ccd9ed081b6dc0bd5af97a41e87f5554de469e7d76025fba535180565f", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, optional: false]}]}, - "gen_stage": {:hex, :gen_stage, "0.14.0", "65ae78509f85b59d360690ce3378d5096c3130a0694bab95b0c4ae66f3008fad", [:mix], []}, - "goth": {:hex, :goth, "0.5.1", "28452a4c7eecba346ec0e2bd16bd53ad2c754a413cb8ea3038610c3d8122930d", [:mix], [{:httpoison, "~> 0.11", [hex: :httpoison, optional: false]}, {:json_web_token, "~> 0.2.10", [hex: :json_web_token, optional: false]}, {:poison, "~> 2.1 or ~> 3.0", [hex: :poison, optional: false]}]}, - "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, optional: false]}, {:idna, "5.1.2", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, optional: false]}]}, + "gen_stage": {:hex, :gen_stage, "0.14.2", "6a2a578a510c5bfca8a45e6b27552f613b41cf584b58210f017088d3d17d0b14", [:mix], [], "hexpm"}, + "goth": {:hex, :goth, "1.1.0", "85977656822e54217bc0472666f1ce15dc3921495ef5f4f0774ef15503bae207", [:mix], [{:httpoison, "~> 0.11 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.0", [hex: :joken, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "1.5.1", "0f55b5b673b03c5c327dac7015a67cb571b99b631acc0bc1b0b98dcd6b9f2104", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, + "joken": {:hex, :joken, "2.1.0", "bf21a73105d82649f617c5e59a7f8919aa47013d2519ebcc39d998d8d12adda9", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm"}, + "jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"}, "json_web_token": {:hex, :json_web_token, "0.2.10", "61041d56369422c5e3a770cf7d7bf27224b3c4c12d3a7d79b43a002df766db22", [:mix], [{:poison, "~> 3.1", [hex: :poison, optional: false]}]}, "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, optional: false]}]}, "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, optional: false]}]}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], []}, - "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], []}, + "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], []}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, }