Current section
16 Versions
Jump to
Current section
16 Versions
Compare versions
15
files changed
+381
additions
-169
deletions
| @@ -130,7 +130,7 @@ The package can be installed as: | |
| 130 130 | |
| 131 131 | ```elixir |
| 132 132 | def deps do |
| 133 | - [{:xarango, "~> 0.5.7"}] |
| 133 | + [{:xarango, "~> 0.6.0"}] |
| 134 134 | end |
| 135 135 | ``` |
| @@ -28,4 +28,4 @@ | |
| 28 28 | {<<"name">>,<<"httpoison">>}, |
| 29 29 | {<<"optional">>,false}, |
| 30 30 | {<<"requirement">>,<<"> 0.0.0">>}]]}. |
| 31 | - {<<"version">>,<<"0.5.7">>}. |
| 31 | + {<<"version">>,<<"0.6.0">>}. |
| @@ -1,31 +1,74 @@ | |
| 1 1 | defmodule Xarango.AQL do |
| 2 2 | |
| 3 | - defstruct [:collection, :filters, :sort, :limit, :skip] |
| 3 | + defstruct [:graph, :collection, :filters, :sort, :limit, :skip, :for, :options, :return] |
| 4 4 | |
| 5 5 | def from(collection) do |
| 6 | - %Xarango.AQL{collection: collection, filters: []} |
| 6 | + collection = collection_name(collection) |
| 7 | + %Xarango.AQL{filters: [], collection: collection, for: "FOR x IN #{collection}", return: "RETURN x"} |
| 7 8 | end |
| 8 9 | |
| 10 | + def any(%{vertex: %{_id: node_id}}, relation) do |
| 11 | + %Xarango.AQL{filters: [], for: "FOR x IN ANY '#{node_id}' #{relation}", return: "RETURN x"} |
| 12 | + end |
| 13 | + def any(%{vertex: %{_id: from_id}}, relation, %{vertex: %{_id: to_id}}) do |
| 14 | + %Xarango.AQL{filters: [], for: "FOR x, y IN ANY SHORTEST_PATH '#{from_id}' TO '#{to_id}' #{relation}", return: "RETURN [x, y]"} |
| 15 | + end |
| 16 | + def outbound(%{vertex: %{_id: node_id}}, relation) do |
| 17 | + outbound(%{id: node_id}, relation) |
| 18 | + end |
| 19 | + def outbound(%{id: node_id}, relation) do |
| 20 | + %Xarango.AQL{filters: [], for: "FOR x IN OUTBOUND '#{node_id}' #{relation}", return: "RETURN x"} |
| 21 | + end |
| 22 | + def outbound(%{vertex: %{_id: from_id}}, relation, %{vertex: %{_id: to_id}}) do |
| 23 | + %Xarango.AQL{filters: [], for: "FOR x, y IN OUTBOUND SHORTEST_PATH '#{from_id}' TO '#{to_id}' #{relation}", return: "RETURN [x, y]"} |
| 24 | + end |
| 25 | + def inbound(%{vertex: %{_id: node_id}}, relation) do |
| 26 | + inbound(%{id: node_id}, relation) |
| 27 | + end |
| 28 | + def inbound(%{id: node_id}, relation) do |
| 29 | + %Xarango.AQL{filters: [], for: "FOR x IN INBOUND '#{node_id}' #{relation}", return: "RETURN x"} |
| 30 | + end |
| 31 | + def inbound(%{vertex: %{_id: from_id}}, relation, %{vertex: %{_id: to_id}}) do |
| 32 | + %Xarango.AQL{filters: [], for: "FOR x, y IN INBOUND SHORTEST_PATH '#{from_id}' TO '#{to_id}' #{relation}", return: "RETURN [x, y]"} |
| 33 | + end |
| 34 | + |
| 35 | + |
| 36 | + |
| 9 37 | def filter(aql, filters) do |
| 10 | - %Xarango.AQL{aql | filters: add_filters(aql, filters) } |
| 38 | + %Xarango.AQL{aql | filters: parse_filters(aql, filters) } |
| 11 39 | end |
| 12 40 | defdelegate where(aql, filters), to: __MODULE__, as: :filter |
| 13 41 | |
| 14 42 | def sort(aql, sort, dir\\:asc) do |
| 15 | - %Xarango.AQL{aql | sort: add_sort(aql, sort, dir) } |
| 43 | + %Xarango.AQL{aql | sort: parse_sort(aql, sort, dir) } |
| 16 44 | end |
| 17 45 | |
| 18 46 | def limit(aql, limit, skip\\nil) do |
| 19 | - %Xarango.AQL{aql | limit: add_limit(aql, limit, skip) } |
| 47 | + %Xarango.AQL{aql | limit: parse_limit(aql, limit, skip) } |
| 48 | + end |
| 49 | + |
| 50 | + def options(aql, options) do |
| 51 | + %Xarango.AQL{aql | options: parse_options(aql, options) } |
| 52 | + end |
| 53 | + |
| 54 | + def graph(aql, graph) do |
| 55 | + %Xarango.AQL{aql | graph: parse_graph(aql, graph) } |
| 56 | + end |
| 57 | + |
| 58 | + def fulltext(aql, field, value) do |
| 59 | + %Xarango.AQL{aql | for: parse_fulltext(aql, field, value)} |
| 20 60 | end |
| 21 61 | |
| 22 62 | def to_aql(aql) do |
| 23 | - ["FOR r IN #{aql.collection.name}"] |
| 63 | + [aql.for] |
| 64 | + |> add_to_query(aql.graph) |
| 24 65 | |> add_to_query(aql.filters) |
| 25 66 | |> add_to_query(aql.sort) |
| 67 | + |> add_to_query(aql.options) |
| 26 68 | |> add_to_query(aql.limit) |
| 27 | - |> Kernel.++(["RETURN r"]) |
| 69 | + |> Kernel.++([aql.return]) |
| 28 70 | |> Enum.join(" ") |
| 71 | + |> String.replace("\"", "'") |
| 29 72 | end |
| 30 73 | |
| 31 74 | defp add_to_query(query, nil), do: query |
| @@ -33,38 +76,57 @@ defmodule Xarango.AQL do | |
| 33 76 | query ++ items |
| 34 77 | end |
| 35 78 | |
| 36 | - defp add_filters(aql, filters) do |
| 79 | + defp parse_filters(aql, filters) do |
| 37 80 | filters |
| 38 81 | |> Enum.reduce(aql.filters, fn {key, value}, f -> f ++ [to_filter(key, value)] end) |
| 39 82 | end |
| 40 83 | defp to_filter(key, value) when is_binary(value) do |
| 41 | - "FILTER r.#{key} == \"#{value}\"" |
| 84 | + "FILTER x.#{key} == '#{value}'" |
| 42 85 | end |
| 43 86 | defp to_filter(key, value) do |
| 44 | - "FILTER r.#{key} == #{value}" |
| 87 | + "FILTER x.#{key} == #{value}" |
| 45 88 | end |
| 46 89 | |
| 47 | - defp add_sort(_aql, sort, dir) when is_list(sort) do |
| 90 | + defp parse_sort(_aql, sort, dir) when is_list(sort) do |
| 48 91 | dir = Atom.to_string(dir) |> String.upcase |
| 49 | - sort = Enum.map(sort, fn s -> "r.#{s}" end) |> Enum.join(", ") |
| 92 | + sort = Enum.map(sort, fn s -> "x.#{s}" end) |> Enum.join(", ") |
| 50 93 | ["SORT #{sort} #{dir}"] |
| 51 94 | end |
| 52 | - defp add_sort(_aql, sort, dir) do |
| 95 | + defp parse_sort(_aql, sort, dir) do |
| 53 96 | dir = Atom.to_string(dir) |> String.upcase |
| 54 | - ["SORT r.#{sort} #{dir}"] |
| 97 | + ["SORT x.#{sort} #{dir}"] |
| 55 98 | end |
| 56 99 | |
| 57 | - defp add_limit(_aql, limit, nil) do |
| 100 | + def parse_options(_aql, options) do |
| 101 | + options = options |> Enum.into(%{}) |> Xarango.Util.to_javascript |
| 102 | + ["OPTIONS #{options}"] |
| 103 | + end |
| 104 | + |
| 105 | + defp parse_limit(_aql, limit, nil) do |
| 58 106 | ["LIMIT #{limit}"] |
| 59 107 | end |
| 60 | - defp add_limit(_aql, limit, skip) do |
| 108 | + defp parse_limit(_aql, limit, skip) do |
| 61 109 | ["LIMIT #{skip}, #{limit}"] |
| 62 110 | end |
| 63 111 | |
| 112 | + defp parse_graph(_aql, graph) do |
| 113 | + graph_name = case graph do |
| 114 | + %{name: name} -> name |
| 115 | + name -> name |
| 116 | + end |
| 117 | + ["GRAPH '#{graph_name}'"] |
| 118 | + end |
| 64 119 | |
| 120 | + defp parse_fulltext(aql, field, value, type\\"prefix:") do |
| 121 | + "FOR x IN FULLTEXT(#{aql.collection}, '#{field}', '#{type}#{value}')" |
| 122 | + end |
| 65 123 | |
| 66 | - |
| 67 | - |
| 68 | - |
| 124 | + defp collection_name(collection) do |
| 125 | + case collection do |
| 126 | + %{name: name} -> name |
| 127 | + %{collection: name} -> name |
| 128 | + name when is_binary(name) -> name |
| 129 | + end |
| 130 | + end |
| 69 131 | |
| 70 132 | end |
| \ No newline at end of file |
| @@ -15,37 +15,37 @@ defmodule Xarango.Collection do | |
| 15 15 | end |
| 16 16 | |
| 17 17 | def collection(collection, database\\nil) do |
| 18 | - url(collection.name, database) |
| 18 | + url(name(collection), database) |
| 19 19 | |> get |
| 20 20 | |> to_collection |
| 21 21 | end |
| 22 22 | |
| 23 23 | def properties(collection, database\\nil) do |
| 24 | - url("#{collection.name}/properties", database) |
| 24 | + url("#{name(collection)}/properties", database) |
| 25 25 | |> get |
| 26 26 | |> to_collection |
| 27 27 | end |
| 28 28 | |
| 29 29 | def count(collection, database\\nil) do |
| 30 | - url("#{collection.name}/count", database) |
| 30 | + url("#{name(collection)}/count", database) |
| 31 31 | |> get |
| 32 32 | |> to_collection |
| 33 33 | end |
| 34 34 | |
| 35 35 | def figures(collection, database\\nil) do |
| 36 | - url("#{collection.name}/figures", database) |
| 36 | + url("#{name(collection)}/figures", database) |
| 37 37 | |> get |
| 38 38 | |> to_collection |
| 39 39 | end |
| 40 40 | |
| 41 41 | def revision(collection, database\\nil) do |
| 42 | - url("#{collection.name}/revision", database) |
| 42 | + url("#{name(collection)}/revision", database) |
| 43 43 | |> get |
| 44 44 | |> to_collection |
| 45 45 | end |
| 46 46 | |
| 47 47 | def checksum(collection, database\\nil) do |
| 48 | - url("#{collection.name}/checksum", database) |
| 48 | + url("#{name(collection)}/checksum", database) |
| 49 49 | |> get |
| 50 50 | |> to_collection |
| 51 51 | end |
| @@ -57,22 +57,25 @@ defmodule Xarango.Collection do | |
| 57 57 | end |
| 58 58 | |
| 59 59 | def destroy(collection, database\\nil) do |
| 60 | - url(collection.name, database) |
| 60 | + url(name(collection), database) |
| 61 61 | |> delete |
| 62 62 | end |
| 63 | - |
| 63 | + |
| 64 64 | def ensure(collection, database\\nil, indexes\\[]) do |
| 65 65 | try do |
| 66 66 | collection(collection, database) |
| 67 67 | rescue |
| 68 68 | Xarango.Error -> |
| 69 | - create(collection, database) |
| 70 | - Enum.each indexes, fn index -> |
| 71 | - Index.create(index, collection.name, database) |
| 72 | - end |
| 69 | + collection = create(collection, database) |
| 70 | + Enum.each(indexes, &Index.create(&1, name(collection), database)) |
| 71 | + collection |
| 73 72 | end |
| 74 73 | end |
| 75 74 | |
| 75 | + defp name(%{name: name}), do: name |
| 76 | + defp name(%{collection: name}), do: name |
| 77 | + defp name(name) when is_binary(name), do: name |
| 78 | + |
| 76 79 | def __destroy_all(database\\nil) do |
| 77 80 | collections(database) |
| 78 81 | |> Enum.reject(&Map.get(&1, :isSystem)) |
| @@ -26,6 +26,14 @@ defmodule Xarango.Domain.Document do | |
| 26 26 | SimpleQuery.first_example(%SimpleQuery{example: params, collection: _collection().name}, _database()) |
| 27 27 | |> to_document |
| 28 28 | end |
| 29 | + def one?(params) do |
| 30 | + try do |
| 31 | + one(params) |
| 32 | + rescue |
| 33 | + Xarango.Error -> nil |
| 34 | + error -> raise error |
| 35 | + end |
| 36 | + end |
| 29 37 | def list(params, options\\[]) do |
| 30 38 | case options[:cursor] do |
| 31 39 | cursor when is_binary(cursor) -> |
Loading more files…