[Dbix-class] Re: Refactoring Tangram::Expr and
Tangram::Relational::Engine - looking for a SQL AST module
Darren Duncan
darren at DarrenDuncan.net
Sat Jul 30 03:42:04 CEST 2005
This is reply is to multiple messages, including the posting each by
Sam Vilain and Matt S Trout, as well as a private email from the
latter (plus a tidbit for Todd Hepler re subject "design thought").
At 4:23 PM +1200 7/29/05, Sam Vilain wrote:
>Matt S. Trout and I discussed requirements for an extension to SQL::Abstract
>and/or a new module along similar lines that could serve as a base for the
>SQL generation performed by Tangram and DBIx::Class.
As you both stated before, I believe that my new Rosetta/SQL::Routine
framework can serve as this base. In fact, I designed the framework
partly for this very task, to form a common base for things like
object relational mappers that is higher level than the common base
of DBI. Likewise, I anticipate that such object relational mapping
modules won't want to expose Rosetta's API directly through their own
API any more than they expose DBI's, though I have no problem if you
do. Using Rosetta is principally similar to using DBI, in how its
API is structured; the main difference is that you use SQL ASTs
instead of SQL strings.
>We investigated a few CPAN modules, but none of them seemed quite flexible
>enough. SQL::Routine seemed to fit the bill, but isn't lightweight nor coded
>in a style which I personally find maintainable; however it might prove to be
>an invaluable source of details, or maybe it will prove easier to work with
>Darren to address our concerns with the module so that it is more suitable.
I am willing to do what it takes to ensure SQL::Routine et al meets
your needs. Ideally I can just adapt the standard module to provide
the kind of API or hooks that you need. Or, in a worse case
scenario, I can assist you with maintaining a stripped down branch of
it. As for maintainable, well, the big thing about SQL::Routine is
that it is heavily data defined, though the data can't be changed by
users of the module (for simplicity). This means heavier up front,
but it also scales to more features much better with relatively
little added code. The rest of Rosetta isn't so data defined as
SQL::Routine, so it may look more like what you're used to.
>Please note that this is a relatively small component of the overall picture,
>and that it is very comfortably cushioned away from the user APIs of either
>DBIx::Class or Tangram. Discussion on each of the above points is encouraged.
Exactly.
>15:59 < mugwump> 1. I think we both agree that it needs to be a lightweight,
> "pure" SQL AST module
>15:59 < mst> yes
While SQL::Routine looks complex, it is in fact very pure, doing
nothing but maintaining the heavily data-defined AST. It was
designed that way on purpose; the purity even goes to the point that
string SQL generators etc are separate and dependent projects rather
than being bundled or built-in. Most of its "weight" is actually
documentation, and most of that is in separate POD-only files.
>16:00 < mst> 3. The SQL Engine will have a callback system to interrogate its
> hosting ORM for info and object values
This doesn't exist yet, but lets work out what you need. For all we
know, you may want to store some info in the SQL::Routine model that
you would otherwise store elsewhere. It is a unified schema plus SQL
statement representation model.
>16:01 < mugwump> 4. it needs to support partial ASTs,
You can do that; SQL::Routine has a multi-level API, and the lowest
level is very piecemeal oriented.
>and know how to convert
> natural join syntax to explicit join syntax (if I've got my
> terms right)
>16:01 < mst> I think so, and I definitely get your meaning. yes.
Currently, SQL::Routine has no concept of natural joins per se, and I
have no plan to add it; you must specify within it what your join
conditions and result columns are. This actually isn't very hard
except that your OO->relational model must have explicit knowledge of
the table columns, which I believe is the norm with OO-relational
mappers. Its only modules that use arbitrarily defined user queries
that may have to scan a database schema to fill in the blanks.
This said, SQL::Routine also lets you reuse and nest query/view
definitions, so that may give you natively some of what you want.
>16:02 < mugwump> 5. it needs to be easily subclassable for SQL dialects ?
This concept is irrelevant to the SQL::Routine way of doing things.
At its core, SQL::Routine says mainly *what* you want to do (as SQL
in general is designed to do, being a 4th-level language). How that
is implemented, at the detail of SQL dialects, is the job of other
modules that use SQL::Routine (through they can choose to
wrap-subclass it); SQL::Routine::SQLBuilder is an example of this,
and that is configurable for multiple SQL dialects.
>16:03 < mst> 6. it should be possibly to plug into it in multiple
>directions to
> (a) add additional features (if you don't need complex joins,
> don't load them) and (b) allow SQL dialect support
This sort of pluggability matter is only relevant to other modules
that use SQL::Routine, not SQL::Routine itself; representing those
things in the model is cheap, and removing that support saves next to
nothing.
>16:17 < mugwump> also, 7. it needs to support sub-selects, named parameter
> binding, and all other SQL constructs often overlooked, such
> as GROUP BY & HAVING, etc.
None of these are overlooked by SQL::Routine/Rosetta. They were
designed to address such common omissions in other modules. And
supporting them is also cheap.
At 9:15 AM +0100 7/29/05, Matt S Trout wrote:
>The other thing we've looked at is Darren Duncan's Rosetta + SQL::Routine
>libraries, which are quite complex (at least to me at first look) but
>extremely powerful. Darren e-mailed me (independently of us starting to
>look at his code) with
>http://darrenduncan.net/OSCON/OSCON2005LightningTalk.txt
>which gives an interesting summary indeed.
For those of you not on dbi-users to have heard it before, I am
looking for feedback on this talk, which even now I don't know if
Mark Jason Dominus has approved it or not. Essentially, which things
mentioned are the most or least attention grabbing, and what can be
summarized without losing its impact. This currently needs to lose
about 25% of its length for me to be able to read it aloud within 5
minutes.
>I'm trying to persuade Darren he should subscribe to one/both lists; in the
>mean time, comments on this as well as the points in Sam's e-mail are of
>course most welcome. So get thinking!
And so I have.
At 8:49 AM +0100 7/29/05, Matt S Trout wrote (by private email):
>Your expertise and your knowledge of the somewhat formidable libraries in
>question would be very much appreciated.
I hope that they will become considerably less formidable over time.
>This one sentence: "Views are updateable" strongly suggests to me that
>Rosetta is going to be the solution of choice. Thanks very much for that
>link, it's provided me a much better overview than my attempts at getting
>my head round the docs :)
Okay, the updateable views thing works like this:
1. SQL::Routine allows you to define the use of a view in all of the
same ways as a table, meaning, select from it or use it in larger
queries, insert into it, update and delete against it.
2. The Rosetta::Engine::Generic module (and its helper,
SQL::Routine::SQLBuilder), will by default try to exploit a
database's built-in support for updateable views, which are defined
by the SQL:2003 standard. The better databases should support this
internally, so not much more work for us than to work with those
actions against a table. MySQL v5.x has this feature, for example.
3. When a database's native support is inadequate or nonexistent,
then Rosetta::Engine::Generic will go to the trouble to generate
multiple or transformed SQL and issue these multiples against the
database.
4. Anyone, even you, is welcome to make a different
Rosetta::Engine::* module that does this better.
An Engine can do whatever it wants to satisfy the user request. Even
use LWP or MyApp::File or whatever, instead of a SQL database. That
last one's looking at you, Todd Hepler.
As a final note, I'm in the middle of another large update across the
line, so you shouldn't actually start to use Rosetta/SQL::Routine yet
(though you can start to study it). I plan to post a snapshot
tonight or tomorrow, with the balance hopefully any day thereafter.
This will be followed by a list post "Rosetta developer preview #3".
Until then, Generic doesn't actually connect the dots and implement
table create or select/update/delete/etc.
-- Darren Duncan
More information about the Dbix-class
mailing list