Add fu->redirect, change $st->row behavior on 0 results, minor fixes

And with this, I have a working rewrite of the manned.org backend into
FU. \o/

The $st->row methods are very useful even for queries that may not
return anything, so their old behavior was unhelpful. Interestingly
enough, the error-on-multiple-rows did catch an actual bug in
Manned.org, so I'm keeping that behavior.
This commit is contained in:
Yorhel 2025-02-24 15:54:32 +01:00
parent fbbaa23842
commit 06e2f950fe
9 changed files with 62 additions and 34 deletions

View file

@ -12,6 +12,8 @@ our $in_log = 0;
sub default_fmt($msg, @extra) {
my $pre = '';
$msg =~ s/^\s+//;
$msg =~ s/\s+$//;
if ($msg =~ /\n/) {
$msg =~ s/(^|\n)/\n# /g;
$msg .= "\n";
@ -25,7 +27,6 @@ sub default_fmt($msg, @extra) {
sub log_write($msg) {
local $SIG{__WARN__} = undef if $capture_warn;
chomp $msg;
my $line = (!$in_log && eval {
local $in_log = 1;
$fmt->($msg)

View file

@ -237,24 +237,26 @@ if no rows are returned or if its value is I<NULL>.
=item $st->rowl
Return the first row as a list. Throws an error if the query does not return
exactly one row.
Return the first row as a list, or an empty list if no rows are returned.
Throws an error if the query returned more than one row.
my($id, $title) = $conn->q('SELECT id, title FROM books LIMIT 1')->rowl;
# ($id, $title) = (1, 'Revelation Space');
=item $st->rowa
Return the first row as an arrayref, equivalent to C<< [$st->rowl] >> but
might be slightly more efficient.
Return the first row as an arrayref, equivalent to C<< [$st->rowl] >> but might
be slightly more efficient. Returns C<undef> if the query did not generate any
rows.
my $row = $conn->q('SELECT id, title FROM books LIMIT 1')->rowa;
# $row = [1, 'Revelation Space'];
=item $st->rowh
Return the first row as a hashref. Also throws an error if the query returns
multiple columns with the same name.
Return the first row as a hashref. Returns C<undef> if the query did not
generate any rows. Throws an error if the query returns multiple columns with
the same name.
my $row = $conn->q('SELECT id, title FROM books LIMIT 1')->rowh;
# $row = { id => 1, title => 'Revelation Space' };

View file

@ -51,7 +51,7 @@ sub VALUES {
: SQL 'VALUES (', COMMA(@_), ')';
}
sub IN($a) {
sub IN :prototype($) ($a) {
confess "Expected arrayref" if ref $a ne 'ARRAY';
bless \$a, 'FU::SQL::in'
}

View file

@ -38,7 +38,7 @@ sub uri_unescape :prototype($) ($s) {
sub query_decode :prototype($) ($s) {
my %o;
for (split /&/, $s//'') {
my($k,$v) = map uri_unescape($_), split /=/;
my($k,$v) = map uri_unescape($_), split /=/, $_, 2;
$v //= builtin::true;
if (ref $o{$k}) { push $o{$k}->@*, $v }
elsif (exists $o{$k}) { $o{$k} = [ $o{$k}, $v ] }