Skip to content

A Golang library for planning queries in a structured order

License

Notifications You must be signed in to change notification settings

arquivei/queryplanner

Repository files navigation

QueryPlanner

A Golang library for planning queries in a structured order


Table of Contents

QueryPlanner is a generic library that aims to provide a framework for structuring queries that might need to reach different services or go through different steps to enrich a response. The library provides a way of describing the query's steps(IndexProviders/FieldProviders) and it's dependencies.

Stack Version
Golang v1.21
golangci-lint v1.46.2
    • Any Golang programming language version installed, preferred 1.21 or later.
  • go get -u github.com/arquivei/queryplanner
    
  • go mod vendor
    go mod tidy
    
    • Import the package

      import (
          "github.com/arquivei/queryplanner"
      )
    • Define a request struct that implements queryplanner.Request interface

        type Request struct {
        	Fields []string
        }
        
        func (r *Request) GetRequestedFields() []string {
        	return r.Fields
        }
      • This struct will be passed to all your providers and can be used to pass information such as pagination and filters.
    • Define a struct to be filled by your providers

      type Person struct {
      	Name      *string 
      	FirstName *string
      }
    • Define a provider that implements the queryplanner.IndexProvider interface

      type indexProvider struct {}
      
      func (p *indexProvider) Provides() []queryplanner.Index {
          return []queryplanner.Index{
      		{
      			Name: "Name",
      			Clear: func(d queryplanner.Document) {
      				doc, _ := d.(*Person)
      				doc.Name = nil
      			},
      	    },
          }
      }
      
      func (p *indexProvider) Execute(ctx context.Context, request queryplanner.Request, fields []string) (*queryplanner.Payload, error) {
          return &queryplanner.Payload{
      		Documents: []queryplanner.Document{
      		    &Person{
      		        Name: "Maria Joana",
      		    },
      		},
          }, nil
      }
      • This is the first provider to be executed and it has the responsability of setting the payload documents that will be modified by the other providers.
    • Define a provider that implements the queryplanner.FieldProvider interface

      type fieldProvider struct {}
      
      func (p *fieldProvider) Provides() []queryplanner.Field {
          return []queryplanner.Field{
      		{
      			Name: "Name",
      			Fill: func(index int, ec queryplanner.ExecutionContext) error {
      			    doc := ec.Payload.Documents[i].(*Person)
      			    doc.FirstName = strings.Split(doc.Name, " ")[0]
      			    return nil
      			},
      			Clear: func(d queryplanner.Document) {
      				doc, _ := d.(*Person)
      				doc.Name = nil
      			},
      	    },
          }
      }
      
      func (p *fieldProvider) DependsOn() []queryplanner.FieldName {
      	return []queryplanner.FieldName{
      		"Name",
      	}
      }
      • The field provider must say what fields it depends on to be used and what fields it provides.
    • Finally you can create your queryplanner and make requests to it:

      import (
          "github.com/arquivei/queryplanner"
      )
      
      func main() {
          // Create the planner
          planner, err := queryplanner.NewQueryPlanner(indexProvider{}, fieldProvider{})
      	if err != nil {
      		panic(err)
      	}
      	
      	// Make requests to it
      	payload, err := planner.Plan(Request{ 
      	    Fields: []string{"Name", "FirstName"}
      	}).Execute()
      }
  • For more in-depth examples of how to use the library, check the examples folder.

  • queryplanner 0.1.0 (May 31, 2022)

    • [New] Documents: Code of Conduct, Contributing, License and Readme.
    • [New] Setting github's workflow with golangci-lint
    • [New] Decoupling this package from Arquivei's API projects.

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

We use Semantic Versioning for versioning. For the versions available, see the tags on this repository.

This project is licensed under the BSD 3-Clause - see the LICENSE.md file for details.

All contact may be doing by marcos.filho@arquivei.com.br