-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It's handy to be able to drop in a faster JSON library, such as Jsonrs, for use cases with very large requests and responses, as JSON encoding and decoding time is greatly reduced.
- Loading branch information
Showing
12 changed files
with
193 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,123 +1,143 @@ | ||
defmodule Snap.Bulk.Action do | ||
@moduledoc false | ||
@callback to_action_json(struct()) :: map() | ||
@callback to_document_json(struct()) :: map() | nil | ||
end | ||
|
||
defmodule Snap.Bulk.Action.Create do | ||
@moduledoc """ | ||
Represents a create step in a `Snap.Bulk` operation | ||
""" | ||
@behaviour Snap.Bulk.Action | ||
|
||
@enforce_keys [:doc] | ||
defstruct [:_index, :_id, :require_alias, :doc] | ||
defstruct [:index, :id, :require_alias, :doc] | ||
|
||
@type t :: %__MODULE__{ | ||
_index: String.t() | nil, | ||
_id: String.t() | nil, | ||
index: String.t() | nil, | ||
id: String.t() | nil, | ||
require_alias: boolean() | nil, | ||
doc: map() | ||
} | ||
|
||
@doc false | ||
def to_action_json(%__MODULE__{index: index, id: id, require_alias: require_alias}) do | ||
values = %{_index: index, _id: id, require_alias: require_alias} | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> Enum.into(%{}) | ||
|> then(fn values -> %{"create" => values} end) | ||
end | ||
|
||
@doc false | ||
def to_document_json(%__MODULE__{doc: doc}) do | ||
doc | ||
end | ||
end | ||
|
||
defmodule Snap.Bulk.Action.Delete do | ||
@moduledoc """ | ||
Represents a delete step in a `Snap.Bulk` operation | ||
""" | ||
@enforce_keys [:_id] | ||
defstruct [:_index, :_id, :require_alias] | ||
@behaviour Snap.Bulk.Action | ||
|
||
@enforce_keys [:id] | ||
defstruct [:index, :id, :require_alias] | ||
|
||
@type t :: %__MODULE__{ | ||
_index: String.t() | nil, | ||
_id: String.t(), | ||
index: String.t() | nil, | ||
id: String.t(), | ||
require_alias: boolean() | nil | ||
} | ||
|
||
@doc false | ||
def to_action_json(%__MODULE__{index: index, id: id, require_alias: require_alias}) do | ||
values = %{_index: index, _id: id, require_alias: require_alias} | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> Enum.into(%{}) | ||
|> then(fn values -> %{"delete" => values} end) | ||
end | ||
|
||
@doc false | ||
def to_document_json(_), do: nil | ||
end | ||
|
||
defmodule Snap.Bulk.Action.Index do | ||
@moduledoc """ | ||
Represents an index step in a `Snap.Bulk` operation | ||
""" | ||
@behaviour Snap.Bulk.Action | ||
|
||
@enforce_keys [:doc] | ||
defstruct [:_index, :_id, :require_alias, :doc] | ||
defstruct [:index, :id, :require_alias, :doc] | ||
|
||
@type t :: %__MODULE__{ | ||
_index: String.t() | nil, | ||
_id: String.t() | nil, | ||
index: String.t() | nil, | ||
id: String.t() | nil, | ||
require_alias: boolean() | nil, | ||
doc: map() | ||
} | ||
|
||
@doc false | ||
def to_action_json(%__MODULE__{index: index, id: id, require_alias: require_alias}) do | ||
values = %{_index: index, _id: id, require_alias: require_alias} | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> Enum.into(%{}) | ||
|> then(fn values -> %{"index" => values} end) | ||
end | ||
|
||
@doc false | ||
def to_document_json(%__MODULE__{doc: doc}) do | ||
doc | ||
end | ||
end | ||
|
||
defmodule Snap.Bulk.Action.Update do | ||
@moduledoc """ | ||
Represents an update step in a `Snap.Bulk` operation | ||
""" | ||
@behaviour Snap.Bulk.Action | ||
|
||
@enforce_keys [:doc] | ||
defstruct [ | ||
:_id, | ||
:_index, | ||
:_source, | ||
:id, | ||
:index, | ||
:require_alias, | ||
:doc, | ||
:doc_as_upsert, | ||
:require_alias, | ||
:script, | ||
:upsert | ||
:script | ||
] | ||
|
||
@type t :: %__MODULE__{ | ||
_id: String.t() | nil, | ||
_index: String.t() | nil, | ||
_source: boolean() | nil, | ||
id: String.t() | nil, | ||
index: String.t() | nil, | ||
require_alias: boolean() | nil, | ||
doc: map(), | ||
doc_as_upsert: boolean() | nil, | ||
require_alias: boolean() | nil, | ||
script: map() | nil, | ||
upsert: map() | nil | ||
script: map() | nil | ||
} | ||
end | ||
|
||
defimpl Jason.Encoder, for: Snap.Bulk.Action.Create do | ||
require Jason.Helpers | ||
|
||
def encode(%Snap.Bulk.Action.Create{_index: index, _id: id, require_alias: require_alias}, opts) do | ||
values = [_index: index, _id: id, require_alias: require_alias] | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> then(fn values -> %{"create" => Jason.OrderedObject.new(values)} end) | ||
|> Jason.Encode.map(opts) | ||
end | ||
end | ||
|
||
defimpl Jason.Encoder, for: Snap.Bulk.Action.Delete do | ||
require Jason.Helpers | ||
|
||
def encode(%Snap.Bulk.Action.Delete{_index: index, _id: id, require_alias: require_alias}, opts) do | ||
values = [_index: index, _id: id, require_alias: require_alias] | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> then(fn values -> %{"delete" => Jason.OrderedObject.new(values)} end) | ||
|> Jason.Encode.map(opts) | ||
end | ||
end | ||
|
||
defimpl Jason.Encoder, for: Snap.Bulk.Action.Update do | ||
require Jason.Helpers | ||
|
||
def encode(%Snap.Bulk.Action.Update{_index: index, _id: id, require_alias: require_alias}, opts) do | ||
values = [_index: index, _id: id, require_alias: require_alias] | ||
@doc false | ||
def to_action_json(%__MODULE__{index: index, id: id, require_alias: require_alias}) do | ||
values = %{_index: index, _id: id, require_alias: require_alias} | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> then(fn values -> %{"update" => Jason.OrderedObject.new(values)} end) | ||
|> Jason.Encode.map(opts) | ||
|> Enum.into(%{}) | ||
|> then(fn values -> %{"update" => values} end) | ||
end | ||
end | ||
|
||
defimpl Jason.Encoder, for: Snap.Bulk.Action.Index do | ||
require Jason.Helpers | ||
|
||
def encode(%Snap.Bulk.Action.Index{_index: index, _id: id, require_alias: require_alias}, opts) do | ||
values = [_index: index, _id: id, require_alias: require_alias] | ||
@doc false | ||
def to_document_json(%__MODULE__{doc: doc, doc_as_upsert: doc_as_upsert, script: script}) do | ||
values = %{doc: doc, doc_as_upsert: doc_as_upsert, script: script} | ||
|
||
values | ||
|> Enum.reject(&is_nil(elem(&1, 1))) | ||
|> then(fn values -> %{"index" => Jason.OrderedObject.new(values)} end) | ||
|> Jason.Encode.map(opts) | ||
|> Enum.into(%{}) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,35 @@ | ||
defmodule Snap.Bulk.Actions do | ||
@moduledoc false | ||
|
||
alias Snap.Bulk.Action.{Create, Index, Update, Delete} | ||
|
||
@doc """ | ||
Encodes a list of bulk action structs into line separated JSON for feeding to the | ||
/_bulk endpoint. | ||
""" | ||
def encode(actions) do | ||
encode_actions([], actions) | ||
def encode(actions, json_library \\ Jason) do | ||
encode_actions([], actions, json_library) | ||
end | ||
|
||
defp encode_actions(iolist, []) do | ||
defp encode_actions(iolist, [], _json_library) do | ||
iolist | ||
end | ||
|
||
defp encode_actions(iolist, [head | tail]) do | ||
updated_iolist = [iolist, encode_action(head)] | ||
encode_actions(updated_iolist, tail) | ||
end | ||
|
||
defp encode_action(%type{} = action) when type in [Create, Index] do | ||
doc = action.doc | ||
|
||
doc_json = | ||
doc | ||
|> Jason.encode!() | ||
|
||
action_json = encode_action_command(action) | ||
|
||
[action_json, "\n", doc_json, "\n"] | ||
defp encode_actions(iolist, [head | tail], json_library) do | ||
updated_iolist = [iolist, encode_action(head, json_library)] | ||
encode_actions(updated_iolist, tail, json_library) | ||
end | ||
|
||
defp encode_action(%Delete{} = action) do | ||
action_json = encode_action_command(action) | ||
|
||
[action_json, "\n"] | ||
end | ||
|
||
defp encode_action(%Update{} = action) do | ||
doc = action.doc | ||
|
||
doc_json = | ||
%{doc: doc} | ||
|> Jason.encode!() | ||
|
||
action_json = encode_action_command(action) | ||
defp encode_action(%type{} = action, json_library) do | ||
action_json = type.to_action_json(action) | ||
doc_json = type.to_document_json(action) | ||
|
||
[action_json, "\n", doc_json, "\n"] | ||
if doc_json do | ||
[encode_json(action_json, json_library), "\n", encode_json(doc_json, json_library), "\n"] | ||
else | ||
[encode_json(action_json, json_library), "\n"] | ||
end | ||
end | ||
|
||
defp encode_action_command(action) do | ||
Jason.encode!(action) | ||
defp encode_json(json, json_library) do | ||
json_library.encode!(json) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.