Arel

2 311 vues

Publié le

Presentation of Arel, a relational algebra for Ruby at the 5th Apero Ruby in Paris

Publié dans : Technologie, Business
0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
2 311
Sur SlideShare
0
Issues des intégrations
0
Intégrations
28
Actions
Partages
0
Téléchargements
18
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Arel

  1. 1. Arel Jean-Fran¸ois Trˆn c a Ruby France, 5e Ap´ro Ruby e lundi 14 avril 2008 Trˆn Jean-Fran¸ois a c AREL
  2. 2. Jean-Fran¸ois Trˆn c a jftran@rubyfrance.org Trˆn Jean-Fran¸ois a c AREL
  3. 3. Arel Alg`bre relationnelle ou ActiveRelation e Trˆn Jean-Fran¸ois a c AREL
  4. 4. Qu’est-ce qu’Arel ? Biblioth`que ´crite par Nick Kallen. e e Trˆn Jean-Fran¸ois a c AREL
  5. 5. Qu’est-ce qu’Arel ? Biblioth`que ´crite par Nick Kallen. e e Nick Kallen : auteur de has finder, int´gr´ dans Rails sous le e e nom de Name Scoped (sera dispo dans Rails 2.1) Trˆn Jean-Fran¸ois a c AREL
  6. 6. Qu’est-ce qu’Arel ? Biblioth`que ´crite par Nick Kallen. e e Nick Kallen : auteur de has finder, int´gr´ dans Rails sous le e e nom de Name Scoped (sera dispo dans Rails 2.1) Arel se veut le ”Rack des ORM”. Trˆn Jean-Fran¸ois a c AREL
  7. 7. Alg`bre relationnelle e Alg`bre relationnelle : th´orie ` la base des Bases de donn´es e e a e relationnelles. pour les d´tails, demandez ` Codd de vous expliquer, pour e a moi mes cours de BD sont loins ! En gros, on a des relations, on peut y op´rer des op´rations e e comme la S´lection, la Projection, le Produit Cart´sien, le e e Rename, l’Union, la Diff´rence, la Division, les Jointures... e Trˆn Jean-Fran¸ois a c AREL
  8. 8. Installation Sur GitHub : http://github.com/nkallen/arel/tree/master git clone git://github.com/nkallen/arel.git Trˆn Jean-Fran¸ois a c AREL
  9. 9. ORM Builder Un ORM Builder, c’est-`-dire qu’on peut construire son a propre ORM en se basant sur Arel. Trˆn Jean-Fran¸ois a c AREL
  10. 10. ORM Builder Un ORM Builder, c’est-`-dire qu’on peut construire son a propre ORM en se basant sur Arel. Celui va g´n´rer le SQL en traversant une sorte d’AST. e e Trˆn Jean-Fran¸ois a c AREL
  11. 11. ORM Builder Un ORM Builder, c’est-`-dire qu’on peut construire son a propre ORM en se basant sur Arel. Celui va g´n´rer le SQL en traversant une sorte d’AST. e e Plus puissant qu’un QueryBuilder car Arel travaille sur des relations et ne fait pas de concat´nation de chaˆ e ınes (seulement en dernier lieu). Trˆn Jean-Fran¸ois a c AREL
  12. 12. ORM Builder Un ORM Builder, c’est-`-dire qu’on peut construire son a propre ORM en se basant sur Arel. Celui va g´n´rer le SQL en traversant une sorte d’AST. e e Plus puissant qu’un QueryBuilder car Arel travaille sur des relations et ne fait pas de concat´nation de chaˆ e ınes (seulement en dernier lieu). Arel : se veut un middleware pour ORM. Trˆn Jean-Fran¸ois a c AREL
  13. 13. ORM Builder Pas de gestion du mapping table/classe Ruby. Trˆn Jean-Fran¸ois a c AREL
  14. 14. ORM Builder Pas de gestion du mapping table/classe Ruby. Pas de gestion des associations au sens d’ActiveRecord. Trˆn Jean-Fran¸ois a c AREL
  15. 15. ORM Builder Pas de gestion du mapping table/classe Ruby. Pas de gestion des associations au sens d’ActiveRecord. peut-ˆtre utilis´ pour refactoriser le code interne e e d’ActiveRecord (ou de DataMapper ou...). Trˆn Jean-Fran¸ois a c AREL
  16. 16. ORM Builder Pas de gestion du mapping table/classe Ruby. Pas de gestion des associations au sens d’ActiveRecord. peut-ˆtre utilis´ pour refactoriser le code interne e e d’ActiveRecord (ou de DataMapper ou...). On d´finit son API publique au dessus d’Arel comme on le e souhaite (Ambition ?). Trˆn Jean-Fran¸ois a c AREL
  17. 17. Closure under composition C’est quoi la ”closure under composition” ? J’en sais rien, et vous ? closure : ”In mathematics, a set is said to be closed under some operation if the operation on members of the set produces a member of the set.” (Wikipedia ”closure (mathematics”)”) Trˆn Jean-Fran¸ois a c AREL
  18. 18. SQL g´n´r´ e ee #to_sql Les exemples suivants sont faits en passant #to_sql Ici avec ActiveRecord et l’adaptateur SQLite pour le quoting SQL. Trˆn Jean-Fran¸ois a c AREL
  19. 19. D´finition des tables des exemples e create_table :users, :force => true do |t| t.string :name end create_table :articles do |t| t.string :title t.integer :comments_count t.references :user end Trˆn Jean-Fran¸ois a c AREL
  20. 20. CRUD Insertion Delete Update Trˆn Jean-Fran¸ois a c AREL
  21. 21. CRUD avec ActiveRelation::Table users = ActiveRelation::Table.new(:users) users.select(...) users.insert(users[:name] => ’Iron Man’) users.update(...) users.delete(...) Trˆn Jean-Fran¸ois a c AREL
  22. 22. CRUD : Delete ActiveRelation::Deletion.new(articles.select(articles[:id]. DELETE FROM articles WHERE articles.quot;idquot; = 1 Update Trˆn Jean-Fran¸ois a c AREL
  23. 23. CRUD : Insertion ActiveRelation::Insertion.new( articles, articles[:title] => ’chti’).to_sql INSERT INTO articles (articles.quot;titlequot;) VALUES (’coucou’) Trˆn Jean-Fran¸ois a c AREL
  24. 24. Attributs ActiveRelation::Attribute.new(articles, :id) mˆme chose que : e articles[:id] Trˆn Jean-Fran¸ois a c AREL
  25. 25. Pr´dicats e Avec les Attributs, on peut composer des pr´dicats (´galit´, e e e inclusion, op´rateurs binaires) e Trˆn Jean-Fran¸ois a c AREL
  26. 26. Pr´dicats : Equality e articles[:id].eq(’foo’).class # => ActiveRelation::Equality Trˆn Jean-Fran¸ois a c AREL
  27. 27. Pr´dicats : Equality e ActiveRelation::Equality.new( articles[:user_id], users[:id] ) # SQL => quot;articles.quot;user_idquot; = users.quot;idquot;quot; identique ` : a articles[:user_id].eq(users[:id]) # SQL => quot;articles.quot;user_idquot; = users.quot;idquot;quot; Trˆn Jean-Fran¸ois a c AREL
  28. 28. Pr´dicats : Equality (suite) e articles[:id].eq(’foo’) # SQL => quot;articles.quot;idquot; = 0quot; articles[:title].eq(’foo’) # SQL => quot;articles.quot;titlequot; = ’foo’quot; articles[:title].eq(nil) # SQL => quot;articles.quot;titlequot; IS NULLquot; articles[:title].eq(true) # SQL => quot;articles.quot;titlequot; = ’t’quot; Trˆn Jean-Fran¸ois a c AREL
  29. 29. Pr´dicats : ActiveRelation::Binary e articles[:id].lt(5) # SQL => quot;articles.quot;idquot; < 5quot; articles[:id].lteq(5) # SQL => quot;articles.quot;idquot; <= 5quot; articles[:id].gt(7) # SQL => quot;articles.quot;idquot; > 7quot; articles[:id].gteq(7) # SQL => quot;articles.quot;idquot; >= 7quot; Trˆn Jean-Fran¸ois a c AREL
  30. 30. ActiveRelation::Expression articles[:id].count.class # => ActiveRelation::Expression Trˆn Jean-Fran¸ois a c AREL
  31. 31. ActiveRelation::Expression : COUNT, MAX, MIN, AVG articles[:id].count # SQL => quot;COUNT(articles.quot;idquot;)quot; articles[:id].maximum # SQL => quot;MAX(articles.quot;idquot;)quot; articles[:id].minimum # SQL => quot;MIN(articles.quot;idquot;)quot; articles[:id].sum # SQL => quot;SUM(articles.quot;idquot;)quot; articles[:id].average # SQL => quot;AVG(articles.quot;idquot;)quot; Trˆn Jean-Fran¸ois a c AREL
  32. 32. Inclusion articles[:id].in(1..4) # SQL => quot;articles.quot;idquot; BETWEEN 1 AND 4quot; articles[:id].in([1, 3, 5]) # SQL => quot;articles.quot;idquot; IN (1, 3, 5)quot; Trˆn Jean-Fran¸ois a c AREL
  33. 33. Inclusion (suite) users # SQL => quot;SELECT users.quot;idquot;, users.quot;namequot; FROM usersquot; articles[:id].in(users) # SQL => quot;articles.quot;idquot; IN (SELECT users.quot;idquot;, users.quot;namequot; FROM users)quot; articles[:user_id].in( users.select(users[:id].in(1..5)) ) # => quot;articles.quot;user_idquot; IN (SELECT users.quot;idquot;, users.quot;namequot; FROM users WHERE users.quot;idquot; BETWEEN 1 AND 5)quot; Trˆn Jean-Fran¸ois a c AREL
  34. 34. Select users.select(users[:id].in(1..5)) Trˆn Jean-Fran¸ois a c AREL
  35. 35. Sub Select articles.select( articles[:user_id].in( users.select(users[:id].in(1..5)).project(users[:id]) ) ).to_sql SELECT articles.quot;idquot;, articles.quot;titlequot;, articles.quot;comments_countquot;, articles.quot;user_idquot; FROM articles WHERE articles.quot;user_idquot; IN (SELECT users.quot;idquot; FROM users WHERE users.quot;idquot; BETWEEN 1 AND 5) Trˆn Jean-Fran¸ois a c AREL
  36. 36. Exemple plus compliqu´ e articles.select( articles[:user_id].in( users.select( users[:id].in(1..5) ).project(users[:id]) ).project(articles[:id].maximum).to_sql SELECT MAX(articles.quot;idquot;) FROM articles WHERE articles.quot;user_idquot; IN ( SELECT users.quot;idquot; FROM users WHERE users.quot;idquot; BETWEEN 1 AND 5) Trˆn Jean-Fran¸ois a c AREL
  37. 37. Order articles.select.order(articles[:title]).to_sql SELECT articles.quot;idquot;, articles.quot;titlequot;, articles.quot;comments_countquot;, articles.quot;user_idquot; FROM articles WHERE ORDER BY articles.quot;titlequot; Trˆn Jean-Fran¸ois a c AREL
  38. 38. Jointures articles.join(users).on(articles[:user_id].eq(users[:id])) SELECT articles.quot;idquot;, articles.quot;titlequot;, articles.quot;comments_countquot;, articles.quot;user_idquot;, users.quot;idquot;, users.quot;namequot; FROM articles INNER JOIN users ON articles.quot;user_idquot; = users.quot;idquot; Trˆn Jean-Fran¸ois a c AREL
  39. 39. Jointures articles. project(articles[:user_id]). join(users). on(articles[:user_id].eq(users[:id])) SELECT articles.quot;user_idquot;, users.quot;idquot;, users.quot;namequot; FROM articles INNER JOIN users ON articles.quot;user_idquot; = users.quot;idquot;quot; Trˆn Jean-Fran¸ois a c AREL
  40. 40. Outer Join articles.outer_join(users). on(articles[:user_id].eq(users[:id])) => SELECT articles.quot;idquot;, articles.quot;titlequot;, articles.quot;comments_countquot;, articles.quot;user_idquot;, users.quot;idquot;, users.quot;namequot; FROM articles LEFT OUTER JOIN users ON articles.quot;user_idquot; = users.quot;idquot; Trˆn Jean-Fran¸ois a c AREL
  41. 41. Outer Join pour Has many, Belongs to def user_has_many_articles(user_relation) user_relation. outer_join(@articles). on(user_relation[:id].eq(@articles[:user_id])) end @user = ActiveRelation::Table(:users) user_has_many_photos(@user).select ... def article_belongs_to_camera(article_relation) article_relation. outer_join(@cameras). on(photo_relation[foreign_key].equals(@cameras[primary_ ) end Trˆn Jean-Fran¸ois a c AREL
  42. 42. Renommage ActiveRelation::Rename.new( articles, articles[:id] => :koala ) SELECT articles.quot;idquot; AS ’koala’, articles.quot;titlequot;, articles.quot;comments_countquot;, articles.quot;user_idquot; FROM articles identique ` : a articles.rename(articles[:id], :koala) Trˆn Jean-Fran¸ois a c AREL
  43. 43. Agr´gation e articles. aggregate(articles[:user_id], articles[:id].count). group(articles[:user_id]). rename(articles[:id].count, :cnt). as(’articles_count’) SELECT articles.quot;user_idquot;, COUNT(articles.quot;idquot;) AS quot;c FROM articles GROUP BY articles.quot;user_idquot; Trˆn Jean-Fran¸ois a c AREL
  44. 44. Expressions avec LIKE, expressions temporelles (?) Prepared statements pour ActiveRecord DataMapper API Trˆn Jean-Fran¸ois a c AREL
  45. 45. Pr´dicats e Trˆn Jean-Fran¸ois a c AREL

×