Slideshare.net (beta)

 
Post to TwitterPost to Twitter
Post: 
Myspace Hi5 Friendster Xanga LiveJournal Facebook Blogger Tagged Typepad Freewebs BlackPlanet gigya icons

All comments

Add a comment on Slide 1

If you have a SlideShare account, login to comment; else you can comment as a guest


Showing 1-50 of 0 (more)

Demystifying DBIx::Class

From jshirley, 3 months ago

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

305 views  |  0 comments  |  0 favorites  |  6 downloads  |  1 embed (Stats)
 

Categories

Add Category
 
 
 
 

Groups / Events

 

 
Embed
options

More Info

This slideshow is Public
Total Views: 305
on Slideshare: 303
from embeds: 2

Slideshow transcript

Slide 1: Demystifying DBIx::Class Jay Shirley <jshirley@coldhardcode.com> http://our.coldhardcode.com/svn/DBIC-Beer

Slide 2: Mystic?

Slide 3: Why are ORMs scary?

Slide 4: Why are ORMs scary? • Enterprise-y

Slide 5: Why are ORMs scary? • Enterprise-y • Loss of control

Slide 6: Why are ORMs scary? • Enterprise-y • Loss of control • History (Class::DBI)

Slide 7: Why are ORMs scary? • Enterprise-y • Loss of control • History (Class::DBI) • (A triumph of multiple inheritance)

Slide 8: Retort.

Slide 9: Enterprise-y

Slide 10: Enterprise-y • Enterprise = Java

Slide 11: Enterprise-y • Enterprise = Java • DBIx::Class is written in perl

Slide 12: Loss of Control

Slide 13: Loss of Control • Still programmatic

Slide 14: Loss of Control • Still programmatic • Use SQL::Abstract rather than SQL

Slide 15: Loss of Control • Still programmatic • Use SQL::Abstract rather than SQL • Same thing

Slide 16: Loss of Control • Still programmatic • Use SQL::Abstract rather than SQL • Same thing • (except patches welcome)

Slide 17: Class::DBI

Slide 18: Class::DBI Sorry Schwern

Slide 19: Why DBIx::Class? • I like it. You’ll see why. • TIMTOWDI: • Rose::DB • Alzabo

Slide 20: Objects • Relations are only a third of an ORM

Slide 21: Objects • Relations are only a third of an ORM • What’s an object?

Slide 22: Objects • Relations are only a third of an ORM • What’s an object? • Database columns

Slide 23: Objects • Relations are only a third of an ORM • What’s an object? • Database columns • Table

Slide 24: Objects • Relations are only a third of an ORM • What’s an object? • Database columns • Table • Indexes

Slide 25: A Use Case

Slide 26: Beer

Slide 27: Yes, Beer.

Slide 28: Or... • Beer has many distributers • Beer has many reviews • Beer belongs to a brewer

Slide 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;

Slide 30: And indexes: __PACKAGE__->add_unique_index(...);

Slide 31: That gives you: • Deployable SQL (CREATE TABLE, etc) • The foundation for relationships: • $beer->brewer # DTRT

Slide 32: Managing Relations • A beer is: • made by a brewer • distributed by distributers • reviewed by people

Slide 33: Simple Relationships belongs_to is the opposite end of has_many

Slide 34: Simple Relationships belongs_to is the opposite end of has_many has_one, might_have means just that

Slide 35: Simple Relationships belongs_to is the opposite end of has_many has_one, might_have means just that many_to_many gets complicated

Slide 36: Creating a relation __PACKAGE__->belongs_to( ‘brewer’, # Accessor ‘Beer::Schema::Brewer’, # Related Class ‘brewer_pk1’ # My Column );

Slide 37: For simplicity... Brewers, Distributors and Beers are all easy All the same, except Beer has a brewer (brewer_pk1)

Slide 38: Using it (Manager) use Beer::Schema; my $schema = Beer::Schema ->connect( $dsn );

Slide 39: $schema # Fetch a result set my $rs = $schema->resultset(‘Beer’);

Slide 40: Result Sets # Everything is a result set. $rs->count; # How many Beers?

Slide 41: Everything is a Result Set $rs2 = $rs->search({ name => ‘Stout’ }); $rs2->count; # It chains together.

Slide 42: Chained Result Sets are what make DBIC Great

Slide 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;

Slide 44: Why? $rs ->search({ $long_query }) ->search({ $more_filters }) ->search({ $even_more });

Slide 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/ ] } ); }

Slide 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' )

Slide 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

Slide 48: Pretty.

Slide 49: Even More: Managing your schema

Slide 50: Create Table Statements $schema->create_ddl_dir( [ 'SQLite', 'MySQL', ‘PostgreSQL’ ], $VERSION, \"$destination\" );

Slide 51: SQLite CREATE TABLE beer ( pk1 INTEGER PRIMARY KEY NOT NULL, name varchar(128) NOT NULL, brewer_pk1 integer(16) NOT NULL );

Slide 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;

Slide 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) );

Slide 54: Get a working database $schema->deploy; # Yes, it is this simple.

Slide 55: And now for tests