]> Frank Brehm's Git Trees - books.git/commitdiff
weiter Umbau auf Transaktionen
authorFrank Brehm <frank@brehm-online.com>
Tue, 2 Mar 2010 21:22:37 +0000 (21:22 +0000)
committerFrank Brehm <frank@brehm-online.com>
Tue, 2 Mar 2010 21:22:37 +0000 (21:22 +0000)
db/changes-01.sql [new file with mode: 0644]
lib/FrBr/Books/Db/Result/Kategorien.pm
lib/FrBr/Books/Db/Result/Orte.pm
lib/FrBr/Books/Plugin/Category.pm
lib/FrBr/Books/Plugin/Ort.pm

diff --git a/db/changes-01.sql b/db/changes-01.sql
new file mode 100644 (file)
index 0000000..ceac7ea
--- /dev/null
@@ -0,0 +1,66 @@
+--
+-- Änderungen an der Datenstruktur
+--
+
+--
+-- $Id$
+-- $URL$
+--
+
+-- ----------------------------------------------------------------------------------
+-- Tabelle `kategorien` aufmotzen.
+
+ALTER TABLE `kategorien`
+  ADD `created_at` datetime,
+  ADD `created_by` int(10) unsigned,
+  ADD `changed_at` datetime,
+  ADD `changed_by` int(10) unsigned,
+  ADD KEY `created_by` (`created_by`),
+  ADD KEY `changed_by` (`changed_by`),
+  ADD CONSTRAINT `kategorien_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`user_id`),
+  ADD CONSTRAINT `kategorien_ibfk_2` FOREIGN KEY (`changed_by`) REFERENCES `users` (`user_id`);
+
+UPDATE `kategorien` SET
+  `created_at` = NOW(),
+  `created_by` = 1,
+  `changed_at` = NOW(),
+  `changed_by` = 1;
+
+COMMIT;
+
+ALTER TABLE `kategorien`
+  MODIFY `created_at` datetime         NOT NULL COMMENT 'Wann erstellt',
+  MODIFY `created_by` int(10) unsigned NOT NULL COMMENT 'Von welcher User-Id erstellt',
+  MODIFY `changed_at` datetime         NOT NULL COMMENT 'Wann geändert',
+  MODIFY `changed_by` int(10) unsigned NOT NULL COMMENT 'Von welcher User-Id geändert';
+
+-- ----------------------------------------------------------------------------------
+-- Tabelle `orte` aufmotzen.
+
+ALTER TABLE `orte`
+  ADD `created_at` datetime,
+  ADD `created_by` int(10) unsigned,
+  ADD `changed_at` datetime,
+  ADD `changed_by` int(10) unsigned,
+  ADD KEY `created_by` (`created_by`),
+  ADD KEY `changed_by` (`changed_by`),
+  ADD CONSTRAINT `orte_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`user_id`),
+  ADD CONSTRAINT `orte_ibfk_2` FOREIGN KEY (`changed_by`) REFERENCES `users` (`user_id`);
+
+UPDATE `orte` SET
+  `created_at` = NOW(),
+  `created_by` = 1,
+  `changed_at` = NOW(),
+  `changed_by` = 1;
+
+COMMIT;
+
+ALTER TABLE `orte`
+  MODIFY `created_at` datetime         NOT NULL COMMENT 'Wann erstellt',
+  MODIFY `created_by` int(10) unsigned NOT NULL COMMENT 'Von welcher User-Id erstellt',
+  MODIFY `changed_at` datetime         NOT NULL COMMENT 'Wann geändert',
+  MODIFY `changed_by` int(10) unsigned NOT NULL COMMENT 'Von welcher User-Id geändert';
+
+-- ----------------------------------------------------------------------------------
+
+-- vim: noai : ts=4 fenc=utf-8 filetype=sql expandtab :
index afb4e8d5ac478824d36ae40fe39d176bf2dbb9a6..7a5e080f72b539488816756421224740254392df 100644 (file)
@@ -11,13 +11,20 @@ use base 'DBIx::Class';
 __PACKAGE__->load_components("Core");
 __PACKAGE__->table("kategorien");
 __PACKAGE__->add_columns(
-  "id"             => { data_type => "INT",     default_value => undef, is_nullable => 0, size => 10 },
-  "kategorie_name" => { data_type => "VARCHAR", default_value => undef, is_nullable => 0, size => 100, },
+  "id"             => { data_type => "INT",      default_value => undef, is_nullable => 0, size => 10 },
+  "kategorie_name" => { data_type => "VARCHAR",  default_value => undef, is_nullable => 0, size => 100, },
+  "created_at"     => { data_type => "DATETIME", default_value => undef, is_nullable => 0, size => 19, },
+  "created_by"     => { data_type => "INT",      default_value => undef, is_nullable => 0, size => 10 },
+  "changed_at"     => { data_type => "DATETIME", default_value => undef, is_nullable => 0, size => 19, },
+  "changed_by"     => { data_type => "INT",      default_value => undef, is_nullable => 0, size => 10 },
 );
 __PACKAGE__->set_primary_key("id");
 __PACKAGE__->add_unique_constraint("kategorie_name", ["kategorie_name"]);
 
 
+__PACKAGE__->belongs_to( "created_by", "FrBr::Books::Db::Result::Users", { 'foreign.user_id' => "self.created_by" },);
+__PACKAGE__->belongs_to( "changed_by", "FrBr::Books::Db::Result::Users", { 'foreign.user_id' => "self.changed_by" },);
+
 __PACKAGE__->has_many( 'buch_kategorie' => 'FrBr::Books::Db::Result::Buch2kategorie', { 'foreign.kategorie_id' => 'self.id' } );
 __PACKAGE__->many_to_many( 'buecher' => 'buch_kategorie', 'buch' );
 
index 349bf967ca500f2b53e886fab4d2fa49e3acb2ea..54e90257b97d61347464ef6567ab713cf45526ee 100644 (file)
@@ -11,14 +11,20 @@ use base 'DBIx::Class';
 __PACKAGE__->load_components("Core");
 __PACKAGE__->table("orte");
 __PACKAGE__->add_columns(
-  "id"       => { data_type => "INT",     default_value => undef, is_nullable => 0, size => 10 },
-  "name"     => { data_type => "VARCHAR", default_value => undef, is_nullable => 0, size => 100, },
-  "descr"    => { data_type => "TEXT",    default_value => undef, is_nullable => 0, size => 65535, },
-  "statisch" => { data_type => "ENUM",    default_value => "n",   is_nullable => 0, size => 1 },
+  "id"         => { data_type => "INT",      default_value => undef, is_nullable => 0, size => 10 },
+  "name"       => { data_type => "VARCHAR",  default_value => undef, is_nullable => 0, size => 100, },
+  "descr"      => { data_type => "TEXT",     default_value => undef, is_nullable => 0, size => 65535, },
+  "statisch"   => { data_type => "ENUM",     default_value => "n",   is_nullable => 0, size => 1 },
+  "created_at" => { data_type => "DATETIME", default_value => undef, is_nullable => 0, size => 19, },
+  "created_by" => { data_type => "INT",      default_value => undef, is_nullable => 0, size => 10 },
+  "changed_at" => { data_type => "DATETIME", default_value => undef, is_nullable => 0, size => 19, },
+  "changed_by" => { data_type => "INT",      default_value => undef, is_nullable => 0, size => 10 },
 );
 __PACKAGE__->set_primary_key("id");
 __PACKAGE__->add_unique_constraint("name", ["name"]);
 
+__PACKAGE__->belongs_to( "created_by", "FrBr::Books::Db::Result::Users", { 'foreign.user_id' => "self.created_by" },);
+__PACKAGE__->belongs_to( "changed_by", "FrBr::Books::Db::Result::Users", { 'foreign.user_id' => "self.changed_by" },);
 
 __PACKAGE__->has_many( 'buecher' => 'FrBr::Books::Db::Result::Buecher', { 'foreign.orts_id' => 'self.id' } );
 
index f2157e5d8b45cf7ea7719be256a777c2971848be..656b4449f13415bb915fde205071c3aa284fd653 100644 (file)
@@ -53,9 +53,15 @@ Listenlänge einer Seite (wenn seitenweise gewünscht wird).
 Rueckgabe: Im skalaren Kontext eine Array-Ref von Hash-Refs mit allen Kategorien, die den uebergebenen Suchkriterien entsprechen:
 
   $res = [
-    { 'id'          => 1,
-      'name'        => 'Science Fiction',
-      'count_books'    => 22,
+    { 'id'              => 1,
+      'name'            => 'Science Fiction',
+      'count_books'     => 22,
+      'created_at'      => '2010-02-22 12:13:14',
+      'id_created_by'   => 1,
+      'name_created_by' => 'Frank Brehm',
+      'changed_at'      => '2010-02-29 13:14:15',
+      'id_changed_by'   => 2,
+      'name_changed_by' => 'Doris Hennig',
     },
     { 'id'     => 2,
       ...
@@ -105,18 +111,38 @@ sub b_get_category_list {
     $c->log->debug(  get_output_string( $K, "Anzahl gefundene Kategorien: ", $anzahl_kategorien ) ) if $c->stash->{'debug_level'} >= 2;
 
     my $other_params = {};
-    $other_params->{'order_by'} = [ 'kategorie_name' ];
+    $other_params->{'join'} = [
+        'buch_kategorie',
+        'created_by',
+        'changed_by',
+    ];
+    $other_params->{'order_by'} = [ 'me.kategorie_name' ];
     $other_params->{'select'} = [
         'me.id',
         'me.kategorie_name',
-               { 'count' => 'buch_kategorie.id' }
+        'me.created_by',
+        'created_by.vorname',
+        'created_by.nachname',
+        'me.created_at',
+        'me.changed_by',
+        'changed_by.vorname',
+        'changed_by.nachname',
+        'me.changed_at',
+               { 'count' => 'buch_kategorie.id' },
     ];
     $other_params->{'as'} = [
         'id',
         'kategorie_name',
+        'created_by',
+        'created_by_vorname',
+        'created_by_nachname',
+        'created_at',
+        'changed_by',
+        'changed_by_vorname',
+        'changed_by_nachname',
+        'changed_at',
                'count_books',
     ];
-       $other_params->{'join'} = [ 'buch_kategorie'];
        $other_params->{'group_by'} = [ 'me.id' ];
  
        if ( $page ) {
@@ -125,11 +151,28 @@ sub b_get_category_list {
        }
  
     for my $cat_rs ( $c->model('Schema::Kategorien')->search( $search_params, $other_params )->all() ) {
+
+        my $vorname = '';
         my $cat = {};
+
         $cat->{'id'}          = $cat_rs->id();
         $cat->{'name'}        = $cat_rs->kategorie_name();
         $cat->{'count_books'} = $cat_rs->get_column('count_books');
+
+        $cat->{'id_created_by'}   = $cat_rs->get_column('created_by');
+        $cat->{'created_at'}      = $cat_rs->get_column('created_at');
+        $cat->{'name_created_by'} = $cat_rs->get_column('created_by_nachname');
+        $vorname                  = $cat_rs->get_column('created_by_vorname');
+        $cat->{'name_created_by'} = $vorname . ' ' . $cat->{'name_created_by'} if $vorname;
+
+        $cat->{'id_changed_by'}   = $cat_rs->get_column('changed_by');
+        $cat->{'changed_at'}      = $cat_rs->get_column('changed_at');
+        $cat->{'name_changed_by'} = $cat_rs->get_column('changed_by_nachname');
+        $vorname                  = $cat_rs->get_column('changed_by_vorname');
+        $cat->{'name_changed_by'} = $vorname . ' ' . $cat->{'name_changed_by'} if $vorname;
+
         push @$list, $cat;
+
     }
 
     return ( wantarray ? ( $list, 0 ) : $list ) unless scalar @$list;
@@ -284,33 +327,84 @@ sub b_save_category {
 
     $c->log->debug( $K . "aufgerufen." ) if $c->stash->{'debug_level'} > 2;
 
+    my $schema =  $c->model('Schema')->{'schema'};
     my $storage = $c->model('Schema')->storage;
 
-    my $save_func = sub {
-        my ( $storage, $dbh, $category_id, $cat_name ) = @_;
-        my $sql = <<ENDE;
-INSERT INTO `kategorien` (
-    `id`, `kategorie_name` )
-  VALUES (
-    ?, ? )
-  ON DUPLICATE KEY UPDATE
-    `id` = LAST_INSERT_ID(`id`), `kategorie_name` = ?
-ENDE
-
-        if ( $storage->debug() ) {
-            my $text = $sql;
-            $text =~ s/\s+$//;
-            $text .= ": " . join( ", ", map { $dbh->quote($_) } ( $category_id, $cat_name, $cat_name ) ) . "\n";
-            warn $text;
+       my $row = {};
+       my $search_params = {};
+
+    my $tmp = $cat->{'name'};
+    $tmp = '' unless defined $tmp;
+    $tmp =~ s/^\s+//;
+    $tmp =~ s/\s+$//;
+       $row->{'kategorie_name'} = $tmp;
+
+    if ( $cat->{'id'} ) {
+        $search_params->{'kategorie_name'} = $row->{'kategorie_name'};
+        $search_params->{'id'} = { '!=' => $cat->{'id'} };   
+        $c->log->debug( get_output_string( $K, "Suche nach doppelter Kategorie mit: ", $search_params ) );
+        if ( $c->model('Schema::Kategorien')->count( $search_params ) ) {
+            die sprintf( "Die Kategorie '%s' existiert bereits.\n", $row->{'kategorie_name'} );
         }
+        $row->{'id'} = $cat->{'id'};
+    }
+
+    my $user_id = $c->stash->{'current_user_id'} || 1;
+    $row->{'changed_at'} = \'NOW()';
+    $row->{'changed_by'} = $user_id;
+
+    $c->log->debug( get_output_string( $K, "Zu speichernde Kategorie: ", $row ) ) if $c->stash->{'debug_level'} >= 3;
+    my $id = undef;
+
+    # Der Transaktionscode ...
+    my $txn_code = sub {
+
+        my $key_hash = {};
+        $key_hash->{'key'} = $row->{'id'} ? 'primary' : 'kategorie_name';
+
+        my $rs = $c->model('Schema::Kategorien')->update_or_new( $row, $key_hash );
 
-        my $sth = $dbh->prepare($sql);
-        $sth->execute( $category_id, $cat_name, $cat_name );
+        if ( $rs->in_storage() ) {
+
+            $c->log->debug( $K . "Die Kategorie gibt es schon ..." );
+
+            $rs->set_column( 'id' => \'LAST_INSERT_ID(`id`)' );
+            my $spalten = {};
+            %$spalten = $rs->get_columns();
+            $c->log->debug( get_output_string( $K, "Die Spalten der Kategorie: ", $spalten ) );
+            undef $spalten;
+
+            $rs->update();
+
+        }
+        else {
+            $c->log->debug( $K . "Neue Kategorie ..." );
+            $rs->set_column( 'created_by' => $user_id );
+            $rs->set_column( 'created_at' => \'NOW()' );
+            my $spalten = {};
+            %$spalten = $rs->get_columns();
+            $c->log->debug( get_output_string( $K, "Die Spalten der Kategorie: ", $spalten ) );
+            undef $spalten;
+
+            $rs->insert();
+        }
+
+        $id = $storage->last_insert_id();
+
+    };
+
+    # Und ab ...
+    eval {
+        $schema->txn_do($txn_code);
     };
 
-    $storage->dbh_do( $save_func, $cat->{'id'}, $cat->{'name'} );
+    if ($@) {                             # Transaction failed
+        my $msg = $@ =~ /Rollback failed/i ? "Rollback nicht erfolgreich!" : $@;
+        die $msg . "\n";
+        return undef;
+    }
 
-    return $storage->last_insert_id();
+    return $id;
 
 }
 
index bb4366aa9b5fcb60d0ec90b0f8d6ca3d790ef924..4ba10927e5e326489d266b29e715f7f5a11aa70a 100644 (file)
@@ -53,12 +53,18 @@ Rueckgabe: Eine Array-Ref von Hash-Refs mit allen Aufbewahrungsorten, die den ue
 
   $res = [
     {
-        'id'          => 1,
-        'name'        => 'Ausgeliehen',
-        'descr'       => '',
-        'statisch'    => 'y',
-               'count_books' => 16,
-               'books'         => [
+        'id'              => 1,
+        'name'            => 'Ausgeliehen',
+        'descr'           => '',
+        'statisch'        => 'y',
+               'count_books'     => 16,
+        'created_at'      => '2010-02-22 12:13:14',
+        'id_created_by'   => 1,
+        'name_created_by' => 'Frank Brehm',
+        'changed_at'      => '2010-02-29 13:14:15',
+        'id_changed_by'   => 2,
+        'name_changed_by' => 'Doris Hennig',
+               'books'           => [
                  {
                        'id'                 => 8,
                        'title'              => 'Die Elfen',
@@ -136,22 +142,42 @@ sub b_get_ortsliste {
     $c->log->debug(  get_output_string( $K, "Anzahl gefundene Orte: ", $anzahl_orte ) ) if $c->stash->{'debug_level'} >= 2;
 
     my $other_params = {};
-    $other_params->{'order_by'} = [ 'name' ];
+       $other_params->{'join'} = [
+        'buecher',
+        'created_by',
+        'changed_by',
+    ];
+    $other_params->{'order_by'} = [ 'me.name' ];
     $other_params->{'select'} = [
         'me.id',
         'me.name',
         'me.descr',
         'me.statisch',
-               { 'count' => 'buecher.id' }
+        'me.created_by',
+        'created_by.vorname',
+        'created_by.nachname',
+        'me.created_at',
+        'me.changed_by',
+        'changed_by.vorname',
+        'changed_by.nachname',
+        'me.changed_at',
+               { 'count' => 'buecher.id' },
     ];
     $other_params->{'as'} = [
         'id',
         'name',
         'descr',
         'statisch',
+        'created_by',
+        'created_by_vorname',
+        'created_by_nachname',
+        'created_at',
+        'changed_by',
+        'changed_by_vorname',
+        'changed_by_nachname',
+        'changed_at',
                'count_books',
     ];
-       $other_params->{'join'} = [ 'buecher'];
        $other_params->{'group_by'} = [ 'me.id' ];
  
        if ( $page ) {
@@ -160,19 +186,35 @@ sub b_get_ortsliste {
        }
  
     for my $ort_rs ( $c->model('Schema::Orte')->search( $search_params, $other_params )->all() ) {
+
+        my $vorname = '';
         my $ort = {};
+
         $ort->{'id'}          = $ort_rs->id();
         $ort->{'name'}        = $ort_rs->name();
         $ort->{'descr'}       = $ort_rs->descr();
         $ort->{'statisch'}    = $ort_rs->statisch();
         $ort->{'count_books'} = $ort_rs->get_column('count_books');
+
+        $ort->{'id_created_by'}   = $ort_rs->get_column('created_by');
+        $ort->{'created_at'}      = $ort_rs->get_column('created_at');
+        $ort->{'name_created_by'} = $ort_rs->get_column('created_by_nachname');
+        $vorname                  = $ort_rs->get_column('created_by_vorname');
+        $ort->{'name_created_by'} = $vorname . ' ' . $ort->{'name_created_by'} if $vorname;
+
+        $ort->{'id_changed_by'}   = $ort_rs->get_column('changed_by');
+        $ort->{'changed_at'}      = $ort_rs->get_column('changed_at');
+        $ort->{'name_changed_by'} = $ort_rs->get_column('changed_by_nachname');
+        $vorname                  = $ort_rs->get_column('changed_by_vorname');
+        $ort->{'name_changed_by'} = $vorname . ' ' . $ort->{'name_changed_by'} if $vorname;
+
         push @$list, $ort;
+
     }
 
     return ( wantarray ? ( $list, 0 ) : $list ) unless scalar @$list;
     return ( wantarray ? ( $list, $anzahl_orte ) : $list ) unless $params->{'get_books'};
 
-
        for my $ort ( @$list ) {
 
                $ort->{'books'} = [];
@@ -310,8 +352,95 @@ sub b_save_ort {
 
     $c->log->debug( $K . "aufgerufen." ) if $c->stash->{'debug_level'} > 2;
 
+    my $schema =  $c->model('Schema')->{'schema'};
     my $storage = $c->model('Schema')->storage;
 
+       my $row = {};
+       my $search_params = {};
+
+    my $tmp = $ort->{'name'};
+    $tmp = '' unless defined $tmp;
+    $tmp =~ s/^\s+//;
+    $tmp =~ s/\s+$//;
+       $row->{'name'} = $tmp;
+
+    if ( $ort->{'id'} ) {
+        $search_params->{'name'} = $row->{'name'};
+        $search_params->{'id'} = { '!=' => $ort->{'id'} };   
+        $c->log->debug( get_output_string( $K, "Suche nach doppeltem Aufbewahrungsort mit: ", $search_params ) );
+        if ( $c->model('Schema::Orte')->count( $search_params ) ) {
+            die sprintf( "Der Aufbewahrungsort '%s' existiert bereits.\n", $row->{'name'} );
+        }
+        $row->{'id'} = $ort->{'id'};
+    }
+
+    $tmp = $ort->{'descr'};
+    $tmp = '' unless defined $tmp;
+    $tmp =~ s/^\s+//;
+    $tmp =~ s/\s+$//;
+       $row->{'descr'} = defined $tmp ? $tmp : undef;
+
+    $row->{'statisch'} = to_bool( $ort->{'statisch'} ) ? 'y' : 'n';
+
+    my $user_id = $c->stash->{'current_user_id'} || 1;
+    $row->{'changed_at'} = \'NOW()';
+    $row->{'changed_by'} = $user_id;
+
+    $c->log->debug( get_output_string( $K, "Zu speichernder Aufbewahrungsort: ", $row ) ) if $c->stash->{'debug_level'} >= 3;
+    my $id = undef;
+
+    # Der Transaktionscode ...
+    my $txn_code = sub {
+
+        my $key_hash = {};
+        $key_hash->{'key'} = $row->{'id'} ? 'primary' : 'name';
+
+        my $rs = $c->model('Schema::Orte')->update_or_new( $row, $key_hash );
+
+        if ( $rs->in_storage() ) {
+
+            $c->log->debug( $K . "Den Aufbewahrungsort gibt es schon ..." );
+
+            $rs->set_column( 'id' => \'LAST_INSERT_ID(`id`)' );
+            my $spalten = {};
+            %$spalten = $rs->get_columns();
+            $c->log->debug( get_output_string( $K, "Die Spalten des Aufbewahrungsorts: ", $spalten ) );
+            undef $spalten;
+
+            $rs->update();
+
+        }
+        else {
+            $c->log->debug( $K . "Neuer Aufbewahrungsort ..." );
+            $rs->set_column( 'created_by' => $user_id );
+            $rs->set_column( 'created_at' => \'NOW()' );
+            my $spalten = {};
+            %$spalten = $rs->get_columns();
+            $c->log->debug( get_output_string( $K, "Die Spalten des Aufbewahrungsorts: ", $spalten ) );
+            undef $spalten;
+
+            $rs->insert();
+        }
+
+        $id = $storage->last_insert_id();
+
+    };
+
+    # Und ab ...
+    eval {
+        $schema->txn_do($txn_code);
+    };
+
+    if ($@) {                             # Transaction failed
+        my $msg = $@ =~ /Rollback failed/i ? "Rollback nicht erfolgreich!" : $@;
+        die $msg . "\n";
+        return undef;
+    }
+
+    return $id;
+
+=pod
+
     my $save_func = sub {
         my ( $storage, $dbh, $orts_id, $orts_name, $orts_desc, $statisch ) = @_;
         my $sql = <<ENDE;
@@ -340,6 +469,8 @@ ENDE
 
     return $storage->last_insert_id();
 
+=cut
+
 }
 
 #-----------------------------------------------------------------------------------