timshannon / bolthold

BoltHold is an embeddable NoSQL store for Go types built on BoltDB
MIT License
648 stars 46 forks source link

improve bolthold.Where / query.And #59

Closed mh-cbon closed 5 years ago

mh-cbon commented 5 years ago

Hi,

some consideratons regarding the query api

The current scheme using bolthold.Where / Query.And over a pointer is not in my opinion the best strategy.

In this silly example, the user has to deal with repetitive code

var q *bolthold.Query
if title!="" {
if q == nil { q = bolthold.Where("Title").Eq(title) }
else{ q = q.And("Title").Eq(title) }
}
if otherthing="" {
if q == nil { q = bolthold.Where("Otherthing").Eq(otherthing) }
else{ q = q.And("Otherthing").Eq(otherthing) }
}
if q == nil { q = new(*bolthold.Query) }
q.Limit(10)
store.Find(some{}, q)

something is broken in this code, could be factorized, a much better out of the box version could look like

var q bolthold.Query
if title!="" {
q.And("Title").Eq(title)   // or q.Where.
}
if otherthing="" {
q.And("Otherthing").Eq(otherthing)  // or q.Where.
}
q.Limit(10)
store.Find(some{}, q)

the and / where mechanic is simplified. in the example they should behave exactly the same way. no matter what who was called first etc. because q is declared as value type there is no need to new or anything else.

as q is value type, Find method change to a value type also. so writing a criterion less query is painful

var q bolthold.Query
store.Find(some{}, q) // vs nil previously

a solution is to adjust Find method in order to take a variadic query parameter, so the user can write

store.Find(some{})

am i missing someting ?

timshannon commented 5 years ago

Just because the Query type is a pointer doesn't mean you still can't write your code the way you want. Just instantiate it so you don't have to check for nil. A nil query and a query with no criteria behave the same.

q := &bolthold.Query{}
if title!="" {
q.And("Title").Eq(title)   // or q.Where.
}
if otherthing="" {
q.And("Otherthing").Eq(otherthing)  // or q.Where.
}
q.Limit(10)
store.Find(some{}, q)