Slides for the talk linq at yapc-eu-2011
-
WARNING:
incomplete code
discussed within.
If you want stuff
to use today,
please go to a
different talk :)
-
Data::Query
a LINQ's
awakening
-
Origins
-
DBIx::Class
-
Further
back?
-
Class::DBI
-
Simple
->search
-
->search(
name => 'Simpson'
);
-
Class
based
-
Returned
arrays
-
(or an
iterator
object)
-
Tangram
-
Object
store
-
Required
control of
the schema
-
Interesting
syntax
-
$storage->select(
$person,
$person->{name} eq 'Simpson'
);
-
Still
returned
arrays
-
Integer
based joins
-
Class::DBI::Sweet
-
"You can't
implement
AR :include"
-
Oh yeah?
-
SQL::Abstract
-
join +
prefetch
-
Still only
arrays or
iterators
-
DBIx::Class
-
Reinvention
of Class::DBI
-
join +
prefetch
-
Arbitrary
equality
joins
-
(only
equality
joins)
-
Originally
class based
-
0.05
-
Giant
refactor
-
search() logic
moved to
iterator class
-
iterator
renamed
-
ResultSet
-
Collection
class
-
Enabled
search
chaining
-
Functional
composition
of queries
-
method older_than ($age) {
$self->search({
age => { '>', $age }
});
}
-
$people->older_than($age)
->called($name);
-
Still using
SQL::Abstract
-
join
prefetch
group_by
having
-
All implemented
internally
-
Design
errors
-
Combining
collection
+ iterator
-
$rs->next
-
Objects
too aware
of their
persistence
-
$row->update
-
Nowhere to
put logic
-
Storage::DBI
-
Storage::DBI
is a god
object
-
ResultSource
-
Table
metadata
-
No true
understanding
of persistence
-
Logic
spread
-
Logic in
Result
ResultSet
-
Worse
still
-
Unintrospectable
query system
-
Too many
ways to
do it
-
{
foo => {
'>', $x,
'<', $y
}
}
-
{
foo => [
-and,
{ '>', $x },
{ '<', $y }
]
}
-
{
-and => [
{ foo => { '>', $x } },
{ foo => { '<', $y } },
]
}
-
-
SQL specific
query system
-
$rs->set_cache(\@objects);
$rs->search(...);
-
This should
not hit the
database :(
-
select
join
group_by
having
-
Syntax
evolved
-
Evolved and
inconsistent
-
No consensus
on a real
solution
-
SQL::Abstract::More
-
(I hate modules
called ::More)
-
(but ldami still
wrote something
useful there :)
-
Final
horror
-
$row->get_column('foo');
-
AAAARGH
-
Why does
this exist?
-
'+select' =>
group_by =>
-
Same row
classes
-
No new
accessors
-
Need a way
to get extra
column values
-
This was
the WRONG
way to do it
-
HashRefInflator
-
HashRefInflator
is less wrong
-
Constructing
a new class
-
*optionally*
constructing
a new class
-
But now it's
too late
-
-
Wait.
-
Is it
too late?
-
DBIx::Class::CDBICompat
-
Why does
this exist?
-
Class::DBI
compatibility
-
Never really
got used
-
People just
converted
-
That's
ok ...
-
That's not
why I
wrote it
-
t/cdbi-t/
-
Powered early
DBIC development
-
"If CDBICompat
passes these ..."
-
"... core
probably
works too"
-
Plus: DBIC
API much more
capable
-
Much less
reliance on
internals
-
Much less
dependence
on bugs
-
Can we
do it?
-
I think
we can.
-
But first ...
-
-
First?
-
First fix
the query
system
-
Data::Query
-
Abstract
Query
Tree
-
Original
prototype
-
SQL::Abstract2
-
Spec:
Rob Kinyon
-
Code:
Ash Berlin
-
MooseX::Declare
-
Hopelessly
overengineered
-
Still SQL
specific
-
*throw*
-
Started
again
-
Spec as
rough guide
-
Goal: make
stuff work
-
Nodes are
hashrefs
-
Why not
objects?
-
Multiple
backends
-
Differing
class
hierarchies
-
Even within
SQL variants!
-
MySQL: CONCAT(x, y)
Postgres: x || y
-
MySQL: Function
Postgres: Operator
-
Treat
everything
as 'op'
-
Backends
decide what
to generate
-
Ops are
typed to
storage
-
SQL only
has =
-
Conversion
must be
pluggable
-
Naive code
makes eq
and == =
-
Smarter code
can check
argument types
-
(and apply
casts - e.g.
x::int = y::int)
-
What does
it look like?
-
{
foo => {
'>', $x,
'<', $y
}
}
-
{
type => DQ_OPERATOR,
operator => {
'SQL.Naive' => 'and'
},
args => [
{
type => DQ_OPERATOR,
operator => {
'SQL.Naive' => '>'
},
args => [ ...
-
{
type => DQ_VALUE,
subtype => {
'Perl' => 'Scalar'
},
value => $x
}
-
Sane.
-
Introspectable.
-
OMG
Verbose!
-
Sugar
Syntax
-
Inspired
by Tangram
-
expr {
$_->foo > $x
&
$_->foo < $y
}
-
&?
-
Operator
overloading
-
Can't overload
|| && and or
-
Can overload
& and |
-
Imperfect.
-
Can do
better
with B::
-
DBIx::Perlish
DBIx::StORM
-
(StORM found
only on backpan
now ...)
-
SELECT { $_ }
FROM { $_->artists }
WHERE { $_->age > 30 }
-
Query object
separate from
result object
-
Layering
queries
-
WHERE nodes
can collapse
-
$rs->set_cache(\@objs)
-
Subsequent
WHEREs can
render
to perl
-
Current
status?
-
SQL::Abstract
'dq' branch
passes all
but one test
-
DBIx::Class::SQLMaker
porting still to come
-
DQ-aware
collection
classes still
to come
-
Lots to do
but this
*will* work
-
A LINQ's
awakening?
-
Well, he's
got one
eye open
-
... now I just
need to feed
him coffee
-
-fx-
-
http://git.shadowcat.co.uk/
git://git.shadowcat.co.uk/dbsrgits/Data-Query.git
git://git.shadowcat.co.uk/dbsrgits/SQL-Abstract.git
-
http://shadowcat.co.uk/blog/matt-s-trout/
irc.perl.org#dbix-class
-
Questions?
-
Thank You
IRC:mst
mst@shadowcat.co.uk
@shadowcat_mst