Wednesday, March 19, 2008

Test in Grails

Grails provide us simplest test framework.if you want to test your function,jutst run following command:
>>grails create unit-test
then Grails will ask you which Domain you want to test.for example type project
Then Grials will generate a class in directory: gwork\gira\workspace\test\integration
Write some code like this
class ProjectTests extends GroovyTestCase {

void testSort() {

def sortByAttribute={property ->
Project.findAll().sort{it."$property"}.title
}


def titles=sortByAttribute("title")
assert titles
assert titles.size()==3
assert titles[0]=="App1"
}
void setUp(){
new Project(title:'App1',description:'This is a test',createDate:new Date()).save()
new Project(title:'App2',description:'This is a test',createDate:new Date()).save()
new Project(title:'App3',description:'This is a test',createDate:new Date()).save()
}
void tearDown(){
Project.list()*.delete()
}
}
Then run command:
>>grails run-test
You will get the test reult.

Dynamic scaffod in Grails

listed the all three command to create dynamic scaffod:
• grails generate-views: Generates views for the specified domain class

• grails generate-controller: Generates a controller for the specified domain class

• grails generate-all: Generates both a controller and associated views

Hpw to change the default context of Grails server

Today I commit my code into google code project.As before my project named sparrow,because sparrow is another project's name so I can't use it now,I changed it to gria.but when I run the command
>>grails run-app
I found the context of Grails server is still sparrow.Oh,how to change it.I found there is application.properties file in my project directory,I edit it like this
app.name=gria
Then the server's context change to gria.

Tuesday, March 18, 2008

The inList conatraint must follow blank constraint

I found an interesting thing,that is if you set the property of Grails's Domain class with a constratint--inList,like this:

priority(inList:["High","Low"])

then,when you open the page to edit or create this domain,you will find that the property can't be select by a HTML select box.So,you must follow another constraint blank and set it false.like this:

priority(inList:["High","Low"],blank:false)

Is it a bug?

Monday, March 17, 2008

Constraint in Grails

Grails use constraint key word for Domain class's constraint.As a note,I summary the constraint in Grails Domain Model.





























































































NameExampleDescription
blanktitle(blank:false)Set to false if a string value cannot be blank
emailemail(email:true)Set to true if the value must be an email address
inListsex(inList:['Man','Woman'])Value must be contain within the given list
lengthtitle(length:1..50)Use a range value to restrict the length of string or range
minage(min:new Date()Set the minimun value
minLengthtitle(minLength:5)Set the minimum length of a string or array property
minSizechildren(minSize:10)Set the minimum size of a collection or number property
matchesname(matches:/[a-zA-Z]/)Matches the supplied regular expression
maxage(max:new Date()Set the maximum value
maxLengthtitle(maxLength:5)Set the maximum length of a string or array property
maxSizechildren(maxSize:10)Set the maximum size of a collection or number property
notEqualname(notEqual:'Eric')Must not equal the special value
nullablenameSet to false if property value cannot be null
rangeage(range:30..60)Must occur within the special range
sizechildren(size:5..15)Use a range to restrict the size of a collection or number
uniquename(unique:true)Set to true if the property must be unique
urlurl(url:true)Set to true if a string value is a url address

HQL in Grail

Today we'll discuss the HQL query in Grail.as you know,Grails's GROM is based on Hibernate.So you can use HQL to implement sql query in Grails.Grails provide three static method:find,findAll and executeQuery.Here are some demonstrate

/**find method*/
//following method will return a project object whose attribute is 'App1'
def project=Project.find('from Project p where p.title=?',['App1'])
/**findAll method*/
//following method will return all of project objects.
def projectList=Project.findAll('from Project')
//Grails also provide a elegant IN operator
def plist=Project.findAll('from Project')
def ilist=Issue.findAll("from Issue as b where b.project in (:p)", [p:plist])
/**executeQuery method*/
def plist=Project.executeQuery("select distinct p.title from Project p")
//it is possible to perform more-advanced queries using joins, aggregate functions, and subqueries.
And also we can some limit for query result number,for example:
def plist=Project.executeQuery("select distinct p.title from Project p",[max:10,offset:5])
)

Sunday, March 16, 2008

Dynamic Finders in Grails

In last section,we discussed the CRUD method in Grails.Now,we'll learn one .of the most powerfull concept of GORM (findBy* method).Following figure shown a example method.
This figure from the book:the definitive guid to grails.
Now I list the available Dynamic Finder method and example:
Expression Arguments Example
Between 2 Project.findByCreateDateBetween(today-10,today)
Equals 1 Project.findByTitleEquals('App1')
GreaterThan 1 Project.findByCreateDateGreaterThan(lastmonth)
GreaterThanOrEqual 1 Project.findByCreateDateGreaterThanOrEqual(lastmon)
IsNull 1 Project.findByTitleIsNull()
IsNotNull 1 Project.findByTitleIsNotNull()
LessThan 1 Project.findByCreateDateLessThan(lastmonth)
LessThanOrEqual 1 Project.findByCreateDateLessThanOrEqual(lastmonth)
Like 1 Project.findByTitleLike('App1%')
NotEqual 1 Project.findByTitleNotEqual('App1')

All of findBy* method only return that fisrt be found object.
There are two cousins method findAllBy* and countBy*.
findAllBy* :return a list that is matched the query logic
countBy* :return a number that is matched result total.

Data operator CRUD in Grails

How to implement CRUD(create,read,update,delete) in Grails.The answer is ,it's simple.Because of the Grails's GROM is based on Hibernate and we have already have the Domain class,and it's alsp maped to database table.So now,you can just simple use save(),update(),delete() method.let me demonstrate how to do these:In this section,I will use the Project and Issue Domain Object in Sparrow.
/**Create data*/
//create a project
def project1=new Project(title:'Project1',description:'Hello world!',createDate:new Date())
//now we have the project object.we will save it.
project1.save()
//as you can see ,we never define the method save().but we can use it,because Grails auto //generate it in runtime for us.when we call this method,the project information will be saved in database table,it's cool.
//Now we'll define issue object
def issue1=new Issue(summary:'Issue1',description:'This is a issue',createDate:new Date(),project:project1)
//we created the issue object,but the different in this place.we have a parameter project:project1 ,because the project and issue has a one-many relationship,so we need point there whcih Project that this Issue belong to.
/**read*/
after we create the object information.we usually need get these data.how to do that?the answer is get(id) and exists(id) method.
//get Project by ID
def p1=Project.get(1)//we will use id parameter get a project,which id is 1
def boolean=Project.exist(1)//the exists method will return ture if it's exists.
The exists method, reads better and is arguably more performant than get method.
if(Project.get(1)){
def p=Project.get(1) //bad performant,because you called twice get method
}
if(Project.exists(1)){
def p=Project.get(1) //better performant
}
/**update Object*/
//update object is easy
def p=Project.get(1)
p.title='New title'
p.save()

/**delete Object*/
def p=Project.get(1)

p.delete()

/**sort,listing,and counting*/

GORM provides a list method, which takes a number of named arguments such as max, offset,
sort, and order to customize the results, the definitions of which are listed here:
• max: The maximum number of instances to return
• offset: The offset relative to 0 of the first result to return
• sort: The property name to sort by
• order: The order of the results, either asc or desc for ascending and descending order respectively

//demonstrate
//get all objecta
def allProject=Project.list()
//get top 10 objects
def topten=Project.list(max:10)
//sort objects
def sortingProject=Project.list(max:10,sort:'createDate')
//sort and order
def sortingProject2=Project.list(max:10,sort:'createDate',order:'desc')
//order by column name
def allBycreateDate=Project.listOrderByCreateDate()
Note:the listByCreateDate is auto generate by Grails.it's a role,that means listOrderBy+property'name

Friday, March 14, 2008

How to create the Domain-class of Grails--Sparrow begin

After several days basic setup and config,our architecture of project Sparrow has been create.Now we'll start our first step:create domain object.

But before the beginning of our process,let me introduce the requirement of our Sparrow.For facilitate,I will illustrate the requirement by a UML diagram.

As you can see, our project will include three functions.
1)create a project.
2)create issues for this project.
3)create issues type for existing issues.

Following is the Domain Class Model :

Now,let's begin.In Grails,it use the Hibernate for ROM ,but as the same time Grails extend the Hibernate,we call this extension "GOM".It's also based on "Convention Role",so we only need create a POJO class by Groovy language.In our project there are three domain class we'll create.Grail provide us a easy to used tool.To do this,just open the command line.type:

>>grails create-domain-class

then enter the class name ,for example :project.
Grails will auto generate a class with capitalize letter.like this:

class Project {
static hasMany=[issues:Issue]//one project can has many issues
String title
String description
Date createDate
}

Note:the hasMany is a key word of Grails,that means one project can has many issues.so Issue class will have a belongsTo attribute.like this:

class Issue {
static belongsTo=Project
Project project
String summary
String description
Date createDate
}

Because of we have create our database(postgreSql).now we run our application.

>>grails run-app

You'll see that grails auto create the database table for these two domain class.
As you can see Grails auto create two field "id" and "version".it's a convention,also id is a default key and it's request.And also,may be you have saw that the property field "createDate" in database table is create_date,because the createDate field has a capitalize letter "D",so it replace by "_d".yes it's also a convention.

Wednesday, March 12, 2008

How to config Grails's datasource

As you can see,there is a directory named conf($App_home$/grails-app/conf),it include many configuration file.Today we'll disscuss how to config Grails's datasoure.Because of Grails leverages Hibernate,it supports every database that Hibernate support.Following list the Grails supported database.
• DB2 7.1, 7.2, 8.1
• HSQLDB
• HypersonicSQL 1.61, 1.7.0, 1.7.2, 1.8
• Microsoft SQL Server 2000
• MySQL 3.23, 4.0, 4.1, 5.0
• Oracle 8i, 9i, 10g
• PostgreSQL 7.1.2, 7.2, 7.3, 7.4, 8.0, 8.1
• SAP DB 7.3
• Sybase 12.5 (JConnect 5.5)
• Timesten 5.1
Let me assume that we use postgresql.Then we should download the JDBC driver from postgresql homepage,and copy it into the directoty lib($App_home$/lib).Then edit the file DataSource.groovy in directory conf.like this(I add some comments for every section):
dataSource {
pooled = true //which allows you to configure whether to use a connection pool or not
driverClassName = "org.postgresql.Driver" //the database driver class name
username = "postgres" //database name
password = "123456" //database password
}
//It is the configurate for hibernate,you can change it fit your want.
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}
// environment specific settings,there are three database for our application.
//sparrow_dev:for development phase.
//sparrow_test:for test phase.
//sparrow_pro:for product phase.
environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop','update'
url = "jdbc:postgresql://127.0.0.1:5432/sparrow_dev"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:postgresql://127.0.0.1:5432/sparrow_test"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:postgresql://127.0.0.1:5432/sparrow_pro"
}
}
}

Now,you can run you application under a database model.congratulation.

Monday, March 10, 2008

What the Grails application directory contains?

When you run command grails create-app,what happened?The answer is it create a lot of directory and file to you.they are the core of a Grails application.Today let me explain what are these folders and files means to you.I make a summary of these stuff as a list:

grails-app:This directory containing core Grails artifacts
+conf: Contains configuration elements,such as DataSource.groovy,UrlMappings.groovy
+controllers :Controllers that handle requests
+domain:Contains domain object class.
+i18n:Contains internationalization message bundles.
+services:Services that encapsulate business logic
+taglib:Dynamic tag libraries
+views:Groovy server page or JSP.
+layouts:the GSP or JSP layouts powered by sitemesh.
grails-test:application unit tests.
hibernate:optional Hibernate configuration.
lib:java lib jar archives
spring:optional Spring configuration.
src:Include other Groovy or Java sources.
+java:Further Java sources for compilation.
+groovy:Further Groovy sources for compilation.
web-app:web application resources (CSS, JavaScript, etc.)

How to change the default servlet version of Grails

Because Grails use Jetty as its default servlet container,so its default servlet version is "2.4".for some reason,may be we need to develop our application under the version 2.3 or 2.5 then how to change its default behavior?Then way is:
1)passs argument -Dservlet.version,for example:
>>grails -Dservlet.version=2.5 run-app
2)Or we can directly edit the Init.groovy file in directory Grails_Home/scripts.find the key "servletVersion" and change its default value from 2.4 to others what you want,for example:
servletVersion = System.getProperty("servlet.version") ? System.getProperty("servlet.version") : "2.5"

How to display database comments of table's columns

If you want to show the comments of a database tbale's column then try this way.
select * from user_col_comments where table_name='table name'
as same principle.we can show the table's comments:
select * from user_tab_comments where table_name='table name'

How to change the default port number of Grails server

Grails use Jetty as its server,and run port 8080 by default.for some reason,we should change it ,for example 9090,how to do?There are two ways:
1) when you do run-app,add command -Dserver.port=9090.for example
>>grails -Dserver.port=9090 run-app
2) if you want to change the port to 9090 as default value,then Edit the file GRAILS_HOME/scripts/Init.groovy and change the phrase 8080 to another port number like 9090 .

A good IDE for develop dynamic language.

Recently,we begin our new project named Sparrow.It's a project manage and trace application.
We decide to find a easy to use and free license IDE for our team.After a several of days,we found a good tools open komodo .It's support a lot of existing dynamic language.such as python,ruby,lisp and several of dynamic language such as django. etc....Also it's support customizable feature ,such as customize command,customize menu etc.. We'll use this IDE in our Sparrow application.

Sunday, March 9, 2008

The Controllers in Grails framework

Grails is an MVC framework and has models,controllers and views to cleanly separate concerns.
So let's create our first controller for our Sparrow.let's assume we want a page to say hello for everyone who access our app.The requirement is simple,it's just print a "hello world "(Yes,always hello world).It's easy to do this in Grails.We need a controllers,type following command:
>>cd sparrow
>>grails create-controller
Grails will ask you what's controller name.pls type hello
After a minute,Grails will create a HelloController.groovy in path /sparrow/grails-app/controllers/
then open it and find the index method.Note every methods in this groovy file are action .the index method is the default behavior when you navigate following url:http://127.0.0.1:8080/sparrow/hello/
We will modify this method like this :
def index = {
render "Hello World!"
}

When you navigate http://127.0.0.1:8080/sparrow/hello/
you'll see a page with "Hello World!" string.Note this file is a standard groovy file.index method is a default method as I said at above.the render also a keyword.We can assume it like Response object's write method in Java servelt.
If you want define other action in hello controller.just define a new method in the file HelloController.groovy.for example.I want to show a good bye information.Just add following method :
def saygoodbye={
render "Good Bye!"
}
then navigate to following url: http://127.0.0.1:8080/sparrow/hello/saygoodbye.
Note:in this url,
the http://127.0.0.1:8080/ is domain and port.
the saprrow is context path.
the hello is controler name.
the saygoodbye is action name.
In future section we'll discuss it detail.

My friend get a new job

From 9 months wait in home,my friend Bony get her new job.She will work for a computer company ,too(like me).I'll congratulate her,and I'll have a dinner with her tonight,it'll be my treat.Oh,one more thing,what's for dinner?I think tuna salad is good,I like it:).
In the end, I wish she have a good luck beginning.God bless her.

Getting start with Grails for our Sparrow app

Today we'll start to our Sparrow app.As a learning project we'll begin from how to create and run an application.
As you can see,our app's name is Sparrow,then how to create it,follow me.
open your command line.type
>>make dir learnapp
>>cd learnapp
>>grails create-app
after this,grails will ask your what's name your project.we'll tyep
>>sparrow
then grails will generate all of you need to start an application.Note,Grails is a role framework.so you will see somes like domain,controllors,tlb folder etc.in the future,we'll create relative file to fit our application.for now,we only need a blamk frame,but it's a runable application.we'll start our first grails app.type following command:
>>cd sparrow
>>grails run-app
You will see some run time information in console.then open your favorite browser then type:
http://127.0.0.1:8080/sparrow/
you will see a welcom page like this:

Grails used Jetty as its default servlet container.In the future,may be you want to move it to other containers such as tomcat .or some appservers such as JBoss.You can just type grails war .Grails will generate a war file for you,then you can make your own deployment in others environment.
Now.through only a few commmand you create a runable application.It's really cool.In the following section,we'll discuss how to add our first domain model project.we'll add some useful feature for our application and introduce what grails's domain model is as same time.

Grails Command-Line Help

Because our Sparrow is a learning project for Grails.So,let me list the command-line help for how to create a project.here they are:
>grails
help:
Usage: grails [target]
Targets:
"create-app" - Create a new grails app
"create-controller" - Create a new controller
"create-service" - Create a new service
"create-domain-class" - Create a new domain class
"create-taglib" - Create a new tag library class
"create-test-suite" - Create a new test suite
"create-job" - Create a quartz scheduled job
"generate-controller" - Generates a controller from a domain class
"generate-views" - Generates the views from a domain class
"generate-all" - Generates all artifacts from a domain class
"test-app" - Run current app's unit tests
"run-app" - Run the application locally and wait
"create-webtest" - Create the functional test layout
"run-webtest" - Run the functional tests for a running app
"shell" - Opens the Grails interactive command line shell
"console" - Opens the Grails interactive swing console
"war" - Create a deployable Web Application Archive (WAR)

While you run these command.you will note at this point that Grails uses the Apache Ant.

Domain model for Sparrow


Today we create the domain model for Sparrow system.For now,it's only a draft version.
Also you can find the soure file from here

Start new project Sparrow

Today we plan to start a new project named Sparrow.It's a project manage framework.In this project we'll provide project manage feature.It'll based on Grails framework,as you will see.we'll create it as a learning project.That means,we'll learning it and development it step by step.

Friday, March 7, 2008

Lock step iteration in Python

Today I will log this big feature in python 2.x.That is lock set iteration.so what's that?let's assume,we have two list and for some reason we want to iteration them in the same time.In other language(eg.Java).we need a nesting loop.But in python .we can use map function,it's build-in.following code is a example.
>>a=(1,2,3)
>>b=(4,5,6)
>>for i in map(None,a,b): print i
The result is :
(1, 4)
(2, 5)
(3, 6)
Wow.It's cool ,right.now assume the length of each list is different.for example,we set them like this
>>a=(1,2,3)
>>b=(4,5,6,7,8)
The result is:
(1, 4)
(2, 5)
(3, 6)
(None, 7)
(None, 8)

As you can see,now we have two extra small list with the element None.Yes,Python auto append a None type in last list,because it is the first parameter in the map function.Until now,it looks good ,right ?we only write one line code ,then map function do two times loop.But it's not elegant.because :
 - It is non-obvious to programmers without a functional
programming background.
- The use of the magic `None' first argument is non-obvious.
- It has arbitrary, often unintended, and inflexible semantics
when the lists are not of the same length: the shorter sequences
are padded with `None'.

Fortunately,we have another function,zip.yes it's good to use.let me give a example:
>>a=(1,2,3)
>>b=(4,5,6,7,8)
>>zip(a,b)
The result is:
(1, 4)
(2, 5)
(3, 6)
Yes,as you can see,no other two redundant list.it's more clearly.of course,if you think that
other twos is useful,you can also use the map function.But now we have another choose.

get up on the wrong side of the bed

It' a bad day today.I feel bad because I have a mistake in my work.I feel bad because I can't put up with my mistake.It should not be happened.It's happened just because I careless of the description in the document.just one sentence I missed.although it is only a small mistake but I can't bear me to do that again.I promise I will never ever slip a cog like this.never!

Wednesday, March 5, 2008

How should I say,I like grails

In my several years development by profession.I used several computer languages,such as C++,Java,Python and many of web framework.But for Grails,I said ,it's really a good framework.because it's based on Groovy language,and very easy to use,also it can access all most of Java library ,that means I never have to give up I have know about Java.So I think I'll be successful.