Sample Andl code: the Dbix CD Sample

One thing I knew and has only been reinforced in early feedback about Andl: you can’t just talk about a new language, you have to show it.

So here is my version of a sample application I found on CPAN: http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual/Example.pod. They’re not strictly comparable, so just take this is as a sample of what Andl code looks like for creating some data and executing some simple queries.

// translation of sample application from http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual/Example.pod

// create the database relvars
artist  := {{ artistid:0, name:'' }}
cd      := {{ cdid:0, artistid:0, title:'', year:0 }}
track   := {{ trackid:0, cdid:0, title:'' }}

// some data in temporary relvars, with auto-generated ordinals
$artist_data := {{name:''}
  ( 'Michael Jackson' ), 
  ( 'Eminem' ),
} [{ *artistid := ord() }]

$cd_data := {{ title:'', name:'' }
  ( 'Thriller',                'Michael Jackson' ),
  ( 'Bad',                     'Michael Jackson' ),
  ( 'The Marshall Mathers LP', 'Eminem' ),
} [{ *cdid := ord() }]

$track_data := {{ title:'', cd:'' }
   ( 'Beat It'         , 'Thriller' ),
   ( 'Billie Jean'     , 'Thriller' ),
   ( 'Dirty Diana'     , 'Bad' ),
   ( 'Smooth Criminal' , 'Bad' ),
   ( 'Leave Me Alone'  , 'Bad' ),
   ( 'Stan'            , 'The Marshall Mathers LP' ),
   ( 'The Way I Am'    , 'The Marshall Mathers LP' ),
 } [{ *trackid := ord() }]

// update the database relvars
artist := union $artist_data
cd := union ($cd_data join artist) [{ title, cdid, artistid, year:=0}]
track := union ($track_data join cd [{ *cd := title }]) [{ trackid, title, cdid }]

// functions to answer various queries
get_tracks_by_cd(t) => cd[ ?(title = t) { *title } ] join track
get_tracks_by_artist(a) => (artist[ ?(name = a) { *name }] join cd) [{ cdid }] join track
get_cd_by_track(t) => track [ ?(title = t) { cdid } ] join cd
get_cds_by_artist(a) => artist [?(name = a) { artistid } ] join cd
get_artist_by_track(t) => (track [?(title = t) { cdid }] join cd) [{ artistid }] join artist
get_artist_by_cd(t) => (cd [?(title = t) { cdid }] join cd) [{ artistid }] join artist

// first show the raw data

crlf := h'd a'
output := crlf & "=== Sample data ===" & crlf
output := artist.pp
output := crlf.pp
output := cd.pp
output := crlf.pp
output := track.pp

// now do the queries

show(title, data:{{ str:'' }}) => do {
    output := title & crlf & data[ {fold(&, "  " & str & crlf)} ]
}

output := crlf & "=== Query results ===" & crlf
show("Track title:", get_tracks_by_cd('Bad') [ {str:=title} ])
show("Track title:", get_tracks_by_artist('Michael Jackson') [ {str:=title} ])
show("CD title:", get_cd_by_track('Stan') [ {str:=title} ])
show("CD title:", get_cds_by_artist('Michael Jackson') [ {str:=title} ])
show("Artist:", get_artist_by_track('Dirty Diana') [ {str:=name} ])
show("Artist:", get_artist_by_cd('The Marshall Mathers LP') [ {str:=name} ])

The output from compiling and running this script looks as follows.

=== Sample data ===

artistid | name           
--------------------------
       0 | Michael Jackson
       1 | Eminem         

text: '
'
cdid   | artistid | title                   | year  
----------------------------------------------------
     0 |        0 | Thriller                |      0
     1 |        0 | Bad                     |      0
     2 |        1 | The Marshall Mathers LP |      0

text: '
'
trackid | cdid   | title          
----------------------------------
      0 |      0 | Beat It        
      1 |      0 | Billie Jean    
      2 |      1 | Dirty Diana    
      3 |      1 | Smooth Criminal
      4 |      1 | Leave Me Alone 
      5 |      2 | Stan           
      6 |      2 | The Way I Am   


=== Query results ===

Track title:
  Dirty Diana
  Smooth Criminal
  Leave Me Alone

Track title:
  Beat It
  Billie Jean
  Dirty Diana
  Smooth Criminal
  Leave Me Alone

CD title:
  The Marshall Mathers LP

CD title:
  Thriller
  Bad

Artist:
  Michael Jackson

Artist:
  Eminem

Leave a Comment

Filed under Code sample

Leave a Reply

Your email address will not be published. Required fields are marked *