[Koha-devel] [RFC: DBIx::Class 2/3] DBix::Class - moving C4::ClassSource over to using DBIx::Class

Andrew Moore andrew.moore at liblime.com
Fri Oct 24 16:10:43 CEST 2008


This is an example of replacing the SQL calls in the first half of the C4/ClassSource.pm
file with calls to the DBIx::Class schema object. I used this module as an example because
it's rather simple and you can see how the more simple SQL operations can get replaced
by calls to the schema object.

I've included some test files that pass both before and after the changes. I'm hopeful
that they demonstrate that the functionality hasn't changed.

I did have to adjust the way that C4::Accounts referenced C4::Circulation. I'm not sure why,
but it was giving errors to explicitly request that MarkIssueReturned be exported when it
was already always unonditionally exported.

One thing to note: While this is a perfectly valid way to transition, I would recommend
that we eventually take one further step. In this file there are two sets of functions
that perform simple operations on two tables. They create, read, update, and delete records
in those tables. I will recommend that we eventaully make a base class that provides those
essential operations and then subclass it for each of our tables that act this way. Then,
we can add in any functionality particular to those subclasses. I haven't addressed that
improvement in these patches.
---
 C4/Accounts.pm                            |    2 +-
 C4/ClassSource.pm                         |   66 ++++++++++++----------------
 t/lib/KohaTest/ClassSource.pm             |   34 +++++++++++++++
 t/lib/KohaTest/ClassSource/ClassSource.pm |   56 ++++++++++++++++++++++++
 4 files changed, 119 insertions(+), 39 deletions(-)
 create mode 100644 t/lib/KohaTest/ClassSource.pm
 create mode 100644 t/lib/KohaTest/ClassSource/ClassSource.pm

diff --git a/C4/Accounts.pm b/C4/Accounts.pm
index c43741b..4050124 100644
--- a/C4/Accounts.pm
+++ b/C4/Accounts.pm
@@ -23,7 +23,7 @@ use C4::Context;
 use C4::Stats;
 use C4::Members;
 use C4::Items;
-use C4::Circulation qw(MarkIssueReturned);
+use C4::Circulation;
 
 use vars qw($VERSION @ISA @EXPORT);
 
diff --git a/C4/ClassSource.pm b/C4/ClassSource.pm
index 4a161ae..4db0656 100644
--- a/C4/ClassSource.pm
+++ b/C4/ClassSource.pm
@@ -64,6 +64,9 @@ sources and sorting rules.
     
 );
 
+use C4::Schema;
+our $schema = C4::Schema->connect();
+
 =head2 GetClassSources
 
   my $sources = GetClassSources();
@@ -91,13 +94,11 @@ foreach my $cn_source (sort keys %$sources) {
 sub GetClassSources {
 
     my %class_sources = ();
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare_cached("SELECT * FROM `class_sources`");
-    $sth->execute();
-    while (my $source = $sth->fetchrow_hashref) {
-        $class_sources{ $source->{'cn_source'} } = $source;
+
+    my @class_sources = $schema->resultset('ClassSources')->search();
+    foreach my $row ( @class_sources ) {
+        $class_sources{ $row->get_column('cn_source') } = { $row->get_columns };
     }
-    $sth->finish();
 
     return \%class_sources;
 
@@ -112,15 +113,14 @@ sub GetClassSources {
 =cut
 
 sub AddClassSource {
-
-    my ($cn_source, $description, $used, $class_sort_rule) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare_cached("INSERT INTO `class_sources` 
-                                           (`cn_source`, `description`, `used`, `class_sort_rule`)
-                                           VALUES (?, ?, ?, ?)");
-    $sth->execute($cn_source, $description, $used, $class_sort_rule);
-    $sth->finish();
-  
+    my ( $cn_source, $description, $used, $class_sort_rule ) = @_;
+    my $new_cs = $schema->resultset('ClassSources')->create(
+        {   cn_source       => $cn_source,
+            description     => $description,
+            used            => $used,
+            class_sort_rule => $class_sort_rule
+        }
+    );
 }
 
 =head2 GetClassSource
@@ -132,14 +132,12 @@ sub AddClassSource {
 =cut
 
 sub GetClassSource {
+    my $cn_source = shift;
 
-    my ($cn_source) = (@_);
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare_cached("SELECT * FROM `class_sources` WHERE cn_source = ?");
-    $sth->execute($cn_source);
-    my $row = $sth->fetchrow_hashref();
-    $sth->finish();
-    return $row;
+    my $rs = $schema->resultset('ClassSources')->find( $cn_source );
+    return unless defined $rs; # in case this one doesn't exist.
+    my %class_source = $rs->get_columns;
+    return \%class_source;
 }
 
 =head2 ModClassSource 
@@ -151,17 +149,14 @@ sub GetClassSource {
 =cut
 
 sub ModClassSource {
-
     my ($cn_source, $description, $used, $class_sort_rule) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare_cached("UPDATE `class_sources` 
-                                    SET  `description` = ?,
-                                         `used` = ?,
-                                         `class_sort_rule` = ?
-                                    WHERE `cn_source` = ?");
-    $sth->execute($description, $used, $class_sort_rule, $cn_source);
-    $sth->finish();
 
+    my $cs = $schema->resultset('ClassSources')->find( $cn_source );
+    return unless defined $cs; # in case this one doesn't exist.
+    $cs->set_column( description     => $description );
+    $cs->set_column( used            => $used );
+    $cs->set_column( class_sort_rule => $class_sort_rule );
+    return $cs->update();
 }
 
 =head2 DelClassSource 
@@ -173,13 +168,8 @@ sub ModClassSource {
 =cut
 
 sub DelClassSource {
-
-    my ($cn_source) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare_cached("DELETE FROM `class_sources` WHERE `cn_source` = ?");
-    $sth->execute($cn_source);
-    $sth->finish();
-
+    my $cn_source = shift;
+    my $deleted = $schema->resultset('ClassSources')->find( $cn_source )->delete;
 }
 
 =head2 GetClassSortRules
diff --git a/t/lib/KohaTest/ClassSource.pm b/t/lib/KohaTest/ClassSource.pm
new file mode 100644
index 0000000..227272b
--- /dev/null
+++ b/t/lib/KohaTest/ClassSource.pm
@@ -0,0 +1,34 @@
+package KohaTest::ClassSource;
+use base qw( KohaTest );
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use C4::Members;
+sub testing_class { 'C4::ClassSource' };
+
+
+sub methods : Test( 1 ) {
+    my $self    = shift;
+    my @methods = qw(
+      GetClassSources
+      AddClassSource
+      GetClassSource
+      ModClassSource
+      DelClassSource
+      GetClassSortRules
+      AddClassSortRule
+      GetClassSortRule
+      ModClassSortRule
+      DelClassSortRule
+      GetSourcesForSortRule
+      GetClassSort
+    );
+
+    can_ok( $self->testing_class, @methods );
+}
+
+1;
+
diff --git a/t/lib/KohaTest/ClassSource/ClassSource.pm b/t/lib/KohaTest/ClassSource/ClassSource.pm
new file mode 100644
index 0000000..e15638c
--- /dev/null
+++ b/t/lib/KohaTest/ClassSource/ClassSource.pm
@@ -0,0 +1,56 @@
+package KohaTest::ClassSource::ClassSource;
+use base qw( KohaTest::ClassSource );
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use C4::ClassSource;
+
+sub round_trip : Test(8) {
+    my $self = shift;
+
+    my $example = {
+        cn_source        => 'foo',
+        class_sort_rule => 'generic',
+        used             => '0',
+        description      => 'example for testing'
+    };
+
+    my $not_there = GetClassSource( $example->{'cn_source'} );
+    ok( ! defined( $not_there ), 'our example is not there to start with' ) or
+      warn( Data::Dumper->Dump( [ $not_there ], [ 'not_there' ] ) );
+
+    my $added = AddClassSource( $example->{'cn_source'}, $example->{'description'}, $example->{'used'}, $example->{'class_sort_rule'} );
+    ok( $added, 'added' );
+
+    my $there = GetClassSource( $example->{'cn_source'} );
+    is_deeply( $there, $example, 'the one we got back is the same as the one we sent in' );
+
+    my $class_sources = GetClassSources();
+    is_deeply( $class_sources->{ $example->{'cn_source'} }, $example )
+      or warn( Data::Dumper->Dump( [ $class_sources ], [ 'class_sources' ] ) );
+
+    my $modified_example = {
+        cn_source        => $example->{'cn_source'},
+        class_sort_rule => 'dewey',
+        used             => '1',
+        description      => 'modified example for testing',
+    };
+      
+    my $modified = ModClassSource( $modified_example->{'cn_source'}, $modified_example->{'description'}, $modified_example->{'used'}, $modified_example->{'class_sort_rule'} );
+    ok( $modified, 'modified' );
+
+    my $found_modified = GetClassSource( $modified_example->{'cn_source'} );
+    is_deeply( $found_modified, $modified_example, 'the one we got back is the same as the one we sent in' );
+
+    my $deleted = DelClassSource( $modified_example->{'cn_source'} );
+    ok( $deleted, 'deleted' );
+    
+    my $not_found = GetClassSource( $modified_example->{'cn_source'} );
+    ok( ! defined( $not_found ), 'deleted' );
+
+}
+
+1;
-- 
1.5.6




More information about the Koha-devel mailing list