Re: Re: [metabase-dev] pearifying metabase: phase 1
| From: | Manuel Lemos | Date: | Thu, 14 Feb 2002 06:55:16 +0000 |
| Subject: | Re: Re: [metabase-dev] pearifying metabase: phase 1 | ||
| References: | 1 2 3 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-4690@lists.php.net to get a copy of this message | ||
Hello,
"Tomas V.V.Cox" wrote:
> > > - DSN support (minor)
> >
> > This was planned to be added to Metabase similarly to JDBC and it seems
> > to PEAR-DB. I just disagree that the database name be required in the
> > DSN as it seems that PEAR-DB requires. Metabase lets you change the
> > database to each you want to connect in the with the same driver object
> > instance. Actually you may perform queries to a server that has no
> > databases installed. So what PEAR-DB does? I haven't checked, but does
> > it fails to connect because you did not specify a database name?
>
> Yes, we expect from the user to connect to a database :-) Anyway our DSN
> parse function does not require any field, it's a task from the driver
> to check what it needs.
Yes, but to make PEAR DB really portable you need to pass always the
database name because PEAR DB connect method effectively connects to a
database server and some database types require that you specify a
database name to connect.
That is unlike Metabase that only establishes connections on demand,
usually before executing the first query. The SetDatabase method just
stores the database name that is passed, so whenever it is need the
driver classes use the database name to specify in the connection
establishment if it is really required. So, Metabase based portable
database applications do not require specifying the database name and
eventually it may not be needed, for instance when you want to create a
database.
> > > - Missing Drivers
> > > Frontbase (minor?: will the frontbase guys write one/modify the current
> > > for us?),
>
> The Frontbase guys have yet support for both PEAR DB and ADODB.
If they want they may develop a Metabase driver as well.
> > > LDAP (minor: I want it myself, but the driver is fairly new and not that
> > > "feature rich" yet, so we should be able to port it)
> >
> > Yes, this is a long shot that in the end you may realize that doesn't
> > quite fit in a database abstraction layer that is supposed to execute
> > SQL queries.
>
> What is different for us in PEAR, is the fact that we don't expect that
> will be able to do the same with all the drivers. This philosophy allows
> us to give support for things like LDAP or DBASE. This doesn't mean that
> the support for real databases engines should be complete and robust.
If you don't expect to make SQL queries with the LDAP driver, I still
think you are trying to hammer it with an abstraction package that most
people expect to use with SQL.
> > > - tableInfo (minor: metabase allready has some of those features)
> >
> > Actually Metabase does not have this yet. I want to add it because I
> > want Metabase manager to be able to reverse engineer schemas of
> > applications already installed by traditional means, to encourage people
> > to migrate to Metabase and use the database independent schema
> > definition.
>
> tableinfo is a hard point, because it's so difficult to implement in
> some drivers (even more info from a result). If we could cooperate for
> trying to complete for all the drivers we will be able to do cool things
> in the future.
I am not sure what you expect that tableinfo do. Metabase applications
do not rely on the fact that it is possible to read database tables
metadata.
The only interest of that for Metabase is to provide a migration path of
non-Metabase users so they can benefit of Metabase schema management
services.
I don't expect that any other type of application would use database
metadata except for schema reverse engineering where the driver should
do the hardwork of suggesting one or more table field property lists so
a Metabase XML schema can be rebuilt from existing database
applications.
> > > Small:
> > > - Error support (small?: maybe not a big deal through the use if
> > > customer error handler feature of metabase)
> >
> > Yes, Metabase error handler callback should be sufficient to implement
> > whatever error handling methods provides. Metabase passes more
> > information to the error handler callback than just the error string
> > returned by the Error() driver method.
>
> If you don't want to clone all the actual functionality of PEAR.php,
> just use it in the future.
Sure Metabase error handler can provide all the hooks to trigger PEAR
error handling, so nobody has to poke existing Metabase code to do that.
> > > - DB_result object (minor)
> >
> > I think you have all in Metabase that you need to emulate PEAR-DB and
> > probably more.
>
> What's the problem here? IMHO you haven't to clone to architecture, only
> the functionality.
That is what I saying. :-)
> > > - error messages (small?)
> >
> > Error messages is not a problem. What Metabase does not provide is error
> > number abstraction.
> >
> > The way I see it, errors are fatal conditions and so in each situation
> > they should be handled the same way regardless of the type of error that
> > happened. So, I never implemented error abstraction because I don't see
> > much point in having a way to distinguish error types programatically.
> > Usually an error string is enough for logging so the programmer can read
> > the exact error message that the database back end returned along with
> > some context information provided by Metabase but all in text because
> > that is what is useful for humans (programmers).
>
> See some examples on how the abstracted error messages are a real good
> thing:
>
> // Create tables on demand
> $dbh->expectError(DB_ERROR_NOSUCHTABLE);
> $res = $dbh->query('DELETE FROM categories');
> $dbh->popExpect();
> if (DB::isError($res) && $res->getCode() == DB_ERROR_NOSUCHTABLE) {
> $dbh->query('CREATE TABLE foo ..');
> }
>
> // This will try to insert a row. If the primary key already
> // exists, then the data will be updated. This system will
> // avoid any race condition.
> $dbh->expectError(DB_ERROR_ALREADY_EXISTS);
> $err = $dbh->query('INSERT INTO ...');
> $dbh->popExpect();
> if (DB::isError($err) && $err->getCode() == DB_ERROR_ALREADY_EXISTS) {
> $dbh->query('UPDATE table SET ..');
> }
>
I don't see any good on this. This is precisely what I said it is not
very well designed.
The reason is simple: you will not be able to make all drivers trigger
these errors that you expect so you have to treat them in some other way
that is the same for errors you did not expect. So you will not be able
to distinguish programming errors for completely unexpected runtime
errors. Because of that, that solution will not work well portably, so
you can make your applications behave the same with all databases.
If you think about it, you will realize that this will only lead to
maintenance nightmares because you will have to provide database
specific support to every user that complains about errors that your
application could not trap the way you thought it was capable of
trapping.
The proper way to do it is by checking status values or query metadata
that will return objective and complete information instead of error
values that may not occur the same way with all databases.
In the examples below, the proper way to do it is by having some
function that lets you figure if the specified table exists or not
before doing the actual query. Anyway, if this is an application that is
supposed to be run only after the table is installed, the application
should not be creating tables or performing any database schema
management because in the real world schema management should be a task
to be performed with DBA permissions, not with application user
permissions.
The other example does is what Metabase Replace function does and your
code is definitly not the right to do it portably.
Do you see now why what you suugested is not a good design?
> > Also, it seems to me that error abstraction is quite utopic because an
> > operation can fail in thousands of ways and a database can return
> > different error codes for each so it will be an hell to categorize all
> > the codes even if the driver can antecipate the meaning of all of them.
>
> Our system is working good, I don't see the real problem.
The real problem is that you can't always handle the same error in
different databases the same way because you may not be able to abstract
it in all databases and so your application will behave differently with
different databases.
> > Another thing that I disagree in PEAR-DB design is that certain
> > conditions that are not errors but just status information is abstracted
> > as errors. For those conditions there should be functions to retrieve
> > them. For instance, querying affected rows or if a driver supports a
> > certain capacity.
> >
> > If a programmer calls a function that is not implemented for a certain
> > driver, that is a programming error, not a run-time error. The program
> > should handle that as a fatal error with any need to distinguish what
> > type of error was that. The right way for programmers to handle the
> > (lack of ) ability of a driver to implement a certain capacity is to
> > query the driver before trying to use it. So there is not need for
> > abstracting this type error either.
>
> Yes, perhaps we could reorder the error numbers so people could
> differentiate between database errors and developer errors.
If you log the error messages they will not have a problem trying to
figure what was a runtime error and what was a programming error.
> > > - API changess like function naming, parameter orders, coding style
> > > stuff (large: a lot of work but nothing too complicated)
> >
> > Forget it for now. Keep in mind that at this point you should be
> > concentrated on making the proof of concept which is wrapping PEAR-DB
> > API around Metabase API and demonstrate that it works as needed so
> > nobody developing PEAR-DB applications need to change their code and the
> > same for Metabase based applications.
>
> Well, to pass the tests at least function naming and parameters order
> should be there no?
You don't need to change anything in Metabase right now. This is the
time to make the proof of concept, not to reformat Metabase code because
that will take much more time that most people can wait for and for now
we just want to figure if the merger is viable.
> > > - different ways of how data is stored in the DB for emulated features:
> > > sequences, NULL ..? (?: this is actually one of those most difficult
> > > areas .. hopefully a simply convert script could take care of it . but
> > > its definitely ugly if certain features have been emulated differently
> > > in the db)
> >
> > Yes, personally this is another thing that I quite don't agree on some
> > PEAR-DB implementations. PEAR-DB should not be executing implicit schema
> > management functions on demand because for security reasons it may not
> > be desired that the current application user have privileges to do it.
> > For instance, it is wrong to create sequence emulation tables on demand
> > because as I said the application user may not have privileges to create
> > tables.
>
> That's why the nextID() method accepts an extra param (bool) $ondemand
> :-)
Again, you may not be able to perform schema management actions in your
database because only a DBA may have permissions to do it, so it is
better to do it separate schema management from the rest of the
operations.
Regards,
Manuel Lemos