Skip to content

Commit

Permalink
api to create custom operators and docs on custom operators
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel Molina committed May 8, 2017
1 parent 8007c13 commit dbffffa
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 38 deletions.
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Support for arrays of all basic Go types and all JSON and arrays operators is pr
* [Query with relationships](#query-with-relationships)
* [Querying JSON](#querying-json)
* [Transactions](#transactions)
* [Caveats](#caveats)
* [Custom operators](#custom-operators)
* [Debug SQL queries](#debug-sql-queries)
* [Benchmarks](#benchmarks)
* [Acknowledgements](#acknowledgements)
Expand Down Expand Up @@ -603,6 +605,67 @@ store.Transaction(func(s *UserStore) error {
* `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.
* Multidimensional arrays or slices are **not supported** except inside a JSON field.

## Custom operators

You can create custom operators with kallax using the `NewOperator` and `NewMultiOperator` functions.

`NewOperator` creates an operator with the specified format. It returns a function that given a schema field and a value returns a condition.

The format is a string in which `:col:` will get replaced with the schema field and `:arg:` will be replaced with the value.

```go
var Gt = kallax.NewOperator(":col: > :arg:")

// can be used like this:
query.Where(Gt(SomeSchemaField, 9000))
```

`NewMultiOperator` does exactly the same as the previous one, but it accepts a variable number of values.

```go
var In = kallax.NewMultiOperator(":col: IN :arg:")

// can be used like this:
query.Where(In(SomeSchemaField, 4, 5, 6))
```

This function already takes care of wrapping `:arg:` with parenthesis.

### Further customization

If you need further customization, you can create your own custom operator.

You need these things:

* A condition constructor (the operator itself) that takes the field and the values to create the proper SQL expression.
* A `ToSqler` that yields your SQL expression.

Imagine we want a greater than operator that only works with integers.

```go
func GtInt(col kallax.SchemaField, n int) kallax.Condition {
return func(schema kallax.Schema) kallax.ToSqler {
// it is VERY important that all SchemaFields
// are qualified using the schema
return &gtInt{col.QualifiedName(schema), n}
}
}

type gtInt struct {
col string
val int
}

func (g *gtInt) ToSql() (sql string, params []interface{}, err error) {
return fmt.Sprintf("%s > ?", g.col), []interface{}{g.val}, nil
}

// can be used like this:
query.Where(GtInt(SomeSchemaField, 9000))
```

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.

## Debug SQL queries

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.
Expand Down
Loading

0 comments on commit dbffffa

Please sign in to comment.