<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://groups.drupal.org" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>Database</title>
 <link>http://groups.drupal.org/database</link>
 <description>Discussions about a database schema API for Drupal</description>
 <language>en</language>
<item>
 <title>Databases: The Next Generation task list</title>
 <link>http://groups.drupal.org/node/14222</link>
 <description>&lt;p&gt;With the new &lt;a href=&quot;http://drupal.org/node/225450&quot;&gt;PDO-based database API&lt;/a&gt; now in core (yay!), there are a number of follow-up tasks that need to be taken care of.  They were left out of the original patch for a variety of reasons, mostly keeping the already massive patch from becoming even more massive. :-)&lt;/p&gt;
&lt;p&gt;The full &lt;a href=&quot;http://drupal.org/project/issues?projects=3060&amp;amp;versions=156281&amp;amp;components=database%20system&amp;amp;states=1,16,8,13,14,15,2,4&amp;amp;priorities=&amp;amp;categories=&amp;amp;users=&quot;&gt;Drupal 7 database issue queue&lt;/a&gt; contains over 50 items that should be addressed at some point, but the following in particular relate directly to DBTNG.  Volunteers welcome and encouraged to help out!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299308&quot; title=&quot;http://drupal.org/node/299308&quot;&gt;http://drupal.org/node/299308&lt;/a&gt; - Explicitly require PDO in the installer.  We do kinda require this now.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/298669&quot; title=&quot;http://drupal.org/node/298669&quot;&gt;http://drupal.org/node/298669&lt;/a&gt; - First steps toward restoring database query logging in order to make devel.module work.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/67349&quot; title=&quot;http://drupal.org/node/67349&quot;&gt;http://drupal.org/node/67349&lt;/a&gt; - Support SQLite databases.  Really.  We want this.  A lot. :-)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/195416&quot; title=&quot;http://drupal.org/node/195416&quot;&gt;http://drupal.org/node/195416&lt;/a&gt; - Make database table prefixes per-connection.  If you want to use prefixing and multiple database connections, well, right now you can&#039;t.  Let&#039;s make it possible.  This does impact SimpleTest, too, but if done properly can probably make simpletest&#039;s code easier.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/111011&quot; title=&quot;http://drupal.org/node/111011&quot;&gt;http://drupal.org/node/111011&lt;/a&gt; - Add foreign key support to Schema API.  Even though core can&#039;t leverage them directly, extra metadata can be useful for PHP-level maintenance.  It also is a prerequisite for letting Views leverage Schema API directly.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299268&quot; title=&quot;http://drupal.org/node/299268&quot;&gt;http://drupal.org/node/299268&lt;/a&gt; - Support &quot;virtual fields&quot; in Schema API.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299176&quot; title=&quot;http://drupal.org/node/299176&quot;&gt;http://drupal.org/node/299176&lt;/a&gt; - Exterminate db_rewrite_sql().  And there will be much rejoicing.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299178&quot; title=&quot;http://drupal.org/node/299178&quot;&gt;http://drupal.org/node/299178&lt;/a&gt; - Support subqueries in FROM clauses.  &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299267&quot; title=&quot;http://drupal.org/node/299267&quot;&gt;http://drupal.org/node/299267&lt;/a&gt; - Add &quot;extenders&quot; to Select queries to support tablesort, pager, and views.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299269&quot; title=&quot;http://drupal.org/node/299269&quot;&gt;http://drupal.org/node/299269&lt;/a&gt; - Flag slave-server-safe queries for better SQL replication.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/299433&quot; title=&quot;http://drupal.org/node/299433&quot;&gt;http://drupal.org/node/299433&lt;/a&gt; - Figure out how we want to remap dynamic query operators.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And of course, convert all of core to the new API so we can remove the BC layer. :-)  That can and should happen in bits and pieces, as well as part of any new patches from now on.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Sun, 24 Aug 2008 09:54:39 +0000</pubDate>
 <dc:creator>Crell@drupal.org</dc:creator>
 <guid isPermaLink="false">14222 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Table &quot;Node&quot; Field &quot;language&quot;</title>
 <link>http://groups.drupal.org/node/12590</link>
 <description>&lt;p&gt;Drupal 6.x.    Table &quot;node&quot;.&lt;/p&gt;
&lt;p&gt;What should the value of the &quot;language&quot; field be if the displayed text is Chinese.&lt;/p&gt;
&lt;p&gt;If a value is required, are there any other things that need to be done so that Chinese symbols are correctly displayed.&lt;/p&gt;
&lt;p&gt;Any help appreciated.&lt;/p&gt;
&lt;p&gt;Steve&lt;br /&gt;
&lt;a href=&quot;http://prime357.org&quot; title=&quot;http://prime357.org&quot;&gt;http://prime357.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ps. I&#039;ve got a &lt;a href=&quot;http://prime357.org/node/109&quot;&gt;thread&lt;/a&gt; running at my site which I think this may be a part issue to it.   As you can imagine it&#039;s becoming very confusing as all I see is either unicode or Chinese symbols (can&#039;t read Chinese).&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/12590#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/5480">chinese</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3305">encode</category>
 <category domain="http://groups.drupal.org/taxonomy/term/5479">encodings</category>
 <category domain="http://groups.drupal.org/taxonomy/term/2797">language</category>
 <group domain="http://groups.drupal.org/australia">Australia</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/mysql">MySQL</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Fri, 20 Jun 2008 04:45:10 +0000</pubDate>
 <dc:creator>superjacent</dc:creator>
 <guid isPermaLink="false">12590 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Looking for Contributors - C++ (and other stuff in time)</title>
 <link>http://groups.drupal.org/node/12566</link>
 <description>&lt;p&gt;Hope I&#039;m not out of line with this request.&lt;/p&gt;
&lt;p&gt;I&#039;m now on the lookout for C++ contributors (and other like stuff in time).   I started the site &lt;a href=&quot;http://prime357.org&quot; title=&quot;http://prime357.org&quot;&gt;http://prime357.org&lt;/a&gt;, which is a separation from my personal blogging (&lt;a href=&quot;http://superjacent.net&quot; title=&quot;http://superjacent.net&quot;&gt;http://superjacent.net&lt;/a&gt; - running) site, in early April this year.    Too much geeky stuff was creeping into the running site.&lt;/p&gt;
&lt;p&gt;The purpose of Prime357 was to track my development in C++ and a place to continue development of the Wordpress to Drupal converter, a &lt;a href=&quot;http://www.realsoftware.com/&quot;&gt;Realbasic&lt;/a&gt; application.   I&#039;ve got some good how-to type tutorials (my opinion) and short demonstration programs which are presented via the Drupal book method.   I first wanted to get some content into the site before seeking contributors so at at least anybody interested could get a feel for my intent (not that it&#039;s set in concrete).&lt;/p&gt;
&lt;p&gt;Unfortunately, as regards C++ my time has been diverted to other IT stuff, the Wordpress converter and very soon &lt;a href=&quot;http://www.purebasic.com/&quot;&gt;Purebasic&lt;/a&gt; development which will in time will replace Realbasic as the development tool for the Wordpress (and phpBB) converter.   I&#039;m getting a heap of hits relating to the C++ stuff and I&#039;d hate to see it dry up.&lt;/p&gt;
&lt;p&gt;Contributors do not have to be fully fledged C++ coding experts but proficient enough to know what they are talking about which translates to explaining why things are/were done in a certain way.   Ideally in normal English, non sms speak.&lt;/p&gt;
&lt;p&gt;What can I offer contributors?   That&#039;s a good question, nothing but a sense of satisfaction.&lt;/p&gt;
&lt;p&gt;I&#039;m Australian based (Melbourne) and the server is in the US.   So any local contributors would be very welcome but that&#039;s not to say international ones wouldn&#039;t be.&lt;/p&gt;
&lt;p&gt;Okay, that&#039;s my pitch.&lt;/p&gt;
&lt;p&gt;Steve&lt;br /&gt;
&lt;a href=&quot;http://prime357.org&quot; title=&quot;http://prime357.org&quot;&gt;http://prime357.org&lt;/a&gt; and &lt;a href=&quot;http://prime357.org/node/108&quot;&gt;Looking for Contributors&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;ps. Where I&#039;ve mentioned C++, if you wanted, you could substitute PHP and/or Drupal itself.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/12566#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/2176">C++</category>
 <group domain="http://groups.drupal.org/australia">Australia</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/mysql">MySQL</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Thu, 19 Jun 2008 11:37:27 +0000</pubDate>
 <dc:creator>superjacent</dc:creator>
 <guid isPermaLink="false">12566 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Base 36 (Vancode) - leading digit/character</title>
 <link>http://groups.drupal.org/node/12038</link>
 <description>&lt;p&gt;I hope this is the right area for this question which refers to the &#039;thread&#039; field of the table &#039;comments&#039;.   I provide a non php solution to convert  &lt;a href=&quot;http://prime357.org/node/63&quot;&gt;Wordpress data to Drupal&lt;/a&gt;.   I recently became aware that the thread field is not a string of decimal numbers but is in fact a string of base 36 (Vancode) numbers.   I&#039;ve created the necessary functions to convert to and from base 36 format but I&#039;m a little confused re - the leading digit/character.&lt;/p&gt;
&lt;p&gt;Here is an excerpt from &lt;a href=&quot;http://api.drupal.org/api/function/int2vancode/5&quot; title=&quot;http://api.drupal.org/api/function/int2vancode/5&quot;&gt;http://api.drupal.org/api/function/int2vancode/5&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Generate vancode.&lt;/p&gt;
&lt;p&gt;Consists of a leading character indicating length, followed by N digits with a numerical value in base 36. Vancodes can be sorted as strings without messing up numerical order.&lt;/p&gt;
&lt;p&gt;It goes: 00, 01, 02, ..., 0y, 0z, 110, 111, ... , 1zy, 1zz, 2100, 2101, ..., 2zzy, 2zzz, 31000, 31001, ...&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;So, &lt;code&gt;decimal 35 = z&lt;/code&gt; and so it is written as &lt;code&gt;0z&lt;/code&gt;.   The leading zero in this case, how does that indicate length?    Therefore &lt;code&gt;decimal 36 = 10&lt;/code&gt; and so is written as &lt;code&gt;110&lt;/code&gt; as per the excerpt above.   Again, how does the leading character &lt;code&gt;1&lt;/code&gt; indicate length when the length of &lt;code&gt;10&lt;/code&gt; is &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Obviously I can see a pattern forming whereby the leading character for the first 36 is 0, the next 36 is 1, the next 2 and so on up until z.   Is there an assumption that the leading character will never be greater than &quot;z&quot;.&lt;/p&gt;
&lt;p&gt;Any help appreciated.&lt;/p&gt;
&lt;p&gt;Steve&lt;br /&gt;
&lt;a href=&quot;http://prime357.org&quot; title=&quot;http://prime357.org&quot;&gt;http://prime357.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: &lt;i&gt;Since no response from the initial group (Database Schema API) I&#039;m posting to other groups I think might be relevant.   Secondary question is, for specific backend database type questions which group or forum is most relevant.   I&#039;ve got other backend database type questions waiting in the wings.&lt;/i&gt;&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/12038#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/5373">base 36</category>
 <category domain="http://groups.drupal.org/taxonomy/term/5372">vancode</category>
 <group domain="http://groups.drupal.org/australia">Australia</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/drubb">DruBB</group>
 <group domain="http://groups.drupal.org/drupal-dojo">Drupal Dojo</group>
 <group domain="http://groups.drupal.org/mysql">MySQL</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Fri, 06 Jun 2008 00:13:04 +0000</pubDate>
 <dc:creator>superjacent</dc:creator>
 <guid isPermaLink="false">12038 at http://groups.drupal.org</guid>
</item>
<item>
 <title>South Bay: Birds of a Feather session at MySQL Con followed by Sun &amp; MySQL party (Both free attendance)</title>
 <link>http://groups.drupal.org/node/10710</link>
 <description>&lt;p&gt;Join &lt;a href=&quot;http://drupal.org/user/18703&quot;&gt;Amazon&lt;/a&gt; (Kieran Lal) and other Drupal community members and leaders at the Drupal Birds of a Feather session at the MySQL Conference &amp;amp; Expo on Wednesday, April 16th at 7:30pm. The BoF takes place in Ballroom “E” at the Santa Clara Convention Center. Afterwards, Sun will be giving away a Playstation 3 and Sun Fire X2100 M2 Server ($2,495) at their party next door. Wear your Drupal shirt!&lt;/p&gt;
&lt;p&gt;More info about the conference:&lt;br /&gt;
&lt;a href=&quot;http://en.oreilly.com/mysql2008&quot; title=&quot;http://en.oreilly.com/mysql2008&quot;&gt;http://en.oreilly.com/mysql2008&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More info about the Sun party:&lt;br /&gt;
&lt;a href=&quot;http://en.oreilly.com/mysql2008/public/schedule/detail/3338&quot; title=&quot;http://en.oreilly.com/mysql2008/public/schedule/detail/3338&quot;&gt;http://en.oreilly.com/mysql2008/public/schedule/detail/3338&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Address:&lt;br /&gt;
5001 Great America Pkwy, Santa Clara, CA&lt;/p&gt;
&lt;p&gt;Driving Directions and Map:&lt;br /&gt;
&lt;a href=&quot;http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=santa+clara+convention+center,+santa+clara,+ca&amp;amp;jsv=107&amp;amp;ie=UTF8&amp;amp;layer=c&amp;amp;cbll=37.436839,-121.965923&amp;amp;ll=37.436839,-121.965923&amp;amp;spn=0.066243,0.12085&amp;amp;z=13&amp;amp;iwloc=B&quot; title=&quot;http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=santa+clara+convention+center,+santa+clara,+ca&amp;amp;jsv=107&amp;amp;ie=UTF8&amp;amp;layer=c&amp;amp;cbll=37.436839,-121.965923&amp;amp;ll=37.436839,-121.965923&amp;amp;spn=0.066243,0.12085&amp;amp;z=13&amp;amp;iwloc=B&quot;&gt;http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=santa+clara+convention+...&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Public Transportation:&lt;/p&gt;
&lt;p&gt;Amtrak&lt;br /&gt;
There is an Amtrak station in Santa Clara at Tasman Ave. and Lafayette Street, underneath the Tasman Avenue overpass. The Great America Santa Clara stop is on the Capitol Corridor route with service to and from Sacramento. There are three trains daily. 1 (800) USA-RAIL.&lt;/p&gt;
&lt;p&gt;BART&lt;br /&gt;
You can take the Santa Clara County Transit to and from the Fremont BART station. (510) 441-2278.&lt;/p&gt;
&lt;p&gt;The Great America VTA Light Rail (&lt;a href=&quot;http://www.vta.org&quot; title=&quot;www.vta.org&quot;&gt;www.vta.org&lt;/a&gt;) stop is directly in front of the hotel and convention center, and provides an easy connection to the San Jose International Airport, Downtown San Jose, Mountain View, and Caltrain. Using Caltrain you can easily connect to San Francisco International Airport, Downtown San Francisco, and BART.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/high-performance&quot;&gt;High performance&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/10710#comments</comments>
 <enclosure url="http://groups.drupal.org/files/k3_sunfirex2100m2_2.jpg" length="25805" type="image/jpeg" />
 <group domain="http://groups.drupal.org/bay-area">Bay Area</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/high-performance">High performance</group>
 <pubDate>Mon, 14 Apr 2008 21:44:28 +0000</pubDate>
 <dc:creator>sooz</dc:creator>
 <guid isPermaLink="false">10710 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Some review and proposal about Drupal 7.x database stack</title>
 <link>http://groups.drupal.org/node/8907</link>
 <description>&lt;p&gt;I start my Drupal + Oracle research since the end of Drupal 4.7 life cycle (around Oct 2006), based on my client&#039;s request. The project is still running, but I am not satisfy about its progress. After keep trace in Drupal database stack implementation for more than years, it is time for focusing on Drupal 7.x development.&lt;/p&gt;
&lt;p&gt;So what are the changes since 4.7.x? And what will be happened for 7.x? I would like to share my research progress with you, and so let&#039;s brain storming for what&#039;s next :-)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_title.png&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;drupal-4.7.x-5.x&quot;&gt;Drupal 4.7.x/5.x&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D5.png&quot;&gt;&lt;img src=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D5.png&quot;&gt;&lt;/a&gt;&lt;br /&gt;
Fig 1.1 Drupal 5.x database stack.&lt;/p&gt;
&lt;p&gt;The case of Drupal 4.7.x and 5.x is very similar: we support both MySQL and PostgreSQL backend, with specific database access API file (e.g. database.mysqli.inc), enclosed with database.inc, and that&#039;s all. We still have some extra abstraction build on top of this simple model, e.g. tablesort.inc and pager.inc, for some useful application layer abstraction.&lt;/p&gt;
&lt;p&gt;During this period, core and contribute developers need to understand the differences between MySQL and PostgreSQL, since database schema must handle manually. I would like to call this as the dark age of our history: we are asking every contribute developers as both MySQL and PostgreSQL expert (but most of us coming with MySQL-only skill set), or else code was not portable. This result in a complicated PostgreSQL support, and so most contribute modules are MySQL only.&lt;/p&gt;
&lt;h2 id=&quot;drupal-6.x&quot;&gt;Drupal 6.x&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D6.png&quot;&gt;&lt;img src=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D6.png&quot;&gt;&lt;/a&gt;&lt;br /&gt;
Fig 2.1 Drupal 6.x database stack.&lt;/p&gt;
&lt;p&gt;For our newest stable Drupal release - 6.x, Schema API is being introduced. We spend a lot of time for its development, during 6.x 1-year development life cycle. It is target to solve the schema problem as mentioned above. Contribute developers are no longer required as bi-expert nor multi-expert: we just need to know how to define our schema in a correct Schema API syntax, Schema API will handle the rest for us. IMHO, it is very powerful, and it is an important improvement for other database development.&lt;/p&gt;
&lt;p&gt;drupal_write_record() is being introduce, too. This handy function will grep out existing cached schema, and build INSERT/UPDATE queries for us automatically. It try to handle all column type binding for normal developers, which is usually very bulky in implementation.&lt;/p&gt;
&lt;p&gt;BTW, the work is not too elegant: all stuff are mixed into database.*.inc, and so files are even split as 2 section (groups &lt;code&gt;database&lt;/code&gt; and &lt;code&gt;schemaapi&lt;/code&gt;) internally. This may increase the difficulty for our core maintenance.&lt;/p&gt;
&lt;p&gt;Most likely, this design is very similar as &lt;a href=&quot;http://docs.moodle.org/en/XML_database_schema&quot;&gt;Moodle 1.7+ XMLDB&lt;/a&gt; implementation.&lt;/p&gt;
&lt;h2 id=&quot;drupal-7.x&quot;&gt;So what&#039;s coming next for Drupal 7.x?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D7_hook.png&quot;&gt;&lt;img src=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D7_hook.png&quot;&gt;&lt;/a&gt;&lt;br /&gt;
Fig 3.1 Well... So what&#039;s coming next for Drupal 7.x?&lt;/p&gt;
&lt;p&gt;The truth is: I don&#039;t know the overall schedule up to this moment. &lt;a href=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint group&lt;/a&gt; is now hard working for this, and going to present their research progress in Boston DrupalCon 2008. Since we are going to use PHP PDO (instead of legacy PHP database connection drivers), people are also focusing on implement Data API or Active record model for a higher level of abstraction. Before they have their final decision, I would like to provide some successful case study as reference, and let&#039;s brain storming for the optimal solution :-)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://edin.no-ip.com/html/files/MoodleDBStack.png&quot;&gt;&lt;img src=&quot;http://edin.no-ip.com/html/files/MoodleDBStack.png&quot;&gt;&lt;/a&gt;&lt;br /&gt;
Fig 3.2 Moodle 1.7+ XMLDB stack. From &lt;a href=&quot;http://docs.moodle.org/en/Development:XMLDB_introduction#The_Stack&quot;&gt;doc.moodle.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When we are talking about improve our database abstraction as more powerful and universal, Moodle 1.7+ XMLDB stack should act as a perfect example (it since &lt;a href=&quot;http://docs.moodle.org/en/Release#Moodle_1.7&quot;&gt;Nov 2006&lt;/a&gt;). As Moodle core uses ADOdb internally, this possibility has been present since the beginning. Plus their XMLDB abstraction, Moodle 1.7+ is able to handle both MySQL, PostgreSQL, Oracle and MSSQL while maintaining everything working properly. I will not detail their implementation within this article, and you may refer to their &lt;a href=&quot;http://docs.moodle.org/en/Development:XMLDB_introduction&quot;&gt;introducetion&lt;/a&gt;, &lt;a href=&quot;http://docs.moodle.org/en/Development:XMLDB_roadmap&quot;&gt;roadmap&lt;/a&gt; and &lt;a href=&quot;http://docs.moodle.org/en/Development:XMLDB_problems&quot;&gt;problems&lt;/a&gt; document.&lt;/p&gt;
&lt;p&gt;The most important idea of Moodle&#039;s XMLDB stack is split-brain handling. They left every layer keep focus on their duty ONLY, and so the final approach is perfect and elegant. This is also similar as the well-known &lt;a href=&quot;http://en.wikipedia.org/wiki/OSI_model&quot;&gt;OSI model&lt;/a&gt;: A layer is a collection of related functions that provides services to the layer above it and receives service from the layer below it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D7_draft.png&quot;&gt;&lt;img src=&quot;http://edin.no-ip.com/html/files/DrupalDBStack_D7_draft.png&quot;&gt;&lt;/a&gt;&lt;br /&gt;
Fig 3.3 Research progress of &lt;a href=&quot;http://edin.no-ip.com/project/siren&quot;&gt;Siren&lt;/a&gt; + personal suggestion.&lt;/p&gt;
&lt;p&gt;Well, &lt;a href=&quot;http://edin.no-ip.com/project/siren&quot;&gt;Siren&lt;/a&gt; is my personal research project besides Drupal 6.x, which target to explore the possibility of multiple database support as like as Moodle, Gallery2, and eGroupWare. Moreover, prepare research progress whenever Drupal 7.x is open for public development (and that&#039;s now). Within this project, we are able to support both 5 database + totally 9 PHP database access drivers, including mysql, mysqli, pgsql, oci8, pdo_mysql, pdo_pgsql, pdo_oci, pdo_sqlite and pdo_ibm.&lt;/p&gt;
&lt;p&gt;It sounds interesting, isn&#039;t it? So what changes I have been made in order to support this approach? Just some step forward improvement: split the handle of function calls into number of individual files, and each layer just keep focus on what they are needed for. E.g. split Schema API related functions into schema.&lt;em&gt;.inc, common DML into common.&lt;/em&gt;.inc, and so on. Surly I plug some extra update to our core queries syntax; but most likely, the idea is just very strict forward. The research progress should belongs to &lt;a href=&quot;http://en.wikipedia.org/wiki/Session_layer&quot;&gt;OSI session layer&lt;/a&gt; when compare with OSI model.&lt;/p&gt;
&lt;p&gt;IMHO, Data API is a must for our future, if Drupal is going to be a web service framework. Acting as a high level abstraction should be the best position for it. It should be similar as the idea of &lt;a href=&quot;http://en.wikipedia.org/wiki/Presentation_layer&quot;&gt;OSI presentation layer&lt;/a&gt;, which is one level below our core application APIs. It may implement as OOP or whatever; BTW, according to its duty and responsibility, it should be separated from PDO database access API (where PDO is much similar as &lt;a href=&quot;http://en.wikipedia.org/wiki/Transport_layer&quot;&gt;OSI transport layer&lt;/a&gt; implementation).&lt;/p&gt;
&lt;p&gt;One statement as conclusion: split-brain handling.&lt;/p&gt;
&lt;h2 id=&quot;other_suggestion&quot;&gt;Any else suggestion?&lt;/h2&gt;
&lt;p&gt;Database driver is something only need to be implement once and forever. Once the design of logic is completed, the rest is all about the style of implementation, e.g. using OOP as ADOdb or traditional function callback as Drupal.&lt;/p&gt;
&lt;p&gt;The design of abstraction layer is also similar, too. Once you get a complete study of the variation between each databases, and able to foresee ALL of the needs of their specific limitation, it is all done. There is no such idea of &quot;Contribute Supported Database&quot; within the above 2 layers, and it is what I call as &quot;No gray area, but only black and white&quot;. Whatever you support it, or else you don&#039;t.&lt;/p&gt;
&lt;p&gt;On the other hand, Data API is much different. It try to serve the need of our application, and so its requirement will keep on changing depend on time. Therefore a split-brain handle should be the most suitable implementation. Please correct me if you have some better idea :-)&lt;/p&gt;
&lt;p&gt;But the truth case is: we are lack of PostgreSQL/Oracle/DB2/SQLite/etc developers, and not enough task force nor union for a complete and perfect support for them. Up to this point, I would like to proposal the idea of &quot;Contribute Supported Database&quot; in this way:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Implement ALL possible database drivers into core, and build an abstraction that cover ALL the needs of them. This is a once forever task, and the base of the rest of discussion.&lt;/li&gt;
&lt;li&gt;ALL core libraries and essential modules for installation MUST implemented as universal, so basic installation MUST function for ALL databases. E.g. node, comment, users, block, etc. This is all the duty of our core developers which need to be ensure before stable release. On the other hand, if MySQL (and maybe SQLite, too) is our main focus, just keep its support as perfect as usual.
&lt;p&gt;&lt;i&gt;P.S. an additional pre-requirement for this point: try to implement ALL core module as SQL-99 compatible by default, and so save a lot of time for further more follow up handling.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Label the optional modules as &quot;Not supported&quot; or &quot;Not perfectly supported&quot; within modules selection page, if that is the case of specific database backend; give a different level of support status; or maybe even, disable its activation checkbox by default. Don&#039;t let our second/third priority database hold our stable release!&lt;/li&gt;
&lt;li&gt;left the issue open for contribute developers if they really hope to let that module function for database A/B/C/etc, and release subversions besides stable release for this purpose. E.g. if now search and forum module are not compatible with Oracle, just let it be as Oracle developers duty!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is my ideal proposal. So how about yours? &lt;a href=&quot;http://edin.no-ip.com/html/files/DrupalDBStack.odg&quot;&gt;Here&lt;/a&gt; is the raw file of above images, please feel free to utilize it if you hope to visualize your idea as above :-)&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8907#comments</comments>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/enterprise">Enterprise</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Fri, 15 Feb 2008 06:40:02 +0000</pubDate>
 <dc:creator>hswong3i</dc:creator>
 <guid isPermaLink="false">8907 at http://groups.drupal.org</guid>
</item>
<item>
 <title>DB support as contribute: is it a good idea?</title>
 <link>http://groups.drupal.org/node/8855</link>
 <description>&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Drupal 6.0 is revamped with &lt;a href=&quot;http://api.drupal.org/api/group/schemaapi/6&quot;&gt;Schema API&lt;/a&gt;, so what&#039;s next for Drupal 7.x? &lt;a href=&quot;http://php.net/pdo&quot;&gt;PDO&lt;/a&gt; for sure! With this powerful &lt;b&gt;data-access&lt;/b&gt; abstraction layer, workload will much reduced for DB abstraction layer designers and developers, and finally benefit our contribute developers and end users.&lt;/p&gt;
&lt;p&gt;By the way, together with the decision of Drupal 7.x + PDO, there is also some voice about &lt;b&gt;moving PostgreSQL&lt;/b&gt; (and so other potential databases support, e.g. Oracle, DB2, MSSQL, etc) &lt;b&gt;support away from core, but contribute&lt;/b&gt;; on the other hand, &lt;b&gt;add official SQLite support&lt;/b&gt; into Drupal core, together with MySQL.&lt;/p&gt;
&lt;p&gt;Is this really a good idea? Or even if it is possible? As an existing Drupal + PostgreSQL users, what will this affect your daily work? As a potential customer of Drupal + Oracle/DB2/MSSQL/etc, is this a good new for you, or just an evil? I would like to provide some brief idea for you within this article.
&lt;/p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;After &lt;a href=&quot;http://cvs.drupal.org/viewvc.py/drupal/drupal/database/database.pgsql?hideattic=0&amp;amp;view=log&quot;&gt;more than 6 years of PostgreSQL supporting in Drupal core&lt;/a&gt;, PostgreSQL users are going to have a revamped experience with Drupal 6.0. Drupal 6.0 will ship with &lt;a href=&quot;http://api.drupal.org/api/group/schemaapi/6&quot;&gt;Schema API&lt;/a&gt;, which simplify most of the variation between databases handling - &lt;a href=&quot;http://en.wikipedia.org/wiki/Data_Definition_Language&quot;&gt;DDL&lt;/a&gt;. This useful improvement will not only benefit our existing core and contribute developers, but also simplify most workload for other database driver development, besides MySQL and PostgreSQL. With Drupal 6.0, we can simply foresee the expand of existing market sharing, together with the explore of hidden customers.&lt;/p&gt;
&lt;p&gt;As Drupal 6.0 is ready to launch, it is also a good timing to plan for Drupal 7.x. As we will only support PHP 5.2.x or above in Drupal 7.x, it is for sure that we will revamp our existing DB abstraction layer with the help of &lt;a href=&quot;http://php.net/pdo&quot;&gt;PDO&lt;/a&gt;. It does simplify and standardize a lot of function call implementation, together with some useful new features. If you are a DB abstraction layer designer and developer, moving your work to PDO will save you a lot of time.&lt;/p&gt;
&lt;p&gt;On the other hand, some people also think it is a good timing for adding &lt;a href=&quot;http://drupal.org/node/39260&quot;&gt;Oracle&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/67349&quot;&gt;SQLite&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/165788&quot;&gt;DB2&lt;/a&gt; and &lt;a href=&quot;http://drupal.org/node/74308&quot;&gt;MSSQL&lt;/a&gt; support into Drupal core. Most of this request are halted for 2~3 years.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot;&gt;Some of the developers&lt;/a&gt; are hard working with the future plan for how Drupal 7.x DB handling should looks like. BTW, the idea is most likely for expand Drupal usability and functionality, but not about maintain nor expand different databases supporting: some developers even think &lt;a href=&quot;http://lists.drupal.org/pipermail/development/2008-January/028343.html&quot;&gt;we should&lt;/a&gt; only official support MySQL and SQLite with Drupal 7.x + PDO, but move away PostgreSQL (nor other potential databases) supporting as contribute level.&lt;/p&gt;
&lt;h2 id=&quot;pdo_does_doesnt&quot;&gt;What PDO Does and Doesn&#039;t?&lt;/h2&gt;
&lt;p&gt;For finding out why this brain storming happen, we need to have some idea about what PDO does and doesn&#039;t:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;PDO is a data-access abstraction layer, but not provide a database abstraction.&lt;/b&gt; E.g., this means we can simply forget the function API differences between &lt;a href=&quot;http://php.net/mysql-connect&quot;&gt;mysql_connect()&lt;/a&gt;, &lt;a href=&quot;http://php.net/mysqli-connect&quot;&gt;mysqli_connect()&lt;/a&gt; and also &lt;a href=&quot;http://php.net/pg_connect&quot;&gt;pg_connect()&lt;/a&gt;: we just need to &lt;a href=&quot;http://www.php.net/manual/en/function.PDO-construct.php&quot;&gt;construct a new-standardized PDO object&lt;/a&gt; with different DSN (Data Source Name). Moreover, we can forget those complicated programming logic differences between &lt;a href=&quot;http://www.php.net/manual/en/function.pg-escape-bytea.php&quot;&gt;pg_escape_bytea()&lt;/a&gt;, &lt;a href=&quot;http://www.php.net/manual/en/function.oci-lob-load.php&quot;&gt;OCI-Lob-&amp;gt;load()&lt;/a&gt; and &lt;a href=&quot;http://www.php.net/db2_lob_read&quot;&gt;db2_lob_read()&lt;/a&gt;, but simply using standard &lt;a href=&quot;http://www.php.net/manual/en/ref.stream.php&quot;&gt;Stream API&lt;/a&gt; as &lt;a href=&quot;http://php.net/pdo#pdo.lobs&quot;&gt;PDO LOB (Large OBject) handling&lt;/a&gt;.
&lt;p&gt;BTW, these are most likely abstracted by Drupal 6.x DB API, e.g. &lt;a href=&quot;http://api.drupal.org/api/function/db_connect/6&quot;&gt;db_connect()&lt;/a&gt;, &lt;a href=&quot;http://api.drupal.org/api/function/db_query/6&quot;&gt;db_query()&lt;/a&gt;, &lt;a href=&quot;http://api.drupal.org/api/function/db_decode_blob/6&quot;&gt;db_decode_blob()&lt;/a&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PDO provide &lt;a href=&quot;http://php.net/pdo#pdo.prepared-statements&quot;&gt;prepared statements and variable binding&lt;/a&gt;, even it is not supported by database, e.g. MySQL.&lt;/b&gt; With PDO variable binding, we may use &lt;code&gt;?&lt;/code&gt; or named-variable (leading with &lt;code&gt;:&lt;/code&gt;, e.g. &lt;code&gt;:value&lt;/code&gt;) within prepare statement. This seems to be a good idea for replace our existing user-space printf-syntax (e.g. %d, %f, %s, %b and %%) as PDO&#039;s C/C++ implementation, and simply forget the relationship between data, data type and database column type. This also give a great hope to &lt;a href=&quot;http://groups.drupal.org/node/8001&quot;&gt;Drupal 7.x Data API&lt;/a&gt; research and development.
&lt;p&gt;So isn&#039;t it perfect? No, it is not... First of all, &lt;b&gt;most databases require special LOB handle during variable binding&lt;/b&gt; (specific PDO::PARAM_LOB manually), e.g. &lt;a href=&quot;http://edin.no-ip.com/viewvc/siren/includes/database.pdo_pgsql.inc?view=markup&quot;&gt;PostgreSQL&lt;/a&gt;, &lt;a href=&quot;http://edin.no-ip.com/viewvc/siren/includes/database.pdo_oci.inc?view=markup&quot;&gt;Oracle&lt;/a&gt;, &lt;a href=&quot;http://edin.no-ip.com/viewvc/siren/includes/database.pdo_ibm.inc?view=markup&quot;&gt;DB2&lt;/a&gt;, etc. Only MySQL and SQLite are able to handle variable binding without type specified. Also, &lt;b&gt;there is no spotlight performance different, even we swap queries variable binding from user-space printf-syntax to PDO&lt;/b&gt;, which is proved by &lt;a href=&quot;http://edin.no-ip.com/project/siren/siren-1.0-rc4#benchmarking_result&quot;&gt;benchmarking result&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PDO isn&#039;t a database abstraction layer, it doesn&#039;t abstract and standardize ANY database variation.&lt;/b&gt; E.g., PDO doesn&#039;t solve the problem of reserved words conflict&lt;/a&gt;, it don&#039;t &lt;a href=&quot;http://drupal.org/node/167335&quot;&gt;abstract any SQL function name variation&lt;/a&gt;, it also have not duty with &lt;a href=&quot;http://drupal.org/node/147947&quot;&gt;resolve the maximum string size limitation across most databases&lt;/a&gt;.
&lt;p&gt;Let&#039;s take Oracle LOB handling as an example: PDO give none of help to &lt;a href=&quot;http://php.net/pdo#pdo.lobs&quot;&gt;Oracle LOB INSERT/UPDATE handling&lt;/a&gt;, we still need to use RETURNING + Schema API. According to &lt;a href=&quot;http://edin.no-ip.com/project/siren&quot;&gt;my research progress&lt;/a&gt; and case of Oracle, using standardized function call is the only benefit of using PDO, but didn&#039;t help or simplify any programming logic or implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IMHO, PDO is very useful for DB abstraction layer designer and developer: it do simplify most of the DB function call variation; BTW, when we are talking about &quot;PDO can improve database abstraction and so software with PDO can support more databases&quot;, it is not really truth. PDO don&#039;t have duty with this ;-(&lt;/p&gt;
&lt;h2 id=&quot;contribute_support&quot;&gt;How about Drupal + PostgreSQL (or other databases) support as contribute?&lt;/h2&gt;
&lt;p&gt;It is for sure that MySQL own around 90-95% of our existing market sharing; it is not question that SQLite is a &lt;a href=&quot;http://www.cliki.net/manifest%20type%20system&quot;&gt;manifest typing&lt;/a&gt; database engine; based on the above PDO stuff information, MySQL and SQLite are both very suitable with PDO lossy-form variable binding technology (able to use &lt;code&gt;?&lt;/code&gt; and named-variable binding without type specified). But when we are talking about &lt;b&gt;&quot;How many percentage of PDO technologies are utilized by MySQL and SQLite?&quot;&lt;/b&gt; and &lt;b&gt;&quot;How many percentage of technologies that PDO NOT covered are used by MySQL and SQLite?&quot;&lt;/b&gt;, I guess the answer may just below &lt;b&gt;70%&lt;/b&gt;...&lt;/p&gt;
&lt;p&gt;So what will happen if we seem MySQL and SQLite as our first priority core supported database, and ONLY focus with them? &lt;b&gt;For sure that we will miss out the rest of 30%, which means the basic elements needed by other databases, within Drupal database abstraction layer.&lt;/b&gt; This also means asking other database drivers implement as contribute is just a nonsense, if we only support a subset of requirement within core.&lt;/p&gt;
&lt;p&gt;On the other hand, writing MySQL-specific queries also generate a lot of incompatible issues for PostgreSQL during Drupal 6.x development life cycle. People also claim that &lt;a href=&quot;http://lists.drupal.org/pipermail/development/2008-January/028295.html&quot;&gt;PostgreSQL issues slow down our Drupal 6.x release&lt;/a&gt;. BTW, there is still a lot of incompatible issues even PostgreSQL is now seems as our &quot;Official Supported Database&quot; in Drupal 6.x, we can simply foresee about the case if we just seems it as contribute supported. It is better say that: &lt;b&gt;we are NOT going to support PostgreSQL anymore!&lt;/b&gt; And so the similar case for other databases driver development: &lt;b&gt;we will have NO WAY to implement other database drivers as contribute support!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;PDO + PostgreSQL + LOB handling should be a good example of this assumption. In case of pdo_pgsql, we need to specify PDO::PARAM_LOB manually during INSERT/UPDATE variable binding, and &lt;a href=&quot;http://bugs.php.net/bug.php?id=37124&quot;&gt;must use Stream API for BLOB decode&lt;/a&gt;. Both of these handling are NOT required by MySQL and SQLite. If our Drupal 7.x Data API design are target for MySQL and SQLite ONLY, it is for sure that NO WAY for PostgreSQL driver implement as contribute: we will have no hook for it!&lt;/p&gt;
&lt;p&gt;As a simple conclusion, &lt;b&gt;multiple database support MUST build inside core, with a complete research of what are they needed for.&lt;/b&gt; There is no shortcut, and no gray area. The support of database is just simply a TRUE/FALSE question. Please don&#039;t be faked by the beautiful wording of &quot;Contribute Supported Database&quot;: it is just a sweet poison candy, that is not the truth case, and I have NEVER seen a successful story about this :-p&lt;/p&gt;
&lt;h2 id=&quot;should_do&quot;&gt;Oh my god! So what should I do for it?&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;If you are an existing Drupal + PostgreSQL user&lt;/b&gt;, it is strongly suggest to keep you eye focus on the &lt;a href=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint group&lt;/a&gt;, comment your needs and wish to them, or else you may be fired away without notice. You may also have a look about &lt;a href=&quot;http://drupal.org/project/issues?text=postgresql&amp;amp;states=1,16,8,13,14,15,2,4&amp;amp;projects=&amp;amp;priorities=&amp;amp;categories=&amp;amp;users=&quot;&gt;issues related to PostgreSQL&lt;/a&gt;, give a hand to it if possible, and &lt;a href=&quot;http://groups.drupal.org/node/6980&quot;&gt;comment them as a Wiki collection&lt;/a&gt;. IMHO, it is a critical timing for Drupal + PostgreSQL besides the past 6 years support period. It is time for &lt;b&gt;YOU&lt;/b&gt; to take &lt;b&gt;YOUR&lt;/b&gt; action, or else will be too late.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;If you are a potential customer or user of Drupal + Oracle/SQLite/DB2/MSSQL/etc&lt;/b&gt;, beside the above suggestion for PostgreSQL, I would also like to invite you to give a hand on some &lt;a href=&quot;http://drupal.org/project/issues?projects=3060&amp;amp;text=Siren&amp;amp;states=1,16,8,13,14,15,2,4&amp;amp;priorities=&amp;amp;categories=&amp;amp;users=&quot;&gt;existing issues&lt;/a&gt;, review and comment them, and finally record your work in another &lt;a href=&quot;http://groups.drupal.org/node/8663&quot;&gt;Wiki tasklist&lt;/a&gt;. According to &lt;a href=&quot;http://edin.no-ip.com/project/siren&quot;&gt;some research founding&lt;/a&gt;, we would able to enrich our database supporting without a critical pain of revamp, based on our existing Drupal 6.x DB API implementation. Most research are now completed, so issues review and comment your point of view should be your highest priority. Please remember that: &lt;b&gt;comment is power&lt;/b&gt;, and &lt;b&gt;YOUR&lt;/b&gt; review is very important for speeding up the core support of your target databases.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;My humble conclusion&lt;/h2&gt;
&lt;p&gt;Every developers have their own background, their own wish, their own needs, and also their own rose garden. I would not like to comment this &lt;b&gt;&quot;PostgreSQL as Contribute&quot;&lt;/b&gt; idea as silly; but at least, it is not my cup of tea.&lt;/p&gt;
&lt;p&gt;On the other hand, supporting more database won&#039;t be a conflict with the research and develop of Drupal&#039;s Schema API or Data API: they are target for a better developer and user experience, serving database abstraction should be one of their core duties. Asking for better abstraction and functionality but reduce the number of supported database, or even close the door for other database should be count as loss focus.&lt;/p&gt;
&lt;p&gt;From my point of view, more choice is always better than just giving me a single solution. The use and choose of database should depend on the needed of each individual case of clients and users, but not forced by developers. If we are already close to our target, there is no point for rollback our 6-years progress on tomorrow.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;A beautiful-sweet-poisoned candy? No thanks!&lt;/b&gt;&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8855#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/2777">db2</category>
 <category domain="http://groups.drupal.org/taxonomy/term/844">mssql</category>
 <category domain="http://groups.drupal.org/taxonomy/term/748">oracle</category>
 <category domain="http://groups.drupal.org/taxonomy/term/4089">PDO</category>
 <category domain="http://groups.drupal.org/taxonomy/term/758">PostgreSQL</category>
 <category domain="http://groups.drupal.org/taxonomy/term/4090">SQLite</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/enterprise">Enterprise</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Wed, 13 Feb 2008 08:45:44 +0000</pubDate>
 <dc:creator>hswong3i</dc:creator>
 <guid isPermaLink="false">8855 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Issues Need Review for Enhance Cross Database Compatibility</title>
 <link>http://groups.drupal.org/node/8663</link>
 <description>&lt;p&gt;Enhance cross database compatibility is important for our Drupal Core, especially when we are going to ship D7 with PHP5.2.x PDO implementation. BTW, this will require number of individual patches, so your help and review are required - add it to the top list with a brief description and an estimate of the time to review. Once reviewed, move the issues to the bottom &quot;reviewed&quot; list, perhaps with your name attached.
&lt;/p&gt;
&lt;h3&gt;Need Review&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/371&quot; title=&quot;http://drupal.org/node/371&quot;&gt;http://drupal.org/node/371&lt;/a&gt; - Resolve ANSI SQL-92/99/2003 reserved words conflict. (just a few minute, but need a lot of follow up)&lt;/li&gt;
&lt;li&gt;&lt;del&gt;http://drupal.org/node/199217 - Split Schema API and shared functions from DB drivers. (just a few minute)&lt;/del&gt; (Already come with TNG DB)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/167335&quot; title=&quot;http://drupal.org/node/167335&quot;&gt;http://drupal.org/node/167335&lt;/a&gt; - Handle database-specific SQL functions/operators by simple abstraction. (just a few minute)&lt;/li&gt;
&lt;li&gt;&lt;del&gt;http://drupal.org/node/199101 - Core queries coding style cleanup for PDO development (should be RTBC, but need a lot of follow up)&lt;/del&gt; (Already come with TNG DB)&lt;/li&gt;
&lt;li&gt;&lt;del&gt;http://drupal.org/node/218128 - Enhance _db_query_callback() for PDO.&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;http://drupal.org/node/183148 - INSERT/UPDATE/DELETE API, drupal_drop_record() and enhance drupal_write_record().&lt;/del&gt; (Already come with TNG DB)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://drupal.org/node/147947&quot; title=&quot;http://drupal.org/node/147947&quot;&gt;http://drupal.org/node/147947&lt;/a&gt; - Replace some TEXT:BIG with BLOB, based on cross database compatibility concern.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Reviewed&lt;/h3&gt;
&lt;h3&gt;Committed without Thorough Review&lt;/h3&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/enterprise">Enterprise</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Tue, 05 Feb 2008 08:48:16 +0000</pubDate>
 <dc:creator>hswong3i</dc:creator>
 <guid isPermaLink="false">8663 at http://groups.drupal.org</guid>
</item>
<item>
 <title>My personal battle target for Druapl 7.x</title>
 <link>http://groups.drupal.org/node/8586</link>
 <description>&lt;p&gt;My primary battle plan should be &lt;a href=&quot;http://drupal.org/node/172541&quot;&gt;enhance Drupal cross database compatibility&lt;/a&gt;. I have involved in this topic for around a year, and I would like to keep it on going. To accomplish this target, I would like to complete the following tasks before D7 code freeze:&lt;/p&gt;
&lt;p&gt;&amp;lt;&lt;/p&gt;
&lt;p&gt;ul&amp;gt;&lt;/p&gt;
&lt;li&gt;&lt;b&gt;Improve Database API for better abstraction&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Something should be done before any other targets, e.g. &lt;a href=&quot;http://drupal.org/node/371&quot;&gt;resolve reserved words conflict&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/199217&quot;&gt;split drivers into individual files for better management&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/167335&quot;&gt;indeed but simple abstraction for different database syntax&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/183148&quot;&gt;add INSERT/UPDATE/DELETE abstraction and enhance drupal_write_record() abstraction&lt;/a&gt;, etc. With a better common base for multiple database development, we will need much less time to study the differences between databases than that of before.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Add PHP PDO supporting&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://drupal.org/node/134580&quot;&gt;Shipping D7 with PHP PDO&lt;/a&gt; should be a spotlight topic, since it is now official package for PHP5.2.x, and legacy drivers will soon be removed in PHP6.x. We may need &lt;a href=&quot;http://drupal.org/node/199101&quot;&gt;some cleanup in our core query syntax&lt;/a&gt;, in order to let PDO get works.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Introduce more database backend&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Up to this point, I would like to introduce some other database backend for D7, e.g. &lt;a&gt;Oracle&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/67349&quot;&gt;SQLite&lt;/a&gt;, &lt;a href=&quot;http://drupal.org/node/165788&quot;&gt;IBM DB2&lt;/a&gt; and also &lt;a href=&quot;http://drupal.org/node/74308&quot;&gt;MSSQL&lt;/a&gt;. If we are able to support SQLite in D7, which also means we are going to standardize our core queries into SQL92 standard, the problem for maintain multiple database backend should no longer a critical problem; if we are able to support Oracle, the most complicated database I guess, this should no longer a problem for us to implement drivers for other databases.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;I have summarize most of my personal battle targets in &lt;a href=&quot;http://drupal.org/project/issues?projects=3060&amp;amp;text=Siren&amp;amp;states=1,16,8,13,14,15,2,4&amp;amp;priorities=&amp;amp;categories=&amp;amp;users=&quot;&gt;here&lt;/a&gt;. Most logic are &lt;a href=&quot;http://edin.no-ip.com/project/siren&quot;&gt;proved as functioning&lt;/a&gt;, and they are all get set for the open of D7 public development. On the other hand, I would like to explore if this may integrate with &lt;a href=&quot;http://groups.drupal.org/node/8001&quot;&gt;other interest musings with Data API&lt;/a&gt;, so we will able get all stuff better in D7 ;-)
&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8586#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3319">Data API</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/347">database support</category>
 <group domain="http://groups.drupal.org/enterprise">Enterprise</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Fri, 01 Feb 2008 03:45:51 +0000</pubDate>
 <dc:creator>hswong3i</dc:creator>
 <guid isPermaLink="false">8586 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Are performance optimisations still going into D6?</title>
 <link>http://groups.drupal.org/node/8492</link>
 <description>&lt;p&gt;I&#039;m assuming it&#039;s too late, but if not here&#039;s an easy performance win for D6:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://drupal.org/node/215080&quot; title=&quot;http://drupal.org/node/215080&quot;&gt;http://drupal.org/node/215080&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The type column of the {system} table is currently a varchar(255) field. Yet in 99% of all Drupal installations it stores either the text &#039;module&#039; or the text &#039;theme&#039; and nothing else. This is already a strong case for making it an int column and defining constants for module and theme. Then, on every page, there is this query:&lt;br /&gt;
SELECT filename FROM system WHERE name = &#039;user&#039; AND type = &#039;module&#039;;&lt;/p&gt;
&lt;p&gt;This query always takes over 1 ms to run making it not a criminally slow query, but relatively slow, nonetheless. This is because the list of indexes available doesn&#039;t help the query much&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;By shortening the {system}.type column to 32 chars and adding an index we reduce the query by around 60%... and this query runs on every page load.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/postgresql&quot;&gt;Postgresql&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8492#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3558">D6</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3714">high performance</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1046">optimization</category>
 <group domain="http://groups.drupal.org/benchmarking-drupal">Benchmarking Drupal</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/high-performance">High performance</group>
 <group domain="http://groups.drupal.org/mysql">MySQL</group>
 <group domain="http://groups.drupal.org/postgresql">Postgresql</group>
 <pubDate>Mon, 28 Jan 2008 15:07:59 +0000</pubDate>
 <dc:creator>robertDouglass</dc:creator>
 <guid isPermaLink="false">8492 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Musings on a Data API</title>
 <link>http://groups.drupal.org/node/8001</link>
 <description>&lt;p&gt;I have been pondering the question of a data API for a while, as have a lot of people. Much of the recent discussion has focused on an Active Record approach to a data API. Now, Active Record is a very powerful architectural pattern. It maps nicely from storage to interface, it can be fairly self-documenting, and it is conceptually simple and approachable.&lt;/p&gt;
&lt;p&gt;It is also, I believe, insufficient.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Active Record&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The basic concept behind &lt;a href=&quot;http://en.wikipedia.org/wiki/Active_record&quot;&gt;Active Record&lt;/a&gt; is a one to one mapping from a database record to a user-space object. That object can then be manipulated as any other object, and then saved back to the database with all SELECT, INSERT, and UPDATE statements built dynamically. Additional features, like automatic foreign key lookup or multi-load capability, are also possible, particularly in PHP 5.&lt;/p&gt;
&lt;p&gt;Active Record, however, has a number of limitations. First is the raw one to one mapping of database fields to object fields. Very often, you want to work with data at a higher level than its database representation. That can be partially solved by adding additional utility methods to a class representing a given table or entity, but that still assumes that there is a close binding between a table and a first class entity in our data model. Take a typical Drupal node structure. While every node has a record in the node table, it frequently has multiple. Nearly every node also joins against other tables depending on the value of the type column. That&#039;s not information we can know before we load the record in the first place.&lt;/p&gt;
&lt;p&gt;The second issue comes with multi-value fields. Multi-value fields, in SQL, are typically handled with a dependent table keyed by the primary table&#039;s primary key and either a local surrogate key or the value itself. Have a look at &lt;a href=&quot;http://drupal.org/project/cck&quot;&gt;CCK&lt;/a&gt;&#039;s dependent tables for a textbook example. They are keyed by nid, vid, and a local delta value.&lt;/p&gt;
&lt;p&gt;Classic Active Record doesn&#039;t handle multi-value fields directly well. Primarily, it is not possible to load an entire object/record with its dependent fields in one query efficiently. The primary table should return a single record, while the dependent tables could return any number of records. While it is possible to run a join on the two tables, that results in a lot of duplicate data being retrieved on each load; the primary table&#039;s fields repeat to match each entry in the dependent table. Now add in multiple multi-value fields and it becomes painfully clear that a single-query load operation for any non-trivial data structure is not possible.&lt;/p&gt;
&lt;p&gt;That leads us to a very important conclusion: Loading a rich data object from the database will always require multiple queries per load, whether they&#039;re loaded all at once or via a lazy-loading mechanism to pull in dependent fields only when needed. Lazy loading also requires a layer of abstraction behind which the lazy loading may occur.&lt;/p&gt;
&lt;p&gt;The third problem of Active Record is that it presumes the data lives in a local SQL database. It is, by definition, a relational-database-centric design. Data, however, is not always database-centric. Files rarely live in a relational database, and practically never in Drupal. As I write this I am working on my second project recently where the bulk of the data that I wanted exposed as a node does not live in Drupal but in a 3rd party system. In one case it was a foreign (non-Drupal) system with its own API and database connection. In the other, the data is coming in from a SOAP connection. Active Record would not have supported either scenario.&lt;/p&gt;
&lt;p&gt;Now, that&#039;s not to say that Active Record is a bad design pattern. It is quite useful in a variety of cases, and I&#039;ve written a number of implementations of it myself (to varying degrees of quality). Drupal 6 now contains the beginnings of an Active Record-style utility suite in the form of &lt;a href=&quot;http://api.drupal.org/api/function/drupal_write_record/6&quot;&gt;drupal_write_record()&lt;/a&gt;. However, for a system with the flexibility and potential of Drupal it is too limiting.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Object-Relational Mapping&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;If Active Record is a database-centric view of data storage, an &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-relational_mapping&quot;&gt;Object-Relational Mapper&lt;/a&gt;, or ORM, is a user object-centric view of the world. In an ORM, the storage of an object is independent of its consumer-facing structure and interface. If it happens to map 1:1 to a database record, that is coincidental. That gives it a lot more flexibility, but also a lot more complexity.&lt;/p&gt;
&lt;p&gt;Because an ORM is more robust, it can do a lot more optimization under the hood. Values can be moved around between tables (as CCK does) without changing its interface. Complex relationships can be modeled in a database-independent way, even tying into non-SQL systems like the file system, SOAP, etc.&lt;/p&gt;
&lt;p&gt;The flip side, however, is that an ORM can be quite complicated for complex queries, even more so than an Active Record setup. Finding all &quot;event nodes created by Bob in March that take place between May and July and have at least 5 attendees&quot; is reasonably straightforward in SQL (albeit a bit verbose). In Active Record it is more difficult, but can still be done if you can access the SQL layer underneath it. In an ORM, such a query becomes very... involved. Some ORMs, like &lt;a href=&quot;http://swik.net/Doctrine&quot;&gt;Doctrine&lt;/a&gt;, develop their own query language to address that problem, which in turn means parsing and interpreting a query language in user-space. PHP is not known for its string parsing and interpreting-fu. That&#039;s why SQL databases are so popular; they are.&lt;/p&gt;
&lt;p&gt;Drupal as of version 6, however, does implement an ORM. Nodes are not built Active Record style. Hooks can add data to nodes from anywhere they want, whether it maps to a database table or not (although it frequently does). However, the ORM is &quot;naked&quot;. That is, there&#039;s no abstraction on data access. Everything is loaded at once into a single blob-o-raw-data that gets returned from node_load(), and then it&#039;s up to modules to not bump into each other and module authors to know what to do with that raw data.&lt;/p&gt;
&lt;p&gt;Nowhere is that more painful, in my experience, than in creating your own node form. Drupal saves the submitted form data back to the node object based on the form structure, not the node structure. Matching those up is entirely the module author&#039;s responsibility, despite the fact that the form structure and node structure frequently have no right to be the same. If they don&#039;t match up, you end up with a hybrid &lt;code&gt;$form_values&lt;/code&gt; and &lt;code&gt;$node&lt;/code&gt; object. That&#039;s just weird.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Thingies&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Despite their additional complexity, I believe an ORM approach to be better long-term for Drupal than an Active Record approach. However, that does not preclude a hybrid approach.&lt;/p&gt;
&lt;p&gt;What would a hybrid approach be? A hybrid approach would involve a Thingie object (that was the working name decided on in Barcelona for first-class entities like nodes, users, files, etc.) that defines multiple fields. Every Thingie is restricted to a list of fields and properties. Each field can lazy-load itself on demand. Each field is also its own object, and can either be implemented Active Record style (tightly bound to the database with lots of automation) or not (to support SOAP or XML-RPC or flat file or even calculate-on-demand fields). That is, everything becomes a self-containing CCK field.&lt;/p&gt;
&lt;p&gt;For nodes, that would mean non-CCK fields largely cease to exist. Each field, however, would have much more flexibility and could potentially return a processed value or array. For users, the profile module as we know it gets replaced by the same structure as nodes would have, potentially even with the same field objects. Files would finally become first-class Thingies, although would be unlikely to have very complex fields. (But then, who knows?)&lt;/p&gt;
&lt;p&gt;The ability to return complex values is important.  Some modules add fields conditionally.  Ideally, they should do so under a module namespaced array.  That is, $node-&amp;gt;mymodule[&#039;some_field&#039;].  With an &quot;all CCK&quot; model, $node-&amp;gt;mymodule becomes an object of its own which could have its own single -&amp;gt;value, multiple properties, even its own methods if necessary.  Some standard methods (which are more flexible than properties) would be a good idea as well for standardized access, especially for theming.&lt;/p&gt;
&lt;p&gt;For multi-value fields, there are two options.  One, all fields could be multi-value.  That&#039;s how CCK works now.  CCK fields have a structure of &lt;code&gt;$node-&amp;gt;field_foo[x]&lt;/code&gt;, where x is a numeric delta.  After the node has been rendered, each delta has a &lt;code&gt;[&amp;#039;view&amp;#039;]&lt;/code&gt; property that has the rendered value of the field and then some combination of other properties for the raw data field(s).  That makes handling multiple values more straightforward but can be annoying to work with when most of your fields are single-value.  Two, multiple fields could be listed as separate fields.  That is, if a node has a single &lt;code&gt;Foo&lt;/code&gt; field and two &lt;code&gt;Bar&lt;/code&gt; fields then they would be accessed as &lt;code&gt;$node-&amp;gt;foo_0&lt;/code&gt;, &lt;code&gt;$node-&amp;gt;bar_0&lt;/code&gt;, &lt;code&gt;$node-&amp;gt;bar_1&lt;/code&gt; rather than as &lt;code&gt;$node-&amp;gt;bar[0]&lt;/code&gt; and &lt;code&gt;$node-&amp;gt;bar[1]&lt;/code&gt;.  That would make treating each field instance separately easier, but referencing an set of fields together more difficult.&lt;/p&gt;
&lt;p&gt;I believe CCK got this one right.  The flexibility and consistency of treating all fields as multi-value is worth the more complex syntax.  However, the syntax could potentially be simplified.  PHP 5&#039;s Iterator interfaces could be useful here.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Objects&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;So far I have assumed that we are talking about a system built on classic objects (that is, objects of a class other than stdClass), not on giant arrays.  Certainly, everything discussed here could be implemented using no classes at all.  Any problem in programming can be solved either by procedural or OOP programming (or functional, if PHP supported that).  However, certain problems are far better suited to one style or the other, where &quot;better&quot; could mean any of less code, more performance, easier to understand, more secure, more flexible, etc.  A complex data model, such as the one Drupal now supports, is, I believe, a case where Object-Oriented principles using well-factored classes and methods is a &quot;better&quot; fit.  As I&#039;ve &lt;a href=&quot;http://drupal.org/node/178263&quot;&gt;said before&lt;/a&gt;, the right tool for the right job.  In this case, objects are the right tool.&lt;/p&gt;
&lt;p&gt;That does not preclude function wrappers where a function would be more convenient.  For example:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;node_load&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$nid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;load&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$nid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Until now there have been very good reasons to not implement heavy OO in Drupal; primarily, PHP 4&#039;s object model didn&#039;t offer any compelling reason to, as it was too primitive and limiting for the sort of functionality we would need out of it.  That is no longer the case in PHP 5.2.&lt;/p&gt;
&lt;p&gt;The other major factor is that Drupal&#039;s current architects come from procedural backgrounds, so Drupal is mostly procedural, so it attracts procedural thinkers, etc.  That is not inherently bad, of course, but at the same time we should not allow that legacy style to hold Drupal back any more than we allow legacy code to hold us back.&lt;/p&gt;
&lt;p&gt;Another advantage of a good (emphasis on good) unified Thingie system is that it would make it easier to create new Thingie types.  Sometimes a one-off project could benefit from a readily-available data API that is not nodes.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Variants&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In Barcelona, &lt;a href=&quot;http://drupal.org/user/16496&quot;&gt;Jeff Eaton&lt;/a&gt; and I spent a fair bit of time bouncing around concepts for an OO Data API.  The main idea that we struck upon was the concept of &quot;variants&quot;.  A &quot;variant&quot; was an alternate version of a given Thingie.  For instance, Revisions of a node are variants of it.  For a file, at a trivial level different resolutions of an image are different variants.  However, that could easily be generalized.  Picture a single File Thingie that is a YouTube-esque video.  One variant of it is a high-res version.  Another variant is a low-res version.  Then there are small, medium, and large thumbnails of it in JPG format.  Then there&#039;s an English, Spanish, and Chinese transcript, as PDFs.  And so on.&lt;/p&gt;
&lt;p&gt;For nodes, revisions and translations would be the obvious variants.  Variants would also need to stack.  That is, one could have node 12, revision 2 of the English version and revision 4 of the German version, but all with the same node id.  That would eliminate one of the largest annoyances of dealing with content translation currently: keeping track of nodes that are translations of each other.&lt;/p&gt;
&lt;p&gt;Each variant would have to have a default, especially since ideally we want variants to be defineable by modules rather than hard-coded.  So for instance, one could load a node like:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;Node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;load&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;12&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, array(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;lang&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;es&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;revision&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;));&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
That is, load node with id 12, the Spanish variant, the revision 2 variant, and default for all other variants.  If lang were not specified, it would mean the English variant.  If revision were not specified, it would mean whatever the most recent revision is.&lt;/p&gt;
&lt;p&gt;However, that quickly runs into a problem of storage.  While a nice API concept, it makes the SQL model more difficult because you then have potentially variable primary keys.  That gets ugly, fast.&lt;/p&gt;
&lt;p&gt;Perhaps those should be hard-coded...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Rendering&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Although one always wants to keep data logic and display logic separated, rendering a Thingie for display is perhaps its most common use.  That means we need to consider how such an API would be used for rendering.  The natural knee-jerk reaction would be something like this:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;$node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;It would also be very wrong.  For one thing, it&#039;s very brittle.  What happens when you want to render as a full node vs. teaser?  As an RSS feed item?  As a JSON response?  Render different node types differently?  Very quickly you end up with a whole bunch of flags on the render() method, and we&#039;re right back where we started.&lt;/p&gt;
&lt;p&gt;More fundamentally, however, it is pulling rendering into the data object.  That means there is poor separation between data access and the presentation layer.&lt;/p&gt;
&lt;p&gt;Rather, we should take advantage of the fact that, in PHP 5, objects are cheap and passing objects is cheap.  The data access object itself should remain pristine, but can then be passed around to other functions and objects at nearly no cost.  We can also take advantage of the strict, rigid structure of the Thingie object as a collection of fields.  That is, we don&#039;t need to render the Thingie!  We render its fields and aggregate them for the theming layer.&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;theme_node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$style &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;html&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mode &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;full&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp; foreach (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() as &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$return&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()] = &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;theme&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;field_&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(), &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$style&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mode&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$return&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Grossly over-simplified, but you get the idea.  ($style would be things like &quot;print&quot;, &quot;html&quot;, or &quot;rss&quot; while $mode would be &quot;teaser&quot;, &quot;full&quot;, etc.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ready, Set, Go&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;One of the big drawbacks of an ORM, particularly one built on lazy-loading is the risk of the &quot;SELECT 1+N Problem&quot;.  That is, imagine the following code:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;$books &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;find_some_books&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;foreach (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$books &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;as &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$book&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp; print &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$book&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;title &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;, &#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$book&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;getAuthor&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Assuming that Author and Book are two separate entity types, we will execute one query to find the books we want (with its title), and then for each book we will execute another query to load the corresponding author object with the author&#039;s name.  That is a performance killer.  Generally, there are two alternative approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Greedy-Loading: The process of loading a Book or Books will also load all related data, period, with whatever joins or additional queries are needed.  That means it can write more efficient queries, but it&#039;s also loading far more data than it probably needs. Do we really need to also load all of the Publisher information?  Doubtful. This is actually what Drupal does currently, although it doesn&#039;t even optimize multi-object loads (unless you&#039;re using a List View, which then acts as a very optimized but complex ActiveRecord-ish loader, not an ORM).&lt;/li&gt;
&lt;li&gt;Semi-lazy loading: If you know in advance that you&#039;re going to want the Author object as well, you can specify that the ORM loader should also pull that data.  That is, you write a JOIN, but you don&#039;t use SQL but some ORM-specific directive, usually a very verbose one.  As I see it, that loses much (though admittedly not all) of the advantages of a lazy-loading ORM: Don&#039;t make me think.  Then if you need to pre-load against multiple other fields, well, pretty soon you have code so complex that you may as well just write your own SQL and be done with it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And neither handle multi-value fields, of course.&lt;/p&gt;
&lt;p&gt;I would propose a third, more flexible approach; let&#039;s take a cue from both jQuery and CCK.  A jQuery object (the &lt;code&gt;$()&lt;/code&gt; thing) is never a single entity.  It is always a set of DOM nodes, sometimes a set of one DOM nodes.  In CCK, a single-value field is, structurally, the same as a multi-value field that only happens to have one value.  Views are all about multi-object queries, although those can also frequently have only one entry.  They&#039;re still treated as multiple entries.&lt;/p&gt;
&lt;p&gt;Set operations are both extremely powerful and very natural.  SQL itself is built on set operations.  Many RPC requests either assume or allow set operations.  There is, in fact, no reason why a single-entity operation cannot be implemented as a set operation.&lt;/p&gt;
&lt;p&gt;OK, not entirely true.  If you have a naked data structure, then you never have an entity but an array of entities, which you then need to &lt;code&gt;foreach()&lt;/code&gt;; that can be clumsy if you don&#039;t practically use multi-value fields often.  That&#039;s another place where having an OO interface is &quot;better&quot; (in this case easier) than a procedural one.  You can encapsulate the loop, much the way jQuery plugins do.  That makes the module-developer-facing API cleaner.  This is a good use-case for Interfaces:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;interface &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Something &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;doSomething&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Thingie &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;implements &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Something &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;doSomething&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() { ... }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;ThingieSet &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;implements &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Something &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$thingies&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;doSomething&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$thingies &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;as &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$thingie&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$thingie&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;doSomething&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$t &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= new &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Thingie&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$t&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;doSomething&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$s &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= new &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;ThingieSet&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$s&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;doSomething&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(); &lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;// Does something to every thingie, even if there&#039;s just one of them.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;But why do we even need a loop?  Moving a loop inside a function call makes the API cleaner, but especially when dealing with SQL databases doesn&#039;t necessarily help performance.  Remember, though, that we&#039;re demanding a rigid Thingie structure.  A Thingie is composed of Fields.  Let those Fields handle their own set operations, especially for lazy loading.  That means each field needs to know what its &quot;load set&quot; is.  That is, suppose we have a Set of Node objects.  When we access, say, the taxonomy field on one node, it should lazy-load &lt;i&gt;all&lt;/i&gt; taxonomy data for the nodes in that Set in a single query and then assign out the data to the appropriate node&#039;s field.  Update operations then can also be grouped, making it possible to load a set of Thingies, set one field on all of them, and then save, with the load and update operations both taking only one query each no matter how many Thingies we&#039;re modifying, and without writing any SQL ourselves.&lt;/p&gt;
&lt;p&gt;I&#039;ve implemented such a system recently for a 3rd-party integration project, and it is actually not difficult to implement.  (Well, the read part, anyway.  The write part is more complicated, but I believe it is solvable.)&lt;/p&gt;
&lt;p&gt;While not as efficient as explicitly specifying the fields we want, it does flatten the cost.  That is, the Book and Author example above would have a cost of 2: one to mass-load books, and one to mass-load authors.  The worst-case scenario for such an approach is that every possible field gets called anyway, or 1 + F.  That is exactly the cost of a &lt;code&gt;node_load()&lt;/code&gt; in Drupal now... except that &lt;code&gt;node_load()&lt;/code&gt; is actually N*(1+F) because it doesn&#039;t do set operations.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Searching&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The other major drawback of an ORM is that non-trivial searching is frequently very verbose.  We need to specify a variety of weird search parameters in a completely data-agnostic fashion.  That means lots of methods, or lots of objects passed into a long method signature with lots of arguments, such as in &lt;a href=&quot;http://qcodo.com/&quot;&gt;Qcodo&lt;/a&gt;.  Or it means a custom query language like Doctrine.  Both are icky.&lt;/p&gt;
&lt;p&gt;To be honest, I see the best course of action here to be &quot;punt&quot;.  Separate loading from searching entirely.  A set-load operation should take simply an array of IDs.  How those IDs are found is a separate question.  They could be from a simple API call, or looked up from a field in another object, or from a Views-like builder, or from a direct SQL query builder, or a hand-rolled 15-line super-complex SQL query (which would be about 1/10th the size of trying to write that query abstractly with fully-OO directives), or retrieved from a remote server via SOAP.  By keeping searching and loading separate, we maximize flexibility while minimizing complexity.  While there will be, in some cases, a cost in terms of additional queries, that cost is relatively flat and, I would argue, a good value.&lt;/p&gt;
&lt;p&gt;Now, combine flexible searching with everything-as-a-set, and you have a very large portion of Views not just in core, but being core itself.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;What not to do&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;There are, of course, a lot of potential pitfalls in any such endeavor.  There are two I will mention in particular.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Deep inheritance.  Deep inheritance hierarchies are well-understood as being dangerously brittle.  Adding functionality requires editing existing code.  You can&#039;t do things &quot;sideways&quot;, as Drupal does nearly everything.  If you want a certain piece of functionality to be part of two classes that otherwise have no reason to be logically children of each other, you&#039;re SOL.  That&#039;s not to say that inheritance is always bad, but it is very easy to get carried away.  Let&#039;s avoid that.
&lt;p&gt;For example, it may seem natural to have a Node class, and then child classes of Node for Page, Story, Event, etc.  However, that&#039;s not how nodes are actually used in Drupal.  A node is a node is a node, but it has some combination of fields on it (even now).  Rather, a Node should continue to have a -&amp;gt;type, which in turn indicates what field objects should be added to a generalized field container.&lt;/li&gt;
&lt;li&gt;Code generation.  I have never understood how the &quot;Don&#039;t Repeat Yourself&quot; and code generation design philosophies can coexist.  Code generation (speaking of logic generation here, not function skeleton generation) is repeating yourself.  In fact, its repeating yourself so much that you make the computer repeat yourself for you.  That&#039;s a sure sign that you are doing something wrong, and need to refactor your  code to actually use inheritance, or composition, or something other than typing out the same code over and over again.  Of course, there is one catch here: PHP 5.2 and earlier does not support late static binding, which means, in essence, static methods can&#039;t be usefully inherited because references to other static methods will always be to the defining class, not the actual class.  Fixing that is a hotly debated topic for PHP 5.3, but that&#039;s still well-off as far as we&#039;re concerned.&lt;/li&gt;
&lt;li&gt;Tight-coupling.  (Nobody expects the Spanish Inquisition!)  A truly pristine data API will require fully and totally divorcing it from the rest of the system, particularly forms.  The node edit form&#039;s save routines, for instance, should not in any way shape or form know anything about SQL.  They should all simply set values on the $node object, and then eventually &lt;code&gt;$node-&amp;gt;save()&lt;/code&gt; gets called and fields internally save themselves.  Similar separation is also necessary for theming.  (Like, can we get comments &lt;i&gt;out&lt;/i&gt; of &lt;code&gt;node_view()&lt;/code&gt;, please?)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;The future&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;What I have described here is, of course, ambitious.  Very ambitious.  It represents a fundamental shift in the way Drupal handles data.  However, I believe that shift is necessary for Drupal&#039;s long-term success.&lt;/p&gt;
&lt;p&gt;Dries has set some rather lofty goals recently.  Web services.  Drupal as the &quot;Linux of the web&quot;.  He doesn&#039;t think small, and neither should we.  A robust, powerful, and above-all decoupled data API moves Drupal from being a CMS or application framework to being something else: A data server.  The menu system acts as a simple router to handle RPC/REST requests, which the data server responds to.  It just so happens that the most common REST request is for an HTML page; at least for now.  In 5-10 years, though?  Will we even be talking about SQL and HTML?  A good data API should be agnostic of both.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Implementation&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;So what would such a system look like in practice?  How would we use hooks with it?  I&#039;m glad you asked!  I&#039;m not entirely sure yet, aside from the samples above.  I have some ideas, however, most of which owe thanks to other members of the Drupal community.  For instance, courtesy of Jeff Eaton (who may credit it elsewhere himself) is &lt;code&gt;hook_nodeapi()&lt;/code&gt; going away in favor of &lt;code&gt;hook_node_info()&lt;/code&gt; defining what field types a given node type has, and then those field types (objects) internally do whatever loading and saving they need.  Adding fields to a node type is accomplished by a simple &lt;code&gt;hook_node_info_alter()&lt;/code&gt;.  &lt;code&gt;hook_user()&lt;/code&gt; would likely suffer a similar fate.&lt;/p&gt;
&lt;p&gt;One of the possibilities discussed in Barcelona was to implement just files using a new Thingie-based system, as a trial balloon.  Despite recent improvements, Drupal&#039;s file handling is still a weak point.  That means the risks of experimentation are lower than if we were to break, say, nodes.  If it works out, we can then extend it to the rest of the system in the next future, and we&#039;ll have a good API behind which to implement things like, say, pluggable storage engines.&lt;/p&gt;
&lt;p&gt;At this point, I welcome feedback from all and sundry on the concepts presented here.  Truthfully, I do not expect it to all happen in Drupal 7.  If it all happens by Drupal 8, it will be aggressive.  However, we do need to have a clear picture of where we are going and how to get there, even if it will take a few versions.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8001#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3321">active records</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3319">Data API</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3565">Object Oriented</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1881">object oriented paradigm</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Sun, 06 Jan 2008 03:38:22 +0000</pubDate>
 <dc:creator>Crell@drupal.org</dc:creator>
 <guid isPermaLink="false">8001 at http://groups.drupal.org</guid>
</item>
<item>
 <title>MySQL Table Type</title>
 <link>http://groups.drupal.org/node/7927</link>
 <description>&lt;p&gt;I think it is safe to say that many developers already using or about to start using MySQL table type InnoDB. Some developers even changing default MySQL storage engine to InnoDB.&lt;br /&gt;
In many cases it make sense to convert table type if not for all tables, then at least for some tables.&lt;br /&gt;
In this situation will be nice if modules developers will state what table type is necessary for those modules and why.&lt;br /&gt;
Otherwise, its has to be investigated and tested for all modules in the project installation. May be it is fun but it is also a lot of time.&lt;br /&gt;
My suggestions for Drupal developers are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;include into modules .install file the indication of MySQL table type in the end of each table creation query like &quot;CREATE TABLE `tablename` (...) ENGINE=InnoDB DEFAULT CHARSET=utf8&quot; or &quot;... ENGINE=MyISAM ...&quot;;&lt;/li&gt;
&lt;li&gt;include into &#039;INSTALL.TXT&#039; file description of why these tables need to have those types.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That will give another developers enough information for making right decision on MySQL optimization of project&#039;s Drupal installations.&lt;br /&gt;
Otherwise, it has to be investigated for each table.&lt;br /&gt;
Please share your experience.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://pandre.org&quot;&gt;Alex Pandre&lt;/a&gt;&lt;br /&gt;
Custom Drupal modules and themes development, SVN for Drupal environment development, Code optimization&lt;br /&gt;
&lt;a href=&quot;http://groups.drupal.org/mysql&quot;&gt;Join MySQL group and post your suggestions in related groups in the same time&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/mysql&quot;&gt;MySQL&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/7927#comments</comments>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/mysql">MySQL</group>
 <pubDate>Tue, 01 Jan 2008 23:57:02 +0000</pubDate>
 <dc:creator>webappl</dc:creator>
 <guid isPermaLink="false">7927 at http://groups.drupal.org</guid>
</item>
<item>
 <title>PHP 5.2.5 breaks SQL Server support; Yet MSFT SQL Driver Works</title>
 <link>http://groups.drupal.org/node/7787</link>
 <description>&lt;p&gt;So, I&#039;ve had some free time latley, and I&#039;ve started back on the database API layers (DB2 and SQL Server currently).&lt;br /&gt;
However, I have found 2 disturbing issues.&lt;/p&gt;
&lt;p&gt;Overview&lt;br /&gt;
First, I&#039;m currently exploring the following 3 ways to connect to sql server:&lt;br /&gt;
1. FreeTDS&lt;br /&gt;
2. php_mssql driver&lt;br /&gt;
3. MSFT SQL Driver ( See pcorbetts posting for a link to the driver )&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;PHP 5.2.5 breaks support for SQL Server&lt;br /&gt;
I&#039;m running PHP 5.2.5. I&#039;ve had a perfectly good working SQL Server installtion, so I thought this was just a PHP upgrade and then I was going to continue to do some module dev. and bug fixing. Well, it seems that with PHP 5.2.5 neither the php_mssql extension OR the FreeTDS driver work with PHP any longer. I have submitted a bug report to PHP ( 43645 ). This has been verified by another developer also.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MSFT SQL Driver works in 5.2.5...but still alpha&lt;br /&gt;
The MSFT SQL Driver DOES work in 5.2.5. However, the driver is still in alpha quality, and will prob. be Spring before I would say it&#039;s a stable beta ( reference the IIS FastCGI module for a MSFT timeline :) ).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It should also be noted that the ntwlib client ( this is the library that allows FreeTDS and the php_mssql libs to connect nativley to SQL Server using TDS [Tabular Data Stream]) is no longer going to be distributed with SQL Server. It&#039;s been deprecated. This kind of  makes sense, given MSFT is prob. going to start branching it&#039;s product away from it&#039;s Sybase origins, so who knows what funky stuff they&#039;ll do with the TDS format. Anyway, I&#039;m still trying to get my head around what direction they&#039;re going to take at this juncture. They must know there&#039;s a need for PHP+MSSQL connectivity, thus the development of the SQL Driver. I know that it is beta ( and as I&#039;ve said before...definatly a TRUE beta, not a &quot;google&quot; beta :) ), but I&#039;m confident this driver will get finished and supported...but I just can&#039;t say when.&lt;/p&gt;
&lt;p&gt;With that said, I&#039;m going to try and continue development by downgrading my PHP, and keeping an eye on the but I opened at php.net.&lt;br /&gt;
That&#039;s all for now, but just thought I&#039;d give a heads up about PHP+MSSQL and esp. the 5.2.5 issue.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/enterprise&quot;&gt;Enterprise&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/7787#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/347">database support</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1029">microsoft</category>
 <category domain="http://groups.drupal.org/taxonomy/term/844">mssql</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/enterprise">Enterprise</group>
 <pubDate>Thu, 20 Dec 2007 18:32:32 +0000</pubDate>
 <dc:creator>Souvent22@drupal.org</dc:creator>
 <guid isPermaLink="false">7787 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Active Records, a possible approach for consistent Data APIs</title>
 <link>http://groups.drupal.org/node/6772</link>
 <description>&lt;p&gt;As mentioned on the other paper &lt;a href=&quot;http://groups.drupal.org/node/6767&quot;&gt;A Data API for Drupal&lt;/a&gt;. Here is a paper that shows how this could be accomplished with some OOP bits implementing the &lt;a href=&quot;http://en.wikipedia.org/wiki/Active_record&quot;&gt;Active Records Pattern&lt;/a&gt;. While keeping the interface procedural.&lt;/p&gt;
&lt;p&gt;We all know that Dupal will not go full OOP. But some OOP code could help us do things not possible with procedural code. Such as lazy loading of nested objects and &#039;on demand&#039; database fields processing.&lt;/p&gt;
&lt;p&gt;Before going this route in Drupal core we would need to rigorously benchmark and carefully weigh the risks and benefits. Record module is intended as a step towards enabling us to thoroughly evaluate these options.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/services&quot;&gt;Services&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/6772#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3321">active records</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3319">Data API</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3320">webservices</category>
 <enclosure url="http://groups.drupal.org/files/drupal_active_records.pdf" length="103289" type="application/pdf" />
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/services">Services</group>
 <pubDate>Thu, 25 Oct 2007 23:53:54 +0000</pubDate>
 <dc:creator>recidive@drupal.org</dc:creator>
 <guid isPermaLink="false">6772 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Data APIs for Drupal 7 and web services support</title>
 <link>http://groups.drupal.org/node/6767</link>
 <description>&lt;p&gt;There&#039;s growing interest in the Drupal community in the prospect of renewing our core data handling APIs. Doing so will increase consistency and efficiency and ease barriers. It will also be a key step in enabling transactional web services.&lt;/p&gt;
&lt;p&gt;In Drupal 6 we took some impressive first steps. What should we tackle for Drupal 7?&lt;/p&gt;
&lt;p&gt;The attached paper, written by Nedjo Rogers and Henrique Recidive and sponsored by CivicSpace, aims to carry this discussion forward and map out both some conceptual space and concrete development tasks.&lt;/p&gt;
&lt;p&gt;An accompanying post will present for review and discussion a proposed Active Records implementation for Drupal, taking advantage of features built into PHP 5.&lt;/p&gt;
&lt;p&gt;Please, wade in and review, critique, and improve!&lt;/p&gt;
&lt;p&gt;(I&#039;m posting this to the Schema API and Services groups as the two most closely matching this topic. We could consider forming a new Data API group as well.)&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/services&quot;&gt;Services&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/6767#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3319">Data API</category>
 <category domain="http://groups.drupal.org/taxonomy/term/2148">web services</category>
 <enclosure url="http://groups.drupal.org/files/drupal_dataapi.pdf" length="160495" type="application/pdf" />
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/services">Services</group>
 <pubDate>Thu, 25 Oct 2007 19:21:19 +0000</pubDate>
 <dc:creator>nedjo</dc:creator>
 <guid isPermaLink="false">6767 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Table creation order</title>
 <link>http://groups.drupal.org/node/4512</link>
 <description>&lt;p&gt;Once foreign keys are specified during table creation, we will have to make sure to create tables in the correct order.  e.g. You can&#039;t create system.schema, whose files table has a uid column, before you create user.schema which creates the users table which hold the master uid column.&lt;/p&gt;
&lt;p&gt;If this proves too difficult we can use ALTER TABLE to put the foreign key contraints in afterward, but that seems much less desireable.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/4512#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1948">schema</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Tue, 12 Jun 2007 01:48:56 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">4512 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Add join/foreign key info to schema</title>
 <link>http://groups.drupal.org/node/4328</link>
 <description>&lt;p&gt;Now that we have four more weeks before D6 code freeze, maybe it is possible to add join relationships/foreign key support into Schema API 1 after all.  Otherwise, it will be another year before this info is in core.  Note that this info does not really &lt;em&gt;have&lt;/em&gt; to be in core---it can be added by a contrib module hook_schema_alter.  But a lot of people would be pretty psyched to have referential integrity for pgsql built in to D6.  So:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make a list of all the key relationships in the core tables.&lt;/li&gt;
&lt;li&gt;Decide how to encode the info in the schema data structure.&lt;/li&gt;
&lt;li&gt;Add foreign key constraints in database.pgsql.inc.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;Profit!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have a pretty good idea for all the steps (at least the first three :-) but, for right now, am just creating this post as a placeholder.  Jump in!&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/4328#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/758">PostgreSQL</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1948">schema</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Fri, 01 Jun 2007 17:31:12 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">4328 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Additions to the API</title>
 <link>http://groups.drupal.org/node/4267</link>
 <description>&lt;p&gt;Now that the schema has been committed to core, I wanted to open up a thread where people could discuss additions an enhancements to the API.&lt;/p&gt;
&lt;p&gt;I posted a patch to add a db_rename_table over on &lt;a href=&quot;http://drupal.org/node/147285&quot;&gt;#147285&lt;/a&gt;. I&#039;ve love to see it get in before the feature freeze.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/4267#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1948">schema</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Mon, 28 May 2007 19:23:34 +0000</pubDate>
 <dc:creator>drewish</dc:creator>
 <guid isPermaLink="false">4267 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Defining Schema data types</title>
 <link>http://groups.drupal.org/node/3801</link>
 <description>&lt;p&gt;Now that Schema almost has a driver for PostgreSQL I needed to resolve the data type issue.  I like Frando&#039;s approach (I seem to say that a lot) of storing &#039;type&#039; and &#039;size&#039; separately because it makes a variety of things easier.  For example:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;$schema[&amp;#039;mytable&amp;#039;] = array(&lt;br /&gt;&amp;nbsp; &amp;#039;cols&amp;#039; =&amp;gt; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;col1&amp;#039; = array(&amp;#039;type&amp;#039; =&amp;gt; &amp;#039;int&amp;#039;, &amp;#039;size&amp;#039; =&amp;gt; &amp;#039;big&amp;#039;, ...)));&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;In a column specifier, &#039;size&#039; is optional and defaults to &#039;normal&#039;.  For type varchar, &#039;size&#039; is ignored.  I changed a few of the constants Frando defined to make them more like what I think people will expect (e.g. &#039;varchar&#039; instead of &#039;string&#039;) and I normalized the size constants so that all types use &#039;big&#039; instead of some using &#039;long&#039;.&lt;/p&gt;
&lt;p&gt;So, what I have so far for MySQL:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $map = array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;varchar:normal&amp;#039; =&amp;gt; &amp;#039;VARCHAR&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:small&amp;#039; =&amp;gt; &amp;#039;SMALLTEXT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:medium&amp;#039; =&amp;gt; &amp;#039;MEDIUMTEXT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:big&amp;#039; =&amp;gt;&amp;nbsp; &amp;#039;LONGTEXT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:normal&amp;#039; =&amp;gt; &amp;#039;TEXT&amp;#039;,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:tiny&amp;#039; =&amp;gt; &amp;#039;TINYINT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:small&amp;#039; =&amp;gt; &amp;#039;SMALLINT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:medium&amp;#039; =&amp;gt; &amp;#039;MEDIUMINT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:big&amp;#039; =&amp;gt; &amp;#039;BIGINT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:normal =&amp;gt; &amp;#039;INT&amp;#039;,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:tiny&amp;#039; =&amp;gt; &amp;#039;FLOAT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:small&amp;#039; =&amp;gt; &amp;#039;FLOAT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:medium&amp;#039; =&amp;gt; &amp;#039;FLOAT&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:big&amp;#039; =&amp;gt; &amp;#039;DOUBLE&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:normal&amp;#039; =&amp;gt; &amp;#039;FLOAT&amp;#039;,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;blob:big&amp;#039; =&amp;gt; &amp;#039;LONGBLOG&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;blob:normal&amp;#039; =&amp;gt; &amp;#039;BLOB&amp;#039;,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;datetime:normal&amp;#039; =&amp;gt; &amp;#039;DATETIME&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;and for PostgreSQL:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $map = array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;varchar:normal&amp;#039; =&amp;gt; &amp;#039;varchar&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:small&amp;#039; =&amp;gt; &amp;#039;text&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:medium&amp;#039; =&amp;gt; &amp;#039;text&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:big&amp;#039; =&amp;gt; &amp;#039;text&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;text:normal&amp;#039; =&amp;gt; &amp;#039;text&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:tiny&amp;#039; =&amp;gt; &amp;#039;smallint&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:small&amp;#039; =&amp;gt; &amp;#039;smallint&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:medium&amp;#039; =&amp;gt; &amp;#039;integer&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:big&amp;#039; =&amp;gt; &amp;#039;bigint&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;int:normal&amp;#039; =&amp;gt; &amp;#039;integer&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:tiny&amp;#039; =&amp;gt; &amp;#039;real&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:small&amp;#039; =&amp;gt; &amp;#039;real&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:medium&amp;#039; =&amp;gt; &amp;#039;real&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:big&amp;#039; =&amp;gt; &amp;#039;double precision&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;float:normal&amp;#039; =&amp;gt; &amp;#039;real&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;blob:big&amp;#039; =&amp;gt; &amp;#039;bytea&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;blob:normal&amp;#039; =&amp;gt; &amp;#039;bytea&amp;#039;,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;datetime:normal&amp;#039; =&amp;gt; &amp;#039;timestamp&amp;#039;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Comments?&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/3801#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1948">schema</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Tue, 24 Apr 2007 13:35:57 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">3801 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Random ID Generation Write up</title>
 <link>http://groups.drupal.org/node/3797</link>
 <description>&lt;p&gt;So, I&#039;ve had a few inquiries over the last few months about random node generation as I have implemented it successfully for a client. I have posted a full write up of it on my blog. Feel free to comment on it here or on my blog; I will post a patch when I have a chance and if there is interest.&lt;/p&gt;
&lt;p&gt;Article link: &lt;a href=&quot;http://earnestberry.com/node/13&quot; title=&quot;http://earnestberry.com/node/13&quot;&gt;http://earnestberry.com/node/13&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/coding-standards-and-performance-optimization&quot;&gt;Coding Standards and Performance Optimization&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/3797#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/354">Hi Performance</category>
 <category domain="http://groups.drupal.org/taxonomy/term/66">identity</category>
 <category domain="http://groups.drupal.org/taxonomy/term/332">performance</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1045">sql</category>
 <group domain="http://groups.drupal.org/washington-dc-drupalers">Washington, DC Drupalers</group>
 <group domain="http://groups.drupal.org/high-performance">High performance</group>
 <group domain="http://groups.drupal.org/enterprise">Enterprise</group>
 <group domain="http://groups.drupal.org/database">Database</group>
 <group domain="http://groups.drupal.org/coding-standards-and-performance-optimization">Coding Standards and Performance Optimization</group>
 <pubDate>Tue, 24 Apr 2007 02:58:43 +0000</pubDate>
 <dc:creator>Souvent22@drupal.org</dc:creator>
 <guid isPermaLink="false">3797 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Using database schema to load nodes in fewer queries</title>
 <link>http://groups.drupal.org/node/3697</link>
 <description>&lt;p&gt;One thing that  becomes possible when Drupal can access its own database schema is that queries which currently are performed separately can instead be performed together.  In particularly, I think it might be possible to load an entire node with a single SELECT query or, at least, in far fewer than Drupal currently uses.  Working proof of concept code is already in the Schema module; it loads all CCK fields, comments, and author info in one query.  Loading more things only requires adding a join entry to the schema data structure (see below).&lt;/p&gt;
&lt;p&gt;Note that I do not yet know if it is &lt;em&gt;faster&lt;/em&gt; to load nodes in one query, only that it seems possible.  I&#039;d like to use this thread to explore the idea and see what people think.  To get started, I&#039;m reposting here (with some updates) a followup I posted in &lt;a href=&quot;http://drupal.org/node/136171&quot; title=&quot;http://drupal.org/node/136171&quot;&gt;http://drupal.org/node/136171&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Suppose I define a CCK type called &quot;type_1&quot; with a single field, &quot;field_1&quot;.  In Schema&#039;s data structure, the table looks like this:&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;$schema[&amp;#039;content_type_type_1&amp;#039;] = array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;cols&amp;#039; =&amp;gt; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;vid&amp;#039; =&amp;gt; array(&amp;#039;type&amp;#039; =&amp;gt; &amp;#039;int&amp;#039;, ... &amp;#039;join&amp;#039; =&amp;gt; array(&amp;#039;node&amp;#039;, &amp;#039;vid&amp;#039;, &amp;#039;one&amp;#039;)),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;nid&amp;#039; =&amp;gt; array(&amp;#039;type&amp;#039; =&amp;gt; &amp;#039;int&amp;#039;, ...),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;field_field_1_value&amp;#039; =&amp;gt; array(&amp;#039;type&amp;#039; =&amp;gt; &amp;#039;longtext&amp;#039;, ...)),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;keys&amp;#039; =&amp;gt; array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#039;PRIMARY&amp;#039; =&amp;gt; array(&amp;#039;vid&amp;#039;)),&lt;br /&gt;);&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;(Actually, that isn&#039;t exactly how it currently looks; the data structure layout is a moving target.)&lt;/p&gt;
&lt;p&gt;So, the table has two columns, vid and nid, and its primary key is vid.  The vid field is a 1-to-1 join to node.vid.&lt;/p&gt;
&lt;p&gt;When a node is loaded, Schema&#039;s hook_nodeapi is called. It looks through the total schema (the sum of all structures like above returned by all modules) to find all joins to node (because this is nodeapi, we know we&#039;re loading from table node) and builds up a SELECT/JOIN list. Suppose the schema contains type_1 as above and another module with a table m2 that joins to node on nid and has columns &#039;foo&#039; and &#039;bar&#039;. schema_nodeapi builds this query:&lt;/p&gt;
&lt;p&gt;SELECT content_type_type_1.nid as content_type_type_1_nid, m2.vid as m2_vid, m2.foo as m2_foo, m2.bar as m2_bar&lt;br /&gt;
FROM node n&lt;br /&gt;
LEFT JOIN content_type_type_1 ON content_type_type_1.vid = v.nid&lt;br /&gt;
LEFT JOIN m2 ON m2.nid = n.nid&lt;br /&gt;
WHERE n.nid = %d&lt;/p&gt;
&lt;p&gt;It executes this query for the nid being loaded and saves the results of this query in $node-&amp;gt;schema_data. schema_data[&#039;content_type_type_1&#039;] contains the array of matching rows from the content_type_type_1 table and schema_data[&#039;m2&#039;] contains the array of matching rows from the m2 table.  So now, CCK&#039;s nodeapi and m2&#039;s nodeapi do not need to execute their own SELECT query. They can both just use $node-&amp;gt;schema_data which is waiting for them. So, we&#039;ve turned three queries into one.&lt;/p&gt;
&lt;p&gt;It gets a little more complex if one or more of the joins are 1-to-many (e.g. comments, multi-valued CCK fields, taxonomy terms, etc.).  However, so long as the joined tables have a primary key, it is possible to identify all of the unique rows of data returned from each table and save them in $node-&amp;gt;schema_data, ignoring the duplicates that come as the result of multiple multi-value joins.  (This code is written and working too but not yet committed as it needs some cleanup first.)&lt;/p&gt;
&lt;p&gt;Currently, this happens in schema_nodeapi() but it obviously could be moved directly into node_load() as part of the initial SELECT into the node table, eliminating another query.&lt;/p&gt;
&lt;p&gt;Schema exports $schema structures for all CCK types and fields so this automatically works for all CCK per-content-type fields in the content_type_* tables and multi-valued or shared per-field fields in content_field_* tables.  Depending on the relative performance of this one query with a bunch of LEFT JOINs, we might be able to eliminate CCK&#039;s field cache table, cutting the data storage requirements for CCK nodes in half without a performance penalty.&lt;/p&gt;
&lt;p&gt;And this isn&#039;t limited to CCK.  As I mentioned above, everything that connects to node could be loaded at once: comments &amp;amp; comment statistics, taxonomy terms, the author&#039;s user record, and all the add-on data currently loaded by many modules (book, event, etc.) that is keyed on nid.&lt;/p&gt;
&lt;p&gt;This does result in a lot of LEFT JOINs.  One optimization is to use node types to eliminate unnecessary joins. For any given node, only a subset of tables that join to node.nid/vid are relevant: content_type_page is only relevant for page nodes, and the book table is only relevant for those node types that book.module is configured to book-enable. Each module could encode in its schema the node types the join is relevant for. For example, if book.module is only enabled for &#039;page&#039; nodes, it could say:&lt;/p&gt;
&lt;p&gt;function book_schema() {&lt;br /&gt;
  $schema[&#039;book&#039;] = array(&lt;br /&gt;
     &#039;cols&#039; =&amp;gt; array(..., &#039;join&#039; =&amp;gt; array(&#039;node&#039;, &#039;nid&#039;, &#039;one&#039;), &#039;node-types&#039; =&amp;gt; array(&#039;page&#039;))&lt;br /&gt;
  );&lt;br /&gt;
  return $schema;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;Schema&#039;s nodeapi knows the type of the node being loaded because node_load already got it, so it can simply skip any join that specifies a node-type list and doesn&#039;t match the current node&#039;s type.  To move this one-query approach into node_load and use this optimization, we will need to keep a cache mapping nid =&amp;gt; node type (note that a node, once created, never changes its type). Since node types are write-only, this could be done as simply as having cron output a file defining a array containing the mapping, so no query is even needed to get the nid =&amp;gt; node type cache, just a file load.  Schema already implements the node-type optimization but I have not yet implemented the nid=&amp;gt;type cache.&lt;/p&gt;
&lt;p&gt;So, this is interesting and all, but the most important question is: Is it faster?  I honestly don&#039;t know.  Maybe one big query with many LEFT JOINs is slower than 10-15 separate queries, each against one or two tables.  There is also some overhead in processing the results of the big query, ignoring duplicate rows, etc.  Performance testing will be necessary.&lt;/p&gt;
&lt;p&gt;I&#039;m also quite sure there are bugs to be worked out, improvements to to made, etc.&lt;/p&gt;
&lt;p&gt;Questions?  Feedback?&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/3697#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/108">CCK</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1948">schema</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Tue, 17 Apr 2007 04:23:23 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">3697 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Defining the schema data structure</title>
 <link>http://groups.drupal.org/node/3694</link>
 <description>&lt;p&gt;One of the first things we to do is define the data structure that modules will use for declaring their tables.  Schema module, Frando&#039;s patch, dopry&#039;s patch, and CCK fields all use different structures though their underlying approaches are  basically the same.  We need to decide what kind of information the data structures must contain and can contain.  This will obviously include at least columns (name, type, length, nullable, default), indices (name, columns, primary vs unique vs multi), and join/relationship information.&lt;/p&gt;
&lt;p&gt;We should be database-independent enough to support a broad range of DBMS&#039;s but not try to be so general that we go crazy.  The vast majority of Drupal uses int, varchar, and longtext columns, with a float here and there.  We don&#039;t have to support everything.&lt;/p&gt;
&lt;p&gt;Defining the join relationships is critical.  Eliminating CREATE TABLE is a primary goal, of course, but I believe the functionality enabled by having join information available will be the killer app for the Schema API.&lt;/p&gt;
&lt;p&gt;So, the floor is open.  What should the table-definition data structure look like?&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/database&quot;&gt;Database&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/3694#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/1240">database</category>
 <category domain="http://groups.drupal.org/taxonomy/term/1948">schema</category>
 <group domain="http://groups.drupal.org/database">Database</group>
 <pubDate>Mon, 16 Apr 2007 20:59:18 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">3694 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Welcome and background</title>
 <link>http://groups.drupal.org/node/3691</link>
 <description>&lt;p&gt;Welcome to the Database Schema API group.  A number of different Drupal developers have independently suggested and/or coded various approaches to abstracting table creation/alteration.  The idea finally seems to have reached critical mass and I suggest that we will be best served by combining everyone&#039;s efforts on the topic.  Hence, this group.&lt;/p&gt;
&lt;p&gt;By way of background, here is some recommended reading on the topic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;May 11, 2006: Adrian, Frando, et al: &lt;i&gt;Extend database abstraction layer&lt;/i&gt;, &lt;a href=&quot;http://drupal.org/node/63049&quot; title=&quot;http://drupal.org/node/63049&quot;&gt;http://drupal.org/node/63049&lt;/a&gt;, &lt;/li&gt;
&lt;li&gt;June 9, 2006: bjaspan: &lt;i&gt;Data-driven database tables and updates&lt;/i&gt;, &lt;a href=&quot;http://lists.drupal.org/pipermail/development/2006-June/016893.html&quot; title=&quot;http://lists.drupal.org/pipermail/development/2006-June/016893.html&quot;&gt;http://lists.drupal.org/pipermail/development/2006-June/016893.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;March 16, 2007: bjaspan: &lt;i&gt;The Schema Project: Database abstraction, reflection, and migration&lt;/i&gt;, &lt;a href=&quot;http://jaspan.com/schema-project-database-abstraction-reflection-and-migration&quot; title=&quot;http://jaspan.com/schema-project-database-abstraction-reflection-and-migration&quot;&gt;http://jaspan.com/schema-project-database-abstraction-reflection-and-mig...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;March 28, 2007: dopry, &lt;i&gt;One Approach to DDL abstraction&lt;/i&gt;, &lt;a href=&quot;http://www.darrelopry.com/node/63&quot; title=&quot;ht