.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Data::ObjectDriver::Driver::Partition 3pm" .TH Data::ObjectDriver::Driver::Partition 3pm "2017-09-30" "perl v5.26.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Data::ObjectDriver::Driver::Partition \- base class for partitioned object drivers .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& package SomeObject; \& \& _\|_PACKAGE_\|_\->install_properties({ \& ... \& primary_key => \*(Aqid\*(Aq, \& driver => Data::ObjectDriver::Driver::Partition\->new(get_driver => \e&find_partition), \& }); \& \& # Say we have a list of 5 arrayrefs of the DBI driver information. \& my @DBI_INFO; \& \& sub find_partition { \& my ($part_key, $args) = @_; \& \& my $id; \& \& if (ref $terms && ref $terms eq \*(AqHASH\*(Aq) { \& # This is a search($terms, $args) call. \& my $terms = $part_key; \& $id = $terms\->{id} \& or croak "Can\*(Aqt determine partition from a search() with no id field"; \& } \& else { \& # This is a lookup($id) or some method invoked on an object where we know the ID. \& my $id = $part_key; \& } \& \& # "ID modulo N" is not a good partitioning strategy, but serves as an example. \& my $partition = $id % 5; \& return Data::ObjectDriver::Driver::DBI\->new( @{ $DBI_INFO[$partition] } ); \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fIData::ObjectDriver::Driver::Partition\fR provides the basic structure for partitioning objects into different databases. Using partitions, you can horizontally scale your application by using different database servers to hold sets of data. .PP To partition data, you need a certain criteria to determine which partition data goes in. Partition drivers use a \f(CW\*(C`get_driver\*(C'\fR function to find the database driver for the correct partition, given either the arguments to a \&\f(CW\*(C`search()\*(C'\fR or the object's primary key for a \f(CW\*(C`lookup()\*(C'\fR, \f(CW\*(C`update()\*(C'\fR, etc where the key is known. .SH "SUGGESTED PRACTICES" .IX Header "SUGGESTED PRACTICES" While you can use any stable, predictable method of selecting the partition for an object, the most flexible way is to keep an unpartitioned table that maps object keys to their partitions. You can then look up the appropriate record in your get_driver method to find the partition. .PP For many applications, you can partition several classes of data based on the \&\s-1ID\s0 of the user account that \*(L"owns\*(R" them. In this case, you would include the user \s-1ID\s0 as the first part of a complex primary key. .PP Because multiple objects can use the same partitioning scheme, often \&\fIData::ObjectDriver::Driver::Partition\fR is subclassed to define the \&\f(CW\*(C`get_driver\*(C'\fR function once and automatically specify it to the \&\fIData::ObjectDriver::Driver::Partition\fR constructor. .PP Note these practices are codified into the \&\fIData::ObjectDriver::Driver::SimplePartition\fR class. .SH "USAGE" .IX Header "USAGE" .ie n .SS """Data::ObjectDriver::Driver::Partition\->new(%params)""" .el .SS "\f(CWData::ObjectDriver::Driver::Partition\->new(%params)\fP" .IX Subsection "Data::ObjectDriver::Driver::Partition->new(%params)" Creates a new partitioning driver. The required members of \f(CW%params\fR are: .IP "\(bu" 4 \&\f(CW\*(C`get_driver\*(C'\fR .Sp A reference to a function to be used to retrieve for a given object or set of search terms. Your function is invoked as either: .RS 4 .IP "\(bu" 4 \&\f(CW\*(C`get_driver(\e%terms, \e%args)\*(C'\fR .Sp Return a driver based on the given \f(CW\*(C`search()\*(C'\fR parameters. .IP "\(bu" 4 \&\f(CW\*(C`get_driver($id)\*(C'\fR .Sp Return a driver based on the given object \s-1ID.\s0 Note that \f(CW$id\fR may be an arrayref, if the class was defined with a complex primary key. .RE .RS 4 .RE .IP "\(bu" 4 \&\f(CW\*(C`pk_generator\*(C'\fR .Sp A reference to a function that, given a data object, generates a primary key for it. This is the same \f(CW\*(C`pk_generator\*(C'\fR given to \f(CW\*(C`Data::ObjectDriver\*(C'\fR's constructor. .ie n .SS """$driver\->search($class, $terms, $args)""" .el .SS "\f(CW$driver\->search($class, $terms, $args)\fP" .IX Subsection "$driver->search($class, $terms, $args)" .ie n .SS """$driver\->lookup($class, $id)""" .el .SS "\f(CW$driver\->lookup($class, $id)\fP" .IX Subsection "$driver->lookup($class, $id)" .ie n .SS """$driver\->lookup_multi($class, @ids)""" .el .SS "\f(CW$driver\->lookup_multi($class, @ids)\fP" .IX Subsection "$driver->lookup_multi($class, @ids)" .ie n .SS """$driver\->exists($obj)""" .el .SS "\f(CW$driver\->exists($obj)\fP" .IX Subsection "$driver->exists($obj)" .ie n .SS """$driver\->insert($obj)""" .el .SS "\f(CW$driver\->insert($obj)\fP" .IX Subsection "$driver->insert($obj)" .ie n .SS """$driver\->update($obj)""" .el .SS "\f(CW$driver\->update($obj)\fP" .IX Subsection "$driver->update($obj)" .ie n .SS """$driver\->remove($obj)""" .el .SS "\f(CW$driver\->remove($obj)\fP" .IX Subsection "$driver->remove($obj)" .ie n .SS """$driver\->fetch_data($what)""" .el .SS "\f(CW$driver\->fetch_data($what)\fP" .IX Subsection "$driver->fetch_data($what)" Performs the named action, by passing these methods through to the appropriate database driver as determined by \f(CW$driver\fR's \f(CW\*(C`get_driver\*(C'\fR function. .SH "DIAGNOSTICS" .IX Header "DIAGNOSTICS" No errors are created by \fIData::ObjectDriver::Driver::Partition\fR itself. Errors may come from a specific partitioning subclass or the driver for a particular database. .SH "BUGS AND LIMITATIONS" .IX Header "BUGS AND LIMITATIONS" There are no known bugs in this module. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIData::ObjectDriver::Driver::SimplePartition\fR .SH "LICENSE" .IX Header "LICENSE" \&\fIData::ObjectDriver\fR is free software; you may redistribute it and/or modify it under the same terms as Perl itself. .SH "AUTHOR & COPYRIGHT" .IX Header "AUTHOR & COPYRIGHT" Except where otherwise noted, \fIData::ObjectDriver\fR is Copyright 2005\-2006 Six Apart, cpan@sixapart.com. All rights reserved.