Re: DBI v2 - The Plan and How You Can Help

2005-08-17 Thread Tim Bunce
On Tue, Aug 16, 2005 at 03:58:54PM -0400, John Siracusa wrote:
 On 8/16/05, Tim Bunce [EMAIL PROTECTED] wrote:
  I was a little dissapointed that there wasn't greater focus on using
  Perl6 features - especially as it would have helped kick-start my own
  understanding of Perl6 topics that I expect to be significant (such as
  Roles and Pairs, to pick two at random). Perhaps the community of
  Perl6+DBI users is too small at this point.
 
 I'm afraid that DBI2 for Perl 6 will fall into the trap that I sometimes
 feel like DBI1 fell into: the curse of being designed before the idioms and
 Best Practices of API design in the language have been established.

 I think it'll take years, and much actual production experience building
 Perl 6 modules before the community learns what works and what doesn't for a
 Perl 6 API (let alone implementation).  So trying to pin down a properly
 Perl-6-ish API before Perl 6 is even through the language design process
 strikes me as a Very Bad Idea.

I remember the early years of Perl 5 development, when a new feature was
added there'd be a period of over-zealous use followed by a hangover as
all the problems and edge-cases became apparent.

With Perl 6 there's going to be some almighty hangovers :)

 That could explain why there were so few Perl 6 related suggestions: no one
 knows how to design a good Perl 6 API yet, and any guess is very likely to
 be wrong.  Instead, suggestions have focused on what we do know: DBI in Perl
 5 and Perl 5 API design.  In that spirit, here's my suggestion: no more
 configuration through magic/tied hashes. (e.g., $dbh-{'AutoCommit'} = 1)
 (Probably goes without saying, but I wanted to make sure someone said it ;)

Hey, it seemed like a good idea at the time :)

(Actually it's still a good idea in many ways, especially in relation to
its behaviour for unknown driver-private attributes and DBI version skew.
But it does need rethinking for DBI2.)

 Anyway, it maybe worthwhile to have a DBI 1.99 first, and then maybe a 1.999
 after that.  Basically, get one or two willing DBD authors who will help you
 to test and then throw away the first two attempts at a Perl 6 DBI API.
 Then at least you'll have some confidence when you commit to a DBI 2.0
 API...which will be several years after Perl 6 is released, I hope.

It'll be DBI 2 as DBI 1 still has a very long life ahead of it, but
it'll be DBI 2.0.00xxx for quite a while :)

 Of course, *someone* has to go first so we can all learn what works best
 in Perl 6.  I'm just saying that maybe DBI, which took the bullet in Perl 5
 to some degree, is under no obligation to do so again.  (This assumes that
 we'll have some way to use Perl 5 DBI within Perl 6 to tide us over, of
 course...) 

I'm in no great rush as one of my core assumptions is that DBI v1 will
be available in Perl 6 via either Ponie or direct embedding of libperl5.so.

Tim.


Re: DBI v2 - The Plan and How You Can Help

2005-08-17 Thread Tim Bunce
On Tue, Aug 16, 2005 at 01:16:19PM -0700, Darren Duncan wrote:
 At 4:04 PM +0100 8/16/05, Tim Bunce wrote:
 I was a little dissapointed that there wasn't greater focus on using
 Perl6 features - especially as it would have helped kick-start my own
 understanding of Perl6 topics that I expect to be significant (such as
 Roles and Pairs, to pick two at random). Perhaps the community of
 Perl6+DBI users is too small at this point.
 
 One way that the Perl 6 thought process can be started is in 
 considering the design principles laid out in Damian's new Best 
 Practices book.  I said to Damian at OSCON that I thought the 
 practices he was putting forward were intended to get people thinking 
 now in Perl 5 about ways of doing things that will be the natural way 
 of doing them in Perl 6; he said something along the lines that I had 
 good insight.  So these practices are probably some good things to 
 keep in mind as we move forward.

Yeap. I'm awaiting delivery of that one, plus several others including
MJDs Higher Order Perl.

 Now, speaking specifically in Perl 6 terms ...
 
 I suggest that DBI v2 has a more formal separation between interface 
 and implementation.  The parts of DBI can be grouped into these 
 categories:
 
 1. Role definitions for the public behaviour/API that DBI-using apps see.
 2. Role definitions for the behaviour/API that DBI drivers/engines must have.
 3. Class definitions that implement #1 and invoke #2.
 4. Class definitions having a generic implementation of #2 or parts 
 thereof, which a driver/engine can complete or override.
 5. Basic utility classes that exist to the side of the above, which 
 such as DBI drivers can optionally use to do some common things 
 without rolling their own.
 6. A basic test suite.

I agree entirely - except for the word basic in item 6 :)

One of the key things missing from DBI 1 was a test suite that could be
reused to test/validate different drivers.

Note that what you've described is essentially just what JDBC is.
Only JDBC has a comprehensive driver test/validate suite.

At the moment I'm thinking in terms of a Parrot-level DBDI modeled on
JDBC, with a thin Perl6-specific DBI layered on top. Other languages
targeting Parrot would have their own thin language adaption layers.

 I also recommend expelling some parts of the DBI distro into their 
 own distros and/or leaving them to third parties.  A prime example is 
 the proxy server/client stuff; that should be a separate project.

I'd like to see someone do a stateless proxy sometime (as I've
outlined previously) and I'll be ensuring there's a serializable RowSet
object available - but, yes, such things should be separate.

Tim.


Re: DBI v2 - The Plan and How You Can Help

2005-08-17 Thread Tim Bunce
On Tue, Aug 16, 2005 at 12:12:02PM -0700, Dean Arnold wrote:
 Tim Bunce wrote:
 
 And nobody mentioned JDBC as a potential model. Odd that.
 
 I was sorely tempted to do so (and did mention it a few times in
 my posts, along w/ ODBC and ADO.NET), but there are some things about
 JDBC which rub me the wrong way (e.g., explicit set/get methods for every
 data type no true binding support; the lame bulk interface; etc.).
 I'm not crazy about all the DataSource business, either.

I think all those are fixable for Perl/Parrot. Same for the painful
need for try  catch every few lines.

 But the threading support, the Factory pattern presented by Statement
 classes, the nice separation of metadata from
 statements/resultsets/connections, and XA would certainly be nice
 models to follow.

That's what I'm thinking. Not only nice but also well proven and widely
understood.

 One area of concern I have is the ability to subclass. I've been
 struggling w/ trying to subclass+extend JDBC the same way I subclass
 DBI for some things, and haven't found any app-neutral solutions just
 yet (trying to wrap another JDBC driver and expose its driver specific
 methods seems to require a lot of extra heavy lifting).

There are lots of people who have problems or complaints about
subclassing the DBI :)

Tim.


Re: DBI v2 - The Plan and How You Can Help

2005-08-17 Thread John Siracusa
On 8/17/05 5:39 AM, Tim Bunce wrote:
 On Tue, Aug 16, 2005 at 03:58:54PM -0400, John Siracusa wrote:
 I think it'll take years, and much actual production experience building
 Perl 6 modules before the community learns what works and what doesn't for a
 Perl 6 API (let alone implementation).  So trying to pin down a properly
 Perl-6-ish API before Perl 6 is even through the language design process
 strikes me as a Very Bad Idea.
 
 I remember the early years of Perl 5 development, when a new feature was
 added there'd be a period of over-zealous use followed by a hangover as
 all the problems and edge-cases became apparent.

Early years?  Just look at inside-out objects or MI with NEXT today!  Maybe
it never ends...for some people, anyway ;)

 With Perl 6 there's going to be some almighty hangovers :)

Understatement of the week :)

 Anyway, it maybe worthwhile to have a DBI 1.99 first, and then maybe a 1.999
 after that.  Basically, get one or two willing DBD authors who will help you
 to test and then throw away the first two attempts at a Perl 6 DBI API.
 Then at least you'll have some confidence when you commit to a DBI 2.0
 API...which will be several years after Perl 6 is released, I hope.
 
 It'll be DBI 2 as DBI 1 still has a very long life ahead of it, but
 it'll be DBI 2.0.00xxx for quite a while :)

I just meant that there should be several, possibly very different, attempts
at DBI2 before the real DBI2 API is pinned down.  Making the experiments
have a 1.99x version helps to prevent people from thinking this is DBI2!
when it's really just the first or second prototype.

As for the actual 1.x DBI reaching 1.99, well, all I can say is to start
using that hundredths place! :)

-John




Re: DBI v2 - The Plan and How You Can Help

2005-08-16 Thread Tim Bunce
On Sat, Jul 09, 2005 at 10:25:32PM +1000, Adam Kennedy wrote:
 In particular, the DBI must not mandate impossible levels of support from 
 the drivers. It will benefit you nothing if the DBI is immaculate and 
 wonderful and incredibly all-singing and all-dancing, but no-one can write 
 a driver for it because the requirements cannot be met by the actual DBMS 
 that Perl + DBI needs to work with.
 
 I concur. Like CPAN as a whole, DBI's strength is in it's complete and 
 near universal coverage of all databases, and insanely great (and 
 occasisionally greatly insane) drivers that do strange and wonderful things.
 
 If we start sacrificing drivers by raising the bar too high, DBI as a 
 whole suffers. Anyone proposing new features for DBI needs to be 
 extremely careful of CYJ syndrome.
 
 Can't You Just (or sometimes Could You Just) syndrome is described here.
 
 http://c2.com/cgi/wiki?CouldYouJust
 http://www.oreillynet.com/pub/wlg/3593
 http://c2.com/cgi/wiki?JustIsaDangerousWord
 
 Go read them now. I'll wait...

That's a significant part of what happened to perl5-porters in The Bad Years.

Many more talkers than doers and much use of we could do ... when
the doing would clearly have to be done by someone else.

 I have an increasing suspicion that having open design processes like 
 the Tim's call for comments plays a big part in it as well.

Did I ever say we'd have an open design process?  :-)

I just called for suggestions, proposals, and random thoughts.
It's my job to mix those in with my own random thoughts and
try to distill something reasonably coherent and Practical.

Then we'll go round the loop a few (dozen) times kicking the tires
and mixing metaphors till enough people are happy enough.
(I get the casting vote on behalf of the silent majority :)

I was a little dissapointed that there wasn't greater focus on using
Perl6 features - especially as it would have helped kick-start my own
understanding of Perl6 topics that I expect to be significant (such as
Roles and Pairs, to pick two at random). Perhaps the community of
Perl6+DBI users is too small at this point.

And nobody mentioned JDBC as a potential model. Odd that.

Still, I'm sure things will liven up once I've put an initial sketch
together...

Tim.


Re: DBI v2 - The Plan and How You Can Help

2005-08-16 Thread John Siracusa
On 8/16/05, Tim Bunce [EMAIL PROTECTED] wrote:
 I was a little dissapointed that there wasn't greater focus on using
 Perl6 features - especially as it would have helped kick-start my own
 understanding of Perl6 topics that I expect to be significant (such as
 Roles and Pairs, to pick two at random). Perhaps the community of
 Perl6+DBI users is too small at this point.

I'm afraid that DBI2 for Perl 6 will fall into the trap that I sometimes
feel like DBI1 fell into: the curse of being designed before the idioms and
Best Practices of API design in the language have been established.

I think it'll take years, and much actual production experience building
Perl 6 modules before the community learns what works and what doesn't for a
Perl 6 API (let alone implementation).  So trying to pin down a properly
Perl-6-ish API before Perl 6 is even through the language design process
strikes me as a Very Bad Idea.

That could explain why there were so few Perl 6 related suggestions: no one
knows how to design a good Perl 6 API yet, and any guess is very likely to
be wrong.  Instead, suggestions have focused on what we do know: DBI in Perl
5 and Perl 5 API design.  In that spirit, here's my suggestion: no more
configuration through magic/tied hashes. (e.g., $dbh-{'AutoCommit'} = 1)
(Probably goes without saying, but I wanted to make sure someone said it ;)

Anyway, it maybe worthwhile to have a DBI 1.99 first, and then maybe a 1.999
after that.  Basically, get one or two willing DBD authors who will help you
to test and then throw away the first two attempts at a Perl 6 DBI API.
Then at least you'll have some confidence when you commit to a DBI 2.0
API...which will be several years after Perl 6 is released, I hope.

Of course, *someone* has to go first so we can all learn what works best
in Perl 6.  I'm just saying that maybe DBI, which took the bullet in Perl 5
to some degree, is under no obligation to do so again.  (This assumes that
we'll have some way to use Perl 5 DBI within Perl 6 to tide us over, of
course...) 

-John




Re: DBI v2 - The Plan and How You Can Help

2005-08-16 Thread Darren Duncan

At 4:04 PM +0100 8/16/05, Tim Bunce wrote:

I was a little dissapointed that there wasn't greater focus on using
Perl6 features - especially as it would have helped kick-start my own
understanding of Perl6 topics that I expect to be significant (such as
Roles and Pairs, to pick two at random). Perhaps the community of
Perl6+DBI users is too small at this point.


One way that the Perl 6 thought process can be started is in 
considering the design principles laid out in Damian's new Best 
Practices book.  I said to Damian at OSCON that I thought the 
practices he was putting forward were intended to get people thinking 
now in Perl 5 about ways of doing things that will be the natural way 
of doing them in Perl 6; he said something along the lines that I had 
good insight.  So these practices are probably some good things to 
keep in mind as we move forward.


Now, speaking specifically in Perl 6 terms ...

I suggest that DBI v2 has a more formal separation between interface 
and implementation.  The parts of DBI can be grouped into these 
categories:


1. Role definitions for the public behaviour/API that DBI-using apps see.

2. Role definitions for the behaviour/API that DBI drivers/engines must have.

3. Class definitions that implement #1 and invoke #2.

4. Class definitions having a generic implementation of #2 or parts 
thereof, which a driver/engine can complete or override.


5. Basic utility classes that exist to the side of the above, which 
such as DBI drivers can optionally use to do some common things 
without rolling their own.


6. A basic test suite.

I also recommend expelling some parts of the DBI distro into their 
own distros and/or leaving them to third parties.  A prime example is 
the proxy server/client stuff; that should be a separate project.


-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-08-16 Thread Dean Arnold

Tim Bunce wrote:



And nobody mentioned JDBC as a potential model. Odd that.



I was sorely tempted to do so (and did mention it a few times in
my posts, along w/ ODBC and ADO.NET), but there are some things about
JDBC which rub me the wrong way (e.g., explicit set/get methods for every
data type; no true binding support; the lame bulk interface; etc.).
I'm not crazy about all the DataSource business, either.

But the threading support, the Factory pattern presented by Statement classes,
the nice separation of metadata from statements/resultsets/connections, and XA
would certainly be nice models to follow.

One area of concern I have is the ability to subclass. I've been struggling
w/ trying to subclass+extend JDBC the same way I subclass DBI for some things,
and haven't found any app-neutral solutions just yet (trying to wrap
another JDBC driver and expose its driver specific methods seems to require
a lot of extra heavy lifting).


Still, I'm sure things will liven up once I've put an initial sketch
together...

Tim.



Dean Arnold
Presicient Corp.


Re: DBI v2 - The Plan and How You Can Help

2005-07-21 Thread Tim Bunce
On Thu, Jul 07, 2005 at 08:32:47AM -0500, Jones Robert TTMS Contractor wrote:
 
  When I go to the donation page and attempt to make a donation, the
 drop-down box does not give DBI as a valid recipient.  Is it possible
 several people may not have donated as they noticed the same results, or
 maybe they did and it all went into the Perl Development Fund instead?

The Perl Foundation default donation page doesn't list the DBI
Development Fund (for various reasons). To get that option you can use
http://dbi.perl.org/donate/ which will redirect you[1]

Thank you.

Tim.

[1] 
https://donate.perlfoundation.org/index.pl?node=Contribution%20Infoselfund=102

 
 
  -Original Message-
  From: Tim Bunce [mailto:[EMAIL PROTECTED] 
  Sent: Friday, July 01, 2005 7:06 PM
  To: perl6-language@perl.org; dbi-users@perl.org
  Subject: DBI v2 - The Plan and How You Can Help
  
  
  Once upon a time I said:
  

  http://groups-beta.google.com/group/perl.dbi.users/msg/caf189d7b404a003?dmode=sourcehl=en
  
  and wrote
  
http://search.cpan.org/~timb/DBI/Roadmap.pod
  
  which yielded:
  

  https://donate.perlfoundation.org/index.pl?node=Fund+Drive+Det
  ailsselfund=102
  
  (A little over $500 of that I effectively put in myself.)
  
  My *sincere* thanks to all those who donated to the fund, especially
  individuals. I had hoped for more corporate response with less from
  individuals and I'm touched by the personal generosity shown.
  
  I've not drawn any money from it yet and doubt that I will myself.
  (I'm considering suggesting that the Perl Foundation make payments
  from the fund to people making specific contributions to the DBI.
  I'm thinking especially of work on a comprehensive test harness.
  But I'll see how the developments below pan out before making
  specific arrangements.)
  
  
  So, that lead to:
  

  http://groups-beta.google.com/group/perl.dbi.dev/browse_frm/th
  read/ef14a9fc0a37441f/fb8fe20a86723da0#fb8fe20a86723da0
  
  Which sums up fairly well where I'm at: DBI v1 will rumble on 
  for Perl 5
  and DBI v2 will be implemented for Perl 6.
  
  
  --- digression ---
  
  At this point I'd like to make a slight digression to highlight the
  amazing work going on in the Perl 6 community at the moment.
  Especially Autrijus' Pugs project which has brought Perl 6 to life.
  Literally. Take a look at:
  
  http://pugscode.org/talks/yapc/slide1.html
  http://use.perl.org/~autrijus/journal
  
  and especially:
  
  http://use.perl.org/~autrijus/journal/24898
  
  Yes, that really is Perl 6 code using the DBI being executed by Pugs.
  
  That's great, and I was truly delighted to see it because it takes the
  pressure off the need to get a DBI working for Perl 6 - because it
  already is working for Perl 6. At least for Pugs. (The Ponie project
  is also likely to provide access to Perl 5 DBI from Perl 6 by enabling
  future versions of Perl 5 to run on Parrot.)
  
  --- digression ---
  
  
  I have recently come to an arrangement that will enable me to put some
  worthwhile development time into DBI (still very much part-time, but
  enough to give it focus and move forward).
  
  My initial goals are:
  
   1. to work on a more detailed specification for the DBI v2 API that
  takes advantage of appropriate features of Perl 6.
  
   2. to work on a more detailed specification for the DBDI API
  
  http://groups-beta.google.com/group/perl.perl6.internals/msg/c
  fcbd9ca7ee6ab4
  
   3. to work on tools to automate building Parrot NCI interfaces to
  libraries (such as database client libraries, obviously :)
  
  
  But I'm hoping you'll join in and help out.
  
  I've kept an eye on Perl 6 and Parrot developments but I'm no 
  expert in
  either. What I'd like *you* to do is make proposals (ideally fairly
  detailed proposals, but vague ideas are okay) for what a Perl 
  6 DBI API
  should look like.
  
  Keep in mind that the role of the DBI is to provide a consistent
  interface to databases at a fairly low level. To provide a 
  *foundation*
  upon which higher level interfaces (such as Class::DBI, 
  Tangram, Alzabo
  etc. in Perl 5) can be built.
  
  So, if you have an interest in the DBI and Perl 6, put your thinking
  cap on, kick back and dream a little dream of how the DBI could be.
  How to make best use of the new features in Perl 6 to make 
  life easier.
  
  Then jot down the details and email them to me (or to 
  dbi-users@perl.org
  if you want to kick them around in public for a while first).
  
  I'm about to fly off for two weeks vacation (in a few hours), 
  blissfully
  absent of any hi-tech gear beyond a mobile phone. When I get back I'll
  gather up your emails and try to distill them into a coherent whole.
  
  Have fun!
  
  Tim.
  


Re: DBI v2 - The Plan and How You Can Help

2005-07-19 Thread Kiran Kumar
We could have an option to do Bulk Inserts  ..


Re: DBI v2 - The Plan and How You Can Help

2005-07-14 Thread Jochen Wiedmann
On 7/14/05, Sam Vilain [EMAIL PROTECTED] wrote:

 Of course it will be entirely possible to layer support for this sort of
 thing atop any DBI interface;

Exactly my point. Please be so kind as to implement your ideas in a
DBI extension. Time and community will prove whether you are right by
using your extension or not.

Fact is, that there are quite some drivers which will never be able to
adhere to your wishes. Blocking them implementing a DBI2 driver seems
(to me) to be a larger problem, compared with the need of using a DBI2
subclass and not DBI2 directly.


Jochen


-- 
What are the first steps on the moon, compared to your child's?


RE: DBI v2 - The Plan and How You Can Help

2005-07-13 Thread Reidy, Ron
Sorry, instead of implicit 'commit', I mean to say implicit conversion.

-
Ron Reidy
Lead DBA
Array BioPharma, Inc.


-Original Message-
From: Reidy, Ron 
Sent: Wednesday, July 13, 2005 9:06 AM
To: Sam Vilain; Dean Arnold
Cc: dbi-users@perl.org; dbi-dev@perl.org; perl6-language@perl.org
Subject: RE: DBI v2 - The Plan and How You Can Help


-Original Message-
From: Sam Vilain [mailto:[EMAIL PROTECTED]
Sent: Tuesday, July 12, 2005 5:04 PM
To: Dean Arnold
Cc: dbi-users@perl.org; dbi-dev@perl.org; perl6-language@perl.org
Subject: Re: DBI v2 - The Plan and How You Can Help


Dean Arnold wrote:
 RE: LOBs and SQL Parse Trees: having recently implemented
 LOB support for a JDBC driver (and soon for a DBD), I can assure
 you that SQL parse trees are unneeded to support them. For databases

 or this;

SELECT
   *
FROM
   FOO
WHERE
   SOME_DATE_COLUMN  ?

 SOME_DATE_COLUMN is the database native date type.  On Oracle you'll
 need to convert the ? to a 'TO_DATE(?)'.

No you do not.  The SQL engine will perform an implicit commit of the data.

-
Ron Reidy
Lead DBA
Array BioPharma, Inc.

 Sam.

This electronic message transmission is a PRIVATE communication which contains
information which may be confidential or privileged. The information is 
intended 
to be for the use of the individual or entity named above. If you are not the 
intended recipient, please be aware that any disclosure, copying, distribution 
or use of the contents of this information is prohibited. Please notify the
sender  of the delivery error by replying to this message, or notify us by
telephone (877-633-2436, ext. 0), and then delete it from your system.


This electronic message transmission is a PRIVATE communication which contains
information which may be confidential or privileged. The information is 
intended 
to be for the use of the individual or entity named above. If you are not the 
intended recipient, please be aware that any disclosure, copying, distribution 
or use of the contents of this information is prohibited. Please notify the
sender  of the delivery error by replying to this message, or notify us by
telephone (877-633-2436, ext. 0), and then delete it from your system.



RE: DBI v2 - The Plan and How You Can Help

2005-07-13 Thread Reidy, Ron
-Original Message-
From: Sam Vilain [mailto:[EMAIL PROTECTED]
Sent: Tuesday, July 12, 2005 5:04 PM
To: Dean Arnold
Cc: dbi-users@perl.org; dbi-dev@perl.org; perl6-language@perl.org
Subject: Re: DBI v2 - The Plan and How You Can Help


Dean Arnold wrote:
 RE: LOBs and SQL Parse Trees: having recently implemented
 LOB support for a JDBC driver (and soon for a DBD), I can assure
 you that SQL parse trees are unneeded to support them. For databases

 or this;

SELECT
   *
FROM
   FOO
WHERE
   SOME_DATE_COLUMN  ?

 SOME_DATE_COLUMN is the database native date type.  On Oracle you'll
 need to convert the ? to a 'TO_DATE(?)'.

No you do not.  The SQL engine will perform an implicit commit of the data.

-
Ron Reidy
Lead DBA
Array BioPharma, Inc.

 Sam.

This electronic message transmission is a PRIVATE communication which contains
information which may be confidential or privileged. The information is 
intended 
to be for the use of the individual or entity named above. If you are not the 
intended recipient, please be aware that any disclosure, copying, distribution 
or use of the contents of this information is prohibited. Please notify the
sender  of the delivery error by replying to this message, or notify us by
telephone (877-633-2436, ext. 0), and then delete it from your system.



Re: DBI v2 - The Plan and How You Can Help

2005-07-13 Thread Sam Vilain

Dean Arnold wrote:

Column 3 is a BYTEA column in Pg and needs special peppering to work.

What sort of peppering ? DBI provides SQL_BLOB, and SQL_CLOB
type descriptors (as well as SQL_BLOB_LOCATOR and SQL_CLOB_LOCATOR), so
presumably DBD::Pg (or any other DBD supporting LOBs) provides the
logic to map from
$sth-bind_param(3, $somelob, SQL_CLOB);

 SOME_DATE_COLUMN is the database native date type. On Oracle you'll
 need to convert the ? to a 'TO_DATE(?)'.
 Er, why ? I haven't used DBD::Oracle lately, but assuming you
 $sth-bind_param(1, '2005-07-13', SQL_DATE),
 I'd assume DBD::Oracle would be smart enough to communicate that

That bind_param peppering is precisely what I'm talking about, thanks
for demonstrating my point.  This requirement to use bind_param to
explicitly tell the DBI which placeholders correspond to which types
is rarely mentioned on any introductions to DBI, and as a result, very
few people carry this out in practice or are prepared to do the
necessary re-work to code bases to perform it.

So, DBD drivers need to hope that the database driver is smart enough to
pull apart the query, match it against the schema and automatically
setup the type correctly.  Perhaps many C database access libraries
provide enough information to do this, and pardon my ignorance for never
having written or worked on a DBD to this level - but I'm guessing that
such query introspection isn't always possible.

And, in a sense, requiring that the DBD is able to introspect the query
and DTRT is an extra restriction that DBD authors need to conform to,
setting the bar for conformance so high that it is practically impossible
to write portable database access code.

Please note that I'm not suggesting that we do away with the existing
interface, for people who don't care about writing portable database
code.  But I'd like to be able to write, for instance;

  use v6;
  use DBI-2;

  my $query = SQL {
  SELECT
  *
  FROM
  FOO
  LEFT JOIN BAR
  ON BAR.FOOID = FOO.ID
  };

  if ($one) {
  $query = SQL::WhereClause {
  ONE = $one
  };
  }

  my $dbh = DBI.connect(:source(myapp));
  my $sth = $dbh.prepare($query);
  my $resultset = $sth.execute();

  for =$resultset - @row {
 ...
  }

So what's happening here?

Well, the SQL construct marks the beginning of a segment of code that
happens to be in an alternate grammar, corresponding to some level of
ANSI SQL.  This builds an object which corresponds to that query.  In
fact, this can happen at compile time!  The SQL { } is actually a
closure that returns a SQL object when it is called.

The later SQL::WhereClause is the same; the variable isn't merely
interpolated, but is closed over, and included as if it were a
placeholder.  The = assignment operator uses the overloaded 
operator on the SQL object, which sees it is being given a query
fragment, and adds it into the appropriate point on the SQL AST.

This should all be quite transparent - of course, an optional (but
portable) method of writing database queries.  And it's all deliciously
Perlish, yielding less fussing around with buggy code stitching together
queries, and more clean expression of queries using a standard language.

Of course it will be entirely possible to layer support for this sort of
thing atop any DBI interface; but this *is* a version 2, we do have
prototypes for the mechanics of all this stuff - and Done Rightâ„¢, it
could actually fulfil the goal of DBI - being able to write
Database-driven applications that are truly independant of the database
product in use.  DBI v1 cuts the porting time down to next to nothing;
but we can get it even closer!

Sorry to bang on about this for so long, I'm sure you're all getting
sick of it by now- I had hoped that the original suggestion was just
going to be acknowledged as a valid way to enhance portability and
flexibility and considered without too much rehashing of what to some
is an old topic.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-12 Thread Dean Arnold

RE: Placeholders: since DBIv1 already supports both forms of
PH's, I see no reason to deprecate or abandon either form.
Furthermore, to my knowledge, none of (ODBC, JDBC, ADO.NET)
has abandonded or deprecated the ? form, so I don't see
the need for DBI to.

RE: LOBs and SQL Parse Trees: having recently implemented
LOB support for a JDBC driver (and soon for a DBD), I can assure
you that SQL parse trees are unneeded to support them. For databases
robust enough to support LOBs, they'll almost always provide
sufficient metadata info and/or SQL syntax to manipulate them;
only databases which don't support LOBs have that difficulty.
Furthermore, a quick review of the current DBI will indicate that
Mssr. Bunce has already implemented some stub methods for
generalized support.

RE: SQL Parse Trees (or other non-SQL query input)

Since none of (ODBC, JDBC, ADO.NET) seems compelled to
impose this concept on driver writers, I don't see why
DBI should be the vanguard.

However, implementing a subclass of DBI to support it
seems technically feasible, so I'd suggest that
those of you championing this requirement implement one
on DBI v1. Feel free to use DBIx::Chart to bootstrap
your project. As the proponents of this notion
are so generous with their requirements for those of us
who develop DBI drivers and/or contribute
development efforts to the DBI itself, I'm sure they won't
object if I provide a few requirements:

1. For DBI drivers which support them, your subclass
must support
- arbitrary numbers and levels of JOINs (including
various outer, and non-equijoins)
- arbitrarily nested subqueries (including correlated)
- HAVING and GROUP BY clauses
- ORDER and LIMIT clauses
- updatable cursors
- database-specific SQL extensions

2. It must function with current versions of 40% of DBD's
created or updated on CPAN since Jan. 1, 2003. Said 40%
must include
- DBD::ODBC
- DBD::Oracle
- DBD::Pg
- DBD::MySQL
- DBD::CSV
- one 'exotic' driver (e.g.,
DBD::iPod or DBD::Amazon, but excluding DBD::Google,
whose syntax is too simplistic for a meaningful test)

(FWIW: Past experience (e.g., execute_array()) leads me to believe
Mssr. Bunce's requirements are likely much higher than 40%, so
choose wisely, grasshopper)

BTW: If you need a list of DBD's meeting said requirement, let me know,
I just pulled one down.

3. It cannot require any changes to either DBI or the
selected DBD's.

4. It must produce a database-independent conforming set of error codes
(feel free to use SQLSTATE aka $h-state)

5. It must be uploaded to CPAN, and list, and demonstrably function against,
the DBD's selected in requirement (2) above.

Once you've implemented the subclass, you'll have empirical proof
of the feasibility, and, more importantly, you'll be able to port
the subclass to DBIv2, without any additional burden on DBI
developers.

Regards,
Dean Arnold
Presicient Corp.



Re: DBI v2 - The Plan and How You Can Help

2005-07-12 Thread Dean Arnold

BTW: If you need a list of DBD's meeting said requirement, let me know,
I just pulled one down.



Sure, send it over.


[   ] DBD-ADO-2.94.tar.gz 31-Jan-2005 02:4041k  GZIP compressed docume
[   ] DBD-ASAny-1.13.tar.gz   31-Oct-2003 15:0030k  GZIP compressed docume
[   ] DBD-Amazon-0.10.tar.gz  23-May-2005 15:4158k  GZIP compressed docume
[   ] DBD-AnyData-0.08.tar.gz 19-Apr-2004 03:1620k  GZIP compressed docume
[   ] DBD-CSV-0.22.tar.gz 31-Mar-2005 18:0636k  GZIP compressed docume
[   ] DBD-Chart-0.81.tar.gz   26-Jan-2005 19:59   212k  GZIP compressed docume
[   ] DBD-DB2-0.78.tar.gz 19-Sep-2004 10:3475k  GZIP compressed docume
[   ] DBD-File-0.34.tar.gz21-Jun-2005 01:14 8k  GZIP compressed docume
[   ] DBD-Google-0.11.tar.gz  04-Mar-2004 18:5120k  GZIP compressed docume
[   ] DBD-Informix-2005.01.. 14-Mar-2005 19:01   267k  GZIP compressed docume
[   ] DBD-Ingres-0.51.tar.gz  12-Jan-2004 06:1846k  GZIP compressed docume
[   ] DBD-InterBase-0.43.t.. 25-Feb-2004 04:3078k  GZIP compressed docume
[   ] DBD-LDAP-0.06.tar.gz12-Mar-2004 21:4825k  GZIP compressed docume
[   ] DBD-Log-0.22.tar.gz 27-May-2005 06:5114k  GZIP compressed docume
[   ] DBD-MaxDB-7_5_00_26... 18-Apr-2005 08:3879k  GZIP compressed docume
[   ] DBD-Mimer-1.00.tar.gz   25-Nov-2003 15:5171k  GZIP compressed docume
[   ] DBD-Mock-0.27.tar.gz11-Jul-2005 11:3634k  GZIP compressed docume
[   ] DBD-Multiplex-1.96.t.. 25-Jan-2005 17:30 9k  GZIP compressed docume
[   ] DBD-ODBC-1.13.tar.gz08-Nov-2004 10:1595k  GZIP compressed docume
[   ] DBD-Oracle-1.16.tar.gz  22-Oct-2004 05:17   230k  GZIP compressed docume
[   ] DBD-Pg-1.43.tar.gz  23-Jun-2005 08:09   128k  GZIP compressed docume
[   ] DBD-PgPP-0.05.readme09-May-2004 08:06 3k
[   ] DBD-PgPP-0.05.tar.gz13-May-2004 12:5616k  GZIP compressed docume
[   ] DBD-PgSPI-0.02.tar.gz   06-Dec-2004 00:3021k  GZIP compressed docume
[   ] DBD-Redbase-0.22.tar.gz 21-Oct-2003 22:5128k  GZIP compressed docume
[   ] DBD-SQLite-1.09.tar.gz  20-Jun-2005 11:42   464k  GZIP compressed docume
[   ] DBD-SQLite2-0.33.tar.gz 10-Sep-2004 11:50   355k  GZIP compressed docume
[   ] DBD-Sprite-0.56.tar.gz  12-Jun-2005 21:5286k  GZIP compressed docume
[   ] DBD-Sybase-1.05.tar.gz  19-Dec-2004 05:01   183k  GZIP compressed docume
[   ] DBD-TSM-0.04.readme 22-Mar-2005 16:05 2k
[   ] DBD-TSM-0.04.tar.gz 23-Jun-2005 16:32 9k  GZIP compressed docume
[   ] DBD-Teradata-1.20.ta.. 17-Sep-2004 19:2736k  GZIP compressed docume
[   ] DBD-Trini-0.01.tar.gz   15-Jul-2003 03:1821k  GZIP compressed docume
[   ] DBD-Unify-0.31.tgz  16-Mar-2004 11:0731k  GZIP compressed tar ar
[   ] DBD-XBase-0.241.tar.gz  21-Nov-2003 09:25   109k  GZIP compressed docume
[   ] DBD-Yaswi-0.01.tar.gz   21-Feb-2005 19:46 4k  GZIP compressed docume
[   ] DBD-iPod-0.01.tar.gz06-Jan-2005 02:4113k  GZIP compressed docume
[   ] DBD-mysql-3.0002.tar.gz 11-Jul-2005 12:49   127k  GZIP compressed docume
[   ] DBD-mysql-AutoTypes-.. 02-Mar-2004 06:03 3k  GZIP compressed docume
[   ] DBD-mysql-SimpleMySQ.. 28-Apr-2004 16:39 4k  GZIP compressed docume
[   ] DBD-mysqlPP-0.04.tar.gz 24-Jan-2003 06:14 7k  GZIP compressed docume

- Dean


Re: DBI v2 - The Plan and How You Can Help

2005-07-12 Thread Sam Vilain

Dean Arnold wrote:

RE: LOBs and SQL Parse Trees: having recently implemented
LOB support for a JDBC driver (and soon for a DBD), I can assure
you that SQL parse trees are unneeded to support them. For databases


Great!

Perhaps you can shed some light on how to do it for this, then.

SQL command;

  INSERT INTO FOO (?, ?, ?, ?);

Column 3 is a BYTEA column in Pg and needs special peppering to work.

or this;

  SELECT
 *
  FROM
 FOO
  WHERE
 SOME_DATE_COLUMN  ?

SOME_DATE_COLUMN is the database native date type.  On Oracle you'll
need to convert the ? to a 'TO_DATE(?)'.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Darren Duncan

I have an additional reply to the following ...

At 10:25 PM +1000 7/9/05, Adam Kennedy wrote:
In any case, I still propose that DBI2 split the driver interface 
into Roles. The main DBI2::Role::Transport role does ONLY what DBI 
does best now. That is, connecting to the database, preparing and 
sending queries, and fetching the results.


Forget the current -tables interface. Drivers can OPTIONALLY 
implement the DBI2::Role::Schema interface to handle interrogation 
of the database schema. The current way we handle it is really messy 
by my standards, and could use a dedicated interface.


As you invent major new features for DBI2, implement them roles. 
DBI2::Role::Transational, DBI2::Role::RFC90210 (the super flashy 
Beverly Hills feature), etc etc.


Exactly what these roles should be I don't want to state with any 
certainty. That's the sort of thing that Tim, with his complete 
understanding of the issues, should be doing on his own.


One of the reasons I like this idea is that it lets DBI define 
multiple Roles that may be mutually exclusive and accomplish the same 
task in different ways.


For example, the idea of whether the interface will accept SQL AST 
objects in addition to or instead of SQL strings.  The standard 
DBI2::Role::Transport will take SQL strings and only SQL strings, as 
the current DBI does.  There can be an additional Role for each AST.


In that situation, there are several case scenarios depending on the 
type of database being used and what the driver maker is willing to 
support.


1. The first case is the common database server that always takes its 
input as string SQL.  In this case, the standard string-taking Role 
will be the most native fit for it, and any AST-supporting Roles 
would have to be, in some fashion, implemented as wrappers on top of 
this, converting their contents to string SQL for the database.


It is assumed that the AST in question would come with its own set of 
SQL generators, either in the same distribution or a separate 
distribution that is an extension to it.  If the DBI driver writer 
chooses to implement the relevant AST-taking Role, it would 
presumably use the AST's own SQL generator to implement that support, 
so the driver writer hardly has any work to do of their own.  Or, if 
the DBI driver writer does not choose to implement the Role, then 
users of said AST would use it as or with a DBI wrapper that invokes 
the SQL generating functionality itself and passes the result to 
DBI2::Role::Transport.


2. The second case is a usually-embedded database server or library 
that does not take string SQL as its native input.  In this case, 
some sort of AST-supporting Role would be the most native fit for it, 
since it is probably easier for that DBI driver to extract the 
information it needs from the AST than to parse string SQL; the 
DBI2::Role::Transport Role would have to be, in some fashion, 
implemented as a wrapper on top of this, which parses string SQL into 
an AST.  Most likely, an externally destributed SQL parser would be 
the best choice, so it can be improved independently of the driver, 
as with any SQL generators.  (SQL::Statement is an example of this 
already being done.)


Now, if support for a string-SQL interface is mandatory for all DBI 
drivers, then it is possible that all AST-taking Roles can be 
implemented on top of the string-taking Role.  As is the case with 
DBI v1.  But, for the sake of those drivers that want ASTs 
internally, having a way for them to get that input natively, through 
officially sanctioned appropriate Roles, that lets those drivers save 
themselves a lot of work and the system is potentially much faster 
and easier to improve, without sacrificing compatability.


A separate advantage of this Roles thing is backwards compatability 
due to a multi-versioned API.  If we wish to implement a significant 
API or implementation change in DBI after DBI 2 is launched, we can 
be free to do so without breaking older programs because they will by 
definition be writing against a specific API version.  We just have 
to maintain a Role for each distinct version that maps what the 
application expects to how things work in the background.


I liken this to a new feature in Mac OS X starting with 10.4 Tiger; 
versioned KPIs (kernal programming interfaces); from now on, it is a 
lot easier for Apple to release significantly changed kernals in 
newer Mac OS X versions without breaking any applications or drivers, 
because those specify a versioned API which continues to exist as a 
wrapper.  See http://arstechnica.com/reviews/os/macosx-10.4.ars/4 for 
what I'm talking about.


However it's done, I'm thinking something akin to that would be good for DBI.

-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Jared Still

 driver://user:[EMAIL PROTECTED]:port/instance
 

I haven't been following this too closely, so my apologies
if already mentioned.

This connect string is very much like the new Easy Connect
Naming method in Oracle 10g.

eg.  sqlplus scott/[EMAIL PROTECTED]:port/service

Note that it is not 'instance', but 'service'.

Jared




Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Adam Kennedy
No - you don't seem to understand. The challenge-response protocol can ask 
someone for the RSA key fob number this time, their mother's maiden name the 
next time, their employee number the time after that, and nothing on the 
fourth occasion. You cannot predict what the extra information requested is 
going to be - so you can't provide the extra information in the initial 
connection attempt because you don't know which extra information is going 
to be needed. That's what provides the security - the unpredictability of 
the question, so that it is hard to pre-programme the answer.


Ah but you can know in advance! :) You may not know the actual result 
per instance, but you CAN know the decision process you'll need to go 
through. Which you can provide as a parameter in the form of a CODE 
reference. :) i.e. a callback


But that's a minor point and overall I completely agree with your 
general ideas.


Adam K


Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Michael Peppler
On Sat, 2005-07-09 at 12:42 +0200, Jochen Wiedmann wrote:
 Jonathan Leffler wrote:
 
  I dunno which DBMS support prepare without a database connection, but I 
  would expect all the mainstream databases to require a database connection. 
 
 +1
 
  I'm also far from convinced that there's any significant benefit in 
  separating the 'create a database handle' from the 'connect to database 
  server' part.
 
 +1
 
 
 Not to mention the effect, that one major charm of DBI is its 
 simplicity: Connect, Execute for updates, inserts, or deletes and
 Connect, Execute, Fetch for select. I can't see an advantage in overly 
 extending the interface.

Personally I tend to agree with you. I haven't read the whole thread,
but I'm not yet convinced that the DBI needs to change that much.
Certainly the Sybase driver won't be able to support many of the
proposed functionality, or won't benefit from the changes (i.e. no speed
gain, no improved flexibility, etc).

Michael
-- 
Michael Peppler  -  [EMAIL PROTECTED]  -  http://www.peppler.org/
Sybase DBA/Developer
Sybase on Linux FAQ: http://www.peppler.org/FAQ/linux.html




Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Darren Duncan

At 6:30 PM -0700 7/11/05, Dean Arnold wrote:

RE: SQL Parse Trees (or other non-SQL query input)
Since none of (ODBC, JDBC, ADO.NET) seems compelled to
impose this concept on driver writers, I don't see why
DBI should be the vanguard.


I should emphasize that I never expected to be able to send any type 
of ASTs over the pipe to the database.  They would still be 
interpreted by the database driver for Perl and/or a wrapper thereon, 
into the database native format.  Its just that, to an application, 
it would appear that the ASTs were going over the pipe, as to their 
effect, even though they weren't behind the scenes.



However, implementing a subclass of DBI to support it
seems technically feasible, so I'd suggest that
those of you championing this requirement implement one
on DBI v1.


I agree.  Already in progress.  In a week or two I should announce 
Rosetta/SQL::Routine Developer Preview #3 and look forward to 
people trying it out and giving me the usual how do I questions. 
But wait until then before making any in-depth analysis, since I have 
some large updates to post first.



As the proponents of this notion
are so generous with their requirements for those of us
who develop DBI drivers and/or contribute
development efforts to the DBI itself, I'm sure they won't
object if I provide a few requirements:


I agree.


1. For DBI drivers which support them, your subclass
must support
- arbitrary numbers and levels of JOINs (including
various outer, and non-equijoins)
- arbitrarily nested subqueries (including correlated)
- HAVING and GROUP BY clauses
- ORDER and LIMIT clauses
- updatable cursors
- database-specific SQL extensions


Rosetta supports the definition of all of the above right now, except 
that the last 2 are incomplete (for now).  I still have to add the 
last mile, which is joining the definition to the implementation, 
though that is what DR3 is for.  See the top of 
SQL::Routine::Language for a summary of what I claim to support.



2. It must function with current versions of 40% of DBD's
created or updated on CPAN since Jan. 1, 2003. Said 40%
must include
- DBD::ODBC
- DBD::Oracle
- DBD::Pg
- DBD::MySQL
- DBD::CSV
- one 'exotic' driver (e.g.,
DBD::iPod or DBD::Amazon, but excluding DBD::Google,
whose syntax is too simplistic for a meaningful test)


My expectation is to support all DBDs that are themselves known to 
work under the newest Perls and DBIs.  Databases that already support 
a feature when it is invoked as a SQL string will be supported for 
that feature by Rosetta prior to those that don't and for which the 
features need to be emulated.



BTW: If you need a list of DBD's meeting said requirement, let me know,
I just pulled one down.


Sure, send it over.


3. It cannot require any changes to either DBI or the
selected DBD's.


Yes.


4. It must produce a database-independent conforming set of error codes
(feel free to use SQLSTATE aka $h-state)


Already done, though the current list of codes is short and pending updates.


5. It must be uploaded to CPAN, and list, and demonstrably function against,
the DBD's selected in requirement (2) above.


I can only personally test against databases that are easy to install 
on Mac OS X 10.3.9 and are free-as-in-beer (eg, SQLite, MySQL); for 
others, I will need assistence to prove that they work.



Once you've implemented the subclass, you'll have empirical proof
of the feasibility, and, more importantly, you'll be able to port
the subclass to DBIv2, without any additional burden on DBI
developers.


I accept your challenge.

-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Sam Vilain

Darren Duncan wrote:
I should emphasize that I never expected to be able to send any type of 
ASTs over the pipe to the database.  They would still be interpreted by 
the database driver for Perl and/or a wrapper thereon, into the database 
native format.  Its just that, to an application, it would appear that 
the ASTs were going over the pipe, as to their effect, even though they 
weren't behind the scenes.


Indeed.  I think the principle bug to fix is getting away from this
notion that all you need to do is do a little bit of template-based
query building, use the DBI and magically expect all database portability
problems to go away.

And then, recommend an approach that *is* portable.  Take your excellent
Rosetta infrastructure, pull the API to pieces, simplify the
documentation, then condone it as another simple and effective way to
write new database driven applications.  And hopefully simplify the DBDs
that necessarily need to do SQL parsing along the way.

So, everyone who is still happy to code to a particular database's SQL
language can continue to do so, but we'll eventually move the Cargo Cult
away from the situation we're in today where there is a vague promise of
portability but so many caveats that it's practically impossible to
write portable code.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Jonathan Leffler
Oh drat - not the DBI connection string discussion again!

On 7/4/05, Darren Duncan [EMAIL PROTECTED] wrote:

 5. All details used to construct a connection handle should be
 completely decomposed rather than shoved into an ungainly data
 source. Examples of what should be distinct (not all being
 applicable at once) are: 1. the DBI driver module to use; 2. the
 internet server IP address or domain name and port; 3. the locally
 defined server device socket; 4. the locally defined service (eg,
 ODBC or SQL*Net) name; 5. the file system file name; 6. the file
 system directory name; 7. some other detail if any for fully in-RAM
 databases; 8. the authorization identifier / user name; 9. the
 password; 10. some other authorization credential, or channel
 encryption details, or whatever else; 11. what kind of database or
 what database product is being used, if known. If the DBI driver
 talks to a client-configurable DBI proxy server, then, it should be
 possible to nest a set of the above settings (eg, as a hash-ref) as
 one part of the main settings given to the proxy client.
 

Only 1, 8 and 9 (driver name, user ID, password) apply to Informix databases 
- and you've missed out the other bit that applies - the database name, and 
optionally database server name hosting it (either 'dbase' or '[EMAIL 
PROTECTED]'). 
These are not the same as 2, 3, 4, 5, 6, 7, 10, or 11, and I can't think how 
any of them (except perhaps 10) could be applied to an IDS connection.

Oh, and if you're going to enhance the connection, please ensure you cover 
challenge-response protocols (where you send an initial username/password 
and the authentication server comes back with a question such as what is 
the number on your RSA key fob at the moment, and the hapless user has to 
type that information in, and the connection management code has to deal 
with this - callbacks and the like.

So, as was discussed emphatically and exhaustively (in January 2005 in 
dbi-dev under 'Proposing an API for the extension for simplifying database 
connections'), this is not readily going to fly with the existing DBMS - 
specifically, not with IDS. Closed-source DBMS are *not* necessarily going 
to adapt to meet the needs of Perl and DBI. You can argue that's their loss 
- you may even be right. But you'll be limiting the acceptability of Perl + 
DBI in some respects. You'll also be annoying the hell out of me if you 
can't define a connection string that will work with Informix (I'm not too 
worried about the challenge-response stuff, though Informix can handle 
that).

Oh - and DBI v2 should have support for scrollable cursors.

-- 
Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h
Guardian of DBD::Informix - v2005.01 - http://dbi.perl.org
I don't suffer from insanity - I enjoy every minute of it.


Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Adam Kennedy
In particular, the DBI must not mandate impossible levels of support from 
the drivers. It will benefit you nothing if the DBI is immaculate and 
wonderful and incredibly all-singing and all-dancing, but no-one can write a 
driver for it because the requirements cannot be met by the actual DBMS that 
Perl + DBI needs to work with.


I concur. Like CPAN as a whole, DBI's strength is in it's complete and 
near universal coverage of all databases, and insanely great (and 
occasisionally greatly insane) drivers that do strange and wonderful things.


If we start sacrificing drivers by raising the bar too high, DBI as a 
whole suffers. Anyone proposing new features for DBI needs to be 
extremely careful of CYJ syndrome.


Can't You Just (or sometimes Could You Just) syndrome is described here.

http://c2.com/cgi/wiki?CouldYouJust
http://www.oreillynet.com/pub/wlg/3593
http://c2.com/cgi/wiki?JustIsaDangerousWord

Go read them now. I'll wait...

This sort of behaviour can play a big part in ending up with second 
system problems.


I have an increasing suspicion that having open design processes like 
the Tim's call for comments plays a big part in it as well.


People are free to comment on things that 1) They won't have to 
implement themselves and (in some cases, but not you Duncan) 2) They 
think they know what they are talking about, but really have no idea 
what it means underneath the surface.


In any case, I still propose that DBI2 split the driver interface into 
Roles. The main DBI2::Role::Transport role does ONLY what DBI does 
best now. That is, connecting to the database, preparing and sending 
queries, and fetching the results.


Forget the current -tables interface. Drivers can OPTIONALLY implement 
the DBI2::Role::Schema interface to handle interrogation of the database 
schema. The current way we handle it is really messy by my standards, 
and could use a dedicated interface.


As you invent major new features for DBI2, implement them roles. 
DBI2::Role::Transational, DBI2::Role::RFC90210 (the super flashy Beverly 
Hills feature), etc etc.


Exactly what these roles should be I don't want to state with any 
certainty. That's the sort of thing that Tim, with his complete 
understanding of the issues, should be doing on his own.


But I _would_ certainly like to see schema/table stuff separated from 
the base connection/query functionality.


While I'm on the topic of DBI, one other feature I'd like to see would 
be something like better support for large objects or various types.


In my personal DBI wrapper I've been using plain SCALAR refs as 
parameters to signify a BLOB, so I can pass by reference without a copy 
of a potentially large memory chunk, and then having to do 
driver-specific translation to bind variables (Oracle) or what have you.


Some base way of default method defining a BLOB object (whether provided 
in memory, or pointing at a file handle to pull the data from at commit 
time) in would be really nice. Even if the way I have to pass the blobs 
to each driver differs, I'd like to be at least be able to say,


This is a DBI2::Data::BLOB object (or something functionally equivalent).

Adam K


Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Jeffrey W. Baker
On Sat, 2005-07-09 at 01:22 -0700, Jonathan Leffler wrote:
 Oh drat - not the DBI connection string discussion again!
 
 On 7/4/05, Darren Duncan [EMAIL PROTECTED] wrote:
 
  5. All details used to construct a connection handle should be
  completely decomposed rather than shoved into an ungainly data
  source. Examples of what should be distinct (not all being
  applicable at once) are: 1. the DBI driver module to use; 2. the
  internet server IP address or domain name and port; 3. the locally
  defined server device socket; 4. the locally defined service (eg,
  ODBC or SQL*Net) name; 5. the file system file name; 6. the file
  system directory name; 7. some other detail if any for fully in-RAM
  databases; 8. the authorization identifier / user name; 9. the
  password; 10. some other authorization credential, or channel
  encryption details, or whatever else; 11. what kind of database or
  what database product is being used, if known. If the DBI driver
  talks to a client-configurable DBI proxy server, then, it should be
  possible to nest a set of the above settings (eg, as a hash-ref) as
  one part of the main settings given to the proxy client.
  
 
 Only 1, 8 and 9 (driver name, user ID, password) apply to Informix databases 
 - and you've missed out the other bit that applies - the database name, and 
 optionally database server name hosting it (either 'dbase' or '[EMAIL 
 PROTECTED]'). 
 These are not the same as 2, 3, 4, 5, 6, 7, 10, or 11, and I can't think how 
 any of them (except perhaps 10) could be applied to an IDS connection.

There are certainly database-specific things to be worked around.  An
improvement to the current DSN scheme would be a URI, as discussed in
the past.  The leading dbi: on every DSN is redundant, so a URI might
look like this:

driver://user:[EMAIL PROTECTED]:port/instance

 Oh, and if you're going to enhance the connection, please ensure you cover 
 challenge-response protocols (where you send an initial username/password 
 and the authentication server comes back with a question such as what is 
 the number on your RSA key fob at the moment, and the hapless user has to 
 type that information in, and the connection management code has to deal 
 with this - callbacks and the like.

Seconded, with request for support of SSL client certificate
authentication.

-jwb


Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Jonathan Leffler
On 7/9/05, Darren Duncan [EMAIL PROTECTED] wrote:
 
 At 1:22 AM -0700 7/9/05, Jonathan Leffler wrote:
 On 7/4/05, Darren Duncan [EMAIL PROTECTED]  wrote:
 5. All details used to construct a connection handle should be
 completely decomposed rather than shoved into an ungainly data
 source. Examples of what should be distinct (not all being
 applicable at once) are: 1. the DBI driver module to use; 2. the
 internet server IP address or domain name and port; 3. the locally
 defined server device socket; 4. the locally defined service (eg,
 ODBC or SQL*Net) name; 5. the file system file name; 6. the file
 system directory name; 7. some other detail if any for fully in-RAM
 databases; 8. the authorization identifier / user name; 9. the
 password; 10. some other authorization credential, or channel
 encryption details, or whatever else; 11. what kind of database or
 what database product is being used, if known. If the DBI driver
 talks to a client-configurable DBI proxy server, then, it should be
 possible to nest a set of the above settings (eg, as a hash-ref) as
 one part of the main settings given to the proxy client.
 
 Only 1, 8 and 9 (driver name, user ID, password) apply to Informix 
 databases -
 
 Re-read that paragraph. It says 'not all being applicable at once'.



Yes - I realized that.


and you've missed out the other bit that applies - the database
 name, and optionally database server name hosting it (either 'dbase'
 or '[EMAIL PROTECTED]'). These are not the same as 2, 3, 4, 5, 6, 7, 10,
 or 11, and I can't think how any of them (except perhaps 10) could
 be applied to an IDS connection.
 
 I think that 2 thru 4 cover this, though I used more generic language



I don't. The server name in IDS is not a host name or domain name, nor is it 
a port number (so 2 is not applicable), nor is it the locally named socket 
(so 3 is not applicable), nor is it the locally defined service (so 4 is not 
applicable).

All of these are identified by, but are distinct from, the IDS server name. 
There is a mechanism (configuration file) that hides all the gory details 
from the user. Users should not need to know sordid details like port 
numbers, or whether the host is on an IPv4 or IPv6 network, etc.

Further, within an IDS instance, there are multiple databases that can be 
separately connected to - '[EMAIL PROTECTED]', '[EMAIL PROTECTED]', '
[EMAIL PROTECTED]', '[EMAIL PROTECTED]'. You must be able to specify the 
database 
within the server instance.

Now, in fact, server1 and server2 could be alternative names for the same 
hunk of disk space, supervised by the same IDS instance but with different 
connection properties - such as encrypted vs unencrypted - but that is 
probably just too confusing. Equally, and more normally, server1 could be on 
a wholly different machine from server2.

[Concrete example: I have many IDS instances running on my machine at work. 
One instance has 4 names:
anubis_17, anubis_17_tcp, anubis_17_str, anubis_17_shm. The first two are 
both network connections - albeit usually using loopback since I usually 
work on the same machine. The third uses a STREAMS pipe; the fourth uses 
shared memory. All allow me to connect to the same set of databases, which 
includes 'sysmaster', 'sysutils', 'stores', 'logged', 'unlogged', 
'mode_ansi'. Each of those databases has its own independent set of system 
catalogs. I can connect to '[EMAIL PROTECTED]' or '[EMAIL PROTECTED]' and 
edit the same data - it's the same database, identified by different server 
names and different connection properties. I also have another IDS instance, 
running an older version of IDS, with server names anubis_23, anubis_23_tcp, 
anubis_23_str, anubis_23_shm - and the same set of databases, but only 
because some of them are standard and the others I keep there to make 
testing DBD::Informix easier. I also have an entry configured for a database 
server called 'smartpts' that is based in Lenexa, KS - I work in Menlo Park, 
CA - about 1800 miles away. I can run $db1 = DBI-connect('
dbi:Informix:[EMAIL PROTECTED]'); $db2 = DBI-connect('
dbi:Informix:[EMAIL PROTECTED]'); to connect to those databases. I can also, in 
general, do distributed queries between the two databases without explicitly 
connecting to the other. And note that I can switch between TCP and SHM 
connections on the local machine (which is
anubis.menlo.ibm.comhttp://anubis.menlo.ibm.com)
simply by changing the server name - I don't have to do any other 
modifications to the connection string.]

Please note that for Informix, the database name (optionally with server 
name) is all you need to specify. (There's an environment variable that 
specifies the default server name if you omit it.) Specifying a 'host name' 
won't work; there is no mechanism for connecting by specifying a host name - 
except as part of the configuration file. Specifying a port number (or 
service name) won't work; there is no mechanism for connecting by specifying 
a port 

Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Jochen Wiedmann

Jonathan Leffler wrote:

I dunno which DBMS support prepare without a database connection, but I 
would expect all the mainstream databases to require a database connection. 


+1

I'm also far from convinced that there's any significant benefit in 
separating the 'create a database handle' from the 'connect to database 
server' part.


+1


Not to mention the effect, that one major charm of DBI is its 
simplicity: Connect, Execute for updates, inserts, or deletes and
Connect, Execute, Fetch for select. I can't see an advantage in overly 
extending the interface.



Jochen


Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Juerd
Jeffrey W. Baker skribis 2005-07-09 11:27 (-0700):
  Oh drat - not the DBI connection string discussion again!
 There are certainly database-specific things to be worked around.  An
 improvement to the current DSN scheme would be a URI, as discussed in
 the past.  The leading dbi: on every DSN is redundant, so a URI might
 look like this:
 driver://user:[EMAIL PROTECTED]:port/instance

I think URIs are the right way to go, and one of the very few things PHP
(though be it with PEAR) did right.

http://pear.php.net/manual/en/package.database.db.intro-dsn.php

It would be fun if we could just steal that design and build on top of
it, for compatibility, but also because other people have already
thought about it and proven that it works.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: DBI v2 - The Plan and How You Can Help

2005-07-10 Thread Darren Duncan

At 10:25 PM +1000 7/9/05, Adam Kennedy wrote:
In any case, I still propose that DBI2 split the driver interface 
into Roles. The main DBI2::Role::Transport role does ONLY what DBI 
does best now. That is, connecting to the database, preparing and 
sending queries, and fetching the results.


Forget the current -tables interface. Drivers can OPTIONALLY 
implement the DBI2::Role::Schema interface to handle interrogation 
of the database schema. The current way we handle it is really messy 
by my standards, and could use a dedicated interface.


As you invent major new features for DBI2, implement them roles. 
DBI2::Role::Transational, DBI2::Role::RFC90210 (the super flashy 
Beverly Hills feature), etc etc.


Exactly what these roles should be I don't want to state with any 
certainty. That's the sort of thing that Tim, with his complete 
understanding of the issues, should be doing on his own.


That sounds like a great idea and a good starting place on which to 
build certain design issues.


In fact, I have already been implementing something similar to that 
in my 'Rosetta' database access library for over a year now.  It has 
a concept of feature support lists where each Rosetta Engine/driver 
must take a standard fine-ish-grained checklist and programmatically 
declare which list items it officially supports.


An application can see what an Engine/driver claims to support before 
trying to use it, and will know whether or not the Engine/driver
can meet its needs or not.  An Engine's/driver's declaration can be 
read by invoking the features() method of some Rosetta Interface 
objects.


An additional use for this feature is that a comprehensive common 
test suite for all Engines/drivers can consult features() prior to 
running its tests so that it can skip any tests that an 
Engine/driver doesn't claim to support; it will only invoke and 
pass/fail features that the Engine/driver claims to support.


See the Rosetta::Details documentation section 'FEATURE SUPPORT 
VALIDATION' for the main summary of feature support lists.


But I _would_ certainly like to see schema/table stuff separated 
from the base connection/query functionality.


I agree.  When you get down to it, schema/table/etc reverse 
engineering is a very complicated and involved process.  Fetching 
lists of tables or columns etc should no more be built in than SQL 
parsing or generating.  In short, anything that can normally be 
fetched or changed using ordinary SQL statements should be left out 
of the DBI core; let wrappers do that stuff through the SQL pipe that 
DBI provides.  This said, it is still very useful for DBI to provide 
a function for fetching a list of auto-detectable data sources, so 
that should stay.


On a similar note, utility functions like quote() should be left out 
of the DBI core, and left to either a separate module or someone's 
wrapper, since it's firmly related to SQL generation.  If people want 
DBI itself to handle stuff like that for them, they should use host 
parameters for the literals in question.


While I'm on the topic of DBI, one other feature I'd like to see 
would be something like better support for large objects or various 
types.


I second that.  Have API methods for fetching or storing by-the-chunk 
pieces of LOBs that one could not do with a traditional bind_param() 
etc since the whole thing won't fit in RAM at once.


-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Darren Duncan

At 12:35 AM -0700 7/9/05, Jonathan Leffler wrote:
I dunno which DBMS support prepare without a database connection, 
but I would expect all the mainstream databases to require a 
database connection.  IBM DB2 does; IBM Informix Dynamic Server 
(IDS) does; someone else commented on this and said Oracle does; I 
would expect both Sybase and MS SQL Server to need the DB connection 
too.  Probably PostgreSQL; not sure about MySQL.  The only systems 
that might not need the DB connection are those that aren't using a 
separate SQL-based database server.


See my subsequent email/s where I left prepare() requiring an open 
database connection, and a separate function (for example, 
'compile'), is split out and handles any prep work that can be done 
without an open connection.


Since you mention that some systems don't have the separate SQL-based 
database server, there are indeed some drivers that can take 
advantage of a separate 'compile' then, so they benefit from a split; 
the worst that happens with the others is a no-op.  Some drivers 
gain, and no one loses anything.


I'm also far from convinced that there's any significant benefit in 
separating the 'create a database handle' from the 'connect to 
database server' part.  The overhead of creating the handle - as 
distinct from make the connection to the DBMS - is negligible. 
There's nothing of any significance that can be done with the 
unconnected handle either - at least, for the mainstream SQL DBMS. 
So, the pre-fork creation of an unconnected handle provides 
negligible savings.  Similar comments apply to the statement handles 
- in IDS, at any rate, there's nothing useful that can be done for 
statements until you've got a database handle.  Or, at the least, 
you'd be moving away from the ODBC paradigm, and the ESQL/C paradgm 
too.


A main benefit of separating out the handle creation and database 
connection is the secondary effect whereby you can pre-associate 
statement handles with it that are expensive to create, such as 
because they generate SQL.  Generating SQL and other such things is 
separate from the database and the speed advantage from separating 
this out as I described is not lost by the fact of what database 
servers don't support, since the databases are never given that work.


A primary effect benefit is any time you want to open the same 
connection more than once; you can configure it once when making the 
handle, and not again no matter how many times you open/close/open 
the connection, or re-open a connection that dies.  Moreover, every 
open from the first to subsequent ones are done in the same way.


Certainly, one can make a DBI wrapper that adds some of those 
advantages, but given their simplicity and universal desirability, 
its better to build them in; any addition of complexity over the 
current DBI is negligible, or it may in fact be less complex than the 
current DBI.


As a general comment on DBI v2; we need to beware of the 
second-system effect (Brooks Mythical Man Month).
In particular, the DBI must not mandate impossible levels of support 
from the drivers.  It will benefit you nothing if the DBI is 
immaculate and wonderful and incredibly all-singing and all-dancing, 
but no-one can write a driver for it because the requirements cannot 
be met by the actual DBMS that Perl + DBI needs to work with.


What you say is fair enough, but I never proposed anything impossible 
or difficult; everything that I am proposing here is easy and simple.


-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Jonathan Leffler
Still late to the party - another one bullet point item...

On 7/4/05, Darren Duncan [EMAIL PROTECTED] wrote:

 4. All host parameters should be named (like :foo) rather than
 positional (like ?), meeting with the SQL:2003 standard. The named
 format is a lot easier to use and flexible, making programmers a lot
 less error prone, more powerful, and particularly more resource
 efficient when the same parameter is conceptually used multiple times
 in a SQL statement (it only has to be bound once). If anyone wants
 to use positional format, it could easily be emulated on top of this.
 Or, if native positional support is still important, then it should
 be a parallel option that can be used at the same time as named in
 any particular SQL statement. See the native API of SQLite 3 for one
 example that (I believe) supports both in parallel. This also means
 that execute() et al should take arguments in a hash rather than an
 array.
 

Can you explain which parts of the SQL:2003 mandate this notation? I've had 
a moderately good poke around my copy of ISO/IEC 9075-2:2003 
(SQL/Foundation) and cannot find this. I'd like a few section numbers listed 
which describe this.

The various places I've looked include: 19.6 (prepare statement), 9 
(Additional Common Rules), 6.4 (value specification and target 
specification). I could have missed something in these places - or I could 
be looking in the wrong place.

The IDS (IBM Informix Dynamic SQL) syntax has a number of places where 
:digits can appear with a meaning other than placeholder, and there are 
also a number of places where :identifier can appear with a meaning other 
than placeholder. So, it would be extremely difficult to add :identifier 
notation into IDS. (One of the bits I had to remove from DBD::Informix was 
code from DBD::Oracle that simulated :identifier notation - because it 
breaks too much else.)

This ties in with my previous comment, too; don't try to demand too much of 
the drivers, or the driver writers. As long as you've got a good surrogate 
system in DBI that can simulate those accurately for DBMS that only support 
'?' (positional) placeholders, then DBI v2 can do what the heck it likes. 
But as soon as it is inaccurate - translates things that should not be 
translated - or cannot do the translation automatically, then you will lose 
drivers (or, more accurately, driver writers).

I'm all in favour of looking at the big picture and trying to see where you 
want to go. However, you must also keep an eye out for the marshes between 
where you are and where you want to go; don't let DBI be sunk by ignoring 
the realities of the available DBMS.

-- 
Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h
Guardian of DBD::Informix - v2005.01 - http://dbi.perl.org
I don't suffer from insanity - I enjoy every minute of it.


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Darren Duncan

At 1:03 AM -0700 7/9/05, Jonathan Leffler wrote:
Can you explain which parts of the SQL:2003 mandate this notation? 
I've had a moderately good poke around my copy of ISO/IEC 
9075-2:2003 (SQL/Foundation) and cannot find this.  I'd like a few 
section numbers listed which describe this.
The various places I've looked include: 19.6 (prepare statement), 9 
(Additional Common Rules), 6.4 (value specification and target 
specification).  I could have missed something in these places - or 
I could be looking in the wrong place.


Yes, I can quote some, in different places.  Look at these:

  SQL:2003, 4.29 Host parameters (pp90,91,92)
  SQL:2003, 5.4 Names and identifiers (pp151,152)
  SQL:2003 Foundation page 152 says:
host parameter name ::= colonidentifier

See that last line in particular.  I don't see how it could be more clear.

This is my main source for the SQL:2003 documentation:

  http://www.wiscorp.com/SQLStandards.html

Or specifically:

  http://www.wiscorp.com/sql/sql_2003_standard.zip (warning, large file)

That page is run by someone leading / high up in the SQL standards group.

Note that those urls are printed in my SQL::Routine::Language POD 
file on CPAN, and the lines with specific pages and section names are 
in source/reference comments/documentation for the 
build_identifier_host_parameter_name() function
in my SQL::Routine::SQLBuilder module.  I do tend to give sources to 
back up  anything important I do, which is good for third party 
validation.


The IDS (IBM Informix Dynamic SQL) syntax has a number of places 
where :digits can appear with a meaning other than placeholder, 
and there are also a number of places where :identifier can appear 
with a meaning other than placeholder.  So, it would be extremely 
difficult to add :identifier notation into IDS.  (One of the bits 
I had to remove from DBD::Informix was code from DBD::Oracle that 
simulated :identifier notation - because it breaks too much else.)


A variety of databases, such as Oracle, already have support for just 
the format I described, which I believe was also in SQL:1999.  In 
fact, I think that Oracle's own extensions of earlier SQL standards 
had a lot of influence on later SQL standards such as this, though I 
can think of multiple differences too.


This ties in with my previous comment, too; don't try to demand too 
much of the drivers, or the driver writers.  As long as you've got a 
good surrogate system in DBI that can simulate those accurately for 
DBMS that only support '?' (positional) placeholders, then DBI v2 
can do what the heck it likes.  But as soon as it is inaccurate - 
translates things that should not be translated - or cannot do the 
translation automatically, then you will lose drivers (or, more 
accurately, driver writers).


I don't see how :foo is significantly more difficult than ? to 
simulate accurately.


I'm all in favour of looking at the big picture and trying to see 
where you want to go.  However, you must also keep an eye out for 
the marshes between where you are and where you want to go; don't 
let DBI be sunk by ignoring the realities of the available DBMS.


At the same time, don't let today's technology limit what you do in 
preparation for tomorrow.  DBI v2 is meant to be a forward-looking 
plan, as Perl 6 is, so we have to consider things that are reasonable 
for inclusion; even if it isn't common for native database support 
now, that isn't to say that native support won't come later, and when 
it does, we'll already be ready, or they'll even take what DBI does 
as a cue for what they can add.


-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Darren Duncan

At 1:22 AM -0700 7/9/05, Jonathan Leffler wrote:
On 7/4/05, Darren Duncan 
mailto:[EMAIL PROTECTED][EMAIL PROTECTED]  wrote:

5. All details used to construct a connection handle should be
completely decomposed rather than shoved into an ungainly data
source.  Examples of what should be distinct (not all being
applicable at once) are: 1. the DBI driver module to use; 2. the
internet server IP address or domain name and port; 3. the locally
defined server device socket; 4. the locally defined service (eg,
ODBC or SQL*Net) name; 5. the file system file name; 6. the file
system directory name; 7. some other detail if any for fully in-RAM
databases; 8. the authorization identifier / user name; 9. the
password; 10. some other authorization credential, or channel
encryption details, or whatever else; 11. what kind of database or
what database product is being used, if known.  If the DBI driver
talks to a client-configurable DBI proxy server, then, it should be
possible to nest a set of the above settings (eg, as a hash-ref) as
one part of the main settings given to the proxy client.

Only 1, 8 and 9 (driver name, user ID, password) apply to Informix databases -


Re-read that paragraph.  It says 'not all being applicable at once'.

and you've missed out the other bit that applies - the database 
name, and optionally database server name hosting it (either 'dbase' 
or '[EMAIL PROTECTED]').  These are not the same as 2, 3, 4, 5, 6, 7, 10, 
or 11, and I can't think how any of them (except perhaps 10) could 
be applied to an IDS connection.


I think that 2 thru 4 cover this, though I used more generic language.

Oh, and if you're going to enhance the connection, please ensure you 
cover challenge-response protocols (where you send an initial 
username/password and the authentication server comes back with a 
question such as what is the number on your RSA key fob at the 
moment, and the hapless user has to type that information in, and 
the connection management code has to deal with this - callbacks and 
the like.


I mentioned those generically in 8 thru 10; the latter is some other 
authorization credential etc.


So, as was discussed emphatically and exhaustively (in January 2005 
in dbi-dev under 'Proposing an API for the extension for simplifying 
database connections'), this is not readily going to fly with the 
existing DBMS - specifically, not with IDS.  Closed-source DBMS are 
*not* necessarily going to adapt to meet the needs of Perl and DBI. 
You can argue that's their loss - you may even be right.  But you'll 
be limiting the acceptability of Perl + DBI in some respects. 
You'll also be annoying the hell out of me if you can't define a 
connection string that will work with Informix (I'm not too worried 
about the challenge-response stuff, though Informix can handle that).


If a database only accepts input in string form, then the DBI driver 
can generate one out of the decomposed information it is given.  No 
trouble here, really; no trouble at all.  The whole point of a DBI 
driver is to map between the DBI interface and how the database 
product natively does things.  It is true that some things can only 
be done by changing the database product itself, but other things can 
be done in the DBI driver, with no support from closed-source DBMS 
necessary.


-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Steve Sapovits

Jared Still wrote:


I use a (Perl) password server for this.

Passwords are stored encrypted in a configuration file.

Clients authenticate with the server, and receive a requested
password (encrypted) across the network, if the client is
entitled.

The user authentication is rudimentary, but it works.
SSH certificates would be better, just need to do it.


This is more of the direction I'm going; i.e., I don't want a
DBI-specific password file as a requirement since I'm looking
at a central way of storing a variety of passwords, DBI and
non-DBI.  I think the file idea is fine as an environment- or
configuration-driven _option_.

--
Steve Sapovits  [EMAIL PROTECTED]


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Jonathan Leffler
Late to the ball - and only picking up on one issue...

On 7/4/05, Darren Duncan [EMAIL PROTECTED] wrote:

 2. Always separate out any usage stages that can be performed apart
 from the database itself. This allows an application to do those
 stages more efficiently, consuming fewer resources of both itself and
 the database.
 
 For example, a pre-forked Apache process can declare all of the
 database and statement handles that it plans to use, and do as much
 of the prepare()-type work that can be done internally as possible,
 prior to forking; all of that work can be done just once, saving CPU,
 and only one instance of it consumes RAM. All actual invocations of
 a database, the open()/connect() and execute() happen after forking,
 and at that point all of the database-involving work is consolidated.
 
 Or even when you have a single process, most of the work you have to
 do, including any SQL generation et al, can be more easily be
 pre-performed and the results cached for multiple later uses. Some
 DBI wrappers may do a lot of work with SQL generation et al and be
 slow, but if this work is mainly preparatory, they can still be used
 in a high-speed environment as that work tends to only need doing
 once. Most of the prep work of a DBI wrapper can be done effectively
 prior to ever opening the database connection.
 

I dunno which DBMS support prepare without a database connection, but I 
would expect all the mainstream databases to require a database connection. 
IBM DB2 does; IBM Informix Dynamic Server (IDS) does; someone else commented 
on this and said Oracle does; I would expect both Sybase and MS SQL Server 
to need the DB connection too. Probably PostgreSQL; not sure about MySQL. 
The only systems that might not need the DB connection are those that aren't 
using a separate SQL-based database server.

I'm also far from convinced that there's any significant benefit in 
separating the 'create a database handle' from the 'connect to database 
server' part. The overhead of creating the handle - as distinct from make 
the connection to the DBMS - is negligible. There's nothing of any 
significance that can be done with the unconnected handle either - at least, 
for the mainstream SQL DBMS. So, the pre-fork creation of an unconnected 
handle provides negligible savings. Similar comments apply to the statement 
handles - in IDS, at any rate, there's nothing useful that can be done for 
statements until you've got a database handle. Or, at the least, you'd be 
moving away from the ODBC paradigm, and the ESQL/C paradgm too.

As a general comment on DBI v2; we need to beware of the second-system 
effect (Brooks Mythical Man Month).

In particular, the DBI must not mandate impossible levels of support from 
the drivers. It will benefit you nothing if the DBI is immaculate and 
wonderful and incredibly all-singing and all-dancing, but no-one can write a 
driver for it because the requirements cannot be met by the actual DBMS that 
Perl + DBI needs to work with.

-- 
Jonathan Leffler [EMAIL PROTECTED] #include disclaimer.h
Guardian of DBD::Informix - v2005.01 - http://dbi.perl.org
I don't suffer from insanity - I enjoy every minute of it.


Re: DBI v2 - The Plan and How You Can Help

2005-07-09 Thread Darren Duncan
Jonathan, while you are well-meaning in your comments, you are 
mis-reading what I have said multiple times and are therefore making 
a straw man argument against it.


Regarding this point:


 5. All details used to construct a connection handle should be

completely decomposed rather than shoved into an ungainly data
source.  Examples of what should be distinct (not all being
applicable at once) are: snip


That's the key part of my proposal right there.  I don't care about 
exactly what break-down of pieces we collectively come up with, as 
long as they are unambiguous, reasonably atomic, account for all the 
possible needs, and have reasonable names.  That 11-point list of 
mine was only meant to be an example of what breaking up a data 
source string can give us; it was not meant to be exhaustive and 
there is no point in arguing at length against what it missed and how 
horrible it is.  No doubt, an IDS and/or components thereof should 
also be in the list of connection parameters.  I'm not arguing 
against what one needs for Informix, either explicitly or implicitly.


All this said, thank you for all the information about Informix how 
you set up your systems, and how many levels of hierarchy there can 
be with a database; eg, a server has 1+ databases, each of which has 
1+ catalogs (and presumably each of those has 1+ schemas and each of 
those 1+ tables and other schema objects).  I will probably find it 
helpful when I plan various DBI-using tasks.


-- Darren Duncan


Re: DBI v2 - The Plan and How You Can Help

2005-07-07 Thread Maxim Sloyko

Sam Vilain wrote:

Maxim Sloyko wrote:

 But this is not the point. The point was that usage of some file with 
passwords by *DEFAULT* is not the way to go, IMHO. It raises more 
problems than it solves.



Can you give an example of such a problem that wasn't already there?

Just to be clear, the file would only need to contain passwords if the
DBD requires them.

Sam.


May be it is just me, but having a bunch of config files is not very 
good. Config files should be for program, not for separate modules of 
that program. They are hard to manage, when there are many of them. 
Besides, DBI is a high level abstraction and it is not a good idea to 
tie it to some file. May be it is better to let DBD:: modules choose? 
For example, you can pass some parameter to the driver in connect 
string, which tells it, where passwords are stored. Something like this 
is impleneted in DBD::Oracle, where you can just pass 'sid' parameter to 
the driver, the rest configuration parameters (except passwords and 
usernames) are read from  oracle config file, from the section to which 
that sid parameter points.


I don't mind if you implement this .dbi feature though, I just want it 
to be invisible :) i.e. don't check this file, if I explicitly supply 
username and password (this is obvious, right?) and show some warnings 
if don't. Say, make a connect parameter use_dot_dbi, which is zero by 
default.


--
Maxim Sloyko


RE: DBI v2 - The Plan and How You Can Help

2005-07-07 Thread Jones Robert TTMS Contractor

 When I go to the donation page and attempt to make a donation, the
drop-down box does not give DBI as a valid recipient.  Is it possible
several people may not have donated as they noticed the same results, or
maybe they did and it all went into the Perl Development Fund instead?



 -Original Message-
 From: Tim Bunce [mailto:[EMAIL PROTECTED] 
 Sent: Friday, July 01, 2005 7:06 PM
 To: perl6-language@perl.org; dbi-users@perl.org
 Subject: DBI v2 - The Plan and How You Can Help
 
 
 Once upon a time I said:
 
   
 http://groups-beta.google.com/group/perl.dbi.users/msg/caf189d
 7b404a003?dmode=sourcehl=en
 
 and wrote
 
   http://search.cpan.org/~timb/DBI/Roadmap.pod
 
 which yielded:
 
   
 https://donate.perlfoundation.org/index.pl?node=Fund+Drive+Det
 ailsselfund=102
 
 (A little over $500 of that I effectively put in myself.)
 
 My *sincere* thanks to all those who donated to the fund, especially
 individuals. I had hoped for more corporate response with less from
 individuals and I'm touched by the personal generosity shown.
 
 I've not drawn any money from it yet and doubt that I will myself.
 (I'm considering suggesting that the Perl Foundation make payments
 from the fund to people making specific contributions to the DBI.
 I'm thinking especially of work on a comprehensive test harness.
 But I'll see how the developments below pan out before making
 specific arrangements.)
 
 
 So, that lead to:
 
   
 http://groups-beta.google.com/group/perl.dbi.dev/browse_frm/th
 read/ef14a9fc0a37441f/fb8fe20a86723da0#fb8fe20a86723da0
 
 Which sums up fairly well where I'm at: DBI v1 will rumble on 
 for Perl 5
 and DBI v2 will be implemented for Perl 6.
 
 
 --- digression ---
 
 At this point I'd like to make a slight digression to highlight the
 amazing work going on in the Perl 6 community at the moment.
 Especially Autrijus' Pugs project which has brought Perl 6 to life.
 Literally. Take a look at:
 
   http://pugscode.org/talks/yapc/slide1.html
   http://use.perl.org/~autrijus/journal
 
 and especially:
 
   http://use.perl.org/~autrijus/journal/24898
 
 Yes, that really is Perl 6 code using the DBI being executed by Pugs.
 
 That's great, and I was truly delighted to see it because it takes the
 pressure off the need to get a DBI working for Perl 6 - because it
 already is working for Perl 6. At least for Pugs. (The Ponie project
 is also likely to provide access to Perl 5 DBI from Perl 6 by enabling
 future versions of Perl 5 to run on Parrot.)
 
 --- digression ---
 
 
 I have recently come to an arrangement that will enable me to put some
 worthwhile development time into DBI (still very much part-time, but
 enough to give it focus and move forward).
 
 My initial goals are:
 
  1. to work on a more detailed specification for the DBI v2 API that
 takes advantage of appropriate features of Perl 6.
 
  2. to work on a more detailed specification for the DBDI API
 
 http://groups-beta.google.com/group/perl.perl6.internals/msg/c
 fcbd9ca7ee6ab4
 
  3. to work on tools to automate building Parrot NCI interfaces to
 libraries (such as database client libraries, obviously :)
 
 
 But I'm hoping you'll join in and help out.
 
 I've kept an eye on Perl 6 and Parrot developments but I'm no 
 expert in
 either. What I'd like *you* to do is make proposals (ideally fairly
 detailed proposals, but vague ideas are okay) for what a Perl 
 6 DBI API
 should look like.
 
 Keep in mind that the role of the DBI is to provide a consistent
 interface to databases at a fairly low level. To provide a 
 *foundation*
 upon which higher level interfaces (such as Class::DBI, 
 Tangram, Alzabo
 etc. in Perl 5) can be built.
 
 So, if you have an interest in the DBI and Perl 6, put your thinking
 cap on, kick back and dream a little dream of how the DBI could be.
 How to make best use of the new features in Perl 6 to make 
 life easier.
 
 Then jot down the details and email them to me (or to 
 dbi-users@perl.org
 if you want to kick them around in public for a while first).
 
 I'm about to fly off for two weeks vacation (in a few hours), 
 blissfully
 absent of any hi-tech gear beyond a mobile phone. When I get back I'll
 gather up your emails and try to distill them into a coherent whole.
 
 Have fun!
 
 Tim.
 


Re: DBI v2 - The Plan and How You Can Help

2005-07-06 Thread Steve Sapovits

Maxim Sloyko wrote:

I don't think this solves the problem, because what I usually want is 
the user to be able to use the application, but unable to see the DB 
password. So the user should have read permission set for the file, 
but on the other hand he shouldn't. It's not not a problem for Web App, 
though.


Storing passwords encrypted, decrypting before using doesn't cover this?
I've played around with Crypt::CBC (and different ciphers) for this sort
of thing but admittedly have not applied this to any production systems
yet.  You still have a key somewhere to hide/obscure.  You can also use
Perl source filters to totally encrypt the source -- something else I've
done but not in production.  Just some things you may want to look at ...

--
Steve Sapovits  [EMAIL PROTECTED]


Re: DBI v2 - The Plan and How You Can Help

2005-07-06 Thread Sam Vilain

Maxim Sloyko wrote:
 But this is not the point. The point was that usage of some file with 
passwords by *DEFAULT* is not the way to go, IMHO. It raises more 
problems than it solves.


Can you give an example of such a problem that wasn't already there?

Just to be clear, the file would only need to contain passwords if the
DBD requires them.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-05 Thread Sam Vilain

Darren Duncan wrote:
Okay, considering that using the same name prepare() like this may 
confuse some people, here is a refined solution that uses 3 methods 
instead; please disregard any contrary statements that I previously made:


I think I'm beginning to like it.

Allow me to suggest one or two further refinements...


  # Opt 1: A user that wants the most control can do this (new feature):

  my $sth1 = $dbh.compile( $sql_or_ast ); # always sans connection
  $sth1.prepare(); # always with connection, even if DBD doesn't use it
  $sth1.execute(); # always with connection


To me, the compiled form of the STH is related to the driver, but
re-usable between connections; you should be able to use something like;

  my $sth1 = DBD::SQLite.compile( $sql_or_ast );
  $sth1 = DBI.compile( :statement($sql_or_ast), :driverSQLite );

This would give you a STH which is divorced from the actual DB connection
instance.  Because you constructed it like this, without reference to a
(possibly unconnected) connection object, then $sth1.prepare is not
available.

You'd then need to use something like;

  $sth1.prepare($dbh);
  $dbh.prepare($sth1);

Note I also think what you wrote should work, too.

The new feature is if you decide to use compile(); you then give that 
method the arguments you would have given to prepare(), and you invoke 
prepare() on the result with no arguments; each DBD would decide for 
itself how the work is divided between compile() and prepare() with the 
limitation that compile() is not allowed to access the database; ideally 
the DBD would place as much work there as is possible, which would vary 
between Oracle/Pg/etc.


Agreed.


In particular, I don't think that the DB driver should automatically
get a chance to interfere with SQL::Statement; if they want to do that,
then they should specialise SQL::Statement.  IMHO.
I am operating under the assumption here that while the new DBI is 
designed to effectively support wrapper modules, the wrapper modules 
would also be altered from their current DBI-1-geared designs to 
accomodate DBI-2.

But still, what do you mean by interfere?


Well, when you parse the statement into an AST, the flavour of SQL will
affect how it is parsed and what is allowed.  Eg, Oracle has significant
features in some comments (query hints).  It also has quirky and somewhat
useless keywords like CONNECT BY.

So, when you ask a DBH connected to a driver to parse something, then it
will use that driver's SQL dialect, if one exists, but I still want to be
able to deal with SQL ASTs without implying a SQL flavour.


Either way, you don't want most applications dealing with this complexity
at all, really.
I am operating under the assumption that this system should work if 
there are no external config files that the DBI/DBD would read, and the 
application would provide that information; if its in a file, the 
application would read it in, or would explicitly tell DBI where it is.  
Or at least it should be possible for this to happen, even if a DBD 
defaults to look in a default location when it doesn't get the 
equivalent from the application.


Absolutely, that must work.  But it would still be nice to be able to
config this without digging through the application to see where the
password is written.

Unless there is a design flaw in DBI, we should not have to update that 
module just because a new driver came into existence whose name has not 
yet been hard-coded into DBI.

See this block for example, from DBI.pm v1.48:
 my $dbd_prefix_registry = {
  ad_  = { class = 'DBD::AnyData',},

  [...]

  yaswi_   = { class = 'DBD::Yaswi',},
 };
I mean, what's up with that?  I assume DBI 1 has this for legacy app 
backwards compatability, but DBI version 2 should never have to 
accomodate such abhorrent computer programming practices in its core.


Such a great word, abhorrent.  So fitting for this case.  It sure does
look like an (overprematuremisguided)-optimisation to avoid using the
full module name in an internal hash or something like that.  But then
maybe (Iwenone(Gaia)) are missing some context there.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-05 Thread Adam Kennedy
4. All host parameters should be named (like :foo) rather than 
positional (like ?), meeting with the SQL:2003 standard.  The named 
format is a lot easier to use and flexible, making programmers a lot 
less error prone, more powerful, and particularly more resource 
efficient when the same parameter is conceptually used multiple times in 
a SQL statement (it only has to be bound once).  If anyone wants to use 
positional format, it could easily be emulated on top of this. Or, if 
native positional support is still important, then it should be a 
parallel option that can be used at the same time as named in any 
particular SQL statement.  See the native API of SQLite 3 for one 
example that (I believe) supports both in parallel.  This also means 
that execute() et al should take arguments in a hash rather than an array.


Yes, native positional support is still important.

positions make it very easy to do SQL math.

To express it in overly simplistic code

$foo = [ a = ?, foo ];
$bar = [ b = ?, bar ];

$baz = $foo and $bar;
# $baz now is [ a = ? and b = ?, foo, bar ];

Bearing mind a situation with an arbitrary number and complexity of 
these sql fragments to be added together, doing this sort of thing using 
named placeholders would be a nightmare.


and we'd just end up with every second person implementing a ? to :p1, 
:p2 scheme in their database layers. If you want positional 
placeholders, it needs to be an additional feature, not a replacement 
for positional placeholders.




Re: DBI v2 - The Plan and How You Can Help

2005-07-05 Thread Darren Duncan

At 6:14 PM +1200 7/5/05, Sam Vilain wrote:

I think I'm beginning to like it.
Allow me to suggest one or two further refinements...


  my $sth1 = $dbh.compile( $sql_or_ast ); # always sans connection
  $sth1.prepare(); # always with connection, even if DBD doesn't use it
  $sth1.execute(); # always with connection


FYI, I'm not stuck on the name 'compile'; the method could be called 
something else.  In fact, I still think 'prepare' is more broadly 
descriptive considering the wide range of things that could be 
happening inside that method; I see it as ultimately getting ready 
for the execute() anyway.  The problem is that the word 'prepare' is 
commonly associated with something different, so we're stuck having 
to find a different word.



To me, the compiled form of the STH is related to the driver, but
re-usable between connections; you should be able to use something like;

  my $sth1 = DBD::SQLite.compile( $sql_or_ast );
  $sth1 = DBI.compile( :statement($sql_or_ast), :driverSQLite );

This would give you a STH which is divorced from the actual DB connection
instance.


Yes, that is true.  However, I like for all application calls to go 
through the Interface module (DBI) since that is what the Interface 
is for.  It is also more practical to go by way of the DBI module 
because it can do things for you like certain kinds of validation on 
application input and driver output, so the application or driver 
respectively doesn't have to do those tests for robustness.  Each DBI 
driver can worry less about that its input is correct and focus more 
on its actual work.  (FYI, a common input/output validation is one of 
the main things that the 'Rosetta' module does for its own drivers 
and users.  More so in next release v0.46.)



Because you constructed it like this, without reference to a
(possibly unconnected) connection object, then $sth1.prepare is not
available.


I wouldn't worry about that; the proposed DBI would elegantly handle 
(throw an exception) attempts to invoke methods that depend on an 
open connection when there is none.  People who like to check first 
will also have a $dbh.is_open() method available to them.  I also see 
the situation as no worse than the current DBI v1 where you can 
invoke such things as fetchrow_arrayref() on a $sth that hasn't been 
executed yet.


Oh, and I have another DBI v2 suggestion to add, also following Rosetta design:

1. A $sth should not contain any methods for fetching the result of 
an executed statement; rather, execute() should return an object when 
successful that represents its result; you invoke fetching methods on 
that object.  For example:


  my $rlh = $sth-execute();
  my $rowset = $rlh-fetchrow_arrayref();

This approach is a lot more flexible.


Well, when you parse the statement into an AST, the flavour of SQL will
affect how it is parsed and what is allowed.  Eg, Oracle has significant
features in some comments (query hints).  It also has quirky and somewhat
useless keywords like CONNECT BY.

So, when you ask a DBH connected to a driver to parse something, then it
will use that driver's SQL dialect, if one exists, but I still want to be
able to deal with SQL ASTs without implying a SQL flavour.


You still can.  The point of an abstract syntax tree is that the 
original SQL dialect isn't very important to what it contains (and 
this is how SQL::Routine is); by contrast, a concrete syntax tree 
cares very much about the original syntax and preserves it to the 
last detail.  I don't see a problem here.

...
Except that those AST-like-modules which embed raw SQL fragments 
(like where-clauses) as a matter of course aren't actually that 
abstract and could pose a problem; lots of DBI wrappers are this way, 
unfortunately (but not mine).


I am operating under the assumption that this system should work if 
there are no external config files that the DBI/DBD would read, and 
the application would provide that information; if its in a file, 
the application would read it in, or would explicitly tell DBI 
where it is.  Or at least it should be possible for this to happen, 
even if a DBD defaults to look in a default location when it 
doesn't get the equivalent from the application.


Absolutely, that must work.  But it would still be nice to be able to
config this without digging through the application to see where the
password is written.


Er, I hope you didn't interpret this as the application source code. 
My point was that the database connection details can be part of the 
general application configuration file, which is still data and not 
code.  This way, each application can have distinct database settings 
if it wants to.



Such a great word, abhorrent.  So fitting for this case.  It sure does
look like an (overprematuremisguided)-optimisation to avoid using the
full module name in an internal hash or something like that.  But then
maybe (Iwenone(Gaia)) are missing some context there.


Well, I have also decided that I can 

Re: DBI v2 - The Plan and How You Can Help

2005-07-05 Thread Adam Kennedy

  - optional treatment of the statements as an AST, similar in concept to
SQL::Routine, or Tangram::Expr.  Death to SQL templating systems!


I suspect during this process people are going to want a lot of things 
that layer on top of what we currently see as DBI.


Personally I think Tim got it right to initially only handle 
connectivity and preparation stuff in DBI, and not try to deal with 
schemas or relational-mapping or any of that other gumpf.


I see the issues with the table methods in DBI as an example of this. 
What you want in many situations is something much more details that 
just a list of table names.


So with that in mind.

I'd like to see DBI done as a set of multiple interfaces that each 
driver can choose to support or not support.


For example, the connectivity layer. This currently works very very well 
and has allowed huge numbers of different interfaces to almost every 
database in existance.


Every driver, as they do now, should implement support for this layer.

On top of that, if you really must interact with the database to query 
table names and so on, lets see that done as a separate layer.


DBI2::Schema or something. drivers could then specifically advertise 
support or non-support for that API.


And we could get an interface somewhat richer than the current raw 
hashes one.


Adam K


Re: DBI v2 - The Plan and How You Can Help

2005-07-05 Thread Maxim Sloyko

Sam Vilain wrote:


However, making it in a file in $HOME/.xxx means that the sysadmin can
set it up to be mode 400 or something like that, to ensure other users
can't access it if someone forgot to set the permissions right on the
application code (or, hopefully, configuration file).



I don't think this solves the problem, because what I usually want is 
the user to be able to use the application, but unable to see the DB 
password. So the user should have read permission set for the file, 
but on the other hand he shouldn't. It's not not a problem for Web App, 
though.


--
Maxim Sloyko


Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Richard Nuttall



  - support for automatically pulling database DSN information from a
~/.dbi (or similar) file.  This is constantly re-invented poorly.
Let's just do a connect by logical application name and let the
SysAdmins sort out which DB that connects to, in a standard way.


This reminds me one one thing I hate about DB access, and that is having 
the DB password

stored in plain text.

Of course there are ways to provide some concealment, but nothing 
particularly good or

integrated into the access.

If the connecting by logical application name could also include some 
level of security

access, that would be a big improvement.

R.



Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Dean Arnold

Richard Nuttall wrote:



  - support for automatically pulling database DSN information from a
~/.dbi (or similar) file.  This is constantly re-invented poorly.
Let's just do a connect by logical application name and let the
SysAdmins sort out which DB that connects to, in a standard way.



This reminds me one one thing I hate about DB access, and that is having 
the DB password

stored in plain text.

Of course there are ways to provide some concealment, but nothing 
particularly good or

integrated into the access.

If the connecting by logical application name could also include some 
level of security

access, that would be a big improvement.

R.




Which is why major DBMSs are increasingly relying on SSO
based solutions. (e.g., Kerberos/LDAP authentication).
Not certain if DBI is the proper level to implement that,
(probably needs to be down at the DBD = DBMS level).
And in a standard way may still be wishful thinking.

Also, I'm not sold on the idea that a ~/.dbi file is particularly
secure in that regard. Not neccesarily opposed, just not convinced
its the right solution. (I don't like cleartext passwords either,
but due to the variance in DBMS's authentication methods, I don't know if
DBI can solve that problem).

- Dean


Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Sam Vilain

Richard Nuttall wrote:

  - support for automatically pulling database DSN information from a
~/.dbi (or similar) file.  This is constantly re-invented poorly.
Let's just do a connect by logical application name and let the
SysAdmins sort out which DB that connects to, in a standard way.
This reminds me one one thing I hate about DB access, and that is having 
the DB password

stored in plain text.


Sadly, there is really nothing that can be done about this, other than
casual obscuring of the real password like CVS does in ~/.cvspass

However, making it in a file in $HOME/.xxx means that the sysadmin can
set it up to be mode 400 or something like that, to ensure other users
can't access it if someone forgot to set the permissions right on the
application code (or, hopefully, configuration file).

Of course, for more secure access schemes like kerberos, etc, the file
is really just being a little registry of available data sources.

On a similar note could be allowing overriding the data source used by
an application by setting an environment variable.  That way, the
SysAdmin has got lots of options when it comes to managing different
production levels - Oracle has this with TWO_TASK, and while it's a
PITA when it's not there (no doubt why DBD::Oracle allows this to be
specified in the DSN string), it's also useful for what it's intended
for - switching databases from an operational perspective.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Darren Duncan

Tim et al,

Following are some ideas I have for the new DBI, that were thought 
about greatly as I was both working on Rosetta/SQL::Routine and 
writing Perl 6 under Pugs.  These are all language-independent and 
should be implemented at the Parrot-DBI level for all Parrot-hosted 
languages to take advantage of, rather than just in the Perl 6 
specific additions.  I believe in them strongly enough that they are 
in the core of how Rosetta et al operates (partly released, partly 
pending).


0. There were a lot of good ideas in other people's replies to this 
topic and I won't repeat them here, for the most part.


1. Always use distinct functions/methods to separate the declaration 
and destruction of a resource handle / object from any of its 
activities.  With a database connection handle, both the 
open/connect() and close/disconnect() are $dbh methods; the $dbh 
itself is created separately, such as with a DBI.new_connection() 
function.  With a statement handle, the prepare() is also a $sth 
method like with execute() et al; the $sth itself is created 
separately, such as with a $dbh.new_statement() method.  If new 
handle types are created, such as a separate one for cursors, they 
would likewise be declared and used separately.


With this separation, you can re-use the resource handles more 
easily, and you don't have to re-supply static descriptive 
configuration details each time you use it, but rather only when the 
handle is declared.  At the very least, such static details for a 
connection handle include what DBI implementor/driver module to use; 
as well, these details include what database product is being used, 
and locating details for the database, whether internet address or 
local service name or on-disk file name and so on.  This can 
optionally include the authorization identifier / user name and 
password, or those details can be provided at open() time instead if 
they are likely to be variable.


2. Always separate out any usage stages that can be performed apart 
from the database itself.  This allows an application to do those 
stages more efficiently, consuming fewer resources of both itself and 
the database.


For example, a pre-forked Apache process can declare all of the 
database and statement handles that it plans to use, and do as much 
of the prepare()-type work that can be done internally as possible, 
prior to forking; all of that work can be done just once, saving CPU, 
and only one instance of it consumes RAM.  All actual invocations of 
a database, the open()/connect() and execute() happen after forking, 
and at that point all of the database-involving work is consolidated.


Or even when you have a single process, most of the work you have to 
do, including any SQL generation et al, can be more easily be 
pre-performed and the results cached for multiple later uses.  Some 
DBI wrappers may do a lot of work with SQL generation et al and be 
slow, but if this work is mainly preparatory, they can still be used 
in a high-speed environment as that work tends to only need doing 
once.  Most of the prep work of a DBI wrapper can be done effectively 
prior to ever opening the database connection.


3. Redefine prepare() and execute() such that the first is expressly 
for activities that can be done apart from a database (and hence can 
also be done for a connection handle that is closed at the time) 
while all activities that require database interaction are deferred 
to the second.


Under this new scheme, when a database has native prepared statements 
support that you want to leverage, the database will be invoked to 
prepare said statements the first time you run execute(), and then 
the result of this is cached by DBI or the driver for all subsequent 
execute() to use.  In that case, any input errors detected by the 
database will be thrown at execute() time regardless of their nature; 
only input errors detected by the DBD module itself would be thrown 
at prepare() time.  (Note that module-caught input errors are much 
more likely when the module itself is handling SQL in AST form, 
whereas database-caught input errors are much more likely when SQL is 
always maintained in the program as string form.)  Note also that the 
deferal to execute() time of error detection is what tends to happen 
already with any databases that don't have native prepared statement 
support or for whom the DBI driver doesn't use them; these won't be 
affected by the official definition change.


Now I realize that it may be critically important for an application 
to know at prepare() time about statically-determinable errors, such 
as mal-formed SQL syntax, where error detection is handled just by 
the database.  For their benefit, the prepare()+execute() duality 
could be broken up into more methods, either all used in sequence or 
some alternately to each other, so users get their errors when they 
want them.  But regardless of the solution, it should permit for all 

Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Sam Vilain

Darren Duncan wrote:
3. Redefine prepare() and execute() such that the first is expressly for 
activities that can be done apart from a database (and hence can also be 
done for a connection handle that is closed at the time) while all 
activities that require database interaction are deferred to the second.


That would be nice, but there are some DBDs for which you need the database
on hand for $dbh.prepare() to work.  In particular, DBD::Oracle.

I think that what you are asking for can still work, though;

  # this module creates lots of SQL::Statement derived objects, without
  # necessarily loading DBI.
  use MyApp::Queries %queries;

  # not connect, so doesn't connect
  my $db = DBI.new( :source(myapp) );

  # prepare the objects as far as possible
  my %sths;
  for %queries.kv - $query_id, $query_ast_or_template {
  %sths{$query_id} = $db.prepare($query_ast_or_template);
  }

  # connect
  $db.connect;

  # now proceed as normal
  my $sth = %sthssome_query_id;
  $sth.execute( :param(foo), :this(that) );

So, effectively the prepare can happen at any time, and it's up to the
DBD to decide whether to actually do anything with it immediately or not.
ie, on Pg the STHs would be built before the DB is connected, and on Oracle
they are built the first time they are used (and then cached).

Now I realize that it may be critically important for an application to 
know at prepare() time about statically-determinable errors, such as 
mal-formed SQL syntax, where error detection is handled just by the 
database.  For their benefit, the prepare()+execute() duality could be 
broken up into more methods, either all used in sequence or some 
alternately to each other, so users get their errors when they want 
them.  But regardless of the solution, it should permit for all 
database-independent preparation to be separated out.


OK, so we have these stages;

  1. (optional) generate an AST from SQL
  2. (optional) generate SQL string from an AST
  3. generate a handle for the statement, sans connection
  4. prepare handle for execution, with connection
  5. execute statement

I think these all fit into;

  1. SQL::Statement.new(:sql(...));
  2. $statement.as_sql;
  3. $dbh.prepare($statement) or $dbh.prepare($statement, :nodb);
  4. $dbh.prepare($statement) or $sth.prepare while connected
  5. $sth.execute

In particular, I don't think that the DB driver should automatically
get a chance to interfere with SQL::Statement; if they want to do that,
then they should specialise SQL::Statement.  IMHO.

Perhaps you have some other examples that don't fit this?

5. All details used to construct a connection handle should be 
completely decomposed rather than shoved into an ungainly data 
source.


I interpret this as asking that the detailed parameters to the DBI
connection are expanded into named options rather than simply bundled into
a string.

That, I agree with, and I guess it would be useful occasionally to be
able to specify all that rather than just setting it up once and labelling
those connection parameters with a source that comes from ~/.dbi.
Particularly for writing gui dialogs for interactive database utilities.

Either way, you don't want most applications dealing with this complexity
at all, really.

6. DBI drivers should always be specified by users with their actual 
package name, such as 'DBD::SQLite', and not some alternate or 
abbreviated version that either leaves the 'DBD::' out or is spelled 
differently.  Similarly, the DBI driver loader should simply try to load 
exactly the driver name it is given, without munging of any type.  This 
approach is a lot more simple, flexible and lacks the cludges of the 
current DBI.  DBI driver implementers can also name their module 
anything they want, and don't have to name it 'DBD::*'. A DBI driver 
should not have to conform to anything except a specific API by which it 
is called, which includes its behaviour upon initialization, invocation, 
and destruction.


Is this useful?

I can't see a reason that the DBI.new() / DBI.connect() call shouldn't be
flexible in what it accepts;

  $dbh = DBI.new( :driverRosetta );   # means DBD::Rosetta
  $dbh = DBI.new( :driverRosetta::Emulate::DBD ); # specify full package
  $dbh = DBI.new( :driver(Rosetta::Emulate::DBD) ); # pass type object
  $dbh = DBI.new( :driver(DBD::SQLite.new(:foobar)) ); # pass driver object

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Darren Duncan
Okay, considering that using the same name prepare() like this may 
confuse some people, here is a refined solution that uses 3 methods 
instead; please disregard any contrary statements that I previously 
made:


  # Opt 1: A user that wants the most control can do this (new feature):

  my $sth1 = $dbh.compile( $sql_or_ast ); # always sans connection
  $sth1.prepare(); # always with connection, even if DBD doesn't use it
  $sth1.execute(); # always with connection

  # Opt 2: If they want less control, they do this (same as old DBI):

  my $sth2 = $dbh.prepare( $sql_or_ast ); # combines Opt 1's comp/prep
  $sth2.execute(); # same as Opt 1

  # Opt 3: Alternately, there is this (akin to my older suggestion):

  my $sth3 = $dbh.compile( $sql_or_ast ); # same as Opt 1
  $sth3.execute(); # combines Opt 1's prep/exec

  # Opt 4: Even less control (akin to old DBI's do):

  $dbh.execute( $sql_or_ast ); # combines Opt 1's comp/prep/exec

In this model, when you use just prepare() and execute(), they behave 
identically to the old DBI, including that they require an open 
connection.  So no mystery there.


The new feature is if you decide to use compile(); you then give that 
method the arguments you would have given to prepare(), and you 
invoke prepare() on the result with no arguments; each DBD would 
decide for itself how the work is divided between compile() and 
prepare() with the limitation that compile() is not allowed to access 
the database; ideally the DBD would place as much work there as is 
possible, which would vary between Oracle/Pg/etc.


Invoking just compile() then execute() will cause the execute() to do 
what prepare() normally does against a database, and cache the 
prepared handle.


In option 4, I renamed the old DBI's do() to execute() for 
consistency with the other examples; but this execute() is different 
in that it caches the prepared statement handle.  In any event, with 
all 4 examples, execute() gives you the same result regardless of 
what is called before it.


At 2:49 PM +1200 7/5/05, Sam Vilain wrote:

In particular, I don't think that the DB driver should automatically
get a chance to interfere with SQL::Statement; if they want to do that,
then they should specialise SQL::Statement.  IMHO.


I am operating under the assumption here that while the new DBI is 
designed to effectively support wrapper modules, the wrapper modules 
would also be altered from their current DBI-1-geared designs to 
accomodate DBI-2.


But still, what do you mean by interfere?

5. All details used to construct a connection handle should be 
completely decomposed rather than shoved into an ungainly data 
source.


I interpret this as asking that the detailed parameters to the DBI
connection are expanded into named options rather than simply bundled into
a string.

That, I agree with, and I guess it would be useful occasionally to be
able to specify all that rather than just setting it up once and labelling
those connection parameters with a source that comes from ~/.dbi.
Particularly for writing gui dialogs for interactive database utilities.


I see the act of storing all the data as a single string at any time 
to be a messy affair to be avoided.  The application doesn't have to 
know about the complexity to pass around a hash of values any more 
than it does with a string; but when the application wants to know 
the details, dealing with a hash is easier.



Either way, you don't want most applications dealing with this complexity
at all, really.


I am operating under the assumption that this system should work if 
there are no external config files that the DBI/DBD would read, and 
the application would provide that information; if its in a file, the 
application would read it in, or would explicitly tell DBI where it 
is.  Or at least it should be possible for this to happen, even if a 
DBD defaults to look in a default location when it doesn't get the 
equivalent from the application.


6. DBI drivers should always be specified by users with their 
actual package name, such as 'DBD::SQLite', and not some alternate 
or abbreviated version that either leaves the 'DBD::' out or is 
spelled differently.  Similarly, the DBI driver loader should 
simply try to load exactly the driver name it is given, without 
munging of any type.  This approach is a lot more simple, flexible 
and lacks the cludges of the current DBI.  DBI driver implementers 
can also name their module anything they want, and don't have to 
name it 'DBD::*'. A DBI driver should not have to conform to 
anything except a specific API by which it is called, which 
includes its behaviour upon initialization, invocation, and 
destruction.


Is this useful?

I can't see a reason that the DBI.new() / DBI.connect() call shouldn't be
flexible in what it accepts;

  $dbh = DBI.new( :driverRosetta );   # means DBD::Rosetta
  $dbh = DBI.new( :driverRosetta::Emulate::DBD ); # specify full package
  $dbh = DBI.new( 

Re: DBI v2 - The Plan and How You Can Help

2005-07-03 Thread Sam Vilain

Hey Tim.

 I've kept an eye on Perl 6 and Parrot developments but I'm no expert in
 either. What I'd like *you* to do is make proposals (ideally fairly
 detailed proposals, but vague ideas are okay) for what a Perl 6 DBI API
 should look like.
 Keep in mind that the role of the DBI is to provide a consistent
 interface to databases at a fairly low level. To provide a *foundation*
 upon which higher level interfaces (such as Class::DBI, Tangram, Alzabo
 etc. in Perl 5) can be built.

OK, well based on my experience, here's a few things that would be nice;

  - optional treatment of the statements as an AST, similar in concept to
SQL::Routine, or Tangram::Expr.  Death to SQL templating systems!

Ideally there should be no need for a module like DBD::CSV or even,
eventually, DBD::SQLite to actually generate SQL strings for queries;
the AST is enough for them to go away and run the query.

It should be possible to use either, though - and use /named/
placeholder arguments for either, something like:

use DBI-2;
my $dbi = DBI-connect(...);
my $sth = $dbi-prepare(select * from foo where bar = :bar);
$sth-execute(:bar($bar));

my $table = $dbi-table(foo);
my $sth = $dbi-select
(:all
 :from($table),
 :where($table.bar == $dbh.placeholder(bar))
);
$sth-execute(:bar($bar));

Virtually every major DB abstraction tends to build this, whether or
not they know they're doing it ;).

  - support for automatically pulling database DSN information from a
~/.dbi (or similar) file.  This is constantly re-invented poorly.
Let's just do a connect by logical application name and let the
SysAdmins sort out which DB that connects to, in a standard way.

  - object-oriented modelling of core database objects, so that schema
operations can be made portable, a la Rosetta.  This should really
just constitute re-thinking the existing interfaces, and leaving it
up to the DBD authors to finish them up.

This may also open the door for unifying the way that relationships
such as foreign key constraints, etc are dealt with.

  - make it easier to get ACID right; steal Tangram's `tx_do` transaction
interface; though I'd suggest a name including the perl6-ish `try'

 $dbh.tx_try {

 # ... transaction ...

 };

in fact, if you were to wrap the closure in an atomic{ } block, then
you could probably easily support replaying the transaction in the
event of a forced rollback (so long as the code in the closure has no
side effects ... g)

Also there is the nested transction interface;

$dbh.tx_start;
$dbh.tx_start;
$dbh.tx_commit;
$dbh.tx_commit;  # commit happens here

Some databases can even support nested transactions internally via
SQL SAVEPOINTS.

  - asynchronous/event-based processing of queries, so that we don't need
yet another sub-process when in POE-like environments (which might
include a standard Perl 6 event programming system).

In terms of making things Perl6-ish, you probably want to look at technology
such as coroutines for cursors, and continuations for exception handling, for
their implications to writing transactional applications.

Perl 6 will be able to serialise continuations and probably also coroutines,
so it should be possible for a continuation serialised with an active cursor
in a coroutine to automatically resume itself once the continuation is thaw'ed.

This might happen by simply leaving the transaction open (I hear screams!) in
a single threaded context, or by rolling back, replaying the transaction's
queries on the continuation resume and checking all the database responses
match what was previously read.  At the first sign of discrepancies, the
next database operation would throw a fake ROLLBACK; which would even be
caught and the application transaction replayed from the beginning, if they
used .tx_try :retry(3), :{ ... }

This would make some of the old problems, such as object versioning,
potentially a lot easier to solve.

Allow me to illustrate with some application code;

  my $mvc;

  if ($mvc.controller.action eq edit) {
 my $id = $mvc.controller.edit_id;
 my $object;
 $dbi.tx_try {
$object = $fetch_query.select_only(:id($id));

$mvc.view(:state(edit), :object($object))
   until $mvc.controller.action eq commit;

$update_query.execute(:id($id));

CATCH {
$mvc.view(:state(error),
  :message(object modified by another!));
}

 }, :retry(3);
 $mvc.view(:state(edit), :object($object));
  }

So, depending on the MVC system in use, when you wrote $mvc.view(), it
will have done one of the following things;

Session-based continuations:

1. Serialise the continuation - when it comes across the DBH with an
   active transaction, it creates 

DBI v2 - The Plan and How You Can Help

2005-07-01 Thread Tim Bunce
Once upon a time I said:

  
http://groups-beta.google.com/group/perl.dbi.users/msg/caf189d7b404a003?dmode=sourcehl=en

and wrote

  http://search.cpan.org/~timb/DBI/Roadmap.pod

which yielded:

  https://donate.perlfoundation.org/index.pl?node=Fund+Drive+Detailsselfund=102

(A little over $500 of that I effectively put in myself.)

My *sincere* thanks to all those who donated to the fund, especially
individuals. I had hoped for more corporate response with less from
individuals and I'm touched by the personal generosity shown.

I've not drawn any money from it yet and doubt that I will myself.
(I'm considering suggesting that the Perl Foundation make payments
from the fund to people making specific contributions to the DBI.
I'm thinking especially of work on a comprehensive test harness.
But I'll see how the developments below pan out before making
specific arrangements.)


So, that lead to:

  
http://groups-beta.google.com/group/perl.dbi.dev/browse_frm/thread/ef14a9fc0a37441f/fb8fe20a86723da0#fb8fe20a86723da0

Which sums up fairly well where I'm at: DBI v1 will rumble on for Perl 5
and DBI v2 will be implemented for Perl 6.


--- digression ---

At this point I'd like to make a slight digression to highlight the
amazing work going on in the Perl 6 community at the moment.
Especially Autrijus' Pugs project which has brought Perl 6 to life.
Literally. Take a look at:

http://pugscode.org/talks/yapc/slide1.html
http://use.perl.org/~autrijus/journal

and especially:

http://use.perl.org/~autrijus/journal/24898

Yes, that really is Perl 6 code using the DBI being executed by Pugs.

That's great, and I was truly delighted to see it because it takes the
pressure off the need to get a DBI working for Perl 6 - because it
already is working for Perl 6. At least for Pugs. (The Ponie project
is also likely to provide access to Perl 5 DBI from Perl 6 by enabling
future versions of Perl 5 to run on Parrot.)

--- digression ---


I have recently come to an arrangement that will enable me to put some
worthwhile development time into DBI (still very much part-time, but
enough to give it focus and move forward).

My initial goals are:

 1. to work on a more detailed specification for the DBI v2 API that
takes advantage of appropriate features of Perl 6.

 2. to work on a more detailed specification for the DBDI API
http://groups-beta.google.com/group/perl.perl6.internals/msg/cfcbd9ca7ee6ab4

 3. to work on tools to automate building Parrot NCI interfaces to
libraries (such as database client libraries, obviously :)


But I'm hoping you'll join in and help out.

I've kept an eye on Perl 6 and Parrot developments but I'm no expert in
either. What I'd like *you* to do is make proposals (ideally fairly
detailed proposals, but vague ideas are okay) for what a Perl 6 DBI API
should look like.

Keep in mind that the role of the DBI is to provide a consistent
interface to databases at a fairly low level. To provide a *foundation*
upon which higher level interfaces (such as Class::DBI, Tangram, Alzabo
etc. in Perl 5) can be built.

So, if you have an interest in the DBI and Perl 6, put your thinking
cap on, kick back and dream a little dream of how the DBI could be.
How to make best use of the new features in Perl 6 to make life easier.

Then jot down the details and email them to me (or to dbi-users@perl.org
if you want to kick them around in public for a while first).

I'm about to fly off for two weeks vacation (in a few hours), blissfully
absent of any hi-tech gear beyond a mobile phone. When I get back I'll
gather up your emails and try to distill them into a coherent whole.

Have fun!

Tim.