develooper Front page | perl.dbi2.dev | Postings from October 2005

Drivers and Data Source Names

Thread Next
From:
Tim Bunce
Date:
October 4, 2005 15:19
Subject:
Drivers and Data Source Names
Message ID:
20051004133907.GA10159@timac.local
No comments on 'Assumptions and Principles', but I guess they weren't
very controversial. 

Maybe this next chunk will be more so...

Tim.

=head1 Attributes

Attributes set/get will be via method calls.

XXX need to consider handling of unknown attributes (ie version skew)
and driver-private attributes. c.f. JDBC 4 wrapper pattern.

Separate client-side attributes from server/db-side?

=head1 Drivers

Driver metadata should be accessible without loading db client api lib.
That lets us cheaply and safely 'load' all drivers and at least query metadata.

Need more extensive driver metadata.
Including which attributes a driver needs to connect - for UI.

=head2 Wrapping/Nesting Drivers

It should be simple to wrap one driver within another in order to enhance or
modify the behaviour of the wrapped driver.

The DBI should provide a set of base classes that implement a 'transparent'
wrapper driver.

The logging and profiling of DBI method calls, currently embedded into the
Perl5 DBI method dispatcher, could then be implemented by creating subclasses
of the transparent wrapper driver.

The same mechanism could form the basis of many enhancements such as lazy
connections, SQL rewriting, simple replication/clustering etc. 

If separate 'proxy' drivers implement logging, profiling, proxy etc a single
URI can specify the entire set of nested drivers and which attributes to pass
to to each.  May also need to give different auth to each.
Example: http://www.p6spy.com/

Could also possibly implement automatic failover/back via a wrapper driver.
Semantics: http://dev.mysql.com/doc/mysql/en/cj-configuration-properties.html

If layering over actual jdbc drivers then we'll need a way to pass-thru the
full jdbc uri as a special case.

=head1 Data Source Names

Data Source Names will be valid URIs (RFC 2396: http://www.faqs.org/rfcs/rfc2396.html).

The "resource" being identified is a connection to a database or server instance
along with optional connection attributes.

=head2 "dbi:" Scheme URI Structure

Exact scheme structure to be determined but will conform to the "generic URI"
format and so can be manipulated effectively using modules like URI
L<http://search.cpan.org/~gaas/URI/URI.pm#GENERIC_METHODS>
This includes the use of per-segment path parameters - see section 3.3 of the RFC.

Some generic and specific examples:

	dbi://host/driver/dbname
	dbi://foo.com/mysql/dbname

	dbi:/driver/dbname   # assumes localhost unless driver and dbname imply otherwise
	dbi:/Oracle/TNSNAME

	dbi://user:pass@host:port/dbtype;driver-params/dbname;connection-params
	dbi://fred:poor@foo.com:1234/mysql;foo=bar/testdb;AutoCommit=0;mysql_bop=auto

This works well for most cases except where the datasource is specified by a
path containing slashes. The forward slash characters need to be escaped:

	dbi:/SQLite/%2Fpath%2Fto%2Ffile

but that's hardly friendly, so there's a possible alternative form:

	dbi:/SQLite/&?/path/to/file

or, as the file path logically corresponds to the host:port portion:

	dbi://&/SQLite?/path/to/file

Here the "&" character represents whatever is in the query portion of the URI.
But that's just a handy shorthand for humans, not the canonical form.
Non-trivial DSN URIs should be constructed using the URI module, or similar.

I'm trying to avoid using the 'obvious' forms:

	dbi:/SQLite/absolute/path/to/file     # no
	dbi:/SQLite/./relative/path/to/file   # no

because I want to reserve further levels of the URI path component for other uses.
(Though it partly depends on how the driver nesting/wrapping issue gets resolved.)

=head2 Indirection

Some level of indirection is needed in the interpretation of DSNs.
Multiple 'driver manager like' entities can be given the opportunity to
accept or decline to provide a connection for the given DSN.

This indirection may be used to implement auto proxying or other kinds of
driver layering where one driver recurses into the driver manager to find
the 'real' driver for the DSN that it will then wrap.

The plugin multiple driver managers can also implement name service lookups
to map simple names (like "dbi:sales") into full DSNs via some external
service like LDAP or even a ~/.dbi file. See JDBCs use of JNDI.

A 'driver' could also only serve the purpose of determining which real driver
you wanted to use. Consider this URI:

	dbi:/dsnuri?file:~/.dbi-dsn.txt#myname

The 'dsnuri' driver could open the ~/.dbi-dsn.txt text file and read the DBI URI
identified as 'myname' (ignoring the details of how it's identified for now)
and then load that URI.  Similarly:

	dbi:/dsnuri?http://...
	dbi:/dsnuri?dbi:...         :-)

=head2 Connection Pooling

Driver managers will also be where connection pooling is implemented (or at
least, abstracted).

=cut

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About