Příspěvky se štítkem ‘Grails’

Inicializace integračních testů Grails

26. 6. 2008 v 23.30

Testovací prostředí lze snadno nainicializovat tak, aby bylo stejné jako vývojové. Stačí použít Bootstrap.

class BootstrappedTests extends GroovyTestCase {
  void testBootstrap() {
    new BootStrap().init(null) 
    assert MyDomain.count() == 5   // Zde uz lze provadet testy
    }
}

Vlastní iterační značka v Grails s pojmenovanou proměnnou

18. 6. 2008 v 23.50

Ukážu Vám, jak vytvořit iterační značku v Grails, která může obsahovat jinou značku. Vnitřní značka pak použije proměnnou z iterační značky. Vytvoříme si tedy například značku, která vytvoří x odkazů ve tvaru „/show/1“, „/show/2“, atd. s popisem „Příspěvek číslo 1“, „Příspěvek číslo 2“ atd.:

Pro začátek existuje pěkný a šikovný příklad jednoduché iterační značky na stránkách Grails.

Definice:

def repeat = { attrs, body ->
  def i = Integer.valueOf( attrs["times"] )
  def current = 0
  i.times {
    // predej cislo aktualni iterace standardnim argumentem groovy nazvanym "it"
    // a vysledek pote predej do "out", odkud se vypise do pohledu
    out << body( ++current )
  }
}

Příklad použití:

<g:repeat times="3">
  <p>Opakuj 3-krát! Toto je opakování č. ${it}</p>
</g:repeat>

Jednoduchá úprava značky nevede k požadovanému chování:

<g:repeat times="3"> 
  <g:link action="show" id="${it}">Ahoj číslo  ${it}</g:link> 
</g:repeat>

Takto se vygeneruje jenom třikrát řetězec „Ahoj číslo “, protože proměnná „it“ je tu neznámá.
Je proto zapotřebí upravit definici značky. Přidejme další parametr „var“ jako symbolické jméno aktuálního člena kolekce pro danou iteraci.

def repeat = { attrs, body -> 
  def pars = [:]
 
  attrs.times?.toInteger().times { n -> 
    pars[attrs.var] = n
    out << body(pars) 
  } 
}

Teď můžeme použít značku g:link i uvnitř naší nové značky:

<g:repeat times="3" var="num"> 
  <g:link action="show" id="${num}">Ahoj číslo ${num}</g:link> 
</g:repeat>

Nejsem si jistý, zda je toto chování podporované, ale v každém případě funguje.

Z Mysql na Oracle: migrace aplikace v Grails

30. 5. 2008 v 23.19

Nedávno jsem dokončil migraci našeho prototypu v Grails. Původně jsme ho vyvíjeli na MySQL, ale finální systém musí pracovat na Oracle. V tomto příspěvku shrnu potíže a rozdíly, na které jsem při migraci DB narazil.

Vytvoření uživatele

Jelikož nejsem administrátorem Oracle, chvíli mi trvalo, než jsem dal dohromady skript, který vytvoří uživatele a příslušná práva pro aplikaci v Grails. Tento skript je pouze pro vývoj.

CREATE user grails IDENTIFIED BY grassword;
GRANT connect  TO habilion;
GRANT CREATE TABLE TO habilion;
GRANT CREATE sequence TO habilion;
GRANT unlimited tablespace TO habilion;

Omezení délky identifikátoru

Obvykle nepoužívám identifikátory dlouhé 30 znaků. Ale je tu chyták.
Představte si dvě třídy: Author a Content. Autor může tvořit různý textový obsah.
Představte si teď vícero různých typů obsahu - kniha, noviny, elektronické noviny, vědecký článek…
Tuto situaci můžeme tedy namodelovat následujícími třídami:

Class Content {
  static belongsTo = [ contentAuthor : Author ]
}
 
Class Book extends Content {}
Class Newspaper extends Content {}
Class ElectronicNewspaper extends Content {}
Class ScientificArticle extends Content {}
 
Class Author{
  static hasMany = [ contents : Content ]
}

A teď ten chyták: databázová tabulka ‘content’ obsahuje dlouhé sloupce:

content_author_id
newspaper_content_author_id
electronic_newspaper_content_author_id
book_content_author_id
scientific_article_author_id

Jak je vidět, není vůbec těžké dostat se na hranici 30 znaků. Když se na to podíváte podrobněji, uvidíte řešení. Názvy sloupců jsou složeny z názvu třídy dědící od Content a ze jména proměnné ukazující na nadřízenou entitu.
Přejmenoval jsem tedy contentAuthor na ca, vytvořil getter a setter pro vlastnost contentAuthor a zkontroloval všechny kusy kódu typu “new Book…”. Ať žije MVC!

Velikost sloupce

Druhým velkým problémem byl sloupec String. Měl jsem sloupec s řetězci do 10 000 znaků.

Class Content {
  String abstract
  static constraints = { abstract(maxSize:10000) }
}

Ten se přeložil do datového typu Long. Bohužel je v ovladači Oracle JDBC chyba, která vyvolává při zpracování datového typu Long velmi ošklivé chybové hlášky. Na webu je nějaké náhradní řešení, ale funguje jen s některými verzemi Oracle. Navíc je povolen nejvýš jeden sloupec typu Long v každé tabulce. Změnil jsem tedy velikost na 4000 znaků a sloupec se vytvořil jako VARCHAR2.

A je to!

Aktualizováno: Prázdné řetězce

Musím ještě zmínit fakt, že Oracle nerozlišuje mezi hodnotou null a prázdným řetězcem. Když se tedy pokoušíte uložit do databáze Oracle prázdný řetězec, uloží se ve skutečnosti jako hodnota null.

Problém nastává, když máte sloupec, který nesmí obsahovat null a pokusíte se uložit prázdný řetězec „“. Pro Grails to není hodnota null a nepoužije se tedy předdefinovaná hodnota. Pro Oracle je to null a tudíž porušení integritního omezení…