Last active
November 7, 2017 14:16
-
-
Save Linell/106c2213fb30c14b41a82d9ddb2c7f32 to your computer and use it in GitHub Desktop.
Designed to parse output from https://github.com/ukrbublik/react-awesome-query-builder
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
defmodule Mix.Tasks.Parser do | |
use Mix.Task | |
require IEx | |
@shortdoc "A test of the parser." | |
def run(_args) do | |
Mix.shell.info "Greetings from the parser" | |
# The following tree represents a query that looks like: | |
# (users.enrollment_status == "E" || users.dob == "2017-11-06" || (users.is_member == true && (users.gender == "M" && users.site_id IN ("234siteid")))) | |
tree = Poison.decode!(~s( | |
{ | |
"usedFields":[ | |
"users.enrollment_status", | |
"users.dob", | |
"users.is_member", | |
"users.gender", | |
"users.site_id" | |
], | |
"rules":[ | |
{ | |
"id":"9bab8999-cdef-4012-b456-715f92375987", | |
"field":"users.enrollment_status", | |
"type":"select", | |
"input":"select", | |
"operator":"select_equals", | |
"values":[ | |
{ | |
"type":"select", | |
"value":"E" | |
} | |
] | |
}, | |
{ | |
"id":"aabaa8ab-89ab-4cde-b012-315f92377265", | |
"field":"users.dob", | |
"type":"date", | |
"input":"date", | |
"operator":"equal", | |
"values":[ | |
{ | |
"type":"date", | |
"value":"2017-11-06" | |
} | |
] | |
}, | |
{ | |
"rules":[ | |
{ | |
"id":"9a9b899a-0123-4456-b89a-b15f9237a0de", | |
"field":"users.is_member", | |
"type":"boolean", | |
"input":"boolean", | |
"operator":"equal", | |
"values":[ | |
{ | |
"type":"boolean", | |
"value":true | |
} | |
] | |
}, | |
{ | |
"rules":[ | |
{ | |
"id":"aa98baaa-89ab-4cde-b012-315f9238650b", | |
"field":"users.gender", | |
"type":"select", | |
"input":"select", | |
"operator":"select_equals", | |
"values":[ | |
{ | |
"type":"select", | |
"value":"M" | |
} | |
] | |
}, | |
{ | |
"id":"a9bb8a8b-4567-489a-bcde-f15f92389859", | |
"field":"users.site_id", | |
"type":"select", | |
"input":"select", | |
"operator":"select_any_in", | |
"values":[ | |
{ | |
"type":"multiselect", | |
"value":[ | |
"234siteid" | |
] | |
} | |
] | |
} | |
], | |
"condition":"AND" | |
} | |
], | |
"condition":"AND" | |
} | |
], | |
"condition":"OR" | |
} | |
)) | |
parsed_output = parse(tree) | |
IO.puts parsed_output | |
end | |
def parse(node) do | |
res = Enum.map(Map.get(node, "rules"), &(parse_node/1)) | |
|> Enum.join(" " <> Map.get(node, "condition") <> " ") | |
"(#{res})" | |
end | |
# so every node is a set of tuples -- | |
def parse_node(node) do | |
if (is_top_level_node(node)), do: parse(node), else: sql_from_rule(node) | |
end | |
def is_top_level_node(node) do | |
cond do | |
is_map(node) -> | |
Map.keys(node) |> Enum.member?("condition") | |
true -> # default condition | |
false | |
end | |
end | |
def sql_from_rule(rule) do | |
# IEx.pry | |
field = Map.get(rule, "field") | |
# is there a better way here? | |
value = Map.get(rule, "values") |> List.first |> Map.get("value") | |
# there will be a lot of logic around picking the operator, and | |
# any tips there would be appreciated | |
"#{field} = #{value}" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment