Thursday 27 November 2008

Counting using Grails/Hibernate criteria

Just a quick gotcha for grails criterias when you want to count the results from a query where there is a join involved. If you use

count = criteria.count {
projections {
rowCount()
}
query()
}

You'll get a count for each of the joins, you might think that you could use

count = criteria.count {
projections {
countDistinct('id')
}
query()
}

But that still doesn't work - you have to use

count = criteria.get {
projections {
countDistinct('id')
}
query()
}

Hmmm

Monday 24 November 2008

Autobase 0.5 plugin released

Robert Fischer just announced the latest version of the Autobase plugin which simplifies Liquibase usage by way of providing a Groovy DSL to use it by.

http://github.com/RobertFischer/autobase/wikis/example-usage

Much more compact and more Groovy! Looks like all ur Liquibase migrations r belong to Autobase nao!

Monday 17 November 2008

Groovy Awesomeness

Hey check this out:

Java:


import java.util.Calendar;
import java.util.Date;

public class PrintIndependenceDay {

public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, Calendar.JULY);
calendar.set(Calendar.DATE, 4);
calendar.set(Calendar.YEAR, 1776);
Date time = calendar.getTime();
System.out.println(time);
}
}


Now check the awesomeness groovy gives you:

def calendar = Calendar.instance
calendar.with {
clear()
set MONTH, JULY
set DATE, 4
set YEAR, 1776
println time
}


Here is the full article that explains everything: Getting Groovy with 'with'

rock on

Sunday 16 November 2008

Friday 14 November 2008

Fun With Groovy Categories

Just a quick stupid trick I discovered. Commons Lang's StringUtils class works quite nicely as a category for String, e.g.
    use(StringUtils) {
println 'i can has cheezburger'.substringAfter('i can has ') // prints 'cheezburger'
}
Not only that but the JetGroovy plugin for IntelliJ IDEA will autocomplete all the new String methods inside the use block.

Monday 10 November 2008

Checking HTTP Headers

Disclaimer: This post has nothing to do with Grails, other than the application we're testing is a grails app!

We're starting to "productize" our application. One of the stories is to ensure all javascript, CSS and image files are served with an appropriate set of HTTP headers so they can be cached effectively. For this we're using good old HTTP unit (I'll post about that more when we're finished), but in the meantime I've found the 'tcpdump' command very useful.
sudo tcpdump -A -ilo0 -t -s 1500 port 8080

-A prints ASCII
-i specifies the interface (I'm testing locally so lo0 is the loopback interface)
-t supresses timestamps
-s How many bytes to print (I wanted to see the full packet so set it to 1500)
port 8080 Tells tcpmon to only show me stuff going to or coming from port 8080

This results in output like

...GET /script/N259177905/bundles/stuff.js HTTP/1.1
User-Agent: httpunit/1.5
Cookie: splash=false
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


IP localhost.http-alt > localhost.53121: . ack 1892 win 65535 >nop,nop,timestamp 219937537 219937537<
E..4.n@.@...............:.,A.........(.....
...
IP localhost.http-alt > localhost.53121: . 197931:214263(16332) ack 1892 win 65535 <nop,nop,timestamp 219937537 219937537>
E.@.q.@.@...............:.,A........=......
...HTTP/1.1 200 OK
Content-Type: text/javascript; charset=UTF-8
Expires: Sat, 10 Nov 2018 11:24:54 GMT
Cache-Control: public, max-age=315360000, post-check=315360000, pre-check=315360000
Last-Modified: Sun, 06 Nov 2005 12:00:00 GMT
ETag: 2740050219
Transfer-Encoding: chunked
Server: Jetty(6.1.4)

6000
;(function(){function r(val,args){for(var x=0;x<args.length;x++){val=val.replace('{'+x+'}',args[x]);}
return val;}
function p(){var val=arguments[0];var ret;if(val.indexOf('{0}')!=-1)
ret=function(){return r(val,arguments);}
else ret=function(){return val;}
...

I'm sure there's more I could do to fine tune the output, but it's a good starter for 10!