Packages

Client for Sonic: Fast, lightweight & schema-less search backend

Current section

Files

Jump to
sonix lib sonix.ex
Raw

lib/sonix.ex

defmodule Sonix do
alias Sonix.Tcp
@moduledoc """
Highlevel API
"""
@doc """
Initializes Tcp Client Genserver
## Examples
iex> Sonix.init()
#PID<0.177.0>
"""
def init(host \\ {127,0,0,1}, port \\ 1491) do
{:ok, conn} = Tcp.start_link(host, port, [mode: :binary, packet: :line], 1000)
Tcp.recv(conn)
conn
end
@doc """
Start with a mode
## Examples
iex> Sonix.start(conn, "search", "SecretPassword")
:ok
"""
def start(conn, channel, password) do
:ok = Tcp.send(conn, "START #{channel} #{password}")
Tcp.recv(conn)
end
@doc """
Query/Suggest a term
## Parameters
- opts: default values are [type: "QUERY", collection: "", bucket: "default", term: "", limit: 10, offset: 0]
## Examples
iex> Sonix.search(conn, [type: "QUERY", collection: "messages", "term": "spiderman"])
obj:1
iex> Sonix.suggest(conn, [type: "SUGGEST", collection: "messages", "term": "spider"])
spiderman
"""
@default_search %{type: "QUERY", collection: "", bucket: "default", term: "", limit: 10, offset: 0}
def search(conn, opts \\ []) do
%{type: type, collection: collection, bucket: bucket, term: term, limit: limit, offset: offset} = Enum.into(opts, @default_search)
offset_str = if type == "QUERY", do: "OFFSET(#{offset})" ,else: ""
:ok = Tcp.send(conn, "#{type} #{collection} #{bucket} \"#{term}\" LIMIT(#{limit}) #{offset_str}")
p = Tcp.recv(conn)
"PENDING " <> pending_id = p
x = Tcp.recv(conn)
"EVENT " <> y = x
y |> String.replace("#{type} #{pending_id} ", "") |> String.split(" ") |> Enum.filter(& &1 != "")
end
@doc """
Push a text
## Parameters
- opts: default values are [collection: "", bucket: "default", object: "", term: ""]
## Examples
iex> Sonix.push(conn, [collection: "messages", object: "obj:1", "term": "spiderman is cool"])
:ok
"""
@default_push %{collection: "", bucket: "default", object: "", term: ""}
def push(conn, opts \\ []) do
%{collection: collection, bucket: bucket, object: object, term: term} = Enum.into(opts, @default_push)
:ok = Tcp.send(conn, "PUSH #{collection} #{bucket} #{object} \"#{term}\" ")
case Tcp.recv(conn) do
"OK" -> :ok
"ERR " <> reason -> {:err, reason}
end
end
@doc """
Pop a text
## Parameters
- opts: default values are [collection: "", bucket: "default", object: "", term: ""]
## Examples
iex> Sonix.pop(conn, [collection: "messages", object: "obj:1", "term": "spiderman"])
1
"""
def pop(conn, opts \\ []) do
%{collection: collection, bucket: bucket, object: object, term: term} = Enum.into(opts, @default_push)
:ok = Tcp.send(conn, "POP #{collection} #{bucket} #{object} \"#{term}\" ")
"RESULT " <> n = Tcp.recv(conn)
n |> Integer.parse() |> elem(0)
end
@doc """
Flush a collection, bucket or object
## Parameters
- opts: default values are [collection: "", bucket: "", object: ""]
## Examples
iex> Sonix.flush(conn, [collection: "messages"])
1
"""
@default_flush %{collection: "", bucket: "", object: ""}
def flush(conn, opts \\ []) do
%{collection: collection, bucket: bucket, object: object} = Enum.into(opts, @default_flush)
cmd = cond do
object != "" -> "FLUSHO #{collection} #{bucket} #{object}"
bucket != "" -> "FLUSHB #{collection} #{bucket}"
collection != "" -> "FLUSHC #{collection}"
end
:ok = Tcp.send(conn, cmd)
"RESULT " <> n = Tcp.recv(conn)
n |> Integer.parse() |> elem(0)
end
@doc """
Count items in a collection, bucket or object
## Parameters
- opts: default values are [collection: "", bucket: "", object: ""]
## Examples
iex> Sonix.count(conn, [collection: "messages"])
1
"""
def count(conn, opts \\ []) do
%{collection: collection, bucket: bucket, object: object} = Enum.into(opts, @default_flush)
cmd = cond do
object != "" -> "COUNT #{collection} #{bucket} #{object}"
bucket != "" -> "COUNT #{collection} #{bucket}"
collection != "" -> "COUNT #{collection}"
end
:ok = Tcp.send(conn, cmd)
"RESULT " <> n = Tcp.recv(conn)
n |> Integer.parse() |> elem(0)
end
@doc """
Close a TCP connection
## Examples
iex> Sonix.quit(conn)
:ok
"""
def quit(conn) do
Tcp.send(conn, "QUIT")
Tcp.recv(conn)
end
end