Skip to content

Commit f957b29

Browse files
authored
feat(dictionaries): dictionaries API implementation (#618)
1 parent 3a8e81d commit f957b29

23 files changed

+1337
-48
lines changed

src/main/scala/algolia/AlgoliaClient.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525

2626
package algolia
2727

28+
import algolia.http.HttpPayload
29+
import algolia.objects.{DictionaryEntry, Query}
30+
import algolia.responses.SearchDictionaryResult
31+
import org.slf4j.{Logger, LoggerFactory}
32+
2833
import java.nio.charset.Charset
2934
import java.util.Base64
30-
31-
import algolia.http.HttpPayload
32-
import algolia.objects.Query
3335
import javax.crypto.Mac
3436
import javax.crypto.spec.SecretKeySpec
35-
import org.slf4j.{Logger, LoggerFactory}
36-
3737
import scala.concurrent.duration.Duration
3838
import scala.concurrent.{ExecutionContext, Future}
3939
import scala.util.matching.Regex

src/main/scala/algolia/AlgoliaDsl.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,15 @@
2525

2626
package algolia
2727

28-
import java.time.{Instant, LocalDateTime, ZoneOffset, ZonedDateTime}
29-
import java.time.format.{DateTimeFormatter, DateTimeFormatterBuilder}
30-
3128
import algolia.definitions._
3229
import algolia.dsl._
3330
import algolia.objects._
34-
import org.json4s.{CustomSerializer, Formats}
3531
import org.json4s.JsonAST._
3632
import org.json4s.JsonDSL._
33+
import org.json4s.{CustomSerializer, Formats}
3734

35+
import java.time.format.{DateTimeFormatter, DateTimeFormatterBuilder}
36+
import java.time.{Instant, LocalDateTime, ZoneOffset, ZonedDateTime}
3837
import scala.util.matching.Regex
3938

4039
trait AlgoliaDsl
@@ -69,6 +68,8 @@ trait AlgoliaDsl
6968
with SendDsl
7069
with SetDsl
7170
with RestoreDsl
71+
with DictionaryDsl
72+
with ReplaceDsl
7273

7374
object AlgoliaDsl extends AlgoliaDsl {
7475

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Algolia
5+
* http://www.algolia.com/
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
package algolia.definitions
27+
28+
import algolia.http.{GET, HttpPayload, POST, PUT}
29+
import algolia.objects._
30+
import org.json4s.Formats
31+
import org.json4s.native.Serialization.write
32+
33+
sealed trait BatchDictionaryDefinition extends Definition {
34+
val dictionary: Dictionary[_]
35+
val requestOptions: Option[RequestOptions] = None
36+
37+
val path = Seq("1", "dictionaries", dictionary.name, "batch")
38+
39+
def buildBody(
40+
entries: Seq[_],
41+
action: String,
42+
clearExistingDictionaryEntries: Boolean = false
43+
): Map[String, Any] = {
44+
Map(
45+
"clearExistingDictionaryEntries" -> clearExistingDictionaryEntries,
46+
"requests" -> entries.map(entry =>
47+
Map(
48+
"action" -> action,
49+
"body" -> entry
50+
)
51+
)
52+
)
53+
}
54+
}
55+
56+
case class SaveDictionaryDefinition[A <: DictionaryEntry](
57+
override val dictionary: Dictionary[A],
58+
dictionaryEntries: Seq[A] = List(),
59+
override val requestOptions: Option[RequestOptions] = None
60+
)(implicit val formats: Formats)
61+
extends BatchDictionaryDefinition {
62+
63+
override type T = SaveDictionaryDefinition[A]
64+
65+
def entries(entries: Seq[A]): SaveDictionaryDefinition[A] =
66+
copy(dictionaryEntries = entries)
67+
68+
override private[algolia] def build() = {
69+
val body = buildBody(entries = dictionaryEntries, action = "addEntry")
70+
HttpPayload(
71+
POST,
72+
path,
73+
body = Some(write(body)),
74+
isSearch = false,
75+
requestOptions = requestOptions
76+
)
77+
}
78+
79+
override def options(
80+
requestOptions: RequestOptions
81+
): SaveDictionaryDefinition[A] = copy(requestOptions = Some(requestOptions))
82+
}
83+
84+
case class ReplaceDictionaryDefinition[A <: DictionaryEntry](
85+
override val dictionary: Dictionary[A],
86+
dictionaryEntries: Seq[A] = List(),
87+
override val requestOptions: Option[RequestOptions] = None
88+
)(implicit val formats: Formats)
89+
extends BatchDictionaryDefinition {
90+
91+
override type T = ReplaceDictionaryDefinition[A]
92+
93+
def entries(entries: Seq[A]): ReplaceDictionaryDefinition[A] =
94+
copy(dictionaryEntries = entries)
95+
96+
override private[algolia] def build() = {
97+
val body = buildBody(
98+
entries = dictionaryEntries,
99+
action = "addEntry",
100+
clearExistingDictionaryEntries = true
101+
)
102+
HttpPayload(
103+
POST,
104+
path,
105+
body = Some(write(body)),
106+
isSearch = false,
107+
requestOptions = requestOptions
108+
)
109+
}
110+
111+
override def options(
112+
requestOptions: RequestOptions
113+
): ReplaceDictionaryDefinition[A] =
114+
copy(requestOptions = Some(requestOptions))
115+
}
116+
117+
case class DeleteDictionaryDefinition(
118+
override val dictionary: Dictionary[DictionaryEntry],
119+
objectIDs: Seq[String] = List(),
120+
override val requestOptions: Option[RequestOptions] = None
121+
)(implicit val formats: Formats)
122+
extends BatchDictionaryDefinition {
123+
124+
override type T = DeleteDictionaryDefinition
125+
126+
def objectIDs(objectIDs: Seq[String]): DeleteDictionaryDefinition =
127+
copy(objectIDs = objectIDs)
128+
129+
override private[algolia] def build() = {
130+
val body = buildBody(
131+
entries = objectIDs.map(entry => Map("objectID" -> entry)),
132+
action = "deleteEntry"
133+
)
134+
135+
HttpPayload(
136+
POST,
137+
path,
138+
body = Some(write(body)),
139+
isSearch = false,
140+
requestOptions = requestOptions
141+
)
142+
}
143+
144+
override def options(
145+
requestOptions: RequestOptions
146+
): DeleteDictionaryDefinition =
147+
copy(requestOptions = Some(requestOptions))
148+
}
149+
150+
case class ClearDictionaryDefinition(
151+
override val dictionary: Dictionary[DictionaryEntry],
152+
override val requestOptions: Option[RequestOptions] = None
153+
)(implicit val formats: Formats)
154+
extends BatchDictionaryDefinition {
155+
156+
override type T = ClearDictionaryDefinition
157+
158+
override private[algolia] def build() = {
159+
val body = buildBody(
160+
entries = List.empty,
161+
action = "addEntry",
162+
clearExistingDictionaryEntries = true
163+
)
164+
HttpPayload(
165+
POST,
166+
path,
167+
body = Some(write(body)),
168+
isSearch = false,
169+
requestOptions = requestOptions
170+
)
171+
}
172+
173+
override def options(
174+
requestOptions: RequestOptions
175+
): ClearDictionaryDefinition =
176+
copy(requestOptions = Some(requestOptions))
177+
}
178+
179+
case class SearchDictionaryDefinition[A <: DictionaryEntry](
180+
dictionary: Dictionary[A],
181+
query: QueryDictionary = QueryDictionary(),
182+
requestOptions: Option[RequestOptions] = None
183+
)(implicit val formats: Formats)
184+
extends Definition {
185+
186+
override type T = SearchDictionaryDefinition[A]
187+
188+
def query(q: QueryDictionary): SearchDictionaryDefinition[A] = copy(query = q)
189+
190+
override private[algolia] def build() = {
191+
HttpPayload(
192+
POST,
193+
Seq("1", "dictionaries", dictionary.name, "search"),
194+
body = Some(write(query)),
195+
isSearch = true,
196+
requestOptions = requestOptions
197+
)
198+
}
199+
200+
override def options(
201+
requestOptions: RequestOptions
202+
): SearchDictionaryDefinition[A] = copy(requestOptions = Some(requestOptions))
203+
}
204+
205+
case class SetSettingsDictionaryDefinition(
206+
dictionarySettings: DictionarySettings,
207+
requestOptions: Option[RequestOptions] = None
208+
)(implicit val formats: Formats)
209+
extends Definition {
210+
override type T = SetSettingsDictionaryDefinition
211+
212+
override private[algolia] def build() = {
213+
HttpPayload(
214+
PUT,
215+
Seq("1", "dictionaries", "*", "settings"),
216+
body = Some(write(dictionarySettings)),
217+
isSearch = false,
218+
requestOptions = requestOptions
219+
)
220+
}
221+
222+
override def options(
223+
requestOptions: RequestOptions
224+
): SetSettingsDictionaryDefinition =
225+
copy(requestOptions = Some(requestOptions))
226+
}
227+
228+
case class GetSettingsDictionaryDefinition(
229+
requestOptions: Option[RequestOptions] = None
230+
)(implicit val formats: Formats)
231+
extends Definition {
232+
override type T = GetSettingsDictionaryDefinition
233+
234+
override private[algolia] def build() = {
235+
HttpPayload(
236+
GET,
237+
Seq("1", "dictionaries", "*", "settings"),
238+
isSearch = false,
239+
requestOptions = requestOptions
240+
)
241+
}
242+
243+
override def options(
244+
requestOptions: RequestOptions
245+
): GetSettingsDictionaryDefinition =
246+
copy(requestOptions = Some(requestOptions))
247+
}

src/main/scala/algolia/definitions/TaskStatusDefinition.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,26 @@ case class TaskStatusDefinition(
5151
}
5252

5353
}
54+
55+
case class AppTaskStatusDefinition(
56+
taskId: Long,
57+
requestOptions: Option[RequestOptions] = None
58+
) extends Definition {
59+
60+
type T = AppTaskStatusDefinition
61+
62+
override def options(
63+
requestOptions: RequestOptions
64+
): AppTaskStatusDefinition =
65+
copy(requestOptions = Some(requestOptions))
66+
67+
override private[algolia] def build(): HttpPayload = {
68+
HttpPayload(
69+
GET,
70+
Seq("1", "task", taskId.toString),
71+
isSearch = true,
72+
requestOptions = requestOptions
73+
)
74+
}
75+
76+
}

src/main/scala/algolia/definitions/WaitForTaskDefinition.scala

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,32 @@ package algolia.definitions
2828
import algolia.http.HttpPayload
2929
import algolia.objects.RequestOptions
3030

31+
sealed trait TaskDefinition extends Definition {
32+
val taskId: Long
33+
val baseDelay: Long
34+
val maxDelay: Long
35+
val requestOptions: Option[RequestOptions]
36+
def baseDelay(delay: Long): TaskDefinition
37+
def maxDelay(delay: Long): TaskDefinition
38+
}
39+
3140
case class WaitForTaskDefinition(
32-
taskId: Long,
41+
override val taskId: Long,
3342
index: Option[String] = None,
34-
baseDelay: Long = 100,
35-
maxDelay: Long = Long.MaxValue,
36-
requestOptions: Option[RequestOptions] = None
37-
) extends Definition {
43+
override val baseDelay: Long = 100,
44+
override val maxDelay: Long = Long.MaxValue,
45+
override val requestOptions: Option[RequestOptions] = None
46+
) extends TaskDefinition {
3847

39-
type T = WaitForTaskDefinition
48+
override type T = WaitForTaskDefinition
4049

4150
def from(index: String): WaitForTaskDefinition = copy(index = Some(index))
4251

43-
def baseDelay(delay: Long): WaitForTaskDefinition = copy(baseDelay = delay)
52+
override def baseDelay(delay: Long): WaitForTaskDefinition =
53+
copy(baseDelay = delay)
4454

45-
def maxDelay(delay: Long): WaitForTaskDefinition = copy(maxDelay = delay)
55+
override def maxDelay(delay: Long): WaitForTaskDefinition =
56+
copy(maxDelay = delay)
4657

4758
override def options(requestOptions: RequestOptions): WaitForTaskDefinition =
4859
copy(requestOptions = Some(requestOptions))
@@ -52,4 +63,29 @@ case class WaitForTaskDefinition(
5263

5364
}
5465

66+
case class WaitForAppTaskDefinition(
67+
override val taskId: Long,
68+
override val baseDelay: Long = 100,
69+
override val maxDelay: Long = Long.MaxValue,
70+
override val requestOptions: Option[RequestOptions] = None
71+
) extends TaskDefinition {
72+
73+
type T = WaitForAppTaskDefinition
74+
75+
override def baseDelay(delay: Long): WaitForAppTaskDefinition =
76+
copy(baseDelay = delay)
77+
78+
override def maxDelay(delay: Long): WaitForAppTaskDefinition =
79+
copy(maxDelay = delay)
80+
81+
override def options(
82+
requestOptions: RequestOptions
83+
): WaitForAppTaskDefinition =
84+
copy(requestOptions = Some(requestOptions))
85+
86+
override private[algolia] def build(): HttpPayload =
87+
AppTaskStatusDefinition(taskId).build()
88+
89+
}
90+
5591
case class WaitForTimeoutException(message: String) extends Exception(message)

0 commit comments

Comments
 (0)