Skip to content

Commit 8d531e6

Browse files
committed
# This is a combination of 4 commits.
# The first commit's message is: add_object functions, improved config errors for api/app keys # This is the 2nd commit message: fix # This is the 3rd commit message: fix # This is the 4th commit message: fix
1 parent cb2ace1 commit 8d531e6

File tree

3 files changed

+103
-26
lines changed

3 files changed

+103
-26
lines changed

config/config.exs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
11
use Mix.Config
2-
3-
config :algolia,
4-
application_id: System.get_env("ALGOLIA_APPLICATION_ID"),
5-
api_key: System.get_env("ALGOLIA_API_KEY")

lib/algolia.ex

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,42 @@ defmodule Algolia do
33
Elixir implementation of Algolia search API, using Hackney for http requests
44
"""
55

6-
@application_id Application.fetch_env!(:algolia, :application_id)
7-
@api_key Application.fetch_env!(:algolia, :api_key)
6+
defmodule MissingApplicationIDError do
7+
defexception message: """
8+
The `application_id` settings is required to use Algolia. Please include your
9+
application_id in your application config file like so:
10+
config :algilia, application_id: YOUR_APPLICATION_ID
11+
Alternatively, you can also set the secret key as an environment variable:
12+
ALGOLIA_APPLICATION_ID=YOUR_APP_ID
13+
"""
14+
end
15+
16+
defmodule MissingAPIKeyError do
17+
defexception message: """
18+
The `api_key` settings is required to use Algolia. Please include your
19+
api key in your application config file like so:
20+
config :algolia, api_key: YOUR_API_KEY
21+
Alternatively, you can also set the secret key as an environment variable:
22+
ALGOLIA_API_KEY=YOUR_SECRET_API_KEY
23+
"""
24+
end
25+
26+
def application_id do
27+
Application.get_env(:algolia, :application_id, System.get_env("ALGOLIA_APPLICATION_ID"))
28+
|| raise MissingApplicationIDError
29+
end
30+
31+
def api_key do
32+
Application.get_env(:algolia, :api_key, System.get_env("ALGOLIA_API_KEY"))
33+
|| raise MissingAPIKeyError
34+
end
835

936
defp host(:read, 0),
10-
do: "#{@application_id}-dsn.algolia.net"
37+
do: "#{application_id()}-dsn.algolia.net"
1138
defp host(:write, 0),
12-
do: "#{@application_id}.algolia.net"
39+
do: "#{application_id()}.algolia.net"
1340
defp host(_read_or_write, curr_retry) when curr_retry <= 3,
14-
do: "#{@application_id}-#{curr_retry}.algolianet.com"
41+
do: "#{application_id()}-#{curr_retry}.algolianet.com"
1542

1643
@doc """
1744
Multiple queries
@@ -93,8 +120,8 @@ defmodule Algolia do
93120
|> Path.join(path)
94121

95122
headers = [
96-
"X-Algolia-API-Key": @api_key,
97-
"X-Algolia-Application-Id": @application_id
123+
"X-Algolia-API-Key": api_key(),
124+
"X-Algolia-Application-Id": application_id()
98125
]
99126

100127
:hackney.request(method, url, headers, body, [
@@ -123,15 +150,50 @@ defmodule Algolia do
123150
|> inject_index_into_response(index)
124151
end
125152

153+
@doc """
154+
Add an Object
155+
"""
156+
def add_object(index, object) do
157+
body = object |> Poison.encode!
158+
path = "#{index}"
159+
160+
send_request(:write, :post, path, body)
161+
|> inject_index_into_response(index)
162+
end
163+
164+
@doc """
165+
Add an object with an attribute as the objectID
166+
"""
167+
def add_object(index, object, [id_attribute: id_attribute]) do
168+
save_object(index, object, [id_attribute: id_attribute])
169+
end
170+
171+
@doc """
172+
Add multiple objects
173+
"""
174+
def add_objects(index, objects) do
175+
objects
176+
|> build_batch_request("addObject")
177+
|> send_batch_request(index)
178+
end
179+
180+
@doc """
181+
Add multiple objects, with an attribute as objectID
182+
"""
183+
def add_objects(index, objects, [id_attribute: id_attribute]) do
184+
save_objects(index, objects, [id_attribute: id_attribute])
185+
end
186+
126187
@doc """
127188
Save a single object, without objectID specified, must have objectID as
128189
a field
129190
"""
130191
def save_object(index, object, [id_attribute: id_attribute]) do
131-
object_id = object[id_attribute] || object[to_string id_attribute]
192+
object_id = object[id_attribute] || object[to_string(id_attribute)]
132193

133194
if !object_id do
134-
raise "Object must have an objectID"
195+
raise ArgumentError,
196+
message: "Your object #{object} does not have a attribute #{id_attribute}"
135197
end
136198

137199
save_object(index, object, object_id)
@@ -165,13 +227,13 @@ defmodule Algolia do
165227
def save_objects(index, objects, [id_attribute: id_attribute]) when is_list(objects) do
166228
objects
167229
|> add_object_ids(id_attribute: id_attribute)
168-
|> build_batch_request("updateObject", with_object_id: true)
230+
|> build_batch_request("updateObject")
169231
|> send_batch_request(index)
170232
end
171233

172234
def save_objects(index, objects) when is_list(objects) do
173235
objects
174-
|> build_batch_request("updateObject", with_object_id: true)
236+
|> build_batch_request("updateObject")
175237
|> send_batch_request(index)
176238
end
177239

@@ -208,7 +270,7 @@ defmodule Algolia do
208270

209271
objects
210272
|> add_object_ids(id_attribute: id_attribute)
211-
|> build_batch_request(action, with_object_id: true)
273+
|> build_batch_request(action)
212274
|> send_batch_request(index)
213275
end
214276

@@ -254,18 +316,15 @@ defmodule Algolia do
254316
|> inject_index_into_response(index)
255317
end
256318

257-
defp build_batch_request(objects, action, with_object_id: with_object_id) do
258-
requests = Enum.map objects, fn(object) ->
259-
if with_object_id do
260-
object_id = get_object_id!(object)
261-
262-
%{action: action, body: object, objectID: object_id}
263-
else
264-
%{action: action, body: object}
319+
defp build_batch_request(objects, action) do
320+
requests = Enum.map objects, fn (object) ->
321+
case get_object_id(object) do
322+
{:ok, object_id} -> %{action: action, body: object, objectID: object_id}
323+
_ -> %{action: action, body: object}
265324
end
266325
end
267326

268-
%{ requests: requests }
327+
%{requests: requests}
269328
end
270329

271330
@doc """
@@ -285,7 +344,7 @@ defmodule Algolia do
285344
|> Enum.map(fn (id) ->
286345
%{objectID: id}
287346
end)
288-
|> build_batch_request("deleteObject", with_object_id: true)
347+
|> build_batch_request("deleteObject")
289348
|> send_batch_request(index)
290349
end
291350

test/algolia_test.exs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,28 @@ defmodule AlgoliaTest do
1515
|> Enum.each(&wait/1)
1616
end
1717

18+
test "add object" do
19+
{:ok, %{"objectID" => object_id}} =
20+
"test_1"
21+
|> add_object(%{text: "hello"})
22+
|> wait
23+
24+
assert {:ok, %{"text" => "hello"}} =
25+
get_object("test_1", object_id)
26+
end
27+
28+
test "add multiple objects" do
29+
assert {:ok, %{"objectIDs" => ids}} =
30+
"test_1"
31+
|> add_objects([%{text: "add multiple test"}, %{text: "add multiple test"}, %{text: "add multiple test"}])
32+
|> wait
33+
34+
for id <- ids do
35+
assert {:ok, %{"text" => "add multiple test"}} =
36+
get_object("test_1", id)
37+
end
38+
end
39+
1840
test "list all indexes" do
1941
assert {:ok, %{"items" => items}} = list_indexes
2042
end

0 commit comments

Comments
 (0)