SlideShare una empresa de Scribd logo
1 de 45
Descargar para leer sin conexión
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
Jean-Fran¸ois Trˆn
         c      a
jftran@rubyfrance.org




                Trˆn Jean-Fran¸ois
                  a           c      AREL
Arel




   Alg`bre relationnelle ou ActiveRelation
      e




                       Trˆn Jean-Fran¸ois
                         a           c      AREL
Qu’est-ce qu’Arel ?




      Biblioth`que ´crite par Nick Kallen.
              e    e




                     Trˆn Jean-Fran¸ois
                       a           c      AREL
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
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
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
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
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
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
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
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
ORM Builder




     Pas de gestion du mapping table/classe Ruby.




                   Trˆn Jean-Fran¸ois
                     a           c      AREL
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
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
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
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
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
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
CRUD




       Insertion
       Delete
       Update




                   Trˆn Jean-Fran¸ois
                     a           c      AREL
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
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
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
Attributs




   ActiveRelation::Attribute.new(articles, :id)

   mˆme chose que :
    e

   articles[:id]




                      Trˆn Jean-Fran¸ois
                        a           c      AREL
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
Pr´dicats : Equality
  e




   articles[:id].eq(’foo’).class
   # => ActiveRelation::Equality




                   Trˆn Jean-Fran¸ois
                     a           c      AREL
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
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
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
ActiveRelation::Expression




   articles[:id].count.class
   # => ActiveRelation::Expression




                   Trˆn Jean-Fran¸ois
                     a           c      AREL
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
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
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
Select




   users.select(users[:id].in(1..5))




                         Trˆn Jean-Fran¸ois
                           a           c      AREL
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
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
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
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
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
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
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
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
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
Expressions avec LIKE, expressions temporelles (?)
    Prepared statements
pour ActiveRecord DataMapper API




                   Trˆn Jean-Fran¸ois
                     a           c      AREL
Pr´dicats
  e




            Trˆn Jean-Fran¸ois
              a           c      AREL

Más contenido relacionado

Similar a Arel

Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovyguest6e3bed
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation GroovyJS Bournival
 
Sudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de donnéesSudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de donnéesY. Nicolas
 
La référence Clear php
La référence Clear phpLa référence Clear php
La référence Clear phpDamien Seguy
 
Intégration continue & Qualité logicielle
Intégration continue & Qualité logicielleIntégration continue & Qualité logicielle
Intégration continue & Qualité logicielleDavid Buros
 
Plutniak maisonobe r esto atelier1-introduction
Plutniak maisonobe r esto atelier1-introductionPlutniak maisonobe r esto atelier1-introduction
Plutniak maisonobe r esto atelier1-introductionMarion Maisonobe
 
Initiation Rails Rspec
Initiation Rails RspecInitiation Rails Rspec
Initiation Rails RspecCyril Mougel
 
Mix it 2011 - Clojure
Mix it 2011 - ClojureMix it 2011 - Clojure
Mix it 2011 - Clojurelolopetit
 
Javascript un langage supérieur
Javascript un langage supérieurJavascript un langage supérieur
Javascript un langage supérieurFredy Fadel
 
Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Alexis Sukrieh
 
07 - roles-ansible-automatisation-infrastructure
07 - roles-ansible-automatisation-infrastructure07 - roles-ansible-automatisation-infrastructure
07 - roles-ansible-automatisation-infrastructurebibouechristian
 
DataDrill EXPRESS: Les équations dans DataDrill
DataDrill EXPRESS: Les équations dans DataDrill DataDrill EXPRESS: Les équations dans DataDrill
DataDrill EXPRESS: Les équations dans DataDrill Olivier Pinette
 
PHP 6, la prochaine frontière
PHP 6, la prochaine frontièrePHP 6, la prochaine frontière
PHP 6, la prochaine frontièreDamien Seguy
 
nombres aléatoires en langage C
nombres aléatoires en langage Cnombres aléatoires en langage C
nombres aléatoires en langage Cmohamednacim
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_finalDuchess France
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_finalagnes_crepet
 
Beyond F5 - windbg et .Net
Beyond F5 - windbg et .NetBeyond F5 - windbg et .Net
Beyond F5 - windbg et .NetYann Schwartz
 

Similar a Arel (20)

Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
 
Sudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de donnéesSudoc, Calames, theses.fr et le Web de données
Sudoc, Calames, theses.fr et le Web de données
 
La référence Clear php
La référence Clear phpLa référence Clear php
La référence Clear php
 
Intégration continue & Qualité logicielle
Intégration continue & Qualité logicielleIntégration continue & Qualité logicielle
Intégration continue & Qualité logicielle
 
Plutniak maisonobe r esto atelier1-introduction
Plutniak maisonobe r esto atelier1-introductionPlutniak maisonobe r esto atelier1-introduction
Plutniak maisonobe r esto atelier1-introduction
 
Initiation Rails Rspec
Initiation Rails RspecInitiation Rails Rspec
Initiation Rails Rspec
 
Cours php bac info
Cours php bac infoCours php bac info
Cours php bac info
 
Mix it 2011 - Clojure
Mix it 2011 - ClojureMix it 2011 - Clojure
Mix it 2011 - Clojure
 
Javascript un langage supérieur
Javascript un langage supérieurJavascript un langage supérieur
Javascript un langage supérieur
 
Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Coat::Persistent at FPW2009
Coat::Persistent at FPW2009
 
07 - roles-ansible-automatisation-infrastructure
07 - roles-ansible-automatisation-infrastructure07 - roles-ansible-automatisation-infrastructure
07 - roles-ansible-automatisation-infrastructure
 
DataDrill EXPRESS: Les équations dans DataDrill
DataDrill EXPRESS: Les équations dans DataDrill DataDrill EXPRESS: Les équations dans DataDrill
DataDrill EXPRESS: Les équations dans DataDrill
 
PHP 6, la prochaine frontière
PHP 6, la prochaine frontièrePHP 6, la prochaine frontière
PHP 6, la prochaine frontière
 
nombres aléatoires en langage C
nombres aléatoires en langage Cnombres aléatoires en langage C
nombres aléatoires en langage C
 
Cours php
Cours phpCours php
Cours php
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_final
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_final
 
Beyond F5 - windbg et .Net
Beyond F5 - windbg et .NetBeyond F5 - windbg et .Net
Beyond F5 - windbg et .Net
 
Drools
DroolsDrools
Drools
 

Arel

  • 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. Jean-Fran¸ois Trˆn c a jftran@rubyfrance.org Trˆn Jean-Fran¸ois a c AREL
  • 3. Arel Alg`bre relationnelle ou ActiveRelation e Trˆn Jean-Fran¸ois a c AREL
  • 4. Qu’est-ce qu’Arel ? Biblioth`que ´crite par Nick Kallen. e e Trˆn Jean-Fran¸ois a c AREL
  • 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. 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. 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. 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. 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. 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. 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. 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. ORM Builder Pas de gestion du mapping table/classe Ruby. Trˆn Jean-Fran¸ois a c AREL
  • 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. 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. 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. 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. 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. 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. CRUD Insertion Delete Update Trˆn Jean-Fran¸ois a c AREL
  • 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. 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. 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. Attributs ActiveRelation::Attribute.new(articles, :id) mˆme chose que : e articles[:id] Trˆn Jean-Fran¸ois a c AREL
  • 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. Pr´dicats : Equality e articles[:id].eq(’foo’).class # => ActiveRelation::Equality Trˆn Jean-Fran¸ois a c AREL
  • 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. 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. 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. ActiveRelation::Expression articles[:id].count.class # => ActiveRelation::Expression Trˆn Jean-Fran¸ois a c AREL
  • 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. 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. 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. Select users.select(users[:id].in(1..5)) Trˆn Jean-Fran¸ois a c AREL
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. Expressions avec LIKE, expressions temporelles (?) Prepared statements pour ActiveRecord DataMapper API Trˆn Jean-Fran¸ois a c AREL
  • 45. Pr´dicats e Trˆn Jean-Fran¸ois a c AREL