Skip to content

Instantly share code, notes, and snippets.

@Clokze
Created June 16, 2015 21:12
Show Gist options
  • Select an option

  • Save Clokze/2225b7f36711cc2432ef to your computer and use it in GitHub Desktop.

Select an option

Save Clokze/2225b7f36711cc2432ef to your computer and use it in GitHub Desktop.
defmodule KVServer.Command do
@doc ~S"""
Parses the given `line` into a command.
## Examples
iex> KVServer.Command.parse "CREATE shopping\r\n"
{:ok, {:create, "shopping"}}
iex> KVServer.Command.parse "CREATE shopping \r\n"
{:ok, {:create, "shopping"}}
iex> KVServer.Command.parse "PUT shopping milk 1\r\n"
{:ok, {:put, "shopping", "milk", 1}}
iex> KVServer.Command.parse "GET shopping milk\r\n"
{:ok, {:get, "shopping", "milk"}}
iex> KVServer.Command.parse "DELETE shopping eggs\r\n"
{:ok, {:delete, "shopping", "eggs"}}
Unknown commands or commands with the wrong number of arguments return an
error:
iex> KVServer.Command.parse "UNKNOWN shopping eggs\r\n"
{:error, :unknown_command}
iex> KVServer.Command.parse "GET shopping\r\n"
{:error, :unknown_command}
"""
def parse(line) do
case String.split(line) do
["CREATE", bucket] -> {:ok, {:create, bucket}}
["PUT", bucket, what, quantity] ->
{parsed_quantity, _} = Integer.parse(quantity)
{:ok, {:put, bucket, what, parsed_quantity}}
["GET", bucket, what] -> {:ok, {:get, bucket, what}}
["DELETE", bucket, what] -> {:ok, {:delete, bucket, what}}
_ -> {:error, :unknown_command}
end
end
@doc """
Runs the given command.
"""
def run(command)
def run({:create, bucket}) do
KV.Registry.create(KV.Registry, bucket)
{:ok, "OK\r\n"}
end
def run({:get, bucket, key}) do
lookup bucket, fn pid ->
value = KV.Bucket.get(pid, key)
{:ok, "#{value}\r\nOK\r\n"}
end
end
def run({:put, bucket, key, value}) do
lookup bucket, fn pid ->
KV.Bucket.put(pid, key, value)
{:ok, "OK\r\n"}
end
end
def run({:delete, bucket, key}) do
lookup bucket, fn pid ->
KV.Bucket.delete(pid, key)
{:ok, "OK\r\n"}
end
end
defp lookup(bucket, callback) do
case KV.Registry.lookup(KV.Registry, bucket) do
{:ok, pid} -> callback.(pid)
:error -> {:error, :not_found}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment