If you can't read please download the document
Upload
alexis-sukrieh
View
1.472
Download
0
Embed Size (px)
DESCRIPTION
Coat::Persistent est un ORM écrit pour Perl en s'inspirant de l'API d'ActiveRecord de Rails. Cette présentation a été tenue aux journées Perl 2009
Citation preview
2. Plan
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
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
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
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
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 ?
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
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
45. Les ORM en Perl
46. DBIx::Class 47. Les ORM en Perl
48. DBIx::Class 49. Rose::DB::Object 50. Les ORM en Perl
51. DBIx::Class 52. Rose::DB::Object 53. ... 54. Pourquoi un nouvel ORM ? 55. Les origines de Coat::Persistent
56. Coat : le mini Moose sans dpendances 57. Deux bonnes ides qui mritaient d'tre runies 58. Objectifs pour Coat::Persistent
59. Objectifs pour Coat::Persistent
60. Lger 61. Objectifs pour Coat::Persistent
62. Lger 63. Rapide 64. Objectifs pour Coat::Persistent
65. Lger 66. Rapide 67. Aussi prs que possible de l'API ActiveRecord 68. Objectifs pour Coat::Persistent
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
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
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 :
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
95. C'est une classe qui hrite de Coat::Persistent 96. ce titre, elle bnficie de :
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 :
100. Class->find_or_create_by_foo() 101. Class->find_or_initialize_by_foo() 102. Cration de donnes
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
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
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
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
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
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
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 ...
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
157. svn co svn://svn.sukria.net:2015/Coat-Persistent 158. Bugs : http://rt.cpan.org 159. Pour me contacter : [email protected]