def p = new Expando(
name:'Mary',
pets:[
new Expando(name:'Fido', species:'Dog'),
new Expando(name:'Snickers', species:'Cat')
]
)
def json = new JsonBuilder()
json( {
name p.name,
pets( p.pets.collect {[
name:it.name,
species:it.species
]})
})
JsonOutput.prettyPrint(json.toString())
About digital things I find interesting. Like internet, software development, mobile phones, social media
About Me
- Olaf
- Freelancing software developer / architect, mobile geek. Topics: Software technologies (java, groovy, agile), politics, web, science, green, mobile, android.
Homepage: www.tutaona.com
"The absence of limitations is the enemy of art." - Orson Welles
Montag, 25. Juni 2012
Easy JSON Building
Labels:
groovy
Access Grails Config in Non-DI Classes
ApplicationContext context = servletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) as ApplicationContext ConfigObject grailsConfig = context.getBean(GrailsApplication).config
Labels:
grails
Freitag, 22. Juni 2012
My unity theme for 12.04
Installing Ubuntu-Tweak to get more control over the theme.
sudo add-apt-repository ppa:tualatrix/ppa
sudo apt-get update
sudo apt-get install ubuntu-tweak
Some more colors for ambience and radience gives more choice for the filesystem folders as I don't like the humanity orange.
sudo add-apt-repository ppa:ravefinity-project/ppa
sudo apt-get update
sudo apt-get install humanity-colors
sudo add-apt-repository ppa:ravefinity-project/ppa
sudo apt-get update
sudo apt-get install ambiance-colors radiance-colors
The Zukitvo theme is very nice.
sudo add-apt-repository ppa:webupd8team/themes
sudo apt-get update
Labels:
ubuntu
Using SQL Views With Grails
The Problem
In a recent grails backend project for a conference management system I had a complex synchronization where the initial sync could be quite large. As the clients were iPads and could have connection and bandwidth constraints so the huge initial sync must happen in chunks. So if a client due to connectivity problems fails to receive a chunk it can request it again and not too much of data has to be transferred again. As the iPad knows about it's connection quality the app could even adjust the chunk size to its needs. Large chunks (causing less overhead) when the connection is good and smaller chunks (less data to resend) when the connection is poor. The idea was to use SQL views to create a snapshot of the database and use HQL queries against the views with all it's paging convenience for simple chunk handling code.
The problem was that GORM has no support for views. If you query a view GORM cannot map it to anything as there is no mapping defined. Moreover as the views must have different names for each sync and GORM's mapping of domain classes to tables is defined static but I needed the mapping to be dynamic. That was a hard one to solve.
Creating SQL Views in Grails
That was rather something simple as groovy has support for SQL. So I just take a client ID to make the view's name unique.
The business logic (controller/service)
In a recent grails backend project for a conference management system I had a complex synchronization where the initial sync could be quite large. As the clients were iPads and could have connection and bandwidth constraints so the huge initial sync must happen in chunks. So if a client due to connectivity problems fails to receive a chunk it can request it again and not too much of data has to be transferred again. As the iPad knows about it's connection quality the app could even adjust the chunk size to its needs. Large chunks (causing less overhead) when the connection is good and smaller chunks (less data to resend) when the connection is poor. The idea was to use SQL views to create a snapshot of the database and use HQL queries against the views with all it's paging convenience for simple chunk handling code.
The problem was that GORM has no support for views. If you query a view GORM cannot map it to anything as there is no mapping defined. Moreover as the views must have different names for each sync and GORM's mapping of domain classes to tables is defined static but I needed the mapping to be dynamic. That was a hard one to solve.
Creating SQL Views in Grails
That was rather something simple as groovy has support for SQL. So I just take a client ID to make the view's name unique.
The business logic (controller/service)
def dataSource // the Spring-Bean "dataSource" is auto-injected
@Secured([Role.ROLE_RECEPTIONIST])
def syncUsers = {
def clientId = params.client
long syncpoint = params.syncpoint ? params.syncpoint : 0) as Long)
def roleAttendee = Role.findByAuthority(Role.ROLE_ATTENDEE)
def db = new Sql(dataSource)
def query = "CREATE VIEW syncview_user_"+clientId+" \
AS SELECT u.* FROM user AS u, user_role AS ur \
WHERE ur.user_id = u.id AND ur.role_id = $roleAttendee.id"
db.execute(query)
}
The hibernate interceptor (src/java)
import org.hibernate.EmptyInterceptor
import org.springframework.web.context.request.RequestContextHolder
public class DynamicTableNameInterceptor extends EmptyInterceptor {
public String onPrepareStatement(String sql) {
if(RequestContextHolder.getRequestAttributes()) {
def params = RequestContextHolder.currentRequestAttributes().params
println ">>>> $sql"
println params
//params.each { println it}
sql = sql.replaceAll("from user ", "from syncview_user_"+params.client+" ")
println sql
println "------"
}
return sql //.replaceAll('_SCHEMA_', schema)
}
}
resources.groovy:
beans = {
entityInterceptor(DynamicTableNameInterceptor)
}
Labels:
grails
List Test-App Execution Order
Neat little bash magic
function grailsTestOrder() { grep testsuite target/test-reports/TESTS-TestSuites.xml | grep -v testsuites | cut -d\ -f8-9 | sed -E 's/name="(.*)" package="(.*)"/\2.\1/' | grep . } alias testorder=grailsTestOrder
Labels:
grails
Donnerstag, 10. Mai 2012
Simple Webservices Client
import grails.converters.*;
def url = new URL("http://www.your-needed-webservice-with-a-json-response.com")
def response = JSON.parse(url.newReader())
Labels:
grails
Executing a SQL Script on Startup
import groovy.sql.Sql
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
String sqlFilePath = ApplicationHolder.application.parentContext.servletContext.getRealPath("/data/table_dump.sql")
String sqlString = new File(sqlFilePath).text
Sql sql = Sql.newInstance(CH.config.dataSource.url, CH.config.dataSource.username, CH.config.dataSource.password, CH.config.dataSource.driverClassName)
sql.execute(sqlString)
Labels:
grails
Abonnieren
Posts (Atom)