queryparser

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2022 License: MIT Imports: 5 Imported by: 0

README

Query Parser

Query Parser is library to create your own format to parse query values

Installation

go get -u github.com/0B1t322/QueryParser

Fast start and usage

See cmd dir and test for more examples.

package main

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
	"strings"

	"github.com/0B1t322/QueryParser"
	"github.com/0B1t322/QueryParser/typemapper"
)

// Code below show how to parse with recirsive with diffucal user schemas
type FieldOperation struct {
	Op string	`json:"op"`
	Value string `json:"value"`
}

type Root struct {
	Or   []*Root `json:"or,omitempty"`

	And  []*Root `json:"and,omitempty"`

	Name *FieldOperation `json:"name,omitempty"`
}

func (r *Root) NewParser() *queryparser.Parser {
	return queryparser.New(
		typemapper.NewQueryTypeFactory(),
		r.NewParseSchema(),
	)
}

func (r *Root) getOpearationAndField(field string) (op string, cleanField string) {
	regex := regexp.MustCompile(`(?P<field>.*)\[(?P<op>.*)\]`)
	opAt := regex.SubexpIndex("op")
	fieldAt := regex.SubexpIndex("field")
	submatch := regex.FindStringSubmatch(field)

	return submatch[opAt], submatch[fieldAt]
}

func (r *Root) NameParseSchema() queryparser.ParseSchemaItem {
	return queryparser.ParseSchemaItem{
		IsRegex: true,
		TypeMapFunc: func(field string, values []string) (interface{}, error) {
			op, _ := r.getOpearationAndField(field)

			name := values[0]

			r.Name = &FieldOperation{
				Op: op,
				Value: name,
			}

			return nil, nil
		},
	}
}

func (r *Root) OrParseSchema() queryparser.ParseSchemaItem {
	return queryparser.ParseSchemaItem{
		IsRegex: false,
		TypeMapFunc: func(field string, values []string) (interface{}, error) {
			value := values[0]

			for _, value := range strings.Split(value, ",") {
				subRoot := &Root{}
				subParser := subRoot.NewParser()
				subQuery := url.Values{}
				fieldValie := strings.SplitN(value, "=", 2)
				if len(fieldValie) != 2 {
					continue
				}

				subQuery.Add(fieldValie[0], fieldValie[1])
				subParser.ParseUrlValues(subQuery)
				r.Or = append(r.Or, subRoot)
			}

			return nil, nil
		},
	}
}

func (r *Root) NewParseSchema() queryparser.ParseSchema {
	return queryparser.ParseSchema{
		`name\[.*\]`: r.NameParseSchema(),
		"or": r.OrParseSchema(),
	}
}


// Prints:
/*
{
    "or": [
            {
                "name": {
                        "op": "like",
                        "value": "dan*"
                }
            },
            {
                "name": {
                        "op": "lte",
                        "value": "asd"
                }
            }
    ],
    "name": {
        "op": "eq",
        "value": "some_name"
    }
}
*/
func main() {
	r := &Root{}
	url, _ := url.Parse("http://localhost:8080?name[eq]=some_name&or=name[like]=dan*,name[lte]=asd")
	r.NewParser().ParseUrlValues(
		url.Query(),
	)

	data, _ := json.MarshalIndent(r, "", "\t")

	fmt.Println(string(data))
}

Documentation

Overview

Package queryparser provive instrument to parse query in user format

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Factory

type Factory interface {
	MapRegexField(field string, values []string) (interface{}, error)

	MapField(field string, values []string) (interface{}, error)

	ValidateRegexField(field string, values []string) error

	Validate(field string, values []string) error

	AddQueryTypeMapperField(field string, queryType typemapper.QueryTypeMapper)
}

type FinalizeParseFunc

type FinalizeParseFunc func(result ParseResult, field string, value ResultOrError)

type ParseResult

type ParseResult map[string]ResultOrError

type ParseSchema

type ParseSchema map[string]ParseSchemaItem

type ParseSchemaItem

type ParseSchemaItem struct {
	// Func to validate after parse
	ValidationFunc validator.ValidateFunc

	// Func to map type
	TypeMapFunc typemapper.TypeMapperFunc

	// Func to validate field
	ValidateFieldFunc typemapper.ValidateFieldFunc

	// Func to validate values
	ValidateValuesFunc typemapper.ValidateValuesFunc

	// Check if field is regex
	IsRegex bool

	// Finalize
	FinalizeParseFunc FinalizeParseFunc
}

type Parser

type Parser struct {
	ParseSchema ParseSchema

	Factory Factory
}

func New

func New(
	Factory Factory,
	Schema ParseSchema,
) *Parser

func (*Parser) ParseUrlValues

func (p *Parser) ParseUrlValues(
	urlValues url.Values,
) ParseResult

type ResultOrError

type ResultOrError struct {
	Err    error
	Result interface{}
}

func (ResultOrError) IsError

func (r ResultOrError) IsError() bool

Directories

Path Synopsis
example
Package validator provide types for validate query after parsing
Package validator provide types for validate query after parsing

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL