register
other register

Friday, August 14, 2009

Database Result to Groovy List, Map

Person --* Order --* LineItem *-- Product


def lineItemList = LineItem.findAll()
def t = []
def q = []
def lineItemMap = []
def orderMap = []
def packs
lineItemList.order.person.unique().each { person ->
def p = []
orders = lineItemList.findAll{it.order.person == person}.order
orders.unique().each { order ->
lineItemMap = lineItemList.findAll{it.order == order}
orderMap = [orderId: order.id, lineItemId: lineItemMap.id]
p.add(orderMap)
// Use the statement below to get all the products
//products = LineItem.getAll(lineItemMap.id).product
}
q = [personId: person.id, order: p]
t.add(q)
}


[[personId:1, order:[[orderId:1, lineItemId:[1, 2]], [orderId:2, lineItemId:[3, 4]]]]]

[[personId:1, order:[[orderId:1, lineItemId:[1, 2]]]], [personId:2, order:[[orderId:2, lineItemId:[3, 4]]]]]

Thursday, August 06, 2009

Domain Class (Primary Key) Update and Table Generation

If you set dbCreate = "update" in the DataSource.groovy, then every time you change the domain class, the grails will update the table for you. Sometimes if it doesn't (the primary key (strategy) is changed), then drop the table, and restart the grails application. And it will reflect the changes in the domain class.

To use a manually assigned value as a primary key rather than the default auto_increment one, do:

class Person {
String id

static mapping = {
id generator: 'assigned', column: 'id'
}
}

Monday, August 03, 2009

List (array) of parameter values

Sometimes in a web form, it is useful to allow inputting multiple values to be associated with one

In some scenarios, a web form can allow inputting multiple values to be associated with the same named field:

<form>
<input name="key" type="text">
<input name="key" type="text">
</form>

The posted url is like: ?key=value1&key=value2

In Grails, params['key'] is always used to get parameter value. The default behaviour will return:

a string if the key only has one value (i.e. ?key=value)
a List if the key has many values (i.e. ?key=value1&key=value2)

It causes problems when you are not sure how many values the key is associated with.

Solutions:

In Java Servlet API, there is a method for Interface ServletRequest

java.lang.String[] request getParameterValues(java.lang.String name)

Returns an array of String objects containing all of the values the given request parameter has, or null if the parameter does not exist.

request.getParameterValues('key')
class [Ljava.lang.String;

According to http://groovy.codehaus.org/JN1025-Arrays, we can use the following code to reconstruct the query string:

def queryArray = request.getParameterValues('key')
def queryString = ""
queryArray.each {
queryString += "&key=$it"
}




For the query string like: http://blabla.com/list?personId=1&personId=2

To accommodate this, in Grails scaffolded list closure:


def list = {
def personList
if (params['personId'] != null) {
personList = Person.getAll(Arrays.asList(request.getParameterValues('personId')))
}
else {
personList = Person.list()
}
}


To cast an array into a list, using:

Arrays.asList(array[])


Also refer to http://prideafrica.blogspot.com/2007/01/javalangclasscastexception.html for some useful info regarding [Ljava.lang.String.