]> Frank Brehm's Git Trees - books.git/commitdiff
Buchliste neu generiert
authorFrank Brehm <frank@brehm-online.com>
Mon, 22 Dec 2008 14:47:20 +0000 (14:47 +0000)
committerFrank Brehm <frank@brehm-online.com>
Mon, 22 Dec 2008 14:47:20 +0000 (14:47 +0000)
db/buchautoren.sql
lib/FrBr/Books/Controller/SessionOpts.pm
lib/FrBr/Books/Db/Buch2kategorie.pm
lib/FrBr/Books/Db/Buch2serie.pm
lib/FrBr/Books/Db/Buecher.pm
lib/FrBr/Books/Db/Kategorien.pm
lib/FrBr/Books/Db/Serien.pm
lib/FrBr/Books/Util/Book.pm
lib/FrBr/Books/Util/User.pm

index 8b4c0b75720c9ab069b87f98918f0feb99000f28..1308b87077b9621172610d5847af407223fecba6 100644 (file)
@@ -74,4 +74,53 @@ SELECT ab.`id`            AS `autor2buch_id`,
   RIGHT JOIN `buecher` b ON ab.`buch_id`  = b.`id`
   ORDER BY b.`title`, ab.`buch_id`, ab.`ord_num`;
 
+SELECT `buch_id`, `title`, `title_original`, `untertitel`, `verlag`, `isbn`, `buch_nr`,
+       `ausgabejahr`, `druckjahr`, `seiten`, `preis`, `waehrungs_kuerzel`, `waehrung`, `ort`, `bindungsart`,
+       GROUP_CONCAT( DISTINCT `autor_name` ORDER BY `autor_ord_num` SEPARATOR ', ' ) AS `autoren`,
+       GROUP_CONCAT( DISTINCT `kategorie`  ORDER BY `kategorie`     SEPARATOR ', ' ) AS `kategorien`,
+       GROUP_CONCAT( DISTINCT `serie`      ORDER BY `serie`         SEPARATOR ', ' ) AS `serien`
+  FROM ( SELECT b.`id`                AS `buch_id`,
+                b.`title`             AS `title`,
+                b.`title_original`    AS `title_original`,
+                b.`untertitel`        AS `untertitel`,
+                b.`isbn`              AS `isbn`,
+                b.`buch_nr`           AS `buch_nr`,
+                b.`ausgabejahr`       AS `ausgabejahr`,
+                b.`druckjahr`         AS `druckjahr`,
+                b.`seiten`            AS `seiten`,
+                b.`preis`             AS `preis`,
+                w.`waehrungs_kuerzel` AS `waehrungs_kuerzel`,
+                w.`waehrungs_name`    AS `waehrung`,
+                CONCAT( '`', a.`nachname`,
+                        IF( ISNULL(a.`vorname`),     '', ' ' ), IFNULL( a.`vorname`,     '' ),
+                        IF( ISNULL(a.`mittelname`),  '', ' ' ), IFNULL( a.`mittelname`,  '' ),
+                        IF( ISNULL(a.`name_suffix`), '', ' ' ), IFNULL( a.`name_suffix`, '' ),
+                        '`'
+                )                     AS `autor_name`,
+                ab.`ord_num`          AS `autor_ord_num`,
+                a.`titel`             AS `autor_titel`,
+                a.`vorname`           AS `autor_vorname`,
+                a.`mittelname`        AS `autor_mittelname`,
+                a.`nachname`          AS `autor_nachname`,
+                a.`name_suffix`       AS `autor_name_suffix`,
+                v.`name_short`        AS `verlag`,
+                o.`name`              AS `ort`,
+                CONCAT( '`', k.`kategorie_name`, '`' ) AS `kategorie`,
+                CONCAT( '`', s.`serien_name`, '`' )    AS `serie`,
+                bi.`art_name`         AS `bindungsart`
+           FROM autor2buch AS ab 
+           LEFT  JOIN `autoren`        a  ON ab.`autor_id` = a.`id` 
+           RIGHT JOIN `buecher`        b  ON ab.`buch_id`  = b.`id`
+           LEFT  JOIN `bindungsarten`  bi ON b.`bindungsart_id` = bi.`id` 
+           LEFT  JOIN `verlage`        v  ON b.`verlags_id` = v.`id` 
+           LEFT  JOIN `orte`           o  ON b.`orts_id` = o.`id` 
+           LEFT  JOIN `waehrungen`     w  ON b.`waehrungs_id` = w.`id` 
+           LEFT  JOIN `buch2kategorie` bk ON b.`id` = bk.`buch_id`
+           LEFT  JOIN `kategorien`     k  ON k.`id` = bk.`kategorie_id`
+           LEFT  JOIN `buch2serie`     bs ON b.`id` = bs.`buch_id`
+           LEFT  JOIN `serien`         s  ON s.`id` = bs.`serien_id`
+  ) AS `a`
+  GROUP BY `buch_id`
+  ORDER BY `autoren`, `title`;
+
 -- vim: noai : ts=4 fenc=utf-8 filetype=sql expandtab :
index 750612503e494ceeabf2c9c66824a065c26c9006..6f5c355862f9c089947534e165cba1612205fc06 100644 (file)
@@ -70,6 +70,7 @@ sub index : Private {
         $length = 500 if $length > 500;
         $c->session->{'list_length'} = $length;
         $c->stash->{'list_length'} = $length;
+        delete $c->session->{'book_list_page'} if exists $c->session->{'book_list_page'};
     }
 
     save_user_prefs($c) if $c->user_exists();
index 624cb8a55675a6f8d8fc5e868a1f91ea79ee6a30..89ac0a3161b2f77fc8a0712db21b8d9606518eca 100644 (file)
@@ -21,11 +21,6 @@ __PACKAGE__->add_unique_constraint("buch_id", ["buch_id", "kategorie_id"]);
 __PACKAGE__->might_have( 'buch'      => 'FrBr::Books::Db::Buecher',    { 'foreign.id' => 'self.buch_id' } );
 __PACKAGE__->might_have( 'kategorie' => 'FrBr::Books::Db::Kategorien', { 'foreign.id' => 'self.kategorie_id' } );
 
-# Created by DBIx::Class::Schema::Loader v0.04004 @ 2008-03-17 17:53:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:rYT7qQgF4WvVJQgCDUurIw
-
-
-# You can replace this text with custom content, and it will be preserved on regeneration
 1;
 
 __END__
index 12b51796799adb0fb9493b672d486dd06c3fcd99..2e28b261db2da65e96c7ee28c5ab2b67e5e0bdaa 100644 (file)
@@ -23,11 +23,6 @@ __PACKAGE__->add_unique_constraint("buch_id", ["buch_id", "serien_id"]);
 __PACKAGE__->might_have( 'buch'  => 'FrBr::Books::Db::Buecher', { 'foreign.id' => 'self.buch_id' } );
 __PACKAGE__->might_have( 'serie' => 'FrBr::Books::Db::Serien',  { 'foreign.id' => 'self.serien_id' } );
 
-# Created by DBIx::Class::Schema::Loader v0.04004 @ 2008-03-17 17:53:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0ZVowzPrhFa/hKjsW/G9RQ
-
-
-# You can replace this text with custom content, and it will be preserved on regeneration
 1;
 
 __END__
index 46e4c7d6d87cb13af4b0f2c5dceef6671e526636..3a97efce1fd90fed6c9419f716c76f86348c2f1e 100644 (file)
@@ -37,6 +37,88 @@ __PACKAGE__->might_have( 'bindungsart' => 'FrBr::Books::Db::Bindungsarten', { 'f
 __PACKAGE__->has_many( 'autor_buch' => 'FrBr::Books::Db::Autor2Buch', { 'foreign.buch_id' => 'self.id' } );
 __PACKAGE__->many_to_many( 'autoren' => 'autor_buch', 'autor' );
 
+__PACKAGE__->has_many( 'buch_kategorie' => 'FrBr::Books::Db::Buch2kategorie', { 'foreign.buch_id' => 'self.id' } );
+__PACKAGE__->many_to_many( 'kategorien' => 'buch_kategorie', 'kategorie' );
+
+__PACKAGE__->has_many( 'buch_serie' => 'FrBr::Books::Db::Buch2serie', { 'foreign.buch_id' => 'self.id' } );
+__PACKAGE__->many_to_many( 'serien' => 'buch_serie', 'serie' );
+
+# Make a new ResultSource based on the buecher class
+my $source = __PACKAGE__->result_source_instance();
+my $list_source = $source->new( $source );
+$list_source->source_name( 'BuecherListe' );
+
+# Hand in your query as a scalar reference
+# It will be added as a sub-select after FROM,
+# so pay attention to the surrounding brackets!
+$list_source->name( \<<SQL );
+( SELECT `buch_id`,
+         `title`,
+         `title_original`,
+         `untertitel`,
+         `verlag`,
+         `isbn`,
+         `buch_nr`,
+         `ausgabejahr`,
+         `druckjahr`,
+         `seiten`,
+         `preis`,
+         `waehrungs_kuerzel`,
+         `waehrung`,
+         `ort`,
+         `bindungsart`,
+         GROUP_CONCAT( DISTINCT `autor_name` ORDER BY `autor_ord_num` SEPARATOR ', ' ) AS `autoren`,
+         GROUP_CONCAT( DISTINCT `kategorie`  ORDER BY `kategorie`     SEPARATOR ', ' ) AS `kategorien`,
+         GROUP_CONCAT( DISTINCT `serie`      ORDER BY `serie`         SEPARATOR ', ' ) AS `serien`
+    FROM ( SELECT b.`id`                AS `buch_id`,
+                  b.`title`             AS `title`,
+                  b.`title_original`    AS `title_original`,
+                  b.`untertitel`        AS `untertitel`,
+                  b.`isbn`              AS `isbn`,
+                  b.`buch_nr`           AS `buch_nr`,
+                  b.`ausgabejahr`       AS `ausgabejahr`,
+                  b.`druckjahr`         AS `druckjahr`,
+                  b.`seiten`            AS `seiten`,
+                  b.`preis`             AS `preis`,
+                  w.`waehrungs_kuerzel` AS `waehrungs_kuerzel`,
+                  w.`waehrungs_name`    AS `waehrung`,
+                  CONCAT( '`', a.`nachname`,
+                          IF( ISNULL(a.`vorname`),     '', ' ' ), IFNULL( a.`vorname`,     '' ),
+                          IF( ISNULL(a.`mittelname`),  '', ' ' ), IFNULL( a.`mittelname`,  '' ),
+                          IF( ISNULL(a.`name_suffix`), '', ' ' ), IFNULL( a.`name_suffix`, '' ),
+                          '`'
+                  )                     AS `autor_name`,
+                  ab.`ord_num`          AS `autor_ord_num`,
+                  a.`titel`             AS `autor_titel`,
+                  a.`vorname`           AS `autor_vorname`,
+                  a.`mittelname`        AS `autor_mittelname`,
+                  a.`nachname`          AS `autor_nachname`,
+                  a.`name_suffix`       AS `autor_name_suffix`,
+                  v.`name_short`        AS `verlag`,
+                  o.`name`              AS `ort`,
+                  CONCAT( '`', k.`kategorie_name`, '`' ) AS `kategorie`,
+                  CONCAT( '`', s.`serien_name`, '`' )    AS `serie`,
+                  bi.`art_name`         AS `bindungsart`
+             FROM autor2buch AS ab
+             LEFT  JOIN `autoren`        a  ON ab.`autor_id` = a.`id`
+             RIGHT JOIN `buecher`        b  ON ab.`buch_id`  = b.`id`
+             LEFT  JOIN `bindungsarten`  bi ON b.`bindungsart_id` = bi.`id`
+             LEFT  JOIN `verlage`        v  ON b.`verlags_id` = v.`id`
+             LEFT  JOIN `orte`           o  ON b.`orts_id` = o.`id`
+             LEFT  JOIN `waehrungen`     w  ON b.`waehrungs_id` = w.`id`
+             LEFT  JOIN `buch2kategorie` bk ON b.`id` = bk.`buch_id`
+             LEFT  JOIN `kategorien`     k  ON k.`id` = bk.`kategorie_id`
+             LEFT  JOIN `buch2serie`     bs ON b.`id` = bs.`buch_id`
+             LEFT  JOIN `serien`         s  ON s.`id` = bs.`serien_id`
+    ) AS `a`
+  GROUP BY `buch_id`
+)
+SQL
+
+# Finally, register your new ResultSource with your Schema
+FrBr::Books::Db->register_source( 'BuecherListe' => $list_source );
+
+
 1;
 
 __END__
index e6878bae73bbf9bd34aaf63d9fb159ff31efa701..0d83442f77cdc322192b82dff6b71adac688a088 100644 (file)
@@ -18,11 +18,9 @@ __PACKAGE__->set_primary_key("id");
 __PACKAGE__->add_unique_constraint("kategorie_name", ["kategorie_name"]);
 
 
-# Created by DBIx::Class::Schema::Loader v0.04004 @ 2008-03-17 17:53:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZEMEahjPuJByMUE/OvebIg
+__PACKAGE__->has_many( 'buch_kategorie' => 'FrBr::Books::Db::Buch2kategorie', { 'foreign.kategorie_id' => 'self.id' } );
+__PACKAGE__->many_to_many( 'buecher' => 'buch_kategorie', 'buch' );
 
-
-# You can replace this text with custom content, and it will be preserved on regeneration
 1;
 
 __END__
index 3ffa546213d2630fd665112f3bd310aee97ab775..b67b930444f1f9891a8253522d8caf3f1eab6ef9 100644 (file)
@@ -22,6 +22,9 @@ __PACKAGE__->add_unique_constraint("serien_name", ["serien_name"]);
 # Created by DBIx::Class::Schema::Loader v0.04004 @ 2008-03-17 17:53:52
 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/IzPoWKb7jK+P2HCTO+bCQ
 
+__PACKAGE__->has_many( 'buch_serie' => 'FrBr::Books::Db::Buch2serie', { 'foreign.serien_id' => 'self.id' } );
+__PACKAGE__->many_to_many( 'buecher' => 'buch_serie', 'buch' );
+
 
 # You can replace this text with custom content, and it will be preserved on regeneration
 1;
index cc979320c5e46308ada20f41036441ea439c43ca..bd6faab5de6a1ea8db1b394db6bbe2938de9f48c 100644 (file)
@@ -130,29 +130,47 @@ sub get_booklist {
     $c->log->debug(  get_output_string( $K, "Uebergebene Parameter: ", $params ) ) if $c->stash->{'debug_level'} >= 2;
 
     my $list = [];
-    my $buchmap = {},
     my $anzahl_buecher = 0;
 
+    my $storage = $c->stash->{'storage'};
+
     # Suchparameter zusammensammeln
     my $b_search_params = {};
+    my $order = undef;
 
     if ( $params->{'buch_id'} ) {
-        $b_search_params->{'me.id'} = $params->{'buch_id'};
+        $b_search_params->{'me.buch_id'} = $params->{'buch_id'};
+    }
+    else {
+        $order = collect_sort_criteria($c)
     }
 
     # Suchparameter auf undef setzen, falls es keine gibt.
     $b_search_params = undef unless scalar keys %$b_search_params;
 
     my $other_params = {};
-    $other_params->{'order_by'} = [ 'title' ];
-    $other_params->{'join'}     = [ 'waehrung', 'verlag', 'ort', 'bindungsart' ];
+    $other_params->{'order_by'} = $order;
+    $other_params->{'select'} = [ 'me.buch_id' ];
+    $other_params->{'as'}     = [ 'buch_id' ];
+    $other_params->{'rows'} = $c->stash->{'list_length'} || 20;
+    $other_params->{'page'} = $params->{'page'} || $c->stash->{'page'} || 1;
+
+    my $book_ids = [];
 
-    $anzahl_buecher = $c->model('Schema::Buecher')->count( $b_search_params, $other_params );
+    for my $book ( $c->model('Schema::BuecherListe')->search( $b_search_params, $other_params )->all() ) {
+        push @$book_ids, $book->get_column('buch_id');
+    }
+
+    return ( wantarray ? ( $book_ids, 0 ) : $book_ids ) unless scalar( @$book_ids );
+
+    my $in = "IN ( " . join( ", ", @$book_ids ) . " )";
+    $anzahl_buecher = scalar( @$book_ids );
     $c->log->debug(  get_output_string( $K, "Anzahl gefundene Buecher: ", $anzahl_buecher ) ) if $c->stash->{'debug_level'} >= 2;
 
-    $other_params->{'rows'} = $c->stash->{'list_length'} || 10;
-    $other_params->{'page'} = $params->{'page'} || $c->stash->{'page'} || 1;
+    $b_search_params = { 'me.id' => \$in };
 
+    $other_params = {};
+    $other_params->{'join'}     = [ 'waehrung', 'verlag', 'ort', 'bindungsart' ];
     $other_params->{'select'} = [
         'me.id',
         'me.title',
@@ -204,7 +222,7 @@ sub get_booklist {
         'ort_ist_statisch',
     ];
  
-    my $i = 0;
+    my $buchmap = {};
     for my $book ( $c->model('Schema::Buecher')->search( $b_search_params, $other_params )->all() ) {
         my $buch = {};
         my $id                        = $book->id();
@@ -237,20 +255,12 @@ sub get_booklist {
         $buch->{'kategorie_ids'}      = [];
         $buch->{'serien'}             = [];
         $buch->{'serien_ids'}         = [];
-        push @$list, $buch;
-        $buchmap->{$id} = $i;
-        $i++;
+        $buchmap->{$id} = $buch;
     }
 
-    return ( wantarray ? ( $list, 0 ) : $list ) unless scalar( @$list );
-
     # Autoren zusammensammeln
     my $a_search_params = {};
-    if ( $b_search_params ) {
-        my $in = "IN ( " . join( ", ", keys %$buchmap ) . " )";
-        $a_search_params->{'buch_id'} = \$in;
-    }
-    $a_search_params = undef unless keys %$a_search_params;
+    $a_search_params->{'buch_id'} = \$in;
 
     $other_params = {};
     $other_params->{'order_by'} = [ 'ord_num' ];
@@ -283,12 +293,8 @@ sub get_booklist {
         push @N, $ref->get_column('nachname');
         push @N, $ref->get_column('name_suffix') if $ref->get_column('name_suffix');
         my $autor = join( " ", @N );
-        my $j = $buchmap->{$bid};
-        next unless defined $j;
-        my $buch = $list->[$j];
-        next unless $buch;
-        push @{$buch->{'autoren'}},   $autor;
-        push @{$buch->{'autor_ids'}}, $aid;
+        push @{ $buchmap->{$bid}{'autoren'} },   $autor;
+        push @{ $buchmap->{$bid}{'autor_ids'} }, $aid;
     }
 
     # Kategorien zusammensammeln
@@ -308,12 +314,8 @@ sub get_booklist {
         my $bid  = $ref->get_column('buch_id');
         my $kid  = $ref->get_column('kategorie_id');
         my $name = $ref->get_column('kategorie_name');
-        my $j = $buchmap->{$bid};
-        next unless defined $j;
-        my $buch = $list->[$j];
-        next unless $buch;
-        push @{$buch->{'kategorien'}}, $name;
-        push @{$buch->{'kategorie_ids'}}, $kid;
+        push @{ $buchmap->{$bid}{'kategorien'} },    $name;
+        push @{ $buchmap->{$bid}{'kategorie_ids'} }, $kid;
     }
 
     # Buchserien zusammensammeln
@@ -333,15 +335,115 @@ sub get_booklist {
         my $bid  = $ref->get_column('buch_id');
         my $sid  = $ref->get_column('serien_id');
         my $name = $ref->get_column('serien_name');
-        my $j = $buchmap->{$bid};
-        next unless defined $j;
-        my $buch = $list->[$j];
-        next unless $buch;
-        push @{$buch->{'serien'}}, $name;
-        push @{$buch->{'serien_ids'}}, $sid;
+        push @{ $buchmap->{$bid}{'serien'} },     $name;
+        push @{ $buchmap->{$bid}{'serien_ids'} }, $sid;
+    }
+
+    # HashRef %$buchmap sortiert in ArrayRef $list ummappen
+
+    for my $id ( @$book_ids ) {
+        push @$list, $buchmap->{$id} if $buchmap->{$id};
     }
 
     return ( wantarray ? ( $list, $anzahl_buecher ) : $list );
+
+}
+
+#-----------------------------------------------------------------------------------
+
+=head2 collect_sort_criteria( $c )
+
+Sammelt aus der Sitzung die Sortierkriterien der Buchliste zusammen und gibt diese verwendbar
+für get_booklist() zurück.
+
+Die Sortierkriterien müssen in der Sitzung unter dem Schlüssel 'book_order_criteria'
+als Array-Ref abgelegt sein. Die Elemente der Array-Ref sind entweder Scalare mit den
+Spaltennamen oder Hashrefs der Form [ { 'autoren' => 'desc' }, { 'kategorien' => 'asc' }, ...].
+
+Folgende Spaltennamen dürfen verwendet werden:
+
+  - autoren
+  - title
+  - title_original
+  - bindungsart
+  - verlag
+  - ort
+  - preis
+  - waehrung
+  - ausgabejahr
+  - druckjahr
+  - seiten
+  - kategorien
+  - serien
+
+Falls in $c->session->{'book_order_criteria'} nichts liegt, wird folgendes
+als Voreinstellung verwendet:
+
+    $criteria = [
+        'title',
+    ];
+
+=cut
+
+sub collect_sort_criteria {
+
+    my $c = shift;
+    my $K = ( caller(0) )[3] . "(): ";
+
+    my $order = [];
+
+    my $valid_column = {
+        'autoren'        => 1,
+        'title'          => 1,
+        'title_original' => 1,
+        'bindungsart'    => 1,
+        'verlag'         => 1,
+        'ort'            => 1,
+        'preis'          => 1,
+        'waehrung'       => 1,
+        'ausgabejahr'    => 1,
+        'druckjahr'      => 1,
+        'seiten'         => 1,
+        'kategorien'     => 1,
+        'serien'         => 1,
+    };
+
+    my $used_column = {};
+
+    my $criteria = $c->session->{'book_order_criteria'};
+    unless ( $criteria and ref($criteria) and ref($criteria) eq 'ARRAY' and scalar(@$criteria) ) {
+        $criteria = [
+            'autoren',
+            'title',
+        ];
+    }
+
+    my $col;
+    for my $crit ( @$criteria ) {
+        if ( ref($crit) and ref($crit) eq 'HASH' ) {
+            for my $key ( keys %$crit ) {
+                $col = lc($key);
+                if ( $valid_column->{$col} and not exists $used_column->{$col} ) {
+                    my $dir = $crit->{$key};
+                    $dir = ( $dir =~ /desc/i ) ? 'DESC' : 'ASC';
+                    $used_column->{$col} = 1;
+                    push @$order, ( $dir eq 'ASC' ? $col : \"`$col` DESC" );
+                }
+            }
+        }
+        else {
+            $col = lc($crit);
+            if ( $valid_column->{$col} and not exists $used_column->{$col} ) {
+                push @$order, $col;
+                $used_column->{$col} = 1;
+            }
+        }
+    }
+
+    $order = [ 'title' ] unless scalar( @$order );
+
+    return $order;
+
 }
 
 #-----------------------------------------------------------------------------------
@@ -428,7 +530,6 @@ sub save_book {
     $c->log->debug( $K . "aufgerufen." ) if $c->stash->{'debug_level'} > 2;
 
     my $storage = $c->stash->{'storage'};
-    #$c->log->debug( get_output_string( $K . "Storage: ", $storage ) ) if $c->stash->{'debug_level'} > 4;
 
     my $save_func = sub {
 
index 82ab10b913840b7a5b1078c8d3e4dbc736f28310..7238ba296f9a541f5728ef10765dd0d7300168d7 100644 (file)
@@ -108,6 +108,7 @@ sub restore_user_prefs {
     return unless $prefs;
 
     if ( $prefs->{'list_length'} ) {
+        delete $c->session->{'book_list_page'} if exists $c->session->{'book_list_page'};
         $c->stash->{'list_length'} = $prefs->{'list_length'};
         $c->session->{'list_length'} = $prefs->{'list_length'};
     }