I have the following domain class
class Book {
String title
Date releaseDate
Integer daysOnShelf
Author author
}
How can I list all books where current date is greater than the releaseDate + daysOnShelf? For instance, don't list if 2015-02-10 + 5 (releaseDate + daysOnShelf) since date is less than now.
Can this be done using GORM dynamic finders or Criteria Builder ? e.g.,
def index(Integer max) {
def books = Book.findAll {
releaseDate.plus(daysOnShelf) < new Date()
}
respond books
}
This should acchieve what you want:
Date dateMinusDaysOnShelf = new Date() - daysOnShelf
Book.findAllByReleaseDateLessThan(dateMinusDaysOnShelf)
Related
i'm making a tables cleaning service that takes the table name and the date field as arguments , here is the service code :
def cleanTables(tableName , dateField) {
def comparisonDate
def numOfRecordsDeleted
use (TimeCategory){
comparisonDate=new Date() -1.year
}
numOfRecordsDeleted=tableName.where { dateField <=comparisonDate }.deleteAll()
log.info("deleted : " +numOfRecordsDeleted)
}
i'm successfully passing to this service the table name but i can't pass the date field , so how to get a specific property from a domain for example a domain named Payments got a property dateCreated , so i pass to my service Payments and dateCreated.
With where queries you have access to criteria query methods such as eq(), or in this case, le(). Those methods take the name of the property as an argument, which is what you need. I tweaked the code a bit because you're actually interacting with domain classes, not tables. Small distinction, until you start working with HQL.
def cleanDomainClass(String domainClassName, String dateField) {
def domainClass = Class.forName("some.package.$domainClassName")
def comparisonDate = use (TimeCategory) { new Date() -1.year }
def numOfRecordsDeleted = domainClass.where { le(dateField, comparisonDate) }.deleteAll()
log.info("deleted : $numOfRecordsDeleted")
}
I have several Grails 2.1 domain classes that include dateCreated and lastUpdated fields that GORM manages automatically, eg:
class Person {
Date dateCreated
Date lastUpdated
String name
}
I want Grails to automatically fill in these fields at runtime, but I also want to create some test data where I can manually define the values of these dates. The trouble is that Grails automatically sets the values if these fields with an interceptor even when I have specifically set them.
I have seen this SO question which describes how to allow changes to dateCreated, but I need to change lastUpdated as well. Is this possible?
Whoops, my mistake, the approach in the other question does work, but the entity in question was separately being saved somewhere else. It also seems that you need an explicit flush to make things work:
def withAutoTimestampSuppression(entity, closure) {
toggleAutoTimestamp(entity, false)
def result = closure()
toggleAutoTimestamp(entity, true)
result
}
def toggleAutoTimestamp(target, enabled) {
def applicationContext = (ServletContextHolder.getServletContext()
.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT))
def closureInterceptor = applicationContext.getBean("eventTriggeringInterceptor")
def datastore = closureInterceptor.datastores.values().iterator().next()
def interceptor = datastore.getEventTriggeringInterceptor()
def listener = interceptor.findEventListener(target)
listener.shouldTimestamp = enabled
null
}
def createTestPerson() {
def luke = new Person(name: "Luke Skywalker")
withAutoTimestampSuppression(luke) {
def lastWeek = new Date().minus(7)
luke.dateCreated = lastWeek
luke.lastUpdated = lastWeek
luke.save(failOnError: true, flush: true)
}
}
If it is an integration test you can use an hql update statement to manually set lastUpdated.
I'm new to Grails development.
I have a domain class like this :
class DaySchedule {
Date Todaysdate
String startTime;
String endTime;
String task
int priority
boolean completed
static belongsTo = [ schedule : Schedule ]
}
I have bootstrapped with some test data's. Now I want to do a query, with following condition :
I need to pick each task (which are stored in bootstrap.groovy) which are belongs to a particularTodaysdate.
For example if I have these statements in my BootStrap.groovy :
//other codes
def daySchedule3 = new DaySchedule(Todaysdate:new Date(),
startTime:"6pm",endTime:"10pm",
task:"ReaD git...",completed:false)
def daySchedule4 = new DaySchedule(Todaysdate:new Date()+1,
startTime:"10am",endTime:"12pm",
task:"Read MySQL....",completed:false)
Now clearly the task, ReaD git... belongs to a day (which is today as I have passed new Date() into it).
To find these I came up with a partial solution like this:
def allTasks = DaySchedule.findAllByTaskIsNotNull()
def dates = allTasks.collect { it.Todaysdate }
def tasks = dates.collect {
def queryParameter = new DaySchedule(Todaysdate:it)
def todaysWork = DaySchedule.findAll(queryParameter)
todaysWork.task
}
I have a problem with this code. I couldn't use collectEntries method on the dates and tasks so that I convert it into map of a particular date(i.e dates) with values as tasks. (which is what I tried for!)
Now I'm left lone. I couldn't not able to find a way to guess for which dates the tasks belongs to.
Any other solutions for it?
Thanks in advance.
It sounds like you're trying to get a map with a key of the date, and a value of the task name, for all of the domain objects DaySchedule. You may want to try Collection.groupBy. For example:
def allTasks = DaySchedule.findAllByTaskIsNotNull()
def tasksByDate = [:] // start with empty map
tasksByDate.putAll(
allTasks.groupBy { task ->
// group by just the date portion, ignoring time
// clone since clearTime modifies original
task.todaysDate.clone().clearTime()
}.collect { date, daySchedule ->
// change from map of date -> daySchedule to map of date -> task
[date, daySchedule.task] as MapEntry
}
)
I think you have a design problem somewhere... it would be easier to have something like :
class Task {
Date startTime;
Date endTime;
String description
int priority
boolean completed
static belongsTo = [ schedule : Schedule ]
String toString() {
return "${description} : from ${startTime} to ${endTime}"
}
}
Then, you can list all the dates for which you have tasks in them like this :
java.text.DateFormat df = java.text.DateFormat.getDateInstance(DateFormat.LONG, Locale.US);
def days = Task.list().collect {
df.format(it.startTime);
}.unique()
So now the "days" variable contains an array of strings of unique days present in your database with tasks associated.
If you want to list the tasks by day, you can then do :
days.each { dayString ->
def date = df.parse(dayString)
def dayTasks = Task.findAllByStartTimeBetween(date, date+1)
println "Tasks for ${dayString}"
dayTasks.each {
println " - ${it}"
}
}
Hello I have the follwing domain classes.
class Student {
int age
static hasMany = [courses:Course]
}
class Course {
String name
static hasMany = [students:Student]
}
I want to find the Students taking Course (with id 1), with age 7.
Could I do that with dynamic finder or criteria builder or HQL?
I do not want to do following as it load all students so inefficient:
def course = Course.get(1);
course.students.findAll{ it.age == 7 }
def studs = Student.withCriteria {
eq('age', 7)
courses {
eq('id', 1)
}
}
It's in GORM doc, section "Criteria/Querying Associations".
You can use a dynamic finder:
def students = Student.findByCourseAndAge(Course.load(1), 7)
By using load() instead of get() you avoid retrieving the whole Course instance and just reference its id.
Another option is HQL:
def students = Student.executeQuery(
'from Student s where s.course.id = :courseId and s.age = :age',
[courseId: 1, age: 7])
i have domain classes:
package test
class Credit {
String name;
static hasMany = [debts : Debt]
static constraints = {
}
}
and
package test
class Debt {
Integer amount;
Date date;
static belongsTo =[credits: Credit]
static constraints = {
}
}
Need: select max: 10; order: "desc"; sort: "date" rows of Debt associated with the Сredit.get(id)
How can i do it?
solution:
Debt.findAllByCredits(Credit.get(params.id),[max:10, sort:"date",order:"desc"])
but next question about this example:
why, this code work:
def ok = Debt.findAllByCredits(Credit.get(params.id),[max:10, sort:"date",order:"desc"])
println "true:" + ok
but this code not work correct:
def dd = new Debt(credits: Credit.get(params.id))
def wrong =Debt.findAll(dd)
println "no: "+ wrong
all time return all records in table, why?
you could do something like
def hql = "select d from Debt d where credits = ? order by d.date desc"
Debt.findAll(hql, [credit], [max:10])
you might have to tweak that, but something similar should work. Also note, I am assuming that you have an instance of credit that is the parent of the Debts.
You can also use the methods Grails generates dynamically at runtime, based on the properties of your classes
Debt.findAllByCredit(credit, [max:10,sort:"date",order:"desc"]
again, you will need a reference to a credit object.
Check out the docs at
http://grails.org/doc/latest/
specifically the section on findAll and findAllBy under Domain Classes in the left hand nav.