NAME Mojo::DB::Results::Role::MoreMethods - More methods for DB Results, like Mojo::Pg::Results and Mojo::mysql::Results STATUS SYNOPSIS use Mojo::DB::Results::Role::MoreMethods results_class => 'Mojo::Pg::Results'; my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); my $name = $results->get; my $name = $results->get(0); my $name = $results->get(-3); my ($name) = $results->get; my ($name, $age, $favorite_food) = $results->get; my ($name, $age, $favorite_food) = $results->get(0..2); my ($name, $favorite_food) = $results->get(0, 2); my ($name, $favorite_food) = $results->get(-3, -1); my $name = $results->get_by_name('name'); my ($name) = $results->get_by_name('name'); my ($name, $favorite_food) = $results->get_by_name('name', 'favorite_food'); while (my ($name, $favorite_food) = $results->get('name', 'favorite_food')) { say qq{$name's favorite food is $favorite_food}; } # get the next row as a Mojo::Collection my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); my $full_name = $results->c->join(' '); # or get collection values by name my $first_and_last_name = $results->c_by_name('first_name', 'last_name')->join(' '); # get all rows as collections in a Mojo::Collection my $full_names = $results->collections->map(sub { $_->join(' ') }); # assert that exactly one row is returned where expected (not 0, not more than one) my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); my $name = $results->one; my ($name, $age, $favorite_food) = $results->one; my ($name, $favorite_food) = $results->one_by_name('name', 'favorite_food'); # Flatten results into one Mojo::Collection with names of all people who like Pizza my $results = $db->select(people => ['name'] => {favorite_food => 'Pizza'}); my $names = $results->flatten; say 'Pizza lovers:'; say for $names->each; # access results by a key my $results = $db->select(people => '*'); my $results_by_name = $results->hashify('name'); # $alice_row is a hash my $alice_row = $results_by_name->{Alice}; # access results by multiple keys with a multilevel hash my $results_by_full_name = $results->hashify(['first_name', 'last_name']); # $alice_smith_row is a hash my $alice_smith_row = $results_by_full_name->{Alice}{Smith}; # collect results by a key in a Mojo::Collection behind a hash my $results = $db->select(people => '*'); my $collections_by_name = $results->hashify_collect('name'); # $alice_collection is a Mojo::Collection of all rows with the name 'Alice' as hashes my $alice_collection = $collections_by_name->{Alice}; # collect results by multiple keys in a Mojo::Collection behind a multilevel hash my $collections_by_full_name = $results->hashify_collect(['first_name', 'last_name']); # $alice_smith_row is a hash my $alice_smith_collection = $collections_by_full_name->{Alice}{Smith}; # create a Mojo::Collection of Mojo::Collection's, where all results that share the same key # are grouped in the same inner Mojo::Collection my $results = $db->select(people => '*'); my $name_collections = $results->collect_by('name'); for my $name_collection ($name_collections->each) { say 'Ages for ' . $name_collection->[0]{name}; for my $row ($name_collection->each) { say "$row->{name} is $row->{age} years old"; } } DESCRIPTION Mojo::DB::Results::Role::MoreMethods is a role that that provides additional methods for results classes like Mojo::Pg::Results or Mojo::mysql::Results. Mojo::DB::Results::Role::MoreMethods requires a results class that has at least these methods: * array * arrays * columns * hash * hashes HOW TO APPLY ROLE results_class use Mojo::DB::Results::Role::MoreMethods results_class => 'Mojo::Pg::Results'; # or multiple use Mojo::DB::Results::Role::MoreMethods results_class => ['Mojo::Pg::Results', 'Mojo::mysql::Results']; "results_class" allows you to apply Mojo::DB::Results::Role::MoreMethods to one results class package by providing the results class name, or to multiple by providing an arrayref of results class names. -mysql use Mojo::DB::Results::Role::MoreMethods -mysql; # shortcut for use Mojo::DB::Results::Role::MoreMethods results_class => 'Mojo::mysql::Results'; -mysql is a shortcut for applying Mojo::DB::Results::Role::MoreMethods to Mojo::mysql::Results. This can be used with "-Pg". -Pg use Mojo::DB::Results::Role::MoreMethods -Pg; # shortcut for use Mojo::DB::Results::Role::MoreMethods results_class => 'Mojo::Pg::Results'; -Pg is a shortcut for applying Mojo::DB::Results::Role::MoreMethods to Mojo::Pg::Results. This can be used with "-mysql". with_roles # apply Mojo::Pg::Results::Role::MoreMethods my $pg = Mojo::Pg->new(...); my $results = $pg->db->select(people => ['name'] => {id => 123})->with_roles('+MoreMethods'); my $name = $results->get; # apply Mojo::mysql::Results::Role::MoreMethods my $mysql = Mojo::mysql->new(...); my $results = $mysql->db->select(people => ['name'] => {id => 123})->with_roles('+MoreMethods'); my $name = $results->get; # apply using any results class my $pg = Mojo::Pg->new(...); my $results = $pg->db->select(people => ['name'] => {id => 123})->with_roles('Mojo::DB::Results::Role::MoreMethods'); my $name = $results->get; You may use "with_roles" in Mojo::Base to apply Mojo::DB::Results::Role::MoreMethods to your results classes. These roles are also available to take advantage of with_role's shorthand + notation when using Mojo::Pg::Results or Mojo::mysql::Results: * Mojo::Pg::Results::Role::MoreMethods * Mojo::mysql::Results::Role::MoreMethods These two roles are essentially just aliases for Mojo::DB::Results::Role::MoreMethods. They are just empty roles with only this line: with 'Mojo::DB::Results::Role::MoreMethods'; Mojo::DB::Role::ResultsRoles # example from Mojo::DB::Role::ResultsRoles use Mojo::Pg; my $pg = Mojo::Pg->new(...)->with_roles('Mojo::DB::Role::ResultsRoles'); push @{$pg->results_roles}, 'Mojo::DB::Results::Role::MoreMethods'; my $results = $pg->db->query(...); # $results does Mojo::DB::Results::Role::MoreMethods Mojo::DB::Role::ResultsRoles allows roles to be applied to the results objects returned by database APIs like Mojo::Pg or Mojo::mysql. See its documentation for more information. You may take advantage of with_role's shorthand + notation when using Mojo::Pg or Mojo::mysql objects: # short hand with_roles syntax supported for Mojo::Pg and Mojo::mysql objects push @{$pg->results_roles}, '+MoreMethods'; METHODS get Be sure to call finish, such as "finish" in Mojo::Pg::Results or "finish" in Mojo::mysql::Results, if you are not fetching all of the possible rows. "get" will fetch the next row from sth. SCALAR CONTEXT my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # return the first column my $name = $results->get; # same as above but specifying index my $name = $results->get(0); # negative indexes may be used my $name = $results->get(-3); # any column may be gotten with an index my $age = $results->get(1); When "get" is called in scalar context with no index, it will fetch the next row from sth and return the first column requested in your query. If an index is specified, the value corresponding to the column at that index in the query will be used instead. A negative index may be used just like indexing into Perl arrays. WHILE LOOPS # THIS IS WRONG DO NOT DO THIS. while (my $name = $results->get) { # broken loop... } Because "get" in scalar context may return undef, an empty string or a 0 as values for a column, it cannot be reliably used in while loops (unless used in "LIST CONTEXT"). If you expect one row to be returned, considering using "one" instead. If you would like to use while loops with "get", consider using a while loop in "LIST CONTEXT": while (my ($name) = $results->get) { say $name; } LIST CONTEXT my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # return the first column my ($name) = $results->get; # same as above but specifying index my ($name) = $results->get(0); # multiple indexes may be used my ($name, $favorite_food) = $results->get(0, 2); # negative indexes may be used my ($name, $favorite_food) = $results->get(-3, -1); # get all column values my ($name, $age, $favorite_food) = $results->get; my @person = $results->get; # iterate while (my ($name, $age, $favorite_food) = $results->get) { say qq{$name is $age years old and their favorite food is $favorite_food}; } When "get" is called in list context with no index, it will fetch the next row from sth and return all values for the row as a list. Individual column values may be requested by providing indexes. Negative indexes may also be used just like indexing into Perl arrays. OPTIONS You may provide options to "get" by providing an options hashref as the first argument. die # dies if no next row exists my $name = $results->get({die => 1}); my $name = $results->get({die => 1}, 0); Dies unless there is a next row to be retrieved. See "get_or_die" for this same behavior without needing to provide the die option. The "die" option does nothing if "one" is provided, as "one" is a superset of the functionality of "die". one # dies unless exactly one row was returned in the results my $name = $results->get({one => 1}); my $name = $results->get({one => 1}, 0); Dies unless exactly one row was returned in the results. See "one" for this same behavior without needing to provide the one option. get_by_name Be sure to call finish, such as "finish" in Mojo::Pg::Results or "finish" in Mojo::mysql::Results, if you are not fetching all of the possible rows. "get_by_name" will fetch the next row from sth. SCALAR CONTEXT my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # return the name column my $name = $results->get_by_name('name'); "get_by_name" called in scalar context will fetch the next row from sth and returns the individual value for the column corresponding to the provided name. WHILE LOOPS # THIS IS WRONG DO NOT DO THIS. while (my $name = $results->get_by_name('name')) { # broken loop... } Because "get_by_name" in scalar context may return undef, an empty string or a 0 as values for a column, it cannot be reliably used in while loops (unless used in "LIST CONTEXT"). If you expect one row to be returned, considering using "one_by_name" instead. If you would like to use while loops with "get_by_name", consider using a while loop in "LIST CONTEXT": while (my ($name) = $results->get_by_name('name')) { say $name; } LIST CONTEXT my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # return the name column my ($name) = $results->get_by_name('name'); # multiple names may be used my ($name, $favorite_food) = $results->get('name', 'favorite_food'); # get all column values my ($name, $age, $favorite_food) = $results->get_by_name('name', 'age', 'favorite_food'); # iterate while (my ($name, $age, $favorite_food) = $results->get_by_name('name', 'age', 'favorite_food')) { say qq{$name is $age years old and their favorite food is $favorite_food}; } "get_by_name" fetches the next row from sth and returns the list of values corresponding to the list of column names provided. OPTIONS You may provide options to "get_by_name" by providing an options hashref as the first argument. die # dies if no next row exists my $name = $results->get_by_name({die => 1}); my $name = $results->get_by_name({die => 1}, 0); Dies unless there is a next row to be retrieved. See "get_by_name_or_die" for this same behavior without needing to provide the die option. The "die" option does nothing if "one" is provided, as "one" is a superset of the functionality of "die". one # dies unless exactly one row was returned in the results my $name = $results->get({one => 1}); my $name = $results->get({one => 1}, 0); Dies unless exactly one row was returned in the results. See "one_by_name" for this same behavior without needing to provide the one option. c Be sure to call finish, such as "finish" in Mojo::Pg::Results or "finish" in Mojo::mysql::Results, if you are not fetching all of the possible rows. "c" will fetch the next row from sth. my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); my $full_name = $results->c->join(' '); # iterate while (my $c = $results->c) { my $full_name = $c->join(' '); say "Full name is $full_name"; } "c" fetches the next row from sth and returns the row as a Mojo::Collection. If there is no next row available, undef is returned. You may provide indexes to get just those values in the Mojo::Collection, just as you can do with "get": my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); my $full_name = $results->c(0, 2)->join(' '); # prints "$first_name $last_name" say $full_name; OPTIONS You may provide options to "c" by providing an options hashref as the first argument. die # dies if no next row exists my $person = $results->c({die => 1}); my $person = $results->c({die => 1}, 0, 2); Dies unless there is a next row to be retrieved. See "c_or_die" for this same behavior without needing to provide the die option. The "die" option does nothing if "one" is provided, as "one" is a superset of the functionality of "die". one # dies unless exactly one row was returned in the results my $person = $results->c({one => 1}); my $person = $results->c({one => 1}, 0, 2); Dies unless exactly one row was returned in the results. See "one_c" for this same behavior without needing to provide the one option. c_by_name Be sure to call finish, such as "finish" in Mojo::Pg::Results or "finish" in Mojo::mysql::Results, if you are not fetching all of the possible rows. "c_by_name" will fetch the next row from sth. my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); my $full_name = $results->c_by_name('first_name', 'middle_name', 'last_name')->join(' '); # iterate while (my $c = $results->c_by_name('first_name', 'middle_name', 'last_name')) { my $full_name = $c->join(' '); say "Full name is $full_name"; } "c_by_name" fetches the next row from sth and returns the values corresponding to the provided columns for the next row as a Mojo::Collection. If there is no next row available, undef is returned. OPTIONS You may provide options to "c_by_name" by providing an options hashref as the first argument. die # dies if no next row exists my $person = $results->c_by_name({die => 1}, 'first_name', 'middle_name', 'last_name'); Dies unless there is a next row to be retrieved. See "c_by_name_or_die" for this same behavior without needing to provide the die option. The "die" option does nothing if "one" is provided, as "one" is a superset of the functionality of "die". one # dies unless exactly one row was returned in the results my $person = $results->c({one => 1}, 'first_name', 'middle_name', 'last_name'); Dies unless exactly one row was returned in the results. See "one_c_by_name" for this same behavior without needing to provide the one option. collections my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); my $full_names = $results->collections->map(sub { $_->join(' ') }); "collections" returns a Mojo::Collection of Mojo::Collections. Each inner Mojo::Collection corresponds to one array returned by the results. This is similar to "arrays" in Mojo::Pg::Results or "arrays" in Mojo::mysql::Results, but each arrayref is a Mojo::Collection instead. flatten # Mojo::Collection with names of all people who like Pizza my $results = $db->select(people => ['name'] => {favorite_food => 'Pizza'}); my $names = $results->flatten; # equivalent to $results->arrays->flatten say 'Pizza lovers:'; say for $names->each; "flatten" returns a Mojo::Collection with all result arrays flattened to return a Mojo::Collection with all elements. This is equivalent to calling "flatten" in Mojo::Collection on the arrays method. struct my $struct = $results->struct; Fetch next row from the statement handle with the result object's array method, and return it as a struct. This method is composed from Mojo::DB::Results::Role::Struct. structs my $collection = $results->structs; Fetch all rows from the statement handle with the result object's arrays method, and return them as a Mojo::Collection object containing structs. This method is composed from Mojo::DB::Results::Role::Struct. TRANSFORM METHODS "TRANSFORM METHODS" is a group of methods that build on top of Mojo::Collection::Role::Transform that allow you to transform your results in meaningful and convenient ways. These are: * "hashify" * "hashify_collect" * "collect_by" hashify # access results by a key my $results = $db->select(people => '*'); my $results_by_name = $results->hashify('name'); # $alice_row is a hash my $alice_row = $results_by_name->{Alice}; # access by multiple keys with a multilevel hash my $results_by_full_name = $results->hashify(['first_name', 'last_name']); # $alice_smith_row is a hash my $alice_smith_row = $results_by_full_name->{Alice}{Smith}; # store the value as a struct instead of a hash my $results_by_name = $results->hashify({struct => 1}, 'name'); my $alice_struct = $results_by_name->{Alice}; say 'Alice is ' . $alice_struct->age . ' years old'; "hashify" transforms your results into a hash that stores single rows or values (usually a column value) behind a key or multiple keys (usually column values). "hashify" builds on "hashify" in Mojo::Collection::Role::Transform and adds useful functionality specific to DB results. OPTIONS array my $results = $db->select(people => '*'); my $results_by_name = $results->hashify({array => 1}, 'name'); my $alice_array = $results_by_name->{Alice}; "array" allows you to store the value as an array instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be an array. c my $results = $db->select(people => '*'); my $results_by_name = $results->hashify({c => 1}, 'name'); my $alice_collection = $results_by_name->{Alice}; "c" allows you to store the value as a Mojo::Collection instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a Mojo::Collection. hash my $results = $db->select(people => '*'); my $results_by_name = $results->hashify({hash => 1}, 'name'); # default my $alice_hash = $results_by_name->{Alice}; "hash" allows you to store the value as a hash. This is the default and is the same as providing no option hash: my $results_by_name = $results->hashify('name'); This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a hash. struct my $results = $db->select(people => '*'); my $results_by_name = $results->hashify({struct => 1}, 'name'); my $alice_struct = $results_by_name->{Alice}; "struct" allows you to store the value as a readonly struct provided by Mojo::DB::Results::Role::Struct instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a readonly struct. KEY SINGLE KEY my $results_by_name = $results->hashify('name'); my $alice_row = $results_by_name->{Alice}; A single key may be used to access values. This key should be the name of a returned column. MULTIPLE KEYS my $results_by_full_name = $results->hashify(['first_name', 'last_name']); my $alice_smith_row = $results_by_full_name->{Alice}{Smith}; Multiple keys may be used to access values. Multiple keys should be provided as an arrayref of names of returned columns. SUB # single key my $results_by_name = $results->hashify(sub { $_->{name} }); my $alice_row = $results_by_name->{Alice}; # multiple keys my $results_by_full_name = $results->hashify(sub { @{ $_ }{qw(first_name last_name)} }); my $alice_smith_row = $results_by_full_name->{Alice}{Smith}; Providing a subroutine for the key allows you to create the key (or keys) with the returned row. The row is available either as $_ or as the first argument to the subroutine. The type of the row ("array", "c", "hash", "struct") that is passed to the subroutine depends on any "OPTIONS" value that is passed (default is "hash"). If the subroutine returns one key, the hash will be a "SINGLE KEY" hash. If multiple keys are returned as a list, the hash with be a "MULTIPLE KEYS" hash. VALUE DEFAULT # values are hashes my $results_by_name = $results->hashify('name'); my $alice_hash = $results_by_name->{Alice}; # values are still hashes my $results_by_name = $results->hashify({hash => 1}, 'name'); my $alice_hash = $results_by_name->{Alice}; # values are arrays my $results_by_name = $results->hashify({array => 1}, 'name'); my $alice_array = $results_by_name->{Alice}; # values are Mojo::Collection's my $results_by_name = $results->hashify({c => 1}, 'name'); my $alice_collection = $results_by_name->{Alice}; # values are readonly structs my $results_by_name = $results->hashify({struct => 1}, 'name'); my $alice_struct = $results_by_name->{Alice}; If no value argument is provided, the default is to use the row as the value according to the type specified in "OPTIONS" ("array", "c", "hash", "struct"). The default is "hash". COLUMN # value will be age my $results_by_name = $results->hashify('name', 'age'); my $alice_age = $results_by_name->{Alice}; The value can be provided as a column returned in the results and will be used as the final value in the hash. SUB # value will be the age squared my $results_by_name = $results->hashify('name', sub { $_->{age} * $_->{age} }); my $alice_age_squared = $results_by_name->{Alice}; Providing a subroutine for the value allows you to create the value with the returned row. The row is available either as $_ or as the first argument to the subroutine. The type of the row ("array", "c", "hash", "struct") that is passed to the subroutine depends on any "OPTIONS" value that is passed (default is "hash"). hashify_collect # group results by a key in a hash my $results = $db->select(people => '*'); my $collections_by_name = $results->hashify_collect('name'); # $alice_collection is a Mojo::Collection with all rows with the name Alice as hashes my $alice_collection = $collections_by_name->{Alice}; # group by multiple keys with a multilevel hash my $collections_by_full_name = $results->hashify_collect(['first_name', 'last_name']); # $alice_smith_collection is a Mojo::Collection with all rows with # the first name Alice and last name Smith as hashes my $alice_smith_collection = $collections_by_full_name->{Alice}{Smith}; # group the values as structs instead of hashes my $structs_by_name = $results->hashify_collect({struct => 1}, 'name'); my $alice_structs = $structs_by_name->{Alice}; $alice_structs->each(sub { say 'Alice is ' . $_->age . ' years old'; }); # collect a single column value my $ages_by_name = $results->hashify_collect('name', 'age'); # contains all ages in one Mojo::Collection for all rows with the name Alice my $alice_ages = $ages_by_name->{Alice}; # flatten grouped results my $results = $db->select(people => '*'); my $column_values_by_name = $results->hashify_collect({flatten => 1}, 'name'); # contains all column values in one Mojo::Collection for all rows with the name Alice my $alice_all_column_values = $column_values_by_name->{Alice}; "hashify_collect" allows you to group rows behind a key or multiple keys in a hash. "hashify_collect" builds on "hashify_collect" in Mojo::Collection::Role::Transform and adds useful functionality specific to DB results. OPTIONS array my $results = $db->select(people => '*'); my $collections_by_name = $results->hashify_collect({array => 1}, 'name'); my $alice_collection = $collections_by_name->{Alice}; my $alice_array = $alice_collection->first; "array" allows you to group rows as arrays instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be an array. flatten my $results = $db->select(people => ['name', 'age']); # trivial example returning arrayref to demonstrate flatten my $age_collections_by_name = $results->hashify_collect({flatten => 1}, 'name', sub { [$_->{age}] }); my $alice_ages_collection = $age_collections_by_name->{Alice}; my $age_sum = $alice_ages_collection->reduce(sub { $a + $b }, 0); say "Collective age of Alices is $age_sum years old"; "flatten" flattens all values for a key into the same Mojo::Collection. "flatten" may be combined with the other type options to specify the type of the rows that will be passed to the "KEY" "SUB" or the "VALUE" "SUB". If no "VALUE" is specified, all returned column values for a row will be returned in the order they were requested and flattened into the resulting Mojo::Collection. This works regardless of any type option that is specified: my $results = $db->select(people => ['name', 'age']); # both contain name and age flattened into the collections my $collections_by_name = $results->hashify_collect({hash => 1, flatten => 1}, sub { $_->{name} }); my $collections_by_name = $results->hashify_collect({struct => 1, flatten => 1}, sub { $_->name }); Any value returned by a "VALUE" "SUB" should be an arrayref or list of values and all values will be added to the Mojo::Collection: my $collections_by_name = $results->hashify_collect({flatten => 1}, 'name', sub { $_->{age} }); # flatten not needed in this specific case because it's a list of 1 my $collections_by_name = $results->hashify_collect({flatten => 1}, 'name', sub { [$_->{age}] }); c my $results = $db->select(people => '*'); my $collections_by_name = $results->hashify_collect({c => 1}, 'name'); my $alice_collections = $collections_by_name->{Alice}; $alice_collections->each(sub { say 'Random column value is ' . $_->shuffle->first; }); "c" allows you to group rows as Mojo::Collections instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a Mojo::Collection. hash my $results = $db->select(people => '*'); my $collections_by_name = $results->hashify_collect({hash => 1}, 'name'); # default my $alice_collection = $collections_by_name->{Alice}; "hash" allows you to group the rows as hashes. This is the default and is the same as providing no option hash: my $collections_by_name = $results->hashify_collect('name'); This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a hash. struct my $results = $db->select(people => '*'); my $collections_by_name = $results->hashify_collect({struct => 1}, 'name'); my $alice_collection = $collections_by_name->{Alice}; say q{First Alice's age is } . $alice_collection->first->age; "struct" allows you to group the rows as readonly structs provided by Mojo::DB::Results::Role::Struct instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a readonly struct. KEY SINGLE KEY my $collections_by_name = $results->hashify_collect('name'); my $alice_collection = $collections_by_name->{Alice}; A single key may be used to access collections. This key should be the name of a returned column. MULTIPLE KEYS my $collections_by_full_name = $results->hashify_collect(['first_name', 'last_name']); my $alice_smith_collection = $collections_by_full_name->{Alice}{Smith}; Multiple keys may be used to access collections. Multiple keys should be provided as an arrayref of names of returned columns. SUB # single key my $collections_by_name = $results->hashify_collect(sub { $_->{name} }); my $alice_collection = $collections_by_name->{Alice}; # multiple keys my $collections_by_full_name = $results->hashify_collect(sub { @{ $_ }{qw(first_name last_name)} }); my $alice_smith_collection = $collections_by_full_name->{Alice}{Smith}; Providing a subroutine for the key allows you to create the key (or keys) with the returned row. The row is available either as $_ or as the first argument to the subroutine. The type of the row ("array", "c", "hash", "struct") that is passed to the subroutine depends on any "OPTIONS" value that is passed (default is "hash"). If the subroutine returns one key, the hash will be a "SINGLE KEY" hash. If multiple keys are returned as a list, the hash with be a "MULTIPLE KEYS" hash. VALUE DEFAULT # collections contain hashes my $collections_by_name = $results->hashify_collect('name'); my $alice_collection_of_hashes = $collections_by_name->{Alice}; # collections still contain hashes my $collections_by_name = $results->hashify_collect({hash => 1}, 'name'); my $alice_collection_of_hashes = $collections_by_name->{Alice}; # collections contain arrays my $collections_by_name = $results->hashify_collect({array => 1}, 'name'); my $alice_collection_of_arrays = $collections_by_name->{Alice}; # collections contain Mojo::Collection's my $collections_by_name = $results->hashify_collect({c => 1}, 'name'); my $alice_collection_of_collections = $collections_by_name->{Alice}; # collections contain readonly structs my $collections_by_name = $results->hashify_collect({struct => 1}, 'name'); my $alice_collection_of_structs = $collections_by_name->{Alice}; If no value argument is provided, the default is to collect the rows as the value according to the type specified in "OPTIONS" ("array", "c", "hash", "struct"). The default is "hash". COLUMN # age will be collected my $collections_by_name = $results->hashify_collect('name', 'age'); my $alice_collection_of_ages = $collections_by_name->{Alice}; The value can be provided as a column returned in the results, and this column value for each row will be collected into the corresponding Mojo::Collection based on the key(s). SUB # collected value will be the age squared my $collections_by_name = $results->hashify_collect('name', sub { $_->{age} * $_->{age} }); my $alice_collection_of_ages_squared = $collections_by_name->{Alice}; Providing a subroutine for the value allows you to create the collected values for each returned row. The row is available either as $_ or as the first argument to the subroutine. The type of the row ("array", "c", "hash", "struct") that is passed to the subroutine depends on any "OPTIONS" value that is passed (default is "hash"). You may return a single value, or a list of values to be collected: my $collections_by_name = $results->hashify_collect('name', sub { $_->{age}, $_->{favorite_food} }); collect_by # group results by a key in Mojo::Collection's inside of a Mojo::Collection my $results = $db->select(people => '*'); my $collections_by_name = $results->collect_by('name'); say 'First collection contains rows with name', $collections_by_name->first->first->{name}; # group results by multiple keys my $collections_by_full_name = $results->collect_by(['first_name', 'last_name']); my $first_collection = $collections_by_name->first; say 'First collection contains rows with first name', $first_collection->first->{first_name}, ' and last name ', $first_collection->first->{last_name}; # group the values as structs instead of hashes my $structs_by_name = $results->collect_by({struct => 1}, 'name'); $structs_by_name->first->each(sub { say $_->name, ' is ' . $_->age . ' years old'; }); # collect a single column value my $ages_by_name = $results->collect_by('name', 'age'); say 'First collection contains ages for name', $ages_by_name->first->first->{name}; # flatten grouped results my $results = $db->select(people => '*'); # each inner Mojo::Collection is flattened my $column_values_by_name = $results->collect_by({flatten => 1}, 'name'); "collect_by" allows you to group rows/values that share the same key or multiple keys in Mojo::Collections inside of a Mojo::Collection. "collect_by" builds on "collect_by" in Mojo::Collection::Role::Transform and adds useful functionality specific to DB results. OPTIONS array my $results = $db->select(people => '*'); my $collections_by_name = $results->collect_by({array => 1}, 'name'); "array" allows you to group rows as arrays instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be an array. flatten my $results = $db->select(people => ['name', 'age']); # trivial example returning arrayref to demonstrate flatten my $age_collections_by_name = $results->collect_by({flatten => 1}, 'name', sub { [$_->{age}] }); "flatten" flattens all values for each inner Mojo::Collection. "flatten" may be combined with the other type options to specify the type of the rows that will be passed to the "KEY" "SUB" or the "VALUE" "SUB". If no "VALUE" is specified, all returned column values for a row will be returned in the order they were requested and flattened into the resulting Mojo::Collection. This works regardless of any type option that is specified: my $results = $db->select(people => ['name', 'age']); # both contain name and age flattened into the inner collections my $collections_by_name = $results->collect_by({hash => 1, flatten => 1}, sub { $_->{name} }); my $collections_by_name = $results->collect_by({struct => 1, flatten => 1}, sub { $_->name }); Any value returned by a "VALUE" "SUB" should be an arrayref or list of values and all values will be added to the inner Mojo::Collections: my $collections_by_name = $results->collect_by({flatten => 1}, 'name', sub { $_->{age} }); # flatten not needed in this specific case because it's a list of 1 my $collections_by_name = $results->collect_by({flatten => 1}, 'name', sub { [$_->{age}] }); c my $results = $db->select(people => '*'); my $collections_by_name = $results->collect_by({c => 1}, 'name'); $collections_by_name->first->first->each(sub { say 'Random column value is ' . $_->shuffle->first; }); "c" allows you to group rows as Mojo::Collections instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a Mojo::Collection. hash my $results = $db->select(people => '*'); my $collections_by_name = $results->collect_by({hash => 1}, 'name'); # default "hash" allows you to group the rows as hashes. This is the default and is the same as providing no option hash: my $collections_by_name = $results->collect_by('name'); This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a hash. struct my $results = $db->select(people => '*'); my $collections_by_name = $results->collect_by({struct => 1}, 'name'); my $first_collection = $collections_by_name->first; say $first_collection->first->name, ' is ', $first_collection->first->age, ' years old'; "struct" allows you to group the rows as readonly structs provided by Mojo::DB::Results::Role::Struct instead of the default "hash". This also means the value provided to the "KEY" "SUB" or the "VALUE" "SUB", if used, will be a readonly struct. KEY SINGLE KEY my $collections_by_name = $results->collect_by('name'); A single key may be used to group rows/values into inner Mojo::Collections. This key should be the name of a returned column. MULTIPLE KEYS my $collections_by_full_name = $results->collect_by(['first_name', 'last_name']); Multiple keys may be used to group rows/values into inner Mojo::Collections. Multiple keys should be provided as an arrayref of names of returned columns. SUB # single key my $collections_by_name = $results->collect_by(sub { $_->{name} }); # multiple keys my $collections_by_full_name = $results->collect_by(sub { @{ $_ }{qw(first_name last_name)} }); Providing a subroutine for the key allows you to create the key (or keys) with the returned row. The row is available either as $_ or as the first argument to the subroutine. The type of the row ("array", "c", "hash", "struct") that is passed to the subroutine depends on any "OPTIONS" value that is passed (default is "hash"). If the subroutine returns one key, the hash will be a "SINGLE KEY" hash. If multiple keys are returned as a list, the hash with be a "MULTIPLE KEYS" hash. VALUE DEFAULT # collections contain hashes my $collections_by_name = $results->collect_by('name'); # collections still contain hashes my $collections_by_name = $results->collect_by({hash => 1}, 'name'); # collections contain arrays my $collections_by_name = $results->collect_by({array => 1}, 'name'); # collections contain Mojo::Collection's my $collections_by_name = $results->collect_by({c => 1}, 'name'); # collections contain readonly structs my $collections_by_name = $results->collect_by({struct => 1}, 'name'); If no value argument is provided, the default is to collect the rows as the value according to the type specified in "OPTIONS" ("array", "c", "hash", "struct"). The default is "hash". COLUMN # age will be collected my $collections_by_name = $results->collect_by('name', 'age'); The value can be provided as a column returned in the results, and this column value for each row will be collected into the corresponding inner Mojo::Collection based on the key(s). SUB # collected value will be the age squared my $collections_by_name = $results->collect_by('name', sub { $_->{age} * $_->{age} }); Providing a subroutine for the value allows you to create the collected values for each returned row. The row is available either as $_ or as the first argument to the subroutine. The type of the row ("array", "c", "hash", "struct") that is passed to the subroutine depends on any "OPTIONS" value that is passed (default is "hash"). You may return a single value, or a list of values to be collected: my $collections_by_name = $results->collect_by('name', sub { $_->{age}, $_->{favorite_food} }); DIE METHODS "DIE METHODS" are equivalent to the "get", "get_by_name", "c", and "c_by_name" methods above, however, the die option for these methods is passed as true for you and the method will die if there is no next row to be retrieved. Additionally, "struct_or_die", "array_or_die", and "hash_or_die" are provided. get_or_die my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # all of these die if there is no next row to be retrieved # return the first column my $name = $results->get_or_die; # same as above but specifying index my $name = $results->get_or_die(0); # negative indexes may be used my $name = $results->get_or_die(-3); # any column may be gotten with an index my $age = $results->get_or_die(1); Same as "get", but dies if there is no next row to be retrieved. get_by_name_or_die my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # dies if there is no next row to be retrieved my $name = $results->get_by_name_or_die('name'); Same as "get_by_name", but dies if there is no next row to be retrieved. c_or_die my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); # dies if there is no next row to be retrieved my $full_name = $results->c_or_die->join(' '); Same as "c", but dies if there is no next row to be retrieved. c_by_name_or_die my $results = $db->select(people => ['first_name', 'middle_name', 'last_name']); # dies if there is no next row to be retrieved my $full_name = $results->c_by_name_or_die('first_name', 'middle_name', 'last_name')->join(' '); Same as "c_by_name", but dies if there is no next row to be retrieved. struct_or_die my $results = $db->select(people => '*' => {id => 123}); # dies if there is no next row to be retrieved my $person_struct = $results->struct_or_die; "struct_or_die" is the same as "struct", but dies if there is no next row to be retrieved. array_or_die my $results = $db->select(people => ['first_name', 'middle_name', 'last_name'] => {id => 123}); # dies if there is no next row to be retrieved my $full_name = join ' ', @{ $results->array_or_die }; "array_or_die" is similar to "array" in Mojo::Pg::Results or "array" in Mojo::mysql::Results, but dies if there is no next row to be retrieved. hash_or_die my $results = $db->select(people => '*' => {id => 123}); # dies if there is no next row to be retrieved my $person = $results->hash_or_die; "hash_or_die" is similar to "hash" in Mojo::Pg::Results or "hash" in Mojo::mysql::Results, but dies if there is no next row to be retrieved. ONE METHODS "ONE METHODS" are equivalent to the "get", "get_by_name", "c", "c_by_name", and "struct" methods above, however, the one option for these methods is passed as true for you and the method will die unless exactly one row was returned. Additionally, "one_struct", "one_array" and "one_hash" are provided. one my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # all of these die unless exactly one row was returned # return the first column my $name = $results->one; # same as above but specifying index my $name = $results->one(0); # negative indexes may be used my $name = $results->one(-3); # any column may be gotten with an index my $age = $results->one(1); Same as "get", but dies unless exactly one row was returned. one_by_name my $results = $db->select(people => ['name', 'age', 'favorite_food'] => {id => 123}); # dies unless exactly one row was returned my $name = $results->one_by_name('name'); Same as "get_by_name", but dies unless exactly one row was returned. one_c my $results = $db->select(people => ['first_name', 'middle_name', 'last_name'] => {id => 123}); # dies unless exactly one row was returned my $full_name = $results->one_c->join(' '); Same as "c", but dies unless exactly one row was returned. one_c_by_name my $results = $db->select(people => ['first_name', 'middle_name', 'last_name'] => {id => 123}); # dies unless exactly one row was returned my $full_name = $results->one_c_by_name('first_name', 'middle_name', 'last_name')->join(' '); Same as "c_by_name", but dies unless exactly one row was returned one_struct my $results = $db->select(people => '*' => {id => 123}); # dies unless exactly one row was returned my $person_struct = $results->one_struct; "one_struct" is the same as "struct", but dies unless exactly one row was returned. one_array my $results = $db->select(people => ['first_name', 'middle_name', 'last_name'] => {id => 123}); # dies unless exactly one row was returned my $full_name = join ' ', @{ $results->one_array }; "one_array" is similar to "array" in Mojo::Pg::Results or "array" in Mojo::mysql::Results, but dies unless exactly one row was returned. one_hash my $results = $db->select(people => '*' => {id => 123}); # dies unless exactly one row was returned my $person = $results->one_hash; "one_hash" is similar to "hash" in Mojo::Pg::Results or "hash" in Mojo::mysql::Results, but dies unless exactly one row was returned. AUTHOR Adam Hopkins COPYRIGHT Copyright 2019- Adam Hopkins LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. SEE ALSO * Mojo::Pg::Results * Mojo::mysql::Results * Mojo::DB::Role::ResultsRoles * Mojo::DB::Results::Role::Struct * Role::Tiny * Mojo::Base