Re: The future of database packages in PEAR

From: Date: Fri, 15 Dec 2006 18:21:38 +0000
Subject: Re: The future of database packages in PEAR
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-45263@lists.php.net to get a copy of this message
After a look at the Doctrine documentation, I'm impressed. It would be great to have this become a PEAR package, if the author (Konsta Vesterinen) is interested. Like Mark, I had been thinking about how PHP 5 versions of MDB2 and DB_Table could provide something similar in capability to Doctrine. As Mark mentioned, I'm now close to finishing a first release of a _Database subpackage of DB_Table, which builds a relational database layer above the DB_Table table abstraction layer. (A somewhat outdated discussion, with links to an early version of the phps source, is one the web here: http://www.cems.umn.edu/~morse/DB_Table_Database/docs/about.html) This relational database abstraction layer knows about foreign key and joining table relationships, and so can do things like automating construction of join conditions. DB_DataObjects also has some abiity to do such things. Equivalent features for automating joins already exist in Doctrine. (The most notable difference is the lack of support for multi-column foreign keys in Doctrine, as already noted). Regarding Lukas' suggestion that PEAR developers focus on contributing to Doctrine rather than developing new generations of MDB2 and related classes: The more I look at the documentation for Doctrine, the more I'm inclined to agree. Most of what we might hope to achieve with a PHP 5 rewrite of MDB2 and DB_Table(+_Database) is already there, and apparently well tested in Doctrine. There is a separate advantage to basing further work on PEAR PHP 5 database packages on PDO, because it has been bundled with PHP 5, and because it is coded as a C extension and is purported to be faster than other portable DBALs. There is a problem of complexity: The entire package looks well designed, but it takes some time to get your head around. It would be difficult to learn the entire public API. The size of the API is a potential barrier for more casual or impatient users. This barrier could be reduced if an influx of new developers and users helped write tutorials with relatively simple usage examples. It is also true, moreover, that most of the basic functionality provided by MDB2 alone is provided by PDO, which has a relatively simple API. I don't know if I will be of much help with any of this after I get DB_Table_Database written, because of limited time. The opinions that really matter will be those of people who have more time to contribute. Nonetheless, here are some comments and questions I have after reading the user documentation and trying to absorb some of the API documention (http://doctrine.pengus.net/API/index.html). Some of these are really questions for Konsta. Lukas, if you have a current email address for Konsta, could you forward him this message, and encourage him to sign up for pear-dev and to participate in a discussion? I assume other people will also have questions. Database Management: -------------------- It's not yet clear to me how Doctrine manages the relationship between the php objects that represent tables and the actual RDBMs tables to which they bind. Does instantiation of a table or record objects automatically trigger creation or verification of the existence of a real table (as occurs during instantiation of a DB_Table object)? I found it hard to figure this out. I don't see Doctrine methods for creation, alteration, and dropping of tables and sequences, similar to those provided by the MDB2 Manager classes and the constructor and some methods of DB_Table. There are some reasons to have database management (data definition language) methods integrated with data manipulation and query methods, because it allows table creation and mofification to be based on abstract data types. The MDB2 Manager and MDB2_Schema classes also provide reverse-engineering of table schemas. (I should mention that table modification is inherently more complicated in a database with foreign key relationships, since you have to make sure that the PHP database model remains sane and accurate when tables are modified. This is something that I haven't fully grappled with in DB_Table_Database.) If Doctrine does not contain as rich a set of table and sequence management methods as those of MDB2, a new set of Manager classes might be needed, based on PDO and the Doctrine abstract datatypes. If so, I wonder if this could one of the biggest costs of a refocusing of developer effort. Data Type Abstraction: ---------------------- Doctrine has some nice abstract data types that I don't think exist in MDB2, namely, enumerations, arrays, and objects (arrays and objects are stored in serialized form), as well as those supported by MDB2. One weakness in the current PHP 4 MDB2/DB_Table stack of classes is that the MDB2 and DB_Table abstract data types were defined independently, and are not entirely consistent in either choice of what types to support or how they are stored in different databases. (MDB2 makes more use of native data types, while DB_Table tries to store some things like dates and times in the same way in different RDBMS, using more primivite types). While this has been worked around in the current version of DB_Table, it is something that IMO would be important to fix during any simultaneous PHP 5 rewrites of both packages. More generally, if development of MDB* and MDB*_Table continues, it will be important to try to make the two packages more coherent. One signficant advantage of Doctrine is that it was designed as a single coherent application. A similar level of coherence could be achieved by a simultaneous PHP 5 update of MDB2 and DB_Table, but I don't think it exists yet. One nice feature of MDB2 is the ability to specify the PHP types of the values returned by a query. In contrast, PEAR::DB seems to always return non-null values as strings. It is not clear to me from the user documentation how Doctrine decides the php types of values in the rows returned by queries, or if the user can dictate these. It appears to be possible that the Doctrine could actually have enough information to figure out the appropriate data types automatically (see discussion of DQL below), but I'd like to get this clarified. If Doctrine doesn't include a way to specify returned data types from queries, it is something that should be considered for addition. I'm interested in this partly because I've been trying to figure out how to get DB_Table_Database to choose appropriate data types for columns in the return sets by itself. At a minimum, this requires the ability to specify the types of the columns in the return set and 'knowledge' of the database schema. It is not that hard to implement this for some simple cases, as when the query 'SELECT' clause involves only a series of column names. If the select clause involves expressions or SQL operators, however, it becomes impossible to do this without parsing and analyzing the SQL. SQL Abstraction: ---------------- Doctrine provides a level of SQL query abstraction that does not exist in DB/MDB2/DB_Table (or anywhere else that I know of). In Doctrine, queries can be submitted in a Doctrine Query Language (DQL) that appears to be, essentially, a dialect of SQL, with a very concise way of specifying when known relationships should be used to construct joins. This is silently parsed and internally converted to the appropriate SQL dialect for the backend RDBMS. The use of some sort of RDBMS-indepedendent SQL dialect that can be parsed by the php layer seems to me to be a important advance, both for SQL portability, and because it will enable automation of some things that would otherwise be impossible. In particular, it provides a way of solving my problem of how to teach the php layer to choose php types for the values returned by a query: If the php application parses and analyzes a query, and knows the database schema, it has all the information it needs to do this. I can't tell if Doctrine is already using this information to set return types. Data Type Validation --------------------- DB_Table checks that data is of the correct type for each column before inserting it, and checks that, e.g., date and time variables have the correct formats. The documentation for Doctrine shows how specific validators can be added to columns, including many that are not simply based on the column types (e.g., the email validator). Is there any kind of automatic minimal checking or recasting of data types, based on the declared column types? Referential Integrity --------------------- About the ownsOne and ownsMany methods of declaring relations, the Doctrine documentation says that: "Basically, using the owns* methods is like adding a database level ON CASCADE DELETE constraint on a related component, with the exception that doctrine handles the deletion in application level." Aside from this, how does Doctrine deal with enforcing foreign key integrity? Are foreign key constraints declared in the create table statements, so that they can be enforced by the RDBMS (if supported?) Are foreign keys checked at the application layer upon insertion and updating? If a row that "has" (rather than "owns") another is deleted, is anything done to the referencing columns? What (if anything) is done to referencing columns upon updates of referenced keys? In DB_Table_Database, I've tried provide optional php emulation of all the referential integrity checks and actions that are provided by a fully relational database such as postgreSQL, but not by, e.g., SQLite. This is not a feature that everyone will care about, but it made me curious how Doctrine deals with the issue of referential integrity. XML ---- The documentation for Doctrine emphasizes that configuration of a Doctrine application is not based parsing XML configuration files. Aside from initial configuration, however, XML or some other text format has an important role as a way of communicating a database schema between applications or packages. If, for example, we have form-generation packages separate from Doctrine or MDB2/DB_Table or DB_DataObject, the form generation package will need a format from which it can extract a table or database schema. Similarly, if someone wants to port an application from MDB2/DB_Table to Doctrine, it would be nice if there were a common format for the database schema that one application could output and another could import. If MDB2_schema has the ability to reverse engineer a schema, and Doctrine does not, it would be nice if they could talk to one another. In writing DB_Table_Database, I tried to adopted the MDB2 XML syntax. Igor Feghali and I have now agreed on a syntax for foreign key constraints, which weren't supported by the MDB2 DTD. It might be worth thinking about adopting this or another XML dialect that supports foreign keys as a sort of standard for communication between packages, or at least adding methods to Doctrine to export and import database schemas in some existing XML dialect. Transactions ------------- It appears from the documentation that Doctrine wraps all SQL commands in transactions. If an application issues a series of several related commands, and the programmer wants to wrap the whole sequence in a transaction, will this interfere with the automatic use of transactions, i.e., is it easy to wrap user defined transactions around ones that Doctrine is using internally? How is this done? -- !-------------------------------------------------------------------! ! David Morse email: morse@cems.umn.edu ! ! Dept of Chem Eng & Mat Sci phone: (612)625-0167 ! ! University of Minnesota ! ! Minneapolis, MN 55455 ! !-------------------------------------------------------------------!

« previous php.pear.dev (#45263) next »