Coat::Persistent at FPW2009
-
Upload
alexis-sukrieh -
Category
Technology
-
view
1.472 -
download
0
description
Transcript of Coat::Persistent at FPW2009
- 1. Coat::Persistent Votre base de donnes portes d'objets FPW 2009 13 Juin 2009 Alexis Sukrieh http://www.sukria.net
2. Plan
- Le concept ORM
3. Origines de Coat::Persistent 4. Mise en place de Coat::Persistent 5. Accder aux donnes (lecture/criture) 6. Relations entre tables / modles 7. Fonctionnement du cache 8. Le concept ORM Une mthode moderne etefficace pour manipuler les donnes 9. Le principe ORM
- Un framework Objet
10. Une table devient une classe 11. Une ligne devient une instance 12. Une colonne devient un attribut 13. Le SQL est dsormais une couche de bas niveau 14. Avantages
- Moins de code pour manipuler les donnes
15. Plus de code pour crire l'application 16. Factorisation du problme d'accs aux donnes 17. Facilits et puissance de l'approche Objet 18. Simplicit d'utilisation 19. Avantages
- Moins de code pour manipuler les donnes
20. Plus de code pour crire l'application 21. Factorisation du problme d'accs aux donnes 22. Facilits et puissance de l'approche Objet 23. Simplicit d'utilisation 24. Moins de SQL 25. Avantages
- Moins de code pour manipuler les donnes
26. Plus de code pour crire l'application 27. Factorisation du problme d'accs aux donnes 28. Facilits et puissance de l'approche Objet 29. Simplicit d'utilisation 30. Moins de SQL 31. Moins de SQL 32. Avantages Moins de SQL ??! 33. Avec du SQL ... my $sql='select * from table' ; my $sth=$dbh ->prepare( $sql ); $sth ->execute ordie $! ; while( my $row=$sth ->fetchrow_hashref()) { # ici on joue avec $row ... } On a donc 4 lignes pour pouvoir itrer sur des enregistrements... 34. CATS DON'T LIKE SQL 35. Avec Coat::Persistent foreach my $obj(Table->find()){ # ici on joue avec $obj ... } Je crois que le chat s'est calm... 36. Pourquoi vouloir moins de SQL ?
- Pour les tches rptitives, SQL est lourd
37. Chaque fois qu'une requte SQL apparat dans du code, un risque d'injection est prsent 38. La validation des valeurs soumises en SQL est lourde 39. La prparation des valeurs l'est aussi (escaping, conversion de format) 40. Le temps pass manipuler SQL n'est pas consacr au code mtier 41. Mais le SQL est possible
- On ne ferme pas pour autant la porte au SQL
42. Pour les requtes complexes, SQL reste un bon choix 43. Pour les requtes simples et courantes, il faut l'viter 44. Les ORM en Perl
- Class::DBI
45. Les ORM en Perl
- Class::DBI
46. DBIx::Class 47. Les ORM en Perl
- Class::DBI
48. DBIx::Class 49. Rose::DB::Object 50. Les ORM en Perl
- Class::DBI
51. DBIx::Class 52. Rose::DB::Object 53. ... 54. Pourquoi un nouvel ORM ? 55. Les origines de Coat::Persistent
- ActiveRecord : l'ORM de Ruby on Rails
56. Coat : le mini Moose sans dpendances 57. Deux bonnes ides qui mritaient d'tre runies 58. Objectifs pour Coat::Persistent
- Simple d'utilisation
59. Objectifs pour Coat::Persistent
- Simple d'utilisation
60. Lger 61. Objectifs pour Coat::Persistent
- Simple d'utilisation
62. Lger 63. Rapide 64. Objectifs pour Coat::Persistent
- Simple d'utilisation
65. Lger 66. Rapide 67. Aussi prs que possible de l'API ActiveRecord 68. Objectifs pour Coat::Persistent
- Simple d'utilisation
69. Lger 70. Rapide 71. Aussi prs que possible de l'API ActiveRecord 72. Interoprable (MySQL, SQLite, CSV, ...) 73. Mise en place Comment utiliser Coat::Persistentdans votre projet 74. Installation
- cpan install Coat
75. cpan install Coat::Persistent 76. Le driver DBI pour votre SGBD 77. Une premier modle C::P package Camel ; useCoat; useCoat::Persistent; 78. Une premier modle C::Pavec MySQL package Camel ; useCoat; useCoat::Persistent; Coat::Persistent->map_to_dbi( mysql=>' dbname ',' dbuser ',' dbpass '); 79. Une premier modle C::Pavec SQLite package Camel ; useCoat; useCoat::Persistent; Coat::Persistent->map_to_dbi( sqlite=> ' dbname=dbfile '); 80. Une premier modle C::Pavec CSV package Camel ; useCoat; useCoat::Persistent; Coat::Persistent->map_to_dbi( csv=> ' f_dir=dbfile '); 81. Conventions
- La mapping est possible par dfaut ou par classe
82. Le nom de la classe implique un nom de table 83. La clef primaire se nomme id 84. Une clef trangre se nomme table_id 85. On peut surcharger chacune de ces conventions 86. Surcharger les conventions package Camel ; useCoat; useCoat::Persistenttable_name=> ' camels ', primary_key=> ' cid '; Coat::Persistent->map_to_dbi( csv=> ' f_dir=dbfile '); 87. Terminer le mapping package Camel ; useCoat; useCoat::Persistent; has_p name => (isa => 'Str'); has_p age => (isa => 'Int'); sqlite> create table camel (id int, name varchar(25), age int); 88. Maintenant il est possible :
- Remonter des objets partir de la base
89. Crer de nouvelles entres 90. Modifier des entres existantes 91. Accder au handle de la base de donnes 92. Obtenir des objets partir de requetes SQL complexes 93. Coat::Persistent est en place ! 94. Un modle Coat::Persistent
- C'est une classe qui hrite de Coat::Object
95. C'est une classe qui hrite de Coat::Persistent 96. ce titre, elle bnficie de :
- Mthodes statiques qui s'appliquent une table
97. Mthodes d'instances qui s'appliquent une ligne Pour chaque attribut dclar, des accesseurs et une srie de mthodes sont automatiquement dfinies : 98. Attribut et mthodes La dclaration de l'attribut foo implique :
-
- $obj->foo()
- 99. Class->find_by_foo()
100. Class->find_or_create_by_foo() 101. Class->find_or_initialize_by_foo() 102. Cration de donnes
- Un nouvel objet Coat::Persistent n'est pas sauv en base tant que save() n'est pas appel
103. La mthode create() permet de faire un new() et un save() 104. Des mthodes permettent de faire des crations d'objet avec ou sans sauvegarde selon l'existence d'un enregistrement particulier 105. Cration de donnes
- Class->new() : cre une instance en mmoire
106. $obj->save() : sauve l'instance dans la base de donne 107. Class->create() : cre et sauve l'instance 108. Class->find_or_create_by_ATTR(val) : find_by_ATTR(val) ou create(ATTR => val) 109. Class->find_or_initialize_by_ATTR(val) : find_by_ATTR(val) ou new(ATTR => val) 110. Exemple de cration Perl> my $joe = Camel->new(name =>'joe',age => 7); $Camel1 = Camel=HASH(0x8dcf7a0); Perl> $joe->save 1 sqlite> select * from camel where id = 1; 1|joe|7 111. Exemple de cration (plus court) Perl> my $joe = Camel->create(name =>'night',age => 4); $Camel1 = Camel=HASH(0x8dcf7a0); sqlite> select * from camel where id = 1; 1|joe|7 2|night|4 112. Lecture
- Pour lire les donnes existantes, on utilise un finder
113. Le contexte d'appel est important (on remonte N entres avec un contexte de liste et uniquement la premire en contexte scalaire) 114. Les finders peuvent se dcliner 115. find, find_by_attribut, find(id), find('condition') ... 116. find en contexte de liste Perl> my @camels = Camel->find(); $ARRAY1 = [ Camel=HASH(0x9cfc568), Camel=HASH(0x9cfc718), Camel=HASH(0x9cfc7c8) ]; 117. find avec un id Perl> my $camel = Camel->find(1); $Camel1 = Camel=HASH(0x9cfc568) 118. find avec plusieurs id Perl> my @camels = Camel->find(1,2); $ARRAY1 = [ Camel=HASH(0x9ba0648), Camel=HASH(0x9cfc818) ]; 119. find avec un attribut Perl> my $joe = Camel->find_by_name('joe'); $Camel1 = Camel=HASH(0x9cfc568) Perl> $joe->name; 'joe' 120. find avec une condition Perl> @camels = Camel->find('age > 10'); $Camel1 = Camel=HASH(0x9d0af78); Perl> $camels[0]->age 12 121. find avec des options Perl> my @camels = Camel->find('age > 3',{ order => 'name', limit => '5', }); 122. find avec du SQL Perl> @camels = Camel->find_by_sql('select * from camel where age is not null'); $ARRAY1 = [ Camel=HASH(0x9cfc528), Camel=HASH(0x9cfca78), Camel=HASH(0x94c3380) ]; 123. Modifier Perl> $camel = Camel->find(1); $Camel1 = Camel=HASH(0x9cfc528) Perl> $camel->age(3); 3 Perl> $camel->save; 1 124. Supprimer Perl> $camel = Camel->find(1); $Camel1 = Camel=HASH(0x9cfc528) Perl> $camel->delete; 1 Perl> $camel = Camel->find(1); undef 125. N'oublions pas Coat
- Le hooks de Coat (Moose) s'appliquent trs bien ici
126. Chaque mthode propose par C::P est interceptable via les hooks Coat before, after et around 127. Les mthodes BUILD et DEMOLISH sont implmentables par les objets C::P 128. Types utilisateur et coercition 129. Les hooks
- before save => sub { ... }
130. after save => sub { } 131. sub BUILD { ... } 132. sub DEMOLISH { ... } 133. ... 134. Types et Coercition subtype 'DateTime'=> as 'Str' => where { /d{4}-dd-dd dd:dd:dd/ }; coerce 'DateTime' => from 'Int' => via {convert_time_to_datetime_str($_) }; 135. Types et Coercition has_p 'created_at' => ( is => 'rw', isa => 'DateTime', coerce => 1, ); before 'save' => sub { my ($self) = @_; $self->created_at(time()); }; 136. Les relations entre tables 137. Relations ct SQL ... sqlite> create table master (id int, name varchar(25)); sqlite> alter table camel add column master_id int; 138. et ct Perl package Camel ; useCoat; useCoat::Persistent; has_p name => (isa =>'Str' ); has_p age => (isa =>'Int' ); has_one'master'; ; 139. et ct Perl package Master ; useCoat; useCoat::Persistent; has_p name => (isa =>'Str' ); has_many'camels', class_name => 'Camel'; ; 140. Le matre des chameaux Perl> my $m = Master->create(name => 'Al Kabir') $Master1 = Master=HASH(0x913c168); Perl> my @camels => Camel->find(); $ARRAY1 = [ Camel=HASH(0x913c5e8), Camel=HASH(0x913c588) ]; Perl> map { $_->master($m); $_->save;} @camels; 141. Trouver le matre Perl> my $camel = Camel->find(1); $Camel1 = Camel=HASH(0xa07cd60); Perl> $camel->master $Master1 = Master=HASH(0xa07d050); Perl> $camel->master->name Al Kabir 142. Trouver les chameaux Perl> my $master = Master->find(1); $Master1 = Master=HASH(0xa07d050); Perl> my @camels = $master->camels; $ARRAY1 = [ Camel=HASH(0xa07ce00), Camel=HASH(0xa07d080) ]; 143. Accler les choses
- Pour amliorer les performances, on peut cacher les rsultats des requtes SQL
144. Le cache est activable la demande, par Classe ou pour l'ensemble du processus 145. Pour chaque requte SQL gnre (pour un set de valeurs donnes) C::P maintient une entre en cache avec le rsultat 146. Ce rsultat en cache est retourn s'il existe 147. Accler les choses
- L'expiration des donnes est gre en interne par Cache::FastMmap
148. On peut activer/dsactiver le cache la vole 149. Exemple de Cache Pour l'ensemble du processus (toutes les classes C::P sont affectes) Coat::Persistent ->enable_cache( expire_time=>'1h' , cache_size =>'50m' , share_file =>'/var/cache/myapp.cache' , ); 150. Exemple de Cache Uniquement pour la classe utilise Camel ->enable_cache( expire_time=>'1h' , cache_size =>'50m' , share_file =>'/var/cache/myapp.cache' , ); 151. Pour la suite ...
- Gestion de l'option join dans les finder
152. Migrations (classe Coat::Persistent::Migration) 153. Valider de nouveaux drivers DBI 154. Mthodes manquantes de ActiveRecord 155. Optimisations (occupation mmoire, requtes gnres) 156. Pour Contribuer
- Les patchs sont toujours bienvenus
157. svn co svn://svn.sukria.net:2015/Coat-Persistent 158. Bugs : http://rt.cpan.org 159. Pour me contacter : [email protected]