msfl_visitors
A visitor pattern based approach for converting MSFL to other forms
Usage
require 'msfl'
# Load one of the test datasets
require 'msfl/datasets/car'
require 'msfl_visitors'
filter = { make: "Toyota" }
dataset = MSFL::Datasets::Car.new
MSFLVisitors.get_chewy_clauses dataset, filter
=> [{:clause=>"make == \"Toyota\""}]
Faceted example
require 'msfl'
# Load one of the test datasets
require 'msfl/datasets/car'
require 'msfl_visitors'
filter = { partial: { given: { make: "Toyota" }, filter: { avg_age: 10 } } }
dataset = MSFL::Datasets::Car.new
MSFLVisitors.get_chewy_clauses dataset, filter
=> [{:clause=>{:agg_field_name=>:avg_age, :operator=>:eq, :test_value=>10}, :method_to_execute=>:aggregations}, {:clause=>"make == \"Toyota\""}]
An example of a Foreign
require 'msfl'
# Load one of the test datasets
require 'msfl/datasets/car'
require 'msfl_visitors'
filter = { foreign: { dataset: 'person', filter: { gender: 'female' } } }
dataset = MSFL::Datasets::Car.new
MSFLVisitors.get_chewy_clauses dataset, filter
=> [{:clause=>"has_child( :person ).filter { gender == \"female\" }"}]
An example in which a Foreign is nested in the Given of a Partial
require 'msfl'
# Load one of the test datasets
require 'msfl/datasets/car'
require 'msfl_visitors'
# Given the set of cars where the person that is the owner is male, filter the set to only include those cars that
# were manufactured in 2010
filter = { partial: { given: { foreign: { dataset: 'person', filter: { gender: 'male' } } }, filter: { year: '2010' } } }
dataset = MSFL::Datasets::Car.new
MSFLVisitors.get_chewy_clauses dataset, filter
=> [{:clause=>{:agg_field_name=>:year, :operator=>:eq, :test_value=>"2010"}, :method_to_execute=>:aggregations},
{:clause=>"has_child( :person ).filter { gender == \"male\" }"}]
Architecture
msfl_visitors is designed to consume normalized Mattermark Semantic Filter Language (NMSFL). msfl_visitors implements a parser (parsers/msfl_parser) that converts NMSFL into an AST. msfl_visitors implements a visitor that traverses the ast and produces the well formed output. The behavior of the visitor is controlled through composition at construction. It accepts a collector and a renderer.
MSFLParser
The parser accepts a Hash containing NMSFL and produces an AST. The parser uses a simplified version of the visitor pattern to traverse the NMSFL and produce the AST.
Typically one does not interact with the parser directly, instead a consumer of this gem should interact with the AST.
AST
The abstract syntax tree that represents a certain query filter. In the version of the visitor pattern herein adopted, each node of the AST is responsible for managing its state and traversal of itself and children.
A consumer of this gem creates a new AST instance passing in a Hash of NMSFL. The AST will leverage the MSFL parser to construct itself. The AST object is a Node as it implements the #accept(visitor) method.
visitor
Unlike the classical visitor pattern double dispatch is not strictly achieved through type matching in the visitor. Instead the visitor is just a single service that is composed of a collector and a renderer. The double dispatch is codified inside of a renderer, which like the visitors in the classic pattern can produce multiple output DSLs.
collector
Removed as of 0.3
renderer
Removed as of 0.3