—package
DBIx::Class::SQLA2;
use
strict;
use
warnings;
no
warnings
'experimental::postderef'
;
SQL::Abstract
SQL::Abstract::Classic
)
;
use
Role::Tiny;
__PACKAGE__->mk_group_accessors(
simple
=>
'_connection_info'
);
sub
_render_hashrefrefs {
my
(
$self
,
$list
) =
@_
;
my
@fields
=
ref
$list
eq
'ARRAY'
?
@$list
:
$list
;
return
[
map
{
ref
$_
eq
'REF'
&&
ref
$$_
eq
'HASH'
?
do
{
my
%f
=
$$_
->%*;
my
$as
=
delete
$f
{-as};
\[
$as
?
$self
->render_expr({
-op
=> [
'as'
, \
%f
, {
-ident
=>
$as
} ] })
:
$self
->render_expr(\
%f
)
];
}
:
$_
}
@fields
];
}
sub
_recurse_fields {
my
(
$self
,
$fields
) =
@_
;
if
(
ref
$fields
eq
'REF'
&&
ref
$$fields
eq
'HASH'
) {
return
$self
->
next
::method(
$self
->_render_hashrefrefs(
$fields
)->[0]);
}
return
$self
->
next
::method(
$fields
);
}
sub
select
{
my
(
$self
,
$table
,
$fields
,
$where
,
$rs_attrs
,
$limit
,
$offset
) =
@_
;
if
(
my
$gb
=
$rs_attrs
->{group_by}) {
$rs_attrs
= {
%$rs_attrs
,
group_by
=>
$self
->_render_hashrefrefs(
$gb
) };
}
$self
->
next
::method(
$table
,
$fields
,
$where
,
$rs_attrs
,
$limit
,
$offset
);
}
sub
insert {
# TODO - this works, ish. The issue is that if you have rels involved, you may actually
# hit `insert` before the intended insert. Not sure what to do but put that on the
# user...
my
(
$self
,
$source
,
$cols
,
$attrs
) =
@_
;
$attrs
||= {};
if
(
my
$extra_attrs
=
$self
->{_sqla2_insert_attrs}) {
$attrs
= {
%$attrs
,
%$extra_attrs
};
}
$self
->
next
::method(
$source
,
$cols
,
$attrs
);
}
sub
expand_clause {
my
(
$self
,
$clause
,
$value
) =
@_
;
my
(
$probably_key
,
$expanded
) =
$self
->${ \
$self
->clause_expander(
$clause
) }(
undef
,
$value
);
if
(
$expanded
) {
return
(
$probably_key
=>
$expanded
);
}
else
{
return
(
undef
=>
$probably_key
);
}
}
sub
new {
my
$new
=
shift
->
next
::method(
@_
);
unless
(
grep
{m/^
with
$/}
$new
->clauses_of(
'select'
)) {
$new
->plugin(
"+$_"
)
for
qw/ExtraClausesFixed WindowFunctions Upsert BangOverrides CaseExpr/
;
}
return
$new
;
}
our
$VERSION
=
'0.01_4'
;
1;
=encoding utf8
=head1 NAME
DBIx::Class::SQLA2 - SQL::Abstract v2 support in DBIx::Class
=head1 SYNOPSIS
$schema->connect_call_rebase_sqlmaker('DBIx::Class::SQLA2');
=head1 DESCRIPTION
This is a work in progress for simplifying using SQLA2 with DBIC. This is for using w/ the
most recent version of DBIC.
For a simple way of using this, take a look at L<DBIx::Class::Schema::SQLA2Support>.
B<EXPERIMENTAL>
This role itself will add handling of hashref-refs to select lists + group by clauses,
which will render the inner hashref as if it had been passed through to SQLA2 rather than
doing the recursive function rendering that DBIC does.
=head2 Included Plugins
This will add the following SQLA2 plugins:
=over 2
=item L<SQL::Abstract::Plugin::ExtraClauses>
Adds support for CTEs, and other fun new SQL syntax
=item L<SQL::Abstract::Plugin::WindowFunctions>
Adds support for window functions and advanced aggregates.
=item L<SQL::Abstract::Plugin::Upsert>
Adds support for Upserts (ON CONFLICT clause)
=item L<SQL::Abstract::Plugin::BangOverrides>
Adds some hacky stuff so you can bypass/supplement DBIC's handling of certain clauses
=back
=head1 AUTHOR
Copyright (c) 2022 Veesh Goldman <veesh@cpan.org>
=head1 LICENSE
This module is free software; you may copy this under the same
terms as perl itself (either the GNU General Public License or
the Artistic License)
=cut