Adding Walkers

Custom traversal and query execution for new data models

=begin rakudoc

Overview

Walkers define how a Qwiratry query is executed against a data model.

Use this extension point when the new thing changes how data is traversed: trees, tables, graphs, logic databases, document stores, or any structure whose query execution rules need a custom traversal model.

If the data is still an ordinary tree for query purposes and only the node object shape is new, add a Tree Navigator instead. A navigator teaches the generic tree walker how to find children, parents, and attributes. A walker changes traversal or query execution semantics.

To add support for a new walker:

  • 1. Setup: choose the data model, supported query shapes, and advertised capabilities.

  • 2. Walker: implement Qwiratry::Walker for the data model.

  • 3. Plan: implement Qwiratry::Walker::Plan for reusable execution state.

  • 4. Iterator: return a QueryIterator that outputs matching elements lazily.

  • 5. Discovery/Handover: add metadata and capabilities if the walker should be selected automatically.

  • 6. Testing: test planning, iteration, unsupported queries, and strategy integration.

Setup

Decide what data model the walker supports and which query operators it can interpret. Define the capability metadata that tells Qwiratry and extenders what the walker can do.

Before adding a walker for a tree-shaped model, check whether a Qwiratry::Tree::Navigator::Base is enough. Custom XML nodes, compiler AST nodes, or other document-like objects usually need a navigator unless they also need non-standard traversal or query planning.

If the walker should be discovered automatically, decide what domain metadata callers will attach through Qwiratry::Walker::Providing.

Walker

Required Walker Shape

A concrete walker does Qwiratry::Walker and implements at least plan and iterator.

use Qwiratry::Walker;
use Qwiratry::QueryIterator;

class MyWalker does Qwiratry::Walker {
    method plan(Mu $query, Mu:D $root --> Qwiratry::Walker::Plan) {
        MyPlan.new(:$query, :$root)
    }

    method iterator(Qwiratry::Walker::Plan $plan --> QueryIterator) {
        $plan.iterator
    }
}

Plan

Required Plan Shape

A plan does Qwiratry::Walker::Plan and provides an iterator, the original query, and a human-readable description.

class MyPlan does Qwiratry::Walker::Plan {
    has Mu $.query;
    has Mu $.root;

    method iterator(--> QueryIterator) {
        MyIterator.new(:plan(self))
    }

    method query(--> Mu) {
        $!query
    }

    method describe(--> Str) {
        "MyPlan"
    }
}

Iterator

The plan's iterator method should return a QueryIterator. The iterator is responsible for outputting results lazily and keeping traversal state isolated from other iterators created from the same plan.

Use a context object that does Qwiratry::Context::Context when traversal needs mutable state or strategy integration.

Discovery/Handover

Use Qwiratry::Walker::Providing and capabilities when a walker should be selected automatically or when a master walker should hand part of a query to another domain.

Qwiratry::Walker::Providing.instance.bind-domains($data, <tree>);

Testing

Add tests that prove:

  • The walker creates a plan for supported query shapes.

  • The plan returns an independent iterator each time.

  • The iterator outputs expected matches lazily.

  • Unsupported query elements throw X::Qwiratry::UnknownQueryElement.

  • Discovery metadata selects the walker when expected.

  • Strategies receive hook calls during traversal.

Reference Material

Main Types

  • Qwiratry::Walker

Role implemented by concrete walkers. A walker turns a query and a root value into a reusable plan, then turns that plan into an iterator.

  • Qwiratry::Walker::Plan

Role implemented by execution plans. Plans store the query, root, and any precomputed strategy needed to produce iterators.

  • Qwiratry::QueryIterator::QueryIterator

Role for lazy result streams produced by walker plans.

  • Qwiratry::Context::Context

Role for per-traversal mutable state shared by walkers, iterators, and strategies.

  • Qwiratry::QueryMatch::QueryMatch

Match object used when a strategy is told that an element matched a query.

  • Qwiratry::Walker::Capabilities

Shared capability metadata for walkers and plans.

  • Qwiratry::Walker::Factory

Discovery service for choosing a walker for data.

  • Qwiratry::Walker::Providing

Registry for domain and schema metadata used by walker discovery and handover.

Errors

  • X::Qwiratry::Walker

Base exception for walker-related failures.

  • X::Qwiratry::UnknownQueryElement

Throw when the walker cannot interpret a query element.

  • X::Qwiratry::NoWalkerFound

Thrown when discovery cannot find a suitable walker.

=end rakudoc

Qwiratry v0.0.9

Declarative query and data-walking architecture for Raku, with transformers, molds, walkers, and I/O pipelines.

Authors

  • Tim Nelson

License

Dependencies

SlangifyImplementation::Loader:ver<0.0.9+>Glob::Grammar

Test Dependencies

Provides

  • Qwiratry
  • Qwiratry::Context
  • Qwiratry::Format
  • Qwiratry::Format::Base
  • Qwiratry::Format::CSVdemo
  • Qwiratry::Format::JSONdemo
  • Qwiratry::Location
  • Qwiratry::Location::Base
  • Qwiratry::Location::File
  • Qwiratry::Mold
  • Qwiratry::Mold::Compiler
  • Qwiratry::Mold::Registry
  • Qwiratry::Mold::Slang
  • Qwiratry::Operator::Capability
  • Qwiratry::Operator::IO
  • Qwiratry::Operator::MapReduce
  • Qwiratry::Operator::Navigation
  • Qwiratry::Operator::Set
  • Qwiratry::Query::Evaluator::Eager
  • Qwiratry::Query::Evaluator::Filter
  • Qwiratry::Query::Evaluator::Join
  • Qwiratry::Query::Evaluator::Lazy
  • Qwiratry::Query::Evaluator::MapReduce
  • Qwiratry::Query::Evaluator::Navigation
  • Qwiratry::Query::Evaluator::Relational
  • Qwiratry::Query::Evaluator::Row
  • Qwiratry::Query::Evaluator::Set
  • Qwiratry::Query::Evaluator::Union
  • Qwiratry::Query::Extract
  • Qwiratry::Query::NamedJoins
  • Qwiratry::Query::RelationCommon
  • Qwiratry::Query::Runtime
  • Qwiratry::Query::Selector
  • Qwiratry::Query::Slang
  • Qwiratry::Query::Specificity
  • Qwiratry::Query::Topic
  • Qwiratry::QueryIterator
  • Qwiratry::QueryMatch
  • Qwiratry::Setup
  • Qwiratry::Strategy
  • Qwiratry::Strategy::ControlSignal
  • Qwiratry::Strategy::FinishResult
  • Qwiratry::Strategy::RewriteSpec
  • Qwiratry::Strategy::Traversal
  • Qwiratry::Suggest
  • Qwiratry::Table
  • Qwiratry::Table::Schema
  • Qwiratry::Transformer
  • Qwiratry::Transformer::Copy
  • Qwiratry::Transformer::TreeRewrite
  • Qwiratry::Tree::Navigator
  • Qwiratry::Tree::Navigator::Base
  • Qwiratry::Tree::Navigator::Filesystem
  • Qwiratry::Tree::Navigator::Match
  • Qwiratry::Tree::Navigator::RakuAST
  • Qwiratry::Tree::Replace
  • Qwiratry::Walker
  • Qwiratry::Walker::Capabilities
  • Qwiratry::Walker::Factory
  • Qwiratry::Walker::Implementation::Table
  • Qwiratry::Walker::Implementation::Tree
  • Qwiratry::Walker::Master
  • Qwiratry::Walker::Providing
  • X::Qwiratry

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.