Groovy: Efficiency Oriented ProgrammingLecture 12Master Proteomics & Bioinformatics - University of GenevaAlexandre Massel...
Agenda‣ Linux tip-of-the-day‣ GORM relationships‣ Database batches‣ Application configuration
Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME...
Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME...
Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME...
Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME...
Objects dependancies ↔ domain relationships        (↔ foreign keys constraints)
Different type of relationships
Different type of relationships‣ one-to-one
Different type of relationships‣ one-to-one‣ one-to-many
Different type of relationships‣ one-to-one‣ one-to-many‣ many-to-many
The pedestrian one-to-many‣Message.groovyPerson commiter
The pedestrian one-to-many‣Message.groovyPerson commiter‣ Person.groovySet<Messages> messages=[]def addToMessages(msg){  m...
The pedestrian one-to-many‣Message.groovyPerson commiter‣ Person.groovySet<Messages> messages=[]def addToMessages(msg){  m...
GORM: do not care about SQL/Hibernate
Dependency to a single bean: typed member
Dependency to a list of beans: hasMany
Dependency direction: belongsTo
One-to-one relationship
Example: a Profile object with details for a user        1 Person ↔ 0:1 Profile
one-to-one   (cont’d)
one-to-one                              (cont’d)class Profile { String homePage    static constraints = {      homePage(ur...
one-to-one                            (cont’d)class Profile { String homePage static belongsTo = Person  static constraint...
one-to-one                                      (cont’d) ‣ Setting a profile  joe.profile=new Profile(url=‘http://www.exam...
one-to-one                                      (cont’d) ‣ Setting a profile  joe.profile=new Profile(url=‘http://www.exam...
one-to-one                          (end) void testProfile(){    assert Person.count() == 0    assert Profile.count() == 0...
one-to-one                                                      (end) void testProfile(){    assert Person.count() == 0   ...
one-to-one                                                        (end) void testProfile(){    assert Person.count() == 0 ...
one-to-one                                                        (end) void testProfile(){    assert Person.count() == 0 ...
One-to-many relationship
Example1 Person ↔ n Message
one-to-many‣ Person.groovy  static hasMany = [messages: Message]
one-to-many‣ Person.groovy  static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]
one-to-many‣ Person.groovy  static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]‣ Add...
one-to-many‣ Person.groovy   static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]‣ Ad...
one-to-many‣ Person.groovy   static hasMany = [messages: Message]‣ Message.groovy  static belongsTo = [commiter:Person]‣ A...
many-to-many relationships
Example: a Message contains many Tag           and vice-versa       n Message ↔ m Tag
many-to-many‣ Message.groovy:static hasMany = [tags:Tag]
many-to-many‣ Message.groovy:static hasMany = [tags:Tag]‣ Tag.groovy:class Tag{  String name    static hasMany = [messages...
many-to-many‣ Message.groovy:static hasMany = [tags:Tag]‣ Tag.groovy:class Tag{  String name    belongsTo = Message    sta...
belongsTo: who adds who?
my_msg.addToTags(my_tag).save()
Self referencing domain
Twitter example: a Person is following others
static hasMany = [            messages: Message,            followings: Person                   ]
Application configuration: beyond default
Three environments:development (run-app)test (test-app -integration)production (war deployment)
Goal: a persistent development database
DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy
DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy‣ Global vs environment con...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
hsqldb on file‣ Database is saved in 3 flat files
hsqldb on file‣ Database is saved in 3 flat files‣ e.g. devDb.script CREATE SCHEMA PUBLIC AUTHORIZATION DBA CREATE MEMORY ...
More configuration‣ All configuration files reside into grails-app/conf
More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much
More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much‣ For example, to set f...
Populating the database with batch
Inserting elements at application start:        BootStrap.groovy
grails-app/conf/BootStrap.groovyclass BootStrap { def init = { servletContext ->   }   def destroy = {   }}
grails-app/conf/BootStrap.groovyclass BootStrap { def init = { servletContext ->      environments {         test {       ...
grails-app/conf/BootStrap.groovyimport eop.lec12.twitter.Personimport eop.lec12.twitter.Profileclass BootStrap { def init ...
grails-app/conf/BootStrap.groovyimport eop.lec12.twitter.Personimport eop.lec12.twitter.Profileclass BootStrap { def init ...
Another batch: uploading a list of messages
Uploading a file
Uploading a file1. a local file with a list of contents convertible into messages  (rss feed with publication update from ...
Uploading a file1. a local file with a list of contents convertible into messages  (rss feed with publication update from ...
Uploading a file1. a local file with a list of contents convertible into messages  (rss feed with publication update from ...
Uploading a file1. a local file with a list of contents convertible into messages  (rss feed with publication update from ...
Uploading a file1. a local file with a list of contents convertible into messages  (rss feed with publication update from ...
Input file
Input file‣ Download Scientific American’s feedhttp://rss.sciam.com/ScientificAmerican-Global
Input file‣ Download Scientific American’s feed http://rss.sciam.com/ScientificAmerican-Global‣ Nature’s feed http://feeds...
Input file‣ Download Scientific American’s feed http://rss.sciam.com/ScientificAmerican-Global‣ Nature’s feed http://feeds...
Input file‣ Download Scientific American’s feed http://rss.sciam.com/ScientificAmerican-Global‣ Nature’s feed http://feeds...
http://localhost:8080/eop.lec12.twitter/message/loadListgrails-app/controllers/MessageController.groovy :                 ...
loadList.gspenable the form to upload file   <g:form controller="message" action="loadList"     method="post”     enctype=...
MessageController.groovy def loadList = {  }
MessageController.groovy def loadList = {  if(!params.type){   // the controller is called without parameter        // thu...
MessageController.groovy   def loadList = {    if(!params.type){     // the controller is called without parameter        ...
MessageController.groovy   def loadList = {    if(!params.type){     // the controller is called without parameter        ...
MessageController.groovy   def loadList = {    if(!params.type){     // the controller is called without parameter        ...
MessageController.groovy   def loadList = {    if(!params.type){     // the controller is called without parameter        ...
MessageService‣ generate grails-app/services/MessageService.groovycreate-service message
MessageService‣ generate grails-app/services/MessageService.groovy create-service message‣ In MessageController.groovy, se...
MessageService‣ generate grails-app/services/MessageService.groovy create-service message‣ In MessageController.groovy, se...
Extracting a bean list
All messages: Message.list()
Exact MatchretList=Message.findAllByCommiter(                      Person.findByUsername(params.username)                 ...
Text with wildcard: %retList=Message.findAllByTextLike("%$params.text%")
Match with comparatorretList=Message.findAllByDateGreaterThan(params.date)
Multiple constraintsretList=Message.findAllByTextLikeAndDateGreaterThan(                             "%$params.text%", par...
PaginationretList=Message.findAllByTextLike("%$params.text%",               [max:10, offset:19, sort:‘date’, order:‘desc’]...
More power:Hibernate criteria & HQL
Application configuration: beyond default
Three environments:development (run-app)test (test-app -integration)production (war deployment)
Goal: a persistent development database
DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy
DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy‣ Global vs environment con...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
DataSource.groovy                         (cont’d)environments { development {  dataSource {         // one of create, cre...
hsqldb on file‣ Database is saved in 3 flat files
hsqldb on file‣ Database is saved in 3 flat files‣ e.g. devDb.script CREATE SCHEMA PUBLIC AUTHORIZATION DBA CREATE MEMORY ...
More configuration‣ All configuration files reside into grails-app/conf
More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much
More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much‣ For example, to set f...
groovy & grails - lecture 12
Upcoming SlideShare
Loading in...5
×

groovy & grails - lecture 12

1,008

Published on

GORM relationships
databases batches
application configuration

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,008
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
28
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • &amp;#x201C;terminal&amp;#x201D; shell session\nno export =&gt; variable is not passed to forked process\nbash is not the only shell\ncsh tcsh sh etc... with different notation variations\n
  • &amp;#x201C;terminal&amp;#x201D; shell session\nno export =&gt; variable is not passed to forked process\nbash is not the only shell\ncsh tcsh sh etc... with different notation variations\n
  • &amp;#x201C;terminal&amp;#x201D; shell session\nno export =&gt; variable is not passed to forked process\nbash is not the only shell\ncsh tcsh sh etc... with different notation variations\n
  • &amp;#x201C;terminal&amp;#x201D; shell session\nno export =&gt; variable is not passed to forked process\nbash is not the only shell\ncsh tcsh sh etc... with different notation variations\n
  • relationship are the heart of the domain architectures\nthe expression of the logic of how your objet are built and depends on each others\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • approximative....\n
  • approximative....\n
  • approximative....\n
  • Grails Objet Relational Mapping\nhide SQL complexity beyond a domain description\n...well to some extent\nDomain self constraints in static constraints={}\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • instead of belongsTo = [user:Person]\nconstraints user(nullable:true)\n
  • instead of belongsTo = [user:Person]\nconstraints user(nullable:true)\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • cf last time\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Bean list declaration is symmetrical.\nGORM offers the possibility to put a direction of dependency\n
  • Tag only have a name, which is a unique constrained property\n
  • belongs : directions\n
  • belongs : directions\n
  • belongs : directions\n
  • \n
  • see MessageIntegrationTests / testTags() for more tests and examples\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • i.e. stay on disk, survive restart run-app\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • batch= automatic =1/manual\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • i.e. stay on disk, survive restart run-app\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • groovy & grails - lecture 12

    1. 1. Groovy: Efficiency Oriented ProgrammingLecture 12Master Proteomics & Bioinformatics - University of GenevaAlexandre Masselot - summer 2011
    2. 2. Agenda‣ Linux tip-of-the-day‣ GORM relationships‣ Database batches‣ Application configuration
    3. 3. Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME=$HOME/local/grails-1.3.7
    4. 4. Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME=$HOME/local/grails-1.3.7‣ Prepend the path to give priority: export PATH=$GRAILS_HOME/bin:$PATH
    5. 5. Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME=$HOME/local/grails-1.3.7‣ Prepend the path to give priority: export PATH=$GRAILS_HOME/bin:$PATH‣ Variables are not shared among “parallel” consoles
    6. 6. Linux tip-of-the-day: bash environment variables‣ Set a variable to be read by further terminal process export GRAILS_HOME=$HOME/local/grails-1.3.7‣ Prepend the path to give priority: export PATH=$GRAILS_HOME/bin:$PATH‣ Variables are not shared among “parallel” consoles‣ To set variable a bash startup, edit either ~/.bashrc ~/.profile
    7. 7. Objects dependancies ↔ domain relationships (↔ foreign keys constraints)
    8. 8. Different type of relationships
    9. 9. Different type of relationships‣ one-to-one
    10. 10. Different type of relationships‣ one-to-one‣ one-to-many
    11. 11. Different type of relationships‣ one-to-one‣ one-to-many‣ many-to-many
    12. 12. The pedestrian one-to-many‣Message.groovyPerson commiter
    13. 13. The pedestrian one-to-many‣Message.groovyPerson commiter‣ Person.groovySet<Messages> messages=[]def addToMessages(msg){ msg.commiter=this msg.save() messages.add(msg)}
    14. 14. The pedestrian one-to-many‣Message.groovyPerson commiter‣ Person.groovySet<Messages> messages=[]def addToMessages(msg){ msg.commiter=this msg.save() messages.add(msg)}‣ And we do not mention - added messages already has a commiter member - cascade deletion
    15. 15. GORM: do not care about SQL/Hibernate
    16. 16. Dependency to a single bean: typed member
    17. 17. Dependency to a list of beans: hasMany
    18. 18. Dependency direction: belongsTo
    19. 19. One-to-one relationship
    20. 20. Example: a Profile object with details for a user 1 Person ↔ 0:1 Profile
    21. 21. one-to-one (cont’d)
    22. 22. one-to-one (cont’d)class Profile { String homePage static constraints = { homePage(url:true, blank:false) }}class Person { ... Profile profile static constraints = { ... profile(nullable:true) }}
    23. 23. one-to-one (cont’d)class Profile { String homePage static belongsTo = Person static constraints = { homePage(url:true, blank:false) }}class Person { ... Profile profile static constraints = { ... profile(nullable:true) }}
    24. 24. one-to-one (cont’d) ‣ Setting a profile joe.profile=new Profile(url=‘http://www.example.com’) joe.save()
    25. 25. one-to-one (cont’d) ‣ Setting a profile joe.profile=new Profile(url=‘http://www.example.com’) joe.save() ‣ Deleting cascades: joe.delete()
    26. 26. one-to-one (end) void testProfile(){ assert Person.count() == 0 assert Profile.count() == 0 }
    27. 27. one-to-one (end) void testProfile(){ assert Person.count() == 0 assert Profile.count() == 0 Person p=new Person(firstName:Lucky, lastName:Luke, email:lucky.luke@morris.com, username:lucky_luke ).save(failOnError:true) assert Person.count() == 1 assert Profile.count() == 0 }
    28. 28. one-to-one (end) void testProfile(){ assert Person.count() == 0 assert Profile.count() == 0 Person p=new Person(firstName:Lucky, lastName:Luke, email:lucky.luke@morris.com, username:lucky_luke ).save(failOnError:true) assert Person.count() == 1 assert Profile.count() == 0 p.profile = new Profile(homePage:http://www.morris.com/~lucky-luke) p.save(failOnError:true) assert Person.count() == 1 assert Profile.count() == 1 }
    29. 29. one-to-one (end) void testProfile(){ assert Person.count() == 0 assert Profile.count() == 0 Person p=new Person(firstName:Lucky, lastName:Luke, email:lucky.luke@morris.com, username:lucky_luke ).save(failOnError:true) assert Person.count() == 1 assert Profile.count() == 0 p.profile = new Profile(homePage:http://www.morris.com/~lucky-luke) p.save(failOnError:true) assert Person.count() == 1 assert Profile.count() == 1 p.delete() assert Person.count() == 0 assert Profile.count() == 0 }
    30. 30. One-to-many relationship
    31. 31. Example1 Person ↔ n Message
    32. 32. one-to-many‣ Person.groovy static hasMany = [messages: Message]
    33. 33. one-to-many‣ Person.groovy static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]
    34. 34. one-to-many‣ Person.groovy static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]‣ Add one messagejoe.addToMessages(new Message(...)).save()
    35. 35. one-to-many‣ Person.groovy static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]‣ Add one messagejoe.addToMessages(new Message(...)).save()‣ Delete on messagejoe.removeFromMessages(my_msg).save()
    36. 36. one-to-many‣ Person.groovy static hasMany = [messages: Message]‣ Message.groovy static belongsTo = [commiter:Person]‣ Add one message joe.addToMessages(new Message(...)).save()‣ Delete on message joe.removeFromMessages(my_msg).save()‣ Delete person + all messages joe.delete()
    37. 37. many-to-many relationships
    38. 38. Example: a Message contains many Tag and vice-versa n Message ↔ m Tag
    39. 39. many-to-many‣ Message.groovy:static hasMany = [tags:Tag]
    40. 40. many-to-many‣ Message.groovy:static hasMany = [tags:Tag]‣ Tag.groovy:class Tag{ String name static hasMany = [messages:Message] constraints = { name(unique:true) }}
    41. 41. many-to-many‣ Message.groovy:static hasMany = [tags:Tag]‣ Tag.groovy:class Tag{ String name belongsTo = Message static hasMany = [messages:Message] constraints = { name(unique:true) }}
    42. 42. belongsTo: who adds who?
    43. 43. my_msg.addToTags(my_tag).save()
    44. 44. Self referencing domain
    45. 45. Twitter example: a Person is following others
    46. 46. static hasMany = [ messages: Message, followings: Person ]
    47. 47. Application configuration: beyond default
    48. 48. Three environments:development (run-app)test (test-app -integration)production (war deployment)
    49. 49. Goal: a persistent development database
    50. 50. DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy
    51. 51. DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy‣ Global vs environment configuration dataSource { pooled = true driverClassName = "org.hsqldb.jdbcDriver" username = "sa" password = "" }
    52. 52. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    53. 53. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    54. 54. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    55. 55. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    56. 56. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" "update" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    57. 57. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" "update" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    58. 58. hsqldb on file‣ Database is saved in 3 flat files
    59. 59. hsqldb on file‣ Database is saved in 3 flat files‣ e.g. devDb.script CREATE SCHEMA PUBLIC AUTHORIZATION DBA CREATE MEMORY TABLE MESSAGE(ID BIGINT GENERATED ... CREATE MEMORY TABLE PERSON(ID BIGINT GENERATED ... ALTER TABLE MESSAGE ADD CONSTRAINT FK38EB0007D6D0B12 FOREIGN KEY(COMMITER_ID) REFERENCES PERSON(ID) ALTER TABLE MESSAGE ALTER COLUMN ID RESTART WITH 3 ALTER TABLE PERSON ALTER COLUMN ID RESTART WITH 2 CREATE USER SA PASSWORD "" GRANT DBA TO SA SET WRITE_DELAY 10 SET SCHEMA PUBLIC INSERT INTO MESSAGE VALUES(1,1,Im coming,1) INSERT INTO MESSAGE VALUES(2,0,on Jolly Jumper,1) INSERT INTO PERSON VALUES(1,0,Luke,lucky_luke, lucky.luke@morris.com,2010-05-17 01:18:16.607000000,Lucky)
    60. 60. More configuration‣ All configuration files reside into grails-app/conf
    61. 61. More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much
    62. 62. More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much‣ For example, to set failOnError:true by default on all .save() callsgrails.gorm.save.failOnError = true
    63. 63. Populating the database with batch
    64. 64. Inserting elements at application start: BootStrap.groovy
    65. 65. grails-app/conf/BootStrap.groovyclass BootStrap { def init = { servletContext -> } def destroy = { }}
    66. 66. grails-app/conf/BootStrap.groovyclass BootStrap { def init = { servletContext -> environments { test { } development { } production { } } } def destroy = { }}
    67. 67. grails-app/conf/BootStrap.groovyimport eop.lec12.twitter.Personimport eop.lec12.twitter.Profileclass BootStrap { def init = { servletContext -> environments { test { } development { if(!Person.findByUsername(sci_am)){ def p=new Person(firstName:Scientific, lastName:American, email:info@sciam.com, username:sci_am) p.save() p.profile=new Profile(homePage:http://www.sciam.com).save() } } production { } } } def destroy = { }}
    68. 68. grails-app/conf/BootStrap.groovyimport eop.lec12.twitter.Personimport eop.lec12.twitter.Profileclass BootStrap { def init = { servletContext -> environments { test { } development { if(!Person.findByUsername(sci_am)){ def p=new Person(firstName:Scientific, lastName:American,email:info@sciam.com, username:sci_am) p.save() p.profile=new Profile(homePage:http://www.sciam.com).save() } } production { } } } def destroy = { }}
    69. 69. Another batch: uploading a list of messages
    70. 70. Uploading a file
    71. 71. Uploading a file1. a local file with a list of contents convertible into messages (rss feed with publication update from Scientific American & Nature)
    72. 72. Uploading a file1. a local file with a list of contents convertible into messages (rss feed with publication update from Scientific American & Nature)2. file is uploaded through a web page with a form
    73. 73. Uploading a file1. a local file with a list of contents convertible into messages (rss feed with publication update from Scientific American & Nature)2. file is uploaded through a web page with a form3. a controller/action receive data + params
    74. 74. Uploading a file1. a local file with a list of contents convertible into messages (rss feed with publication update from Scientific American & Nature)2. file is uploaded through a web page with a form3. a controller/action receive data + params4. launch a service action to parse file & insert into database
    75. 75. Uploading a file1. a local file with a list of contents convertible into messages (rss feed with publication update from Scientific American & Nature)2. file is uploaded through a web page with a form3. a controller/action receive data + params4. launch a service action to parse file & insert into database
    76. 76. Input file
    77. 77. Input file‣ Download Scientific American’s feedhttp://rss.sciam.com/ScientificAmerican-Global
    78. 78. Input file‣ Download Scientific American’s feed http://rss.sciam.com/ScientificAmerican-Global‣ Nature’s feed http://feeds.nature.com/nature/rss/current?format=xml
    79. 79. Input file‣ Download Scientific American’s feed http://rss.sciam.com/ScientificAmerican-Global‣ Nature’s feed http://feeds.nature.com/nature/rss/current?format=xml‣ Stored locally in test/data/
    80. 80. Input file‣ Download Scientific American’s feed http://rss.sciam.com/ScientificAmerican-Global‣ Nature’s feed http://feeds.nature.com/nature/rss/current?format=xml‣ Stored locally in test/data/‣ Two loader classes (with tests) to convert rss item into temporary MessageToLoad class src/groovy
    81. 81. http://localhost:8080/eop.lec12.twitter/message/loadListgrails-app/controllers/MessageController.groovy : loadList = {...}grails-app/views/message/loadList.gsp
    82. 82. loadList.gspenable the form to upload file <g:form controller="message" action="loadList" method="post” enctype="multipart/form-data"> <input type="file" name="messagefile"/> <g:select name="type" from="${[sciam, nature] }"/> <input type="submit"/> </g:form> form field with file data
    83. 83. MessageController.groovy def loadList = { }
    84. 84. MessageController.groovy def loadList = { if(!params.type){ // the controller is called without parameter // thus we just display the form return } }
    85. 85. MessageController.groovy def loadList = { if(!params.type){ // the controller is called without parameter // thus we just display the form return } def loaders=[ sciam:new ScientificAmericanMessageLoader(), nature:new NatureMessageLoader() ] def loader=loaders[params.type] }
    86. 86. MessageController.groovy def loadList = { if(!params.type){ // the controller is called without parameter // thus we just display the form return } def loaders=[ sciam:new ScientificAmericanMessageLoader(), nature:new NatureMessageLoader() ] def loader=loaders[params.type] def input=request.getFile("messagefile").inputStream }
    87. 87. MessageController.groovy def loadList = { if(!params.type){ // the controller is called without parameter // thus we just display the form return } def loaders=[ sciam:new ScientificAmericanMessageLoader(), nature:new NatureMessageLoader() ] def loader=loaders[params.type] def input=request.getFile("messagefile").inputStream def n=messageService.loadMessages(loader, input) }
    88. 88. MessageController.groovy def loadList = { if(!params.type){ // the controller is called without parameter // thus we just display the form return } def loaders=[ sciam:new ScientificAmericanMessageLoader(), nature:new NatureMessageLoader() ] def loader=loaders[params.type] def input=request.getFile("messagefile").inputStream def n=messageService.loadMessages(loader, input) flash.uploadedMessage= "file was correctly uploaded with $n entries" }
    89. 89. MessageService‣ generate grails-app/services/MessageService.groovycreate-service message
    90. 90. MessageService‣ generate grails-app/services/MessageService.groovy create-service message‣ In MessageController.groovy, service is referred simply with def messageService
    91. 91. MessageService‣ generate grails-app/services/MessageService.groovy create-service message‣ In MessageController.groovy, service is referred simply with def messageService‣ See project source for actual bean insertion
    92. 92. Extracting a bean list
    93. 93. All messages: Message.list()
    94. 94. Exact MatchretList=Message.findAllByCommiter( Person.findByUsername(params.username) )
    95. 95. Text with wildcard: %retList=Message.findAllByTextLike("%$params.text%")
    96. 96. Match with comparatorretList=Message.findAllByDateGreaterThan(params.date)
    97. 97. Multiple constraintsretList=Message.findAllByTextLikeAndDateGreaterThan( "%$params.text%", params.date )
    98. 98. PaginationretList=Message.findAllByTextLike("%$params.text%", [max:10, offset:19, sort:‘date’, order:‘desc’] )
    99. 99. More power:Hibernate criteria & HQL
    100. 100. Application configuration: beyond default
    101. 101. Three environments:development (run-app)test (test-app -integration)production (war deployment)
    102. 102. Goal: a persistent development database
    103. 103. DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy
    104. 104. DataSource.groovy‣ All database configuration is stored under grails-app/conf/DataSource.groovy‣ Global vs environment configuration dataSource { pooled = true driverClassName = "org.hsqldb.jdbcDriver" username = "sa" password = "" }
    105. 105. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    106. 106. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    107. 107. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    108. 108. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    109. 109. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" "update" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    110. 110. DataSource.groovy (cont’d)environments { development { dataSource { // one of create, create-drop,update dbCreate = "create-drop" "update" url = "jdbc:hsqldb:mem:devDB" "jdbc:hsqldb:file:devDb:devDB" } } test { //skipped } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}
    111. 111. hsqldb on file‣ Database is saved in 3 flat files
    112. 112. hsqldb on file‣ Database is saved in 3 flat files‣ e.g. devDb.script CREATE SCHEMA PUBLIC AUTHORIZATION DBA CREATE MEMORY TABLE MESSAGE(ID BIGINT GENERATED ... CREATE MEMORY TABLE PERSON(ID BIGINT GENERATED ... ALTER TABLE MESSAGE ADD CONSTRAINT FK38EB0007D6D0B12 FOREIGN KEY(COMMITER_ID) REFERENCES PERSON(ID) ALTER TABLE MESSAGE ALTER COLUMN ID RESTART WITH 3 ALTER TABLE PERSON ALTER COLUMN ID RESTART WITH 2 CREATE USER SA PASSWORD "" GRANT DBA TO SA SET WRITE_DELAY 10 SET SCHEMA PUBLIC INSERT INTO MESSAGE VALUES(1,1,Im coming,1) INSERT INTO MESSAGE VALUES(2,0,on Jolly Jumper,1) INSERT INTO PERSON VALUES(1,0,Luke,lucky_luke, lucky.luke@morris.com,2010-05-17 01:18:16.607000000,Lucky)
    113. 113. More configuration‣ All configuration files reside into grails-app/conf
    114. 114. More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much
    115. 115. More configuration‣ All configuration files reside into grails-app/conf‣ Config.groovy handles much‣ For example, to set failOnError:true by default on all .save() callsgrails.gorm.save.failOnError = true
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×