Demystifying DBIx::Class

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    3 Favorites

    Demystifying DBIx::Class - Presentation Transcript

    1. Demystifying DBIx::Class Jay Shirley <jshirley@coldhardcode.com> http://our.coldhardcode.com/svn/DBIC-Beer
    2. Mystic?
    3. Why are ORMs scary?
    4. Why are ORMs scary? • Enterprise-y
    5. Why are ORMs scary? • Enterprise-y • Loss of control
    6. Why are ORMs scary? • Enterprise-y • Loss of control • History (Class::DBI)
    7. Why are ORMs scary? • Enterprise-y • Loss of control • History (Class::DBI) • (A triumph of multiple inheritance)
    8. Retort.
    9. Enterprise-y
    10. Enterprise-y • Enterprise = Java
    11. Enterprise-y • Enterprise = Java • DBIx::Class is written in perl
    12. Loss of Control
    13. Loss of Control • Still programmatic
    14. Loss of Control • Still programmatic • Use SQL::Abstract rather than SQL
    15. Loss of Control • Still programmatic • Use SQL::Abstract rather than SQL • Same thing
    16. Loss of Control • Still programmatic • Use SQL::Abstract rather than SQL • Same thing • (except patches welcome)
    17. Class::DBI
    18. Class::DBI Sorry Schwern
    19. Why DBIx::Class? • I like it. You’ll see why. • TIMTOWDI: • Rose::DB • Alzabo
    20. Objects • Relations are only a third of an ORM
    21. Objects • Relations are only a third of an ORM • What’s an object?
    22. Objects • Relations are only a third of an ORM • What’s an object? • Database columns
    23. Objects • Relations are only a third of an ORM • What’s an object? • Database columns • Table
    24. Objects • Relations are only a third of an ORM • What’s an object? • Database columns • Table • Indexes
    25. A Use Case
    26. Beer
    27. Yes, Beer.
    28. Or... • Beer has many distributers • Beer has many reviews • Beer belongs to a brewer
    29. Which means... package Beer::Schema::Beer; use base 'DBIx::Class'; __PACKAGE__->load_components( qw|Core| ); __PACKAGE__->table('beer'); __PACKAGE__->add_columns( 'pk1' => { data_type => 'integer', size => 16, is_nullable => 0, is_auto_increment => 1 }, 'name' => { data_type => 'varchar', size => 128, is_nullable => 0 }, 'brewer_pk1' => { data_type => 'integer', size => 16, is_nullable => 0, is_foreign_key => 1 }, ); __PACKAGE__->set_primary_key('pk1'); 1;
    30. And indexes: __PACKAGE__->add_unique_index(...);
    31. That gives you: • Deployable SQL (CREATE TABLE, etc) • The foundation for relationships: • $beer->brewer # DTRT
    32. Managing Relations • A beer is: • made by a brewer • distributed by distributers • reviewed by people
    33. Simple Relationships belongs_to is the opposite end of has_many
    34. Simple Relationships belongs_to is the opposite end of has_many has_one, might_have means just that
    35. Simple Relationships belongs_to is the opposite end of has_many has_one, might_have means just that many_to_many gets complicated
    36. Creating a relation __PACKAGE__->belongs_to( ‘brewer’, # Accessor ‘Beer::Schema::Brewer’, # Related Class ‘brewer_pk1’ # My Column );
    37. For simplicity... Brewers, Distributors and Beers are all easy All the same, except Beer has a brewer (brewer_pk1)
    38. Using it (Manager) use Beer::Schema; my $schema = Beer::Schema ->connect( $dsn );
    39. $schema # Fetch a result set my $rs = $schema->resultset(‘Beer’);
    40. Result Sets # Everything is a result set. $rs->count; # How many Beers?
    41. Everything is a Result Set $rs2 = $rs->search({ name => ‘Stout’ }); $rs2->count; # It chains together.
    42. Chained Result Sets are what make DBIC Great
    43. Result Sets return Result Sets $rs->search->search->search- >search->search->search ->search- >search->search->search->search- >search ->search->search->search- >search->search->search ->search- >search->search->search->search- >search ->search->search->search- >search->search->search ->search- >search->search->search->search- >search;
    44. Why? $rs ->search({ $long_query }) ->search({ $more_filters }) ->search({ $even_more });
    45. Actual Use: sub active_members { # All profiles that have purchased a membership. my $query = $rs->search( { 'purchase.saved_object_key' => 'membership', 'membership.expiration_date' => \\'>= NOW()' }, { join => { profile_transactions => { 'transaction' => { 'link_transaction_purchase' => { 'purchase' => 'membership' } } }, }, prefetch => [ 'state', 'country', { profile_transactions => { 'transaction' => { 'link_transaction_purchase' => { 'purchase' => 'membership' } } }, } ], group_by => [ qw/membership_id/ ] } ); }
    46. In SQL: SELECT ... FROM table_profiles me LEFT JOIN profile_transaction profile_transactions ON ( profile_transactions.profile_id = me.profile_id ) JOIN nasa_transactions transaction ON ( transaction.transaction_id = profile_transactions.transaction_id ) LEFT JOIN link_trans_pp link_transaction_purchase ON ( link_transaction_purchase.transaction_id = transaction.transaction_id ) JOIN purchased_products purchase ON ( purchase.purchased_id = link_transaction_purchase.purchased_id ) JOIN nasa_membership membership ON ( membership.membership_id = purchase.saved_product_id ) JOIN state_lookup state ON ( state.state_lookup_id = me.state ) JOIN country_lookup country ON ( country.country_lookup_id = me.country_id ) WHERE ( membership.expiration_date >= NOW() AND purchase.saved_object_key = 'membership' )
    47. Now: my $query = $schema->resultset(‘Profile’)->active_members; $query->count; # How many? $query->search({ first_name => ‘Bob’ }); # All matching members named Bob $query->search({ first_name => ‘Bob’ })->count; while ( my $profile = $query->next ) { $profile->cars; # Get all of this persons cars } # Clean, no ugly SQL
    48. Pretty.
    49. Even More: Managing your schema
    50. Create Table Statements $schema->create_ddl_dir( [ 'SQLite', 'MySQL', ‘PostgreSQL’ ], $VERSION, \"$destination\" );
    51. SQLite CREATE TABLE beer ( pk1 INTEGER PRIMARY KEY NOT NULL, name varchar(128) NOT NULL, brewer_pk1 integer(16) NOT NULL );
    52. DROP TABLE IF EXISTS `beer`; MySQL -- -- Table: `beer` -- CREATE TABLE `beer` ( `pk1` integer(16) NOT NULL auto_increment, `name` varchar(128) NOT NULL, `brewer_pk1` integer(16) NOT NULL, INDEX (`pk1`), INDEX (`brewer_pk1`), PRIMARY KEY (`pk1`), CONSTRAINT `beer_fk_brewer_pk1` FOREIGN KEY (`brewer_pk1`) REFERENCES `brewer` (`pk1`) ON DELETE CASCADE ON UPDATE CASCADE ) Type=InnoDB;
    53. PostgreSQL -- -- Table: beer -- DROP TABLE beer CASCADE; CREATE TABLE beer ( pk1 bigserial NOT NULL, name character varying(128) NOT NULL, brewer_pk1 bigint NOT NULL, PRIMARY KEY (pk1) );
    54. Get a working database $schema->deploy; # Yes, it is this simple.
    55. And now for tests

    + jshirleyjshirley, 2 years ago

    custom

    1994 views, 3 favs, 1 embeds more stats

    These are the slides to my talk I gave at the June more

    More info about this presentation

    © All Rights Reserved

    • Total Views 1994
      • 1992 on SlideShare
      • 2 from embeds
    • Comments 0
    • Favorites 3
    • Downloads 38
    Most viewed embeds
    • 2 views on http://lj-toys.com

    more

    All embeds
    • 2 views on http://lj-toys.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories