Class-DBI-mysql-1.00/0000755000175200017520000000000010306415047013006 5ustar tonytonyClass-DBI-mysql-1.00/t/0000755000175200017520000000000010306415047013251 5ustar tonytonyClass-DBI-mysql-1.00/t/pod.t0000644000175200017520000000020110306414330014203 0ustar tonytonyuse Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); Class-DBI-mysql-1.00/t/mysql.t0000644000175200017520000000412310306414774014611 0ustar tonytony#!/usr/bin/perl -w use strict; use Test::More; my $HAVE_TP = eval { require Time::Piece::MySQL }; plan tests => 8; use_ok "Class::DBI::mysql"; #------------------------------------------------------------------------- # Let the testing begin #------------------------------------------------------------------------- package Foo; use base 'Class::DBI::mysql'; # Find a test database to use. my $db = $ENV{DBD_MYSQL_DBNAME} || 'test'; my $user = $ENV{DBD_MYSQL_USER} || ''; my $pass = $ENV{DBD_MYSQL_PASSWD} || ''; my $tbl = $ENV{DBD_MYSQL_TABLE} || 'tbcdbitest'; __PACKAGE__->set_db(Main => "dbi:mysql:$db", $user => $pass); __PACKAGE__->table($tbl); __PACKAGE__->drop_table; __PACKAGE__->create_table(q{ id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(50) NOT NULL, val SMALLINT UNSIGNED NOT NULL, mydate TIMESTAMP NOT NULL, Myvals ENUM('foo', 'bar') }); __PACKAGE__->set_up_table; __PACKAGE__->autoinflate(dates => 'Time::Piece') if $HAVE_TP; END { __PACKAGE__->drop_table } #------------------------------------------------------------------------- package main; can_ok Foo => "name"; Foo->create({ Name => $_ }) foreach ( ('MySQL has now support'), ( 'for full-text search'), ('Full-text indexes'), ( 'are called collections'), ('Only MyISAM tables'), ('support collections'), ('Function MATCH ... AGAINST()'), ('is used to do a search'), ('Full-text search in MySQL'), ( 'implements vector space model')); # Test random. Is there a sensible way to test this is actually # random? For now we'll just ensure that we get something back. my $obj = Foo->retrieve_random; isa_ok $obj => "Foo", "Retrieve a random row"; SKIP: { skip "Need Time::Piece::MySQL", 2 unless $HAVE_TP; isa_ok $obj->mydate => "Time::Piece", "mydate is a Time::Piece"; is $obj->mydate->ymd, Time::Piece->new->ymd, "From today"; } # Test coltype my $type = Foo->column_type('Myvals'); like $type, qr/^enum/i, "Myvals is an enum"; my @vals = sort Foo->enum_vals('Myvals'); is_deeply \@vals, [qw/bar foo/], "Enum vals OK"; eval { Foo->enum_vals('mydate') }; ok $@, $@; Class-DBI-mysql-1.00/t/pod-coverage.t0000644000175200017520000000024110306414330016000 0ustar tonytonyuse Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; all_pod_coverage_ok(); Class-DBI-mysql-1.00/lib/0000755000175200017520000000000010306415047013554 5ustar tonytonyClass-DBI-mysql-1.00/lib/Class/0000755000175200017520000000000010306415047014621 5ustar tonytonyClass-DBI-mysql-1.00/lib/Class/DBI/0000755000175200017520000000000010306415047015217 5ustar tonytonyClass-DBI-mysql-1.00/lib/Class/DBI/mysql.pm0000644000175200017520000001344510306414726016734 0ustar tonytonypackage Class::DBI::mysql; $VERSION = '1.00'; =head1 NAME Class::DBI::mysql - Extensions to Class::DBI for MySQL =head1 SYNOPSIS package Film; use base 'Class::DBI::mysql'; __PACKAGE__->set_db('Main', 'dbi:mysql:dbname', 'user', 'password'); __PACKAGE__->set_up_table("film"); __PACKAGE__->autoinflate(dates => 'Time::Piece'); # Somewhere else ... my $type = $class->column_type('column_name'); my @allowed = $class->enum_vals('column_name'); my $tonights_viewing = Film->retrieve_random; =head1 DESCRIPTION This is an extension to Class::DBI, containing several functions and optimisations for the MySQL database. Instead of setting Class::DBI as your base class, use this instead. =cut use strict; use base 'Class::DBI'; =head1 METHODS =head2 set_up_table __PACKAGE__->set_up_table("table_name"); Traditionally, to use Class::DBI, you have to set up the columns: __PACKAGE__->columns(All => qw/list of columns/); __PACKAGE__->columns(Primary => 'column_name'); Whilst this allows for more flexibility if you're going to arrange your columns into a variety of groupings, sometimes you just want to create the 'all columns' list. Well, this information is really simple to extract from MySQL itself, so why not just use that? This call will extract the list of all the columns, and the primary key and set them up for you. It will die horribly if the table contains no primary key, or has a composite primary key. =cut __PACKAGE__->set_sql(desc_table => 'DESCRIBE __TABLE__'); sub set_up_table { my $class = shift; $class->table(my $table = shift || $class->table); (my $sth = $class->sql_desc_table)->execute; my (@cols, @pri); while (my $hash = $sth->fetch_hash) { my ($col) = $hash->{field} =~ /(\w+)/; push @cols, $col; push @pri, $col if $hash->{key} eq "PRI"; } $class->_croak("$table has no primary key") unless @pri; $class->columns(Primary => @pri); $class->columns(All => @cols); } =head2 autoinflate __PACKAGE__->autoinflate(column_type => 'Inflation::Class'); __PACKAGE__->autoinflate(timestamp => 'Time::Piece'); __PACKAGE__->autoinflate(dates => 'Time::Piece'); This will automatically set up has_a() relationships for all columns of the specified type to the given class. We currently assume that all classess passed will be able to inflate and deflate without needing extra has_a arguments, with the example of Time::Piece objects, which we deal with using Time::Piece::mysql (which you'll have to have installed!). The special type 'dates' will autoinflate all columns of type date, datetime or timestamp. =cut sub autoinflate { my ($class, %how) = @_; $how{$_} ||= $how{dates} for qw/date datetime timestamp/; my $info = $class->_column_info; foreach my $col (keys %$info) { (my $type = $info->{$col}->{type}) =~ s/\W.*//; next unless $how{$type}; my %args; if ($how{$type} eq "Time::Piece") { eval "use Time::Piece::MySQL"; $class->_croak($@) if $@; $args{inflate} = "from_mysql_$type"; $args{deflate} = "mysql_$type"; } $class->has_a($col => $how{$type}, %args); } } =head2 create_table $class->create_table(q{ name VARCHAR(40) NOT NULL PRIMARY KEY, rank VARCHAR(20) NOT NULL DEFAULT 'Private', serial INTEGER NOT NULL }); This creates the table for the class, with the given schema. If the table already exists we do nothing. A typical use would be: Music::CD->table('cd'); Music::CD->create_table(q{ cdid MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, artist MEDIUMINT UNSIGNED NOT NULL, title VARCHAR(255), year YEAR, INDEX (artist), INDEX (title) }); Music::CD->set_up_table; =head2 drop_table $class->drop_table; Drops the table for this class, if it exists. =cut __PACKAGE__->set_sql( create_table => 'CREATE TABLE IF NOT EXISTS __TABLE__ (%s)'); __PACKAGE__->set_sql(drop_table => 'DROP TABLE IF EXISTS __TABLE__'); sub drop_table { shift->sql_drop_table->execute } sub create_table { my ($class, $schema) = @_; $class->sql_create_table($schema)->execute; } =head2 column_type my $type = $class->column_type('column_name'); This returns the 'type' of this table (VARCHAR(20), BIGINT, etc.) =cut sub _column_info { my $class = shift; (my $sth = $class->sql_desc_table)->execute; return { map { $_->{field} => $_ } $sth->fetchall_hash }; } sub column_type { my $class = shift; my $col = shift or die "Need a column for column_type"; return $class->_column_info->{$col}->{type}; } =head2 enum_vals my @allowed = $class->enum_vals('column_name'); This returns a list of the allowable values for an ENUM column. =cut sub enum_vals { my $class = shift; my $col = shift or die "Need a column for enum_vals"; my $series = $class->_column_info->{$col}->{type}; $series =~ /enum\((.*?)\)/ or die "$col is not an ENUM column"; (my $enum = $1) =~ s/'//g; return split /,/, $enum; } =head2 retrieve_random my $film = Film->retrieve_random; This will select a random row from the database, and return you the relevant object. (MySQL 3.23 and higher only, at this point) =cut __PACKAGE__->add_constructor(_retrieve_random => '1 ORDER BY RAND() LIMIT 1'); sub retrieve_random { shift->_retrieve_random->first } =head1 SEE ALSO L. MySQL (http://www.mysql.com/) =head1 AUTHOR Tony Bowden =head1 BUGS and QUERIES Please direct all correspondence regarding this module to: bug-Class-DBI-mysql@rt.cpan.org =head1 COPYRIGHT AND LICENSE Copyright (C) 2001-2005 Tony Bowden. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =cut 1; Class-DBI-mysql-1.00/README0000644000175200017520000001014410306415020013655 0ustar tonytonyNAME Class::DBI::mysql - Extensions to Class::DBI for MySQL SYNOPSIS package Film; use base 'Class::DBI::mysql'; __PACKAGE__->set_db('Main', 'dbi:mysql:dbname', 'user', 'password'); __PACKAGE__->set_up_table("film"); __PACKAGE__->autoinflate(dates => 'Time::Piece'); # Somewhere else ... my $type = $class->column_type('column_name'); my @allowed = $class->enum_vals('column_name'); my $tonights_viewing = Film->retrieve_random; DESCRIPTION This is an extension to Class::DBI, containing several functions and optimisations for the MySQL database. Instead of setting Class::DBI as your base class, use this instead. METHODS set_up_table __PACKAGE__->set_up_table("table_name"); Traditionally, to use Class::DBI, you have to set up the columns: __PACKAGE__->columns(All => qw/list of columns/); __PACKAGE__->columns(Primary => 'column_name'); Whilst this allows for more flexibility if you're going to arrange your columns into a variety of groupings, sometimes you just want to create the 'all columns' list. Well, this information is really simple to extract from MySQL itself, so why not just use that? This call will extract the list of all the columns, and the primary key and set them up for you. It will die horribly if the table contains no primary key, or has a composite primary key. autoinflate __PACKAGE__->autoinflate(column_type => 'Inflation::Class'); __PACKAGE__->autoinflate(timestamp => 'Time::Piece'); __PACKAGE__->autoinflate(dates => 'Time::Piece'); This will automatically set up has_a() relationships for all columns of the specified type to the given class. We currently assume that all classess passed will be able to inflate and deflate without needing extra has_a arguments, with the example of Time::Piece objects, which we deal with using Time::Piece::mysql (which you'll have to have installed!). The special type 'dates' will autoinflate all columns of type date, datetime or timestamp. create_table $class->create_table(q{ name VARCHAR(40) NOT NULL PRIMARY KEY, rank VARCHAR(20) NOT NULL DEFAULT 'Private', serial INTEGER NOT NULL }); This creates the table for the class, with the given schema. If the table already exists we do nothing. A typical use would be: Music::CD->table('cd'); Music::CD->create_table(q{ cdid MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, artist MEDIUMINT UNSIGNED NOT NULL, title VARCHAR(255), year YEAR, INDEX (artist), INDEX (title) }); Music::CD->set_up_table; drop_table $class->drop_table; Drops the table for this class, if it exists. column_type my $type = $class->column_type('column_name'); This returns the 'type' of this table (VARCHAR(20), BIGINT, etc.) enum_vals my @allowed = $class->enum_vals('column_name'); This returns a list of the allowable values for an ENUM column. retrieve_random my $film = Film->retrieve_random; This will select a random row from the database, and return you the relevant object. (MySQL 3.23 and higher only, at this point) SEE ALSO Class::DBI. MySQL (http://www.mysql.com/) AUTHOR Tony Bowden BUGS and QUERIES Please direct all correspondence regarding this module to: bug-Class-DBI-mysql@rt.cpan.org COPYRIGHT AND LICENSE Copyright (C) 2001-2005 Tony Bowden. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Class-DBI-mysql-1.00/Changes0000644000175200017520000000514110306414736014306 0ustar tonytonyRevision history for Class::DBI::mysql. 1.00 Sat Sep 3 21:44:31 UTC 2005 - Tweak test table SQL some more (RT#12763) for MySQL 5.0+ - Remove deprecated count() method 0.23 2004-02-28 - Tweak SQL for test table to cope with stricter checks in later MySQL versions (thanks to CPAN Testers) 0.22 2003-10-26 - Add 'autoinflate' method. 0.21 2003-10-11 - Add create_table and drop_table methods (Michael Schwern) - add INSTALL file (Mark Veltzer) 0.19 2003-09-28 - Cope with various DESCRIBE TABLE outputs, hopefully. - Bring back the untainting that had vanished (Kingsley Kerce) 0.17 2003-08-13 - cope with new DESCRIBE TABLE output format in MySQL 4.1 [Ken Y Clark] 0.16 2003-06-30 - removed search_match() and initials() which should be implemented in any class that needs them. - deprecated count() in favour of Class::DBI->count_all 0.15 2003-05-30 - added DBD::mysql as a pre-req (thanks to Nicholas Clark) 0.14 2003-03-28 - brought in line with Class::DBI 0.91 - no longer support CURDATE() etc. Much easier to implement things like this in Class::DBI itself now. 0.13 2002-03-09 - untaint the column names in set_up_table - remove retrieve_all (now in Class::DBI itself) 0.12 2001-11-09 - added column_type() 0.11 2001-11-01 - added enum_vals() 0.10 2001-10-07 - brought commit() into line with Class::DBI (needs 0.35) 0.09 2001-10-05 - tweaks to commit() to cope with overloaded values (temporary measure until this gets rolled into Ima::DBI) [commit() still doesn't work with the latest Class::DBI features] 0.08 2001-07-18 - 'initials' method had problem with DISTINCT and ORDER BY in older MySQLs. Changed how it was implemented. 0.07 2001-07-18 - added 'initials' method - Moved to Test::More 0.06 2001-07-08 - reversed order of set-up in set_up_table to specify PRIMARY before ALL, to avoid bug in inheritance where it would add PRIMARY to ALL, even if you were just about to change PRIMARY. - fixed bug with those tighter restrictions! 0.05 2001-07-07 - introduced tighter restrictions on tests for ORDER BY RAND and FULLTEXT searching, which weren't implemented until 3.23.02 - added attributes() and search_range() [Thanks to Tatsuhiko Miyagawa] 0.04 2001-06-23 - first CPAN release - renamed to Class::DBI::mysql at the request of Michael Schwern 0.03 2001-06-23 - fixed bug in test where, if the last table in the database contained an underscore in its name, magically autoincrementing the name would fail to give a valid table name. 0.02 2001-06-14 - added support for CURDATE(), NOW() 0.01 2001-05 - original version (Class::DBI::MySQL) Class-DBI-mysql-1.00/Makefile.PL0000444000175200017520000000155407741752762015004 0ustar tonytonyuse ExtUtils::MakeMaker; my $PACKAGE = 'Class::DBI::mysql'; my $LOCN = 'lib/Class/DBI/mysql.pm'; my $LAST_API_CHANGE = 0.16; eval "require $PACKAGE"; unless ($@) { # Make sure we did find the module. my $inst_version = ${ $PACKAGE . '::VERSION' }; print <<"CHANGE_WARN" if $inst_version < $LAST_API_CHANGE; NOTE: There have been API changes since your installed version ($inst_version)! Please check carefully if these will impact on you: Significant changes: 0.16 - removed search_match() and initials(). - deprecated count() in favour of count_all(); 0.14 - no longer support CURDATE() etc. CHANGE_WARN } WriteMakefile( AUTHOR => 'Tony Bowden ', NAME => $PACKAGE, ABSTRACT_FROM => $LOCN, VERSION_FROM => $LOCN, PREREQ_PM => { 'Class::DBI' => 0.94, 'Test::More' => 0.45, 'DBD::mysql' => 0, }, ); Class-DBI-mysql-1.00/META.yml0000644000175200017520000000065710306415047014267 0ustar tonytony# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Class-DBI-mysql version: 1.00 version_from: lib/Class/DBI/mysql.pm installdirs: site requires: Class::DBI: 0.94 DBD::mysql: 0 Test::More: 0.45 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 Class-DBI-mysql-1.00/INSTALL0000555000175200017520000000070207741760504014051 0ustar tonytonyIn order to run the tests you need a working mysql server running with permissions to create and delete tables. The connection information is taken from the following environment variables which you can set to control this behaviour: dbname: ENV{DBD_MYSQL_DBNAME}, or default to 'test' user: ENV{DBD_MYSQL_USER}, or default to '' password: ENV{DBD_MYSQL_PASSWD}, or default to '' table: ENV{DBD_MYSQL_TABLE}, or default to 'tbcdbitest' Class-DBI-mysql-1.00/MANIFEST0000644000175200017520000000026510306415041014134 0ustar tonytonyChanges INSTALL lib/Class/DBI/mysql.pm Makefile.PL MANIFEST README t/mysql.t t/pod-coverage.t t/pod.t META.yml Module meta-data (added by MakeMaker)