About Data::ObjectDriver
- 2. About D::OD
• Author: Benjamin Trott
• Recently Version: 0.06
• Simple, transparent data interface, with
caching.
• Based on MT::ObjectDriver in MT.
Now MT included D::OD.
- 3. D::OD features
• Built-in supportRAM and Apache inPartitioning.
Support Memcached,
Caching and
caching.
• Have to support master-slaver_handle()/rw_handle().
Can change process for read/write using
structure in mind.
• Implementation is becauseso less model feature.
But implement by myself,
thin, east-to-use.
of
Has ‘has_a’ but not has ‘has_many’.
- 4. Class structures
• Driver definition about how to connection to
Class for
class
db and cache server, and partitioning rules.
• Object classwhat you call.
The model class
Class for definition about how to treat data on tables.
- 5. Class structures
• Other classes
- D::OD::ResultSet
In the middle of an implementation?
Do not use in MT.
- D::OD::Profiler
Simple profiler.
- D::OD::GearmanDBI
I do not know how to use;)
- 6. Simple usase
• Make object class for table
Make sub-class of D::OD::BaseObject,
and set table information using install_properties().
‘driver’ is D::OD::Driver::DBI.
- 7. Simple usage
package Artist;
use strict;
use base qw( Data::ObjectDriver::BaseObject );
__PACKAGE__->install_properties(
datasource => 'artist',
columns => [ qw( id name orig_name band_id ) ],
primary_key => 'id',
driver => Data::ObjectDriver::Driver::DBI->new( %DB_INFO ),
);
1;
- 8. CRUD and etc
• Create
my artist = Artist->new(
name => ' ',
fullname => ' II '
);
$artist->save;
# or
Artist->bulk_insert( [col1, col2], [ [d1, d2], [d1, d2] ]);
- 9. CRUD and etc
• Read
my $artist = Artist->lookup(1);
print $artist->name;
# or
$artist_iter = Artist->search( { name => ' ' } );
@artists = Artist->search( { name => ' ' );
# or
$artists_ref = Artist->lookup_multi( [ 1, 2, 3 ] );
- 12. CRUD and etc
• has_a()
__PACKAGE__->has_a( {
class => 'Band',
column => 'band_id',
cached => 1,
} );
- 13. CRUD and etc
• add_trigger() post_load pre_search pre_insert
pre_save post_save
post_insert pre_update post_update pre_remove
post_remove post_inflate
__PACKAGE__->add_trigger(
pre_insert => sub {
my ( $obj, $orig_obj ) = @_;
...
},
);
- 15. Caching
package Artist;
use strict;
use base qw( Data::ObjectDriver::BaseObject );
__PACKAGE__->install_properties(
...
driver => Data::ObjectDriver::Driver::Cache::Memcached->new(
cache => Cache::Memcached->new( servers => @servers ),
fallback => Data::ObjectDriver::Driver::DBI->new( %DB_INFO ),
),
...
);
1;
- 16. Master-Slave structure
• Only override r_handle().in read process,
r_handle() is method that execute
so this method is used to connect to slave database.
- 17. Master-Slave structure
• Object class
package Artist;
use strict;
use base qw( Data::ObjectDriver::BaseObject );
__PACKAGE__->install_properties(
...
driver => Data::ObjectDriver::Driver::Cache::Memcached->new(
cache => Cache::Memcached->new( servers => @servers ),
fallback => ReplDriver->new( %DB_INFO, slaves => [ slave01, ... ] ),
),
...
);
- 18. Master-Slave structure
• Driver class
package ReplDriver;
use strict;
use base qw( Data::ObjectDriver::Driver::DBI );
__PACKAGE__->mk_accessors( qw( slaves ) );
sub init {
my $driver = shift;
my %param = @_;
$driver->slaves( delete $param{ slaves } );
$driver->SUPER::init( %param );
return $driver;
}
# cont.
- 19. Master-Slave structure
• Driver class(cont.)
# cont.
sub r_handle {
my $driver = shift;
my $db = shift || 'main';
for my $slave ( shuffle @{ $driver->slaves } ) {
# connect to $slave
my $dbh = DBI->connect( $slave->{DB_INFO} );
$driver->dbd->init_dbh($dbh);
return $dbh;
}
$driver->rw_handle($db);
}
1;
- 20. Partitioning
package CD;
use strict;
use base qw( Data::ObjectDriver::BaseObject );
__PACKAGE__->install_properties(
datasource => 'cd',
columns => [ qw( artist_id id title ) ],
primary_key => [ qw( artist_id id ) ],
driver => PartitionDriver->driver,
);
1;
- 21. Partitioning
package PartitionDriver;
use strict;
sub driver {
my $fallback = Data::ObjectDriver::Driver::Partition->new(
get_driver => &find_partition,
);
Data::ObjectDriver::Driver::Cache::Memcached->new(
cache => Cache::Memcached->new( servers => @servers ),
fallback => $fallback,
),
}
# cont.
- 22. Partitioning
# cont.
sub find_partition {
my ( $terms, $args ) = @_;
my $artist = Artist->lookup( $terms->{ artist_id } );
return ReplDriver->new(
%{ $artist->partition_obj->master },
slaves => $artist->partition_obj->slaves,
pk_generator => &pk_generator,
);
}
sub pk_generator {
my $obj = shift;
$obj->id( generate_id() );
1;
},
1;
- 23. Partitioning
my $cd = CD->new(
artist_id => 1,
title => ' '
);
$cd->save;
lookup() is depends on PartitionDriver implementation in partitioning.
- 24. At the end, I wish...
• Built-in support pager using Data::Page.
• Wants count() and more useful methods.
• Hard to execute simple SQL.
(Just do using D::OD::SQL?)
• And hard to execute ‘JOIN’.