A few days ago, while I was writing a bit of Silex code and grumbling at Doctrine DBAL's lack of support for a SQL Merge operation, I wondered if it wouldn't be possible to use DBTNG without the rest of Drupal.
Obviously, although DBTNG is described as having been designed for standalone use: DBTNG should be a stand-alone library with no external dependences other than PHP 5.2 and the PDO database library
, in actual use, the Github DBTNG repo has seen no commit in the last 3 years, and the D8 version is still not a Drupal 8 "Component" (i.e. decoupled code), but still a plain library with Drupal dependencies. How would it fare on its own ? Let's give it a try...
Bring DBTNG to a non-Drupal Composer project
Since Composer does not support sparse checkouts (yet ?), the simplest way to do bring in DBTNG for this little test is to just import the code manually and declare it to the autoloader manually. Let's start by getting just DBTNG out of the latest Drupal 8 checkout:
# Create a fresh repository to hold the example mkdir dbtng_example cd dbtng_example git init # Declare a remote git remote add drupal http://git.drupal.org/project/drupal.git # Enable sparse checkouts to just checkout DBTNG git config core.sparsecheckout true # Declare just what we want to checkout: # 1. The DBTNG classes echo core/lib/Drupal/Core/Database >> .git/info/sparse-checkout # 2. The procedural wrappers, for simplicity in an example echo core/includes/database.inc >> .git/info/sparse-checkout # And checkout DBTNG git pull drupal 8.x ls -l core/ total 8 drwxrwxr-x 2 marand www-data 4096 févr. 8 09:32 includes drwxrwxr-x 3 marand www-data 4096 févr. 8 09:32 libThat's it: DBTNG classes are now available in
core/lib/Drupal/Core/Database
. We can now build a Composer file with PSR-4 autoloading on that code:
{ "autoload": { "psr-4": { "Drupal\\Core\\Database\\": "core/lib/Drupal/Core/Database/" } }, "description": "Drupal Database API as a standalone component", "license": "GPL-2.0+", }We can now build the autoloader:
php composer.phar install
Build the demo app
For this example, we can use the traditional settings.php
configuration for DBTNG, say we store it in app/config/settings.php
and point to a typical Drupal 8 MySQL single-server database:
At this point, our dependencies are ready, let's build some Hello, world in app/hellodbtng.php
. Since this is just an example, we will just list a table using the DBTNG Select query builder:
Enjoy the query results
php app/hellodbtng.php system.schema block 8000 system.schema breakpoint 8000 system.schema ckeditor 8000 system.schema color 8000 system.schema comment 8000 system.schema config 8000 system.schema contact 8000 system.schema contextual 8000 system.schema custom_block 8000 system.schema datetime 8000
Going further
In real life:
- a production project would hopefully not be built like this, by manually extracting files from a repo
- ... and it would probably not use the procedural wrappers, but wrap DBTNG in a service and pass it configuration using a DIC
- I seem to remember a discussion in which the full decoupling of DBTNG for D8 was considered but postponed as nice-to-have rather than essential for Drupal 8.0.
- Which means that a simple integration would probably either
- use the currently available (but obsolete) pre-7.0 version straight from Github (since that package is not available on Packagist, just declare it directly in
composer.json
as explained on http://www.craftitonline.com/2012/03/how-to-use-composer-without-packag… ), - or (better) do the required work to decouple DBTNG from D8 core and submit a core patch for that decoupled version, and use it from the newly-independent DBTNG Component.
- use the currently available (but obsolete) pre-7.0 version straight from Github (since that package is not available on Packagist, just declare it directly in
When I attempted this:
For what it's worth, leveraging a DIC (Symfony's) looked a little like this: https://gist.github.com/EclipseGc/8885836
As I recall there a few a places we call t() directly in DBTNG's code base as well, and I had to transition those over to Utility/String class usages. Is that not the case still?
Eclipse
Last summer I worked on an
Last summer I worked on an alternative comment system (MongoDB-based) for a biggish Pressflow 6 site and, not wanting to code for PF6 in 2013, what I ended up doing was create a small-ish
CoreService
containing methods for the few unavoidable functions (t()
being one of these), and injecting the Drupal core functions to it when running in Pressflow 6 or Drupal 7, and using simpler stub implementations when running unit tests or using the code entirely outside Drupal.The basic idea, of course, being to develop that code so that a migration to D8 in the future would only require rewriting the tiny "module" part for D8 and let that package basically unchanged.
Come to think of it, this is the core of my "Drupal 678" session at Szeged DevDays: http://szeged2014.drupaldays.org/program/sessions/develop-drupal-8-drup… :-)
I'm replying to that comment
I'm replying to that comment since there's no general reply link. I tried this 2+ years later and there are a few minor issues. The URL is now git.drupal.org, composer complained about an extra comma, I changed it to "git pull drupal 8.2.x", and I needed to call Drupal\Core\Database\Database::setMultipleConnectionInfo( $databases ); . Very useful overall.