naivequeryfilters

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: May 22, 2025 License: MIT Imports: 7 Imported by: 0

README

go-naive-queryfilters

package naivequeryfilters_test

import (
	"fmt"
	"net/url"

	naivequeryfilters "github.com/Wayodeni/go-naive-queryfilters"
)

func ExampleBuild() {
	var whitelist = naivequeryfilters.AllowedColumns{
		"col1": func(s string) string { return "table_name.col1" },
		"col2": func(s string) string { return s },
	}
	filter, invalidParams, err := naivequeryfilters.Build(whitelist, url.Values{
		"col1__in":     []string{"1", "2"},
		"col2__not_in": []string{"1"},
		"col3":         []string{"val"},
	})
	if err != nil {
		panic(err)
	}
	if len(invalidParams) != 0 {
		fmt.Printf("passed invalid column names in get parameters: %s\n", invalidParams)
	}
	fmt.Printf("SQL query filters part for WHERE clause: '%s'\nSQL query placeholder values: %v", filter.SqlFilters, filter.PlaceholderValues)
	// Output:
	// passed invalid column names in get parameters: map[col3:[val]]
	// SQL query filters part for WHERE clause: 'table_name.col1 IN (?,?) AND col2 <> ?'
	// SQL query placeholder values: [1 2 1]
}
Output:
passed invalid column names in get parameters: map[col3:[val]]
SQL query filters part for WHERE clause: 'table_name.col1 IN (?,?) AND col2 <> ?'
SQL query placeholder values: [1 2 1]

Simple utility library to generate SQL query filters from get parameters. Inspired by Django (see: https://docs.djangoproject.com/en/5.2/topics/db/queries/#field-lookups)

Supported features:

  • IN and NOT IN for list (or not) of get parameters: .../path?column__in=1&column__in=2&column__in=3
  • exact equality and inequality (using not_in): .../path?column__not_in=1 = column <> 1
  • LIKE using __like operator: col1__like=foo = LOWER(col1) LIKE CONCAT('%', foo, '%')

Planned features:

  • support for operators: BETWEEN, IS NULL, gt, gte, lt, lte, not
  • OR support
  • ordering support (parentheses in resulting SQL)

Documentation

Overview

Django like (django-filter, DRF) queryparam filters to SQL parser.

Supported features:

  • IN and NOT IN for list (or not) of get parameters: `.../path?column__in=1&column__in=2&column__in=3“
  • exact equality and inequality (using not_in): `.../path?column__not_in=1 = column <> 1`
  • LIKE using __like operator: col1__like=foo = `LOWER(col1) LIKE CONCAT('%', foo, '%')`

Planned features:

  • support for operators: BETWEEN, IS NULL, gt, gte, lt, lte, not
  • OR support
  • ordering support (parentheses in resulting SQL)
Example
package main

import (
	"fmt"
	"net/url"

	naivequeryfilters "github.com/Wayodeni/go-naive-queryfilters"
)

func main() {
	var whitelist = naivequeryfilters.AllowedColumns{
		"col1": func(s string) string { return "table_name.col1" },
		"col2": func(s string) string { return s },
	}
	filter, invalidParams, err := naivequeryfilters.Build(whitelist, url.Values{
		"col1__in":     []string{"1", "2"},
		"col2__not_in": []string{"1"},
		"col3":         []string{"val"},
	})
	if err != nil {
		panic(err)
	}
	if len(invalidParams) != 0 {
		fmt.Printf("passed invalid column names in get parameters: %s\n", invalidParams)
	}
	fmt.Printf("SQL query filters part for WHERE clause: '%s'\nSQL query placeholder values: %v", filter.SqlFilters, filter.PlaceholderValues)
}
Output:
passed invalid column names in get parameters: map[col3:[val]]
SQL query filters part for WHERE clause: 'table_name.col1 IN (?,?) AND col2 <> ?'
SQL query placeholder values: [1 2 1]

Index

Examples

Constants

View Source
const (
	OPERATOR_SEPARATOR = "__"
	OPERATOR_IN        = "in"
	OPERATOR_NOT_IN    = "not_in"
	OPERATOR_LIKE      = "like"
)

These constants define operator names in get parameters keys. E.g. ".../path?column__not_in=val" == fmt.Sprintf(".../path?column%s%s=val", OPERATOR_SEPARATOR, OPERATOR_NOT_IN)

View Source
const (
	QUERY_TOKEN_IN         = "IN"
	QUERY_TOKEN_NOT_IN     = "NOT IN"
	QUERY_TOKEN_EQUALS     = "="
	QUERY_TOKEN_NOT_EQUALS = "<>"
	QUERY_TOKEN_LIKE       = "LIKE"
)

These constants define SQL query tokens in which operators will be transformed.

Variables

This map stores "<get param operator>: <sql query token equivalent>" pairs.

Functions

This section is empty.

Types

type AllowedColumns

type AllowedColumns map[string]func(string) string

Map storing "<db column name>: <db column name changing function>".

Matching every column name to function which will optionally return transformed (or completely new) name instead of passed. Primarily used for transforming of aliases like this: "SELECT table.col_name AS new_col_name" into column names like this: "table_name.column_name" to be used in resulting SQL query.

We need that because inside SQL we can't use column aliases inside WHERE conditions: https://stackoverflow.com/questions/13031013/how-do-i-use-alias-in-where-clause

type ErrWrongOperator

type ErrWrongOperator struct {
	Operator  string
	ParamName string
}

This error is thrown when wrong operator is passed in param name. e.g. col__not_listed_op.

func (ErrWrongOperator) Error

func (e ErrWrongOperator) Error() string

type ErrWrongQueryParamName

type ErrWrongQueryParamName struct {
	ParamName string
}

This error is returned when query parameter with wrong key passed. e.g col__name__like.

func (ErrWrongQueryParamName) Error

func (e ErrWrongQueryParamName) Error() string

type Filter

type Filter struct {
	// This field contains resulting SQL filters for WHERE part e.g. `col1 IN (?,?,?) AND col2 = ?`.
	SqlFilters string

	// List of placeholder values for SQL query.
	PlaceholderValues []interface{}
}

Struct holding SQL filtering query with placeholders and placeholder values.

func Build

func Build(filterAllowedColumnNames AllowedColumns, getParams url.Values) (Filter, url.Values, error)

Main library function. Accept whitelist of db table column names with get parameters extracted from url. Returns Filter with SQL query string and placeholder values, wrong column names passed in getParams and error.

Jump to

Keyboard shortcuts

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