Elixir tutorial code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

command.ex 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. defmodule KVServer.Command do
  2. @doc ~S"""
  3. Parses the given `line` into a command.
  4. ## Examples
  5. iex> KVServer.Command.parse("CREATE shopping\n")
  6. {:ok, {:create, "shopping"}}
  7. iex> KVServer.Command.parse("CREATE shopping \n")
  8. {:ok, {:create, "shopping"}}
  9. iex> KVServer.Command.parse("DELETE shopping\n")
  10. {:ok, {:delete, "shopping"}}
  11. iex> KVServer.Command.parse("PUT shopping milk 1\n")
  12. {:ok, {:put, "shopping", "milk", "1"}}
  13. iex> KVServer.Command.parse("GET shopping milk\n")
  14. {:ok, {:get, "shopping", "milk"}}
  15. iex> KVServer.Command.parse("DELETE shopping eggs\n")
  16. {:ok, {:delete, "shopping", "eggs"}}
  17. Unknown commands or commands with the wrong number of arguments return an error:
  18. iex> KVServer.Command.parse("UNKNOWN shopping eggs\n")
  19. {:error, :unknown_command}
  20. iex> KVServer.Command.parse("GET shopping\n")
  21. {:error, :unknown_command}
  22. """
  23. def parse(line) do
  24. case String.split(line) do
  25. ["CREATE", bucket] -> {:ok, {:create, bucket}}
  26. ["DELETE", bucket] -> {:ok, {:delete, bucket}}
  27. ["PUT", bucket, key, value] -> {:ok, {:put, bucket, key, value}}
  28. ["GET", bucket, key] -> {:ok, {:get, bucket, key}}
  29. ["DELETE", bucket, key] -> {:ok, {:delete, bucket, key}}
  30. _ -> {:error, :unknown_command}
  31. end
  32. end
  33. @doc """
  34. Runs the given command.
  35. """
  36. def run(command, registry \\ KV.Registry)
  37. def run({:create, bucket}, registry) do
  38. case KV.Router.route(bucket, KV.Registry, :create, [registry, bucket]) do
  39. {:ok, _} -> {:ok, "OK\n"}
  40. :error -> {:error, :already_exists}
  41. end
  42. end
  43. def run({:delete, bucket}, registry) do
  44. case KV.Router.route(bucket, KV.Registry, :delete, [registry, bucket]) do
  45. :ok -> {:ok, "OK\n"}
  46. :error -> {:error, :not_found}
  47. end
  48. end
  49. def run({:get, bucket, key}, registry) do
  50. lookup(bucket, registry, fn pid ->
  51. value = KV.Bucket.get(pid, key)
  52. {:ok, "#{value}\nOK\n"}
  53. end)
  54. end
  55. def run({:put, bucket, key, value}, registry) do
  56. lookup(bucket, registry, fn pid ->
  57. KV.Bucket.put(pid, key, value)
  58. {:ok, "OK\n"}
  59. end)
  60. end
  61. def run({:delete, bucket, key}, registry) do
  62. lookup(bucket, registry, fn pid ->
  63. KV.Bucket.delete(pid, key)
  64. {:ok, "OK\n"}
  65. end)
  66. end
  67. defp lookup(bucket, registry, callback) do
  68. case KV.Router.route(bucket, KV.Registry, :lookup, [registry, bucket]) do
  69. {:ok, pid} -> callback.(pid)
  70. :error -> {:error, :not_found}
  71. end
  72. end
  73. end