Grails query not inList - grails

I'm writing a criteria to make a query, but I can't figure out how to negate an inList criteria...Is there a way to do something like:
def result = c {
not inList('id', ids)
}
Thanks

Your criteria should like this...
def ids = [1, 2, 3];
def c = Foo.createCriteria();
def results = c.list {
not {'in'("id",ids)}
}
The documentation can be found here. I believe this was just added in grails 2.+

Related

Is there a limit to how many association levels you can reference in a Where query?

This works:
def query = Idea.where {manager.id == id}
This doesn't work:
def query = Idea.where {manager.profile.riding.id == id}
How can I get around this?
Construction Idea.where and Idea.withCriteria are not self-sufficient and not reliable. Always use construction Idea.createCriteria().
def riding = Riding.get(id)
def results = Idea.createCriteria().list() {
manager{
profile{
eq('riding', riding)
}
}
}

How to list my results in a for loop

If i have this snippet from my action
for (c in AuthorList){
def bookCount = Book.countByName(c)
}
How do i make my bookCount into a list
for loop is not required at all. ;)
authorList.collect { Book.countByName( it ) }
should give the list you are looking for.
Try to use <<
def list = []
for (c in AuthorList){
def bookCount = Book.countByName(c)
list << bookCount
}

Checking if a collection is null or empty in Groovy

I need to perform a null or empty check on a collection; I think that !members?.empty is incorrect. Is there a groovier way to write the following?
if (members && !members.empty) {
// Some Work
}
There is indeed a Groovier Way.
if (members) {
//Some work
}
does everything if members is a collection. Null check as well as empty check (Empty collections are coerced to false). Hail Groovy Truth. :)
FYI this kind of code works (you can find it ugly, it is your right :) ) :
def list = null
list.each { println it }
soSomething()
In other words, this code has null/empty checks both useless:
if (members && !members.empty) {
members.each { doAnotherThing it }
}
def doAnotherThing(def member) {
// Some work
}
!members.find()
I think now the best way to solve this issue is code above. It works since Groovy 1.8.1 http://docs.groovy-lang.org/docs/next/html/groovy-jdk/java/util/Collection.html#find(). Examples:
def lst1 = []
assert !lst1.find()
def lst2 = [null]
assert !lst2.find()
def lst3 = [null,2,null]
assert lst3.find()
def lst4 = [null,null,null]
assert !lst4.find()
def lst5 = [null, 0, 0.0, false, '', [], 42, 43]
assert lst5.find() == 42
def lst6 = null;
assert !lst6.find()

Grails lower() in query not working

Let's say I have code like this:
def c = Account.createCriteria()
def results = c {
between("balance", 500, 1000)
eq("branch", "London")
or {
like("holderFirstName", "Fred%")
like("holderFirstName", "Barney%")
}
maxResults(10)
order("holderLastName", "desc")
}
I want to use lower() function to transforming data to lower case
def c = Account.createCriteria()
def results = c {
between("balance", 500, 1000)
eq("branch", "London")
or {
like("lower(holderFirstName)", "Fred%")
like("lower(holderFirstName)", "Barney%")
}
maxResults(10)
order("holderLastName", "desc")
}
My code doesn't work. What is the correct syntax? I have a problem with umlauts so I don't want to use ilike
Don't know which lower function you'd like to use but I guess you want to fetch data based on holderFirstName property ignoring the case.
Here you could use ilike, which is an case-insensitive like:
def c = Account.createCriteria()
def results = c.list {
between("balance", 500, 1000)
eq("branch", "London")
or {
ilike("holderFirstName", "Fred%")
ilike("holderFirstName", "Barney%")
}
maxResults(10)
order("holderLastName", "desc")
}
By the way - you missed to call list() on your criteria ...
Update
You could try to add a formula to your domain class like this:
static mapping = {
lowerFirstName formula: "lower(holder_first_name)"
}
and change the property in your criteria to lowerFirstName:
like("lowerFirstName", "fred%") // changed 'Fred%' to 'fred%'
Code is not tested but should work.
To use database functions in a criteria you need to use sqlRestriction() that add's restrictions directly to the generated sql.
def c = Account.createCriteria()
def results = c.list {
...
sqlRestriction("lower(holder_first_name) like '%%'")
}
Note that with this you use your column name, and not attribute name.
If you are trying to compare for case insensitivity, another option is to use ilike for that purpose. Ilike is similar to Like, but its case insensitive. here
If you do not want to use ilike (as added to the question), I think you alternative approach is executeQuery and hql.
Account.executeQuery(" select * from Account where .... or (lower(holderFirstName) = 'Fred%' ...")

How to sort Domain-Objects with attribute with type JodaTime / DateTime in grails 1.3.7?

I'm working on a small event calendar and i want to sort the events by start time!
I'm using JodaTime Plugin in grails for the startTime attribute. ( http://www.grails.org/JodaTime+Plugin )
So, how can i sort with this datatype? This does not work:
def sortedEvents = events.asList().sort({ a, b -> a.startTime <=> b.startTime } as Comparator)
I hope you can help me!
Thanks,
whitenexx
/EDIT/
This is the code where i'm getting the events:
def getEventsNext(Location location) {
def events = location.events.findAll { it.endTime >= new DateTime() }
def sortedEvents = events.sort{it.startTime}
System.out.println(sortedEvents); //test
return sortedEvents
}
In /event/list action everything works fine with g:sortableColumn (sorting by startTime):
Try this:
def sortedEvents = events.asList().sort{it.startTime}
To reverse the sorting order, use:
def sortedEvents = events.asList().sort{-it.startTime}
FYI, Groovy adds this sort() method to Collection so you can remove asList() from the code above if events is already a Collection.
Try overriding the compareTo method in your domain classes.
For example,
int compareTo(obj) {
startTime.compareTo(obj.startTime)
}
Edit
Sort your events like so:
def sortedEvents = events.sort{e1,e2-> e1.startTime.compareTo(2.startTime)}
Or as suggested by #Don, the groovier equivalent
def sortedEvents = events.sort{e1,e2-> e1.startTime <=> e2.startTime}
Try
def events = location.events.findAll { it.endTime.isAfterNow() }
def sortedEvents = events.sort{it.startTime.toDate()}
JavaDoc for isAfterNow()

Resources