How to set formula in grails domain class? - grails

I am trying to write formula in my domain class which helps me in creating criteria.
class MyClass {
//some fields
Date appointmentTime
String ddmmyy
int year
int month
int day
static transients = [
'ddmmyy',
'year',
'month',
'day'
]
static mapping= {
ddmmyy formula('DATE_FORMAT(appointmentTime)')
year formula('YEAR(appointmentTime)')
month formula('MONTH(appointmentTime)')
day formula('DAYOFMONTH(appointmentTime)')
}
}
Whenever I am trying to use this fields in my criteria it throws error i.e. can not resolve property 'ddmmyy' of 'myClass'.
MyCriteria is:
Date myDate = Calender.instance.time
def results = MyClass.createcriteria().list{
lt('appointmentTime', date+1)
ge('appointmentTime', date)
projections {
groupProperty('ddmmyy')
count('id')
}
}
Any idea why I am getting an exception for this?

You need to make these fields non transient to use in criteria. See reference document
http://gorm.grails.org/6.1.x/hibernate/manual/#derivedProperties

Related

Use getters and setters to create string from 1-7 integers

I'm trying to take a 1-7 integer value and print out a day for each value with an enum.
I get an error in the class mapping from firestore, "isn't a field in the enclosing class"
So if 1 is passed in then "Monday" is given
if 2 is passed in then "Tuesday" is given
enum _Days {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
class HeadingItem implements ListItem {
String _weekday;
final int time;
final DocumentReference reference;
set day(int weekday) {
var value = _Days.values[weekday - 1].toString();
var idx = value.indexOf(".") + 1;
var result = value.substring(idx, value.length);
_weekday = result;
}
String get day {
return _weekday;
}
HeadingItem.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['day'] != null),
assert(map['time'] != null),
day = map['day'], // 'day' isn't a field in the enclosing class <--- this is the error that im stuck on...
time = map['time'];
HeadingItem.fromSnapshot(DocumentSnapshot snapshot) : this.fromMap(snapshot.data, reference: snapshot.reference);
}
Change
String get day {
return _weekday;
}
to this
String day = _weekday;
Notice that in your code, day is technically a set of methods of this that allows us to work with day as if it were a member of this; day is not actually a member.
Thus, in order for your initializer list to work as you intended it to, it would already need to have access to this in order to provide the functionality you want (for example, to set the value of the internal member _weekday).
However, as mentioned in the Language Tour of Dart in the section on Initializer Lists, the initializer list does not have access to this. Rather we should see the initializer list as values to assign to members of this during the instantiation.

C# The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar

I Apologies now, but I'm not great with dates.
I'm passing a date parameter into a MVC Controller(ASP.net)
however sometimes (its happned twice) it does not like a particular time of the day and throws the following error:
Exception: mscorlib The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.
I've had this on the two following values:
Query: dateTime=13%2f03%2f2017+13%3a08
Query: dateTime=12%2f03%2f2017+21%3a07
Using Moment to try and format
function addNewMeeting(date) {
var currentDate = moment().format("DD/MM/YYYY%20HH:mm").toString();
$("#appEventPlaceholder").load("/Meeting/AddEvent?dateTime=" + currentDate,
function () {
$('#eventModal').modal('show');
}
);
};
public ActionResult AddEvent(string date = null, string resourceId = null)
{
..}
I guess i'm doing something wrong with formatting the date? Could someone show me what I should be doing please?
Thank you in advance.
try this Convert.toDateTime(string)

Group by week / month / year in GORM

I have a domain class (minified) as :-
class Expense {
Date dateOfExpense
int amount
}
I am trying to get sum of amount grouped by week/month/ year of expense date.
Referring to 'sqlGroupProjection' method in grails doc http://grails.org/doc/latest/guide/GORM.html,
I tried using following code:-
def results = c {
between("dateOfExpense", fromDate, toDate)
projections {
sqlGroupProjection 'dateOfExpense,sum(amount) as summed',
'MONTH(dateOfExpense)',['date','summed'],[DATE,NUMBER]
}
}
Throws exception:
No such property: DATE for class: grails.orm.HibernateCriteriaBuilder. Stacktrace follows:
Message: No such property: DATE for class: grails.orm.HibernateCriteriaBuilder
Please suggest an approach using sqlGroupProjection method
Create three new numeric fields each for week,month and year in the domain class. These fields won't be mapped to column in the table.
Provide static mapping for the three fields.
static mapping = {
//provide the exact column name of the date field
week formula('WEEK(DATE_OF_EXPENSE)')
month formula('MONTH(DATE_OF_EXPENSE)')
year formula ('YEAR(DATE_OF_EXPENSE)')
}
Now we can group by desired field using
def results = c.list {
between("dateOfExpense", fromDate, toDate)
projections {
switch(groupBy){
case "week":
groupProperty('year')
groupProperty('month')
groupProperty('week')
break;
case "month"
groupProperty('year')
groupProperty('month')
break;
case "year":
groupProperty('year')
break;
}
sum('amount')
}
}
Instead of this
static mapping = {
week formula('WEEK(DATE_OF_EXPENSE)') //provide the exact column name of the date field
month formula('MONTH(DATE_OF_EXPENSE)')
year formula ('YEAR(DATE_OF_EXPENSE)')
}
try this
static mapping = {
week formula: 'WEEK(DATE)'
month formula: 'MONTH(DATE)'
year formula: 'YEAR(DATE)'
}
Try something like
sqlGroupProjection 'MONTH(dateOfExpense) as month, sum(amount) as summed',
'month',['month','summed'],[NUMBER,NUMBER]
This sqlGroupProjection method seems to be poorly supported. Use
def results = c.list {
between("dateOfExpense", fromDate, toDate)
projections {
groupProperty('dateOfExpense')
sum('amount')
}
}
will produce the deserved outcome.
If you want group by the month of the date, see Grails group by date (It totally outweight my answer, actually. But I reach the same solution after trying your code for a long time.)

Grails group by date

I have a domain class with a date-property.
class Transaction {
LocalDate time
BigDecimal amount
}
How can I query for the sum of all transactions grouped by month? I canĀ“t find any support for group by a date-range in GORM.
Add a formula based field to your domain class for the truncated date:
class Transaction {
LocalTime time
BigDecimal amount
String timeMonth
static mapping = {
timeMonth formula: "FORMATDATETIME(time, 'yyyy-MM')" // h2 sql
//timeMonth formula: "DATE_FORMAT(time, '%Y-%m')" // mysql sql
}
}
Then you'll be able to run queries like this:
Transaction.withCriteria {
projections {
sum('amount')
groupProperty('timeMonth')
}
}

How to exclude some columns with GORM with dynamic finders?

I have the following domain object:
class DbDeployment
{
static constraints = {
startDate(nullable: false)
endDate(nullable: true)
username(nullable: true)
fabric(nullable: false)
description(nullable: true)
status(nullable: true)
details(nullable: true)
}
static mapping = {
columns {
details type: 'text'
}
}
Date startDate = new Date()
Date endDate
String username
String fabric
String description
String status
String details // xml representation of the plan
}
I would like to be able to run a query like this:
DbDeployment.findAllByFabric("f1", params)
but I would like to ensure the column details (which is potentially huge) is not retrieved.
Is there a way to do this?
Option 1: Create an association for the large data field(s)
One suggestion from this answer is to break the large data property out into a separate domain, which will cause it to load lazily. Example:
class DbDeployment {
Date startDate = new Date()
Date endDate
...
DbDeploymentDetails details
}
class DbDeploymentDetails {
String details
static belongsTo = DbDeployment
}
Option 2: Using a new domain + mapping to the original table
An answer on a different question links to a Grails mailing list question which has a great answer from Burt Beckwith, but the SO answer doesn't give an example. For the sake of posterity I'll yoink his example from the mailing list and put it here.
It involves creating another domain class without the large field, and then using its static mapping closure to map to the other domain's table.
class DbDeployment {
Date startDate = new Date()
Date endDate
...
String details
}
class SimpleDbDeployment {
Date startDate = new Date()
Date endDate
...
// do not include String details
static mapping = {
table 'db_deployment'
}
}
Then you can just use the finders on SimpleDbDeployment:
SimpleDbDeployment.findAllByFabric('f1', params)
Burt, it'd be great if you would re-answer with your example from the mailing list; I'll cut it out of mine and upvote yours, since you deserve the credit.

Resources