Skip to content

Commit dbffffa

Browse files
author
Miguel Molina
committed
api to create custom operators and docs on custom operators
1 parent 8007c13 commit dbffffa

File tree

3 files changed

+168
-38
lines changed

3 files changed

+168
-38
lines changed

README.md

+63
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Support for arrays of all basic Go types and all JSON and arrays operators is pr
3434
* [Query with relationships](#query-with-relationships)
3535
* [Querying JSON](#querying-json)
3636
* [Transactions](#transactions)
37+
* [Caveats](#caveats)
38+
* [Custom operators](#custom-operators)
3739
* [Debug SQL queries](#debug-sql-queries)
3840
* [Benchmarks](#benchmarks)
3941
* [Acknowledgements](#acknowledgements)
@@ -603,6 +605,67 @@ store.Transaction(func(s *UserStore) error {
603605
* `time.Time` and `url.URL` need to be used as is. That is, you can not use a type `Foo` being `type Foo time.Time`. `time.Time` and `url.URL` are types that are treated in a special way, if you do that, it would be the same as saying `type Foo struct { ... }` and kallax would no longer be able to identify the correct type.
604606
* Multidimensional arrays or slices are **not supported** except inside a JSON field.
605607

608+
## Custom operators
609+
610+
You can create custom operators with kallax using the `NewOperator` and `NewMultiOperator` functions.
611+
612+
`NewOperator` creates an operator with the specified format. It returns a function that given a schema field and a value returns a condition.
613+
614+
The format is a string in which `:col:` will get replaced with the schema field and `:arg:` will be replaced with the value.
615+
616+
```go
617+
var Gt = kallax.NewOperator(":col: > :arg:")
618+
619+
// can be used like this:
620+
query.Where(Gt(SomeSchemaField, 9000))
621+
```
622+
623+
`NewMultiOperator` does exactly the same as the previous one, but it accepts a variable number of values.
624+
625+
```go
626+
var In = kallax.NewMultiOperator(":col: IN :arg:")
627+
628+
// can be used like this:
629+
query.Where(In(SomeSchemaField, 4, 5, 6))
630+
```
631+
632+
This function already takes care of wrapping `:arg:` with parenthesis.
633+
634+
### Further customization
635+
636+
If you need further customization, you can create your own custom operator.
637+
638+
You need these things:
639+
640+
* A condition constructor (the operator itself) that takes the field and the values to create the proper SQL expression.
641+
* A `ToSqler` that yields your SQL expression.
642+
643+
Imagine we want a greater than operator that only works with integers.
644+
645+
```go
646+
func GtInt(col kallax.SchemaField, n int) kallax.Condition {
647+
return func(schema kallax.Schema) kallax.ToSqler {
648+
// it is VERY important that all SchemaFields
649+
// are qualified using the schema
650+
return &gtInt{col.QualifiedName(schema), n}
651+
}
652+
}
653+
654+
type gtInt struct {
655+
col string
656+
val int
657+
}
658+
659+
func (g *gtInt) ToSql() (sql string, params []interface{}, err error) {
660+
return fmt.Sprintf("%s > ?", g.col), []interface{}{g.val}, nil
661+
}
662+
663+
// can be used like this:
664+
query.Where(GtInt(SomeSchemaField, 9000))
665+
```
666+
667+
With most of the operators, `NewOperator` and `NewMultiOperator` are enough, so the usage of these functions is preferred over the completely custom approach. Use it only if there is no other way to build your custom operator.
668+
606669
## Debug SQL queries
607670

608671
It is possible to debug the SQL queries being executed with kallax. To do that, you just need to call the `Debug` method of a store. This returns a new store with debugging enabled.

0 commit comments

Comments
 (0)