fet

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2022 License: MIT Imports: 3 Imported by: 0

README

FET

Build queries dynamically
well-tested Go library that allows you to build queries in dynamic, and programmatic way.

CI



What is FET?

Fet is a library that allows you to build queries in dynamic, and programmatic way. You can build mongo queries with function calls, instead of writing nested maps. And you have a unique, built-in logical control on your queries easily.

Installation

go get github.com/ahmetcanozcan/fet

Getting Started

Main functionality of FET is to build queries with function calls using fet.Build. This function takes a list of fet.Updater and apply this updaters into a new query that can be used on mongo driver functions.

filter := fet.Build(
  fet.Field("name").Eq("dave"),
)

err := collection.FindOne(ctx, filter)


You can build set queries as well, using fet.BuildSet.


filter := fet.Build(
  fet.Field("name").Eq("dave"),
)

query := fet.BuildSet(
  fet.Field("age").Is(18),
)

_, err := collection.UpdateOne(ctx, filter, query)

// is equivalent to

filter := bson.M{
  "name": bson.M{
    "$eq": "dave",
  },
}

query := bson.M{
  "$set": bson.M{
    "age": 18,
  },
}

err := collection.FindOne(ctx, filter, query)

Features

Generic Repository Functions

func (repo *repository) GetByFilters(ctx context.Context, filters ...fet.Updater) (*User, error) {
  // ...
  filter := fet.Build(filters...)
  err := collection.FindOne(ctx, filter).Decode(&user)
  // ...
  return user, err
}

// This function can be called
user, err := repo.GetByFilters(
  ctx,
  fet.WithValueEq("username", "test"),
  fet.WithValueEq("password", "test"),
)

user, err := repo.GetByFilters(
  ctx,
  fet.Field("username").Eq("test"),
  fet.Field("password").Eq("test"),
  fet.Or(
    fet.Field("pretty").Eq(true),
    fet.Field("admin").Eq(true),
  )
)

Checker

checker is basic function that returns true depends on field name and query variable. FET has some built-in checker functions such as IfNotNil, IfNotEmpty, IfNotZeroTime.

filter := fet.Build(
  fet.Field("username").Eq(username),
  fet.Field("cardId").Eq(cardId, fet.IfNotEmpty),
)

// filter is change depends on cardId

// if cardId is empty, filter is equivalent of:
filter := bson.M{
  "username": username,
}

// if cardId is not empty, filter is equivalent of:
filter := bson.M{
  "username": username,
  "cardId": cardId,
}

Struct Picking

if your code reads fields from a struct, you can use the Struct functionality to shortened your code.


type User struct {
  Name string `bson:"name"`
  Age int
  Phone string
}

u := &User{
  Name: "Dave Bowman",
  Age: 18,
  Phone: "",
}

f := fet.Build(
  fet.Field("name").Is(u.Name),
  fet.Field("Phone").Is(u.Phone, fet.IfNotEmpty)
)

f := fet.Struct(u).
  Pick("Name").
  Pick("Phone", fet.IfNotEmpty).
  Build()

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Documentation

Index

Examples

Constants

View Source
const (
	KeywordEq string = "$eq"
	KeywordNe string = "$ne"

	// Array
	KeywordIn           string = "$in"
	KeywordNin          string = "$nin"
	KeywordAll          string = "$all"
	KeywordElemMatch    string = "$elemMatch"
	KeywordAllElemMatch string = "$allElemMatch"

	// Logic
	KeywordOr   string = "$or"
	KeywordAnd  string = "$and"
	KeywordNor  string = "$nor"
	KeywordNand string = "$nand"

	// Comparison
	KeywordGt  string = "$gt"
	KeywordGte string = "$gte"
	KeywordLt  string = "$lt"
	KeywordLte string = "$lte"

	// Element
	KeywordExists string = "$exists"
	KeywordSize   string = "$size"
	KeywordType   string = "$type"

	// Evaluation
	KeywordMod         string = "$mod"
	KeywordRegex       string = "$regex"
	KeywordOptions     string = "$options"
	KeywordText        string = "$text"
	KeywordSearch      string = "$search"
	KeywordComment     string = "$comment"
	KeywordMax         string = "$max"
	KeywordMin         string = "$min"
	KeywordMaxDistance string = "$maxDistance"

	// Bitwise
	KeywordBitwiseAnd string = "$bitwiseAnd"
	KeywordBitwiseOr  string = "$bitwiseOr"
	KeywordBitwiseXor string = "$bitwiseXor"
	KeywordBitwiseNot string = "$bitwiseNot"

	// Geospatial
	KeywordGeoIntersects string = "$geoIntersects"
	KeywordGeoWithin     string = "$geoWithin"
	KeywordNear          string = "$near"
	KeywordWithin        string = "$within"

	// Projection
	KeywordProjection string = "$projection"

	// Update
	KeywordUnset       string = "$unset"
	KeywordSet         string = "$set"
	KeywordSetOnInsert string = "$setOnInsert"

	// Array
	KeywordArrayFilters string = "$arrayFilters"

	// Text
	KeywordTextScore string = "$textScore"

	KeywordCurrentDate string = "$currentDate"
)

Variables

View Source
var (
	// Set is updater for $set query
	Set = getGlobalOperationWithKeywordConstructor(KeywordSet)
	// SetOnInsert is updater for $setOnInsert query
	SetOnInsert = getGlobalOperationWithKeywordConstructor(KeywordSetOnInsert)
	// Unset is updater for $unset query
	Unset = getGlobalOperationWithKeywordConstructor(KeywordUnset)
)
View Source
var (
	// Or is updater for $or query
	Or = getLogicalOperationWithKeywordConstructor(KeywordOr)
	// And is updater for $and query
	And = getLogicalOperationWithKeywordConstructor(KeywordAnd)
	// Nor is updater for $nor query
	Nor = getLogicalOperationWithKeywordConstructor(KeywordNor)
	// Nand is updater for $nand query
	Nand = getLogicalOperationWithKeywordConstructor(KeywordNand)
)
View Source
var (
	ErrNilStruct    = errors.New("fet: nil pointer passed to Struct")
	ErrNotStruct    = errors.New("fet: non-struct passed to Struct")
	ErrInvalidField = errors.New("fet: invalid field")
)

Functions

func Field

func Field(key string) *field

Types

type Checker

type Checker interface {
	Check(key string, value interface{}) bool
}

Checker is an interface that defines how to check a filter has to be eliminated or not.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/ahmetcanozcan/fet"
)

func main() {
	filter := fet.Build(
		fet.Field("username").Eq("dave", fet.IfNotEmpty),
		fet.Field("cardId").Eq("", fet.IfNotEmpty),
		fet.Field("car").Eq(nil, fet.IfNotNil),
	)

	b, _ := json.Marshal(filter)
	fmt.Println(string(b))
}
Output:

{"username":{"$eq":"dave"}}
var IfNotEmpty Checker = CheckerFunc(func(key string, value interface{}) bool {
	return value != ""
})

IfNotEmpty checks if the given value is not a empty empty string.

var IfNotNil Checker = CheckerFunc(func(key string, value interface{}) bool {
	return value != nil
})

IfNotNil checks if the given value is not nil.

var IfNotZero Checker = CheckerFunc(func(key string, value interface{}) bool {
	return value != 0
})

IfNotZero checks if the given value is not zero.

var IfNotZeroTime Checker = CheckerFunc(func(key string, value interface{}) bool {
	var (
		t  time.Time
		ok bool
	)

	if t, ok = value.(time.Time); !ok {
		return true
	}

	return !t.IsZero()
})

IfNotZeroTime checks if the given value is not zero time. if value type is not time.Time then it will return true.

type CheckerFunc added in v0.3.0

type CheckerFunc func(key string, value interface{}) bool

func (CheckerFunc) Check added in v0.3.0

func (cf CheckerFunc) Check(key string, value interface{}) bool

type M

type M map[string]interface{}

M is representation of a MongoDB query, it is fet equivalent of `bson.M`.

func Apply

func Apply(filter M, updaters ...Updater) M

Apply applies the given updaters to the given filter.

Example:

filter := fet.Apply(
	m,
	fet.Field("firstname").Eq("dave"),
	fet.Field("lastname").Eq("bowman"),
)

func Build

func Build(updaters ...Updater) M

Build creates a filter and apply the given updaters to it.

Example:

filter := fet.Build(
	fet.Field("firstname").Eq("dave"),
	fet.Field("lastname").Eq("bowman"),
)
Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/ahmetcanozcan/fet"
)

func main() {
	filter := fet.Build(
		fet.Field("name").Eq("dave"),
		fet.Field("age").Is(10),
	)

	b, _ := json.Marshal(filter)
	fmt.Println(string(b))
}
Output:

{"age":10,"name":{"$eq":"dave"}}

func BuildSet

func BuildSet(updaters ...Updater) M

BuildSet combines Build and Set. is equivalent to:

fet.Build(fet.Set(updaters...))
Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/ahmetcanozcan/fet"
)

func main() {
	query := fet.BuildSet(
		fet.Field("age").Is(18),
	)

	b, _ := json.Marshal(query)
	fmt.Println(string(b))
}
Output:

{"$set":{"age":18}}

type StructUpdater added in v0.3.0

type StructUpdater struct {
	// contains filtered or unexported fields
}

StructUpdater is and updater for struct

func Struct added in v0.3.0

func Struct(s interface{}) *StructUpdater

Struct constructs a StructUpdater for the given struct. if given value is nil or not a struct, panic.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/ahmetcanozcan/fet"
)

func main() {
	type User struct {
		Name  string `bson:"name"`
		Age   int
		Phone string
	}

	u := User{
		Name:  "Dave Bowman",
		Age:   18,
		Phone: "",
	}

	filter := fet.Struct(u).
		Pick("Name").
		Pick("Phone", fet.IfNotEmpty).
		Build()

	b, _ := json.Marshal(filter)
	fmt.Println(string(b))
}
Output:

{"name":"Dave Bowman"}

func (*StructUpdater) Build added in v0.4.0

func (s *StructUpdater) Build() M

func (*StructUpdater) Pick added in v0.3.0

func (s *StructUpdater) Pick(name string, checkers ...Checker) *StructUpdater

Pick picks the given field from struct with the given checkers. if the struct field has `bson` tag, otherwise use fieldname Example:

fet.Struct(user).Pick("firstname").Pick("lastname")

func (*StructUpdater) PickAll added in v0.3.0

func (s *StructUpdater) PickAll(checkers ...Checker) *StructUpdater

PickAll picks all the fields from the given struct. use given checkers to all fields.

func (*StructUpdater) Update added in v0.3.0

func (s *StructUpdater) Update(m M)

type Updater

type Updater interface {
	Update(m M)
}

Updater is an interface that defines how to update a filter.

func Group added in v0.3.0

func Group(u ...Updater) Updater

Group returns a Updater that applies the given updaters.

type WithFunc

type WithFunc func(M)

func (WithFunc) Update

func (w WithFunc) Update(filter M)

Directories

Path Synopsis
_example

Jump to

Keyboard shortcuts

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