CRM-17394 - Initialize DB slightly later. Fix query-log and redundant SET NAMES.
authorTim Otten <totten@civicrm.org>
Mon, 16 Nov 2015 00:07:36 +0000 (16:07 -0800)
committerTim Otten <totten@civicrm.org>
Sun, 22 Nov 2015 20:22:18 +0000 (12:22 -0800)
Strictly speaking, this patch does two different things:
 * Initialize DB slightly later. This fixes a race among settings-manager, DB init, and query logging.
 * Call `SET NAMES utf8` once during connection init. Before, it was called once for every DAO object.

Based on quick spot-check, it still seems to store UTF-8 data. To be safe,
I've added an extra error-check to ensure that the `SET NAMES utf8` is still
called before we actually use the DAO.

CRM/Core/DAO.php
CRM/Core/Error.php
Civi/Core/Container.php

index 335a3fd50c03e8d7c324987d98f7b35e9a919afb..0d2c617d6882d1abf5e7f8dafa24fc72048e616a 100644 (file)
@@ -99,6 +99,7 @@ class CRM_Core_DAO extends DB_DataObject {
    *   The database connection string.
    */
   public static function init($dsn) {
+    Civi::$statics[__CLASS__]['init'] = 1;
     $options = &PEAR::getStaticProperty('DB_DataObject', 'options');
     $options['database'] = $dsn;
     if (defined('CIVICRM_DAO_DEBUG')) {
@@ -108,6 +109,7 @@ class CRM_Core_DAO extends DB_DataObject {
     if (CRM_Utils_Constant::value('CIVICRM_MYSQL_STRICT', CRM_Utils_System::isDevelopment())) {
       CRM_Core_DAO::executeQuery('SET SESSION sql_mode = STRICT_TRANS_TABLES');
     }
+    CRM_Core_DAO::executeQuery('SET NAMES utf8');
   }
 
   /**
@@ -354,7 +356,12 @@ class CRM_Core_DAO extends DB_DataObject {
    */
   public function initialize() {
     $this->_connect();
-    $this->query("SET NAMES utf8");
+    if (empty(Civi::$statics[__CLASS__]['init'])) {
+      // CRM_Core_DAO::init() must be called before CRM_Core_DAO->initialize().
+      // This occurs very early in bootstrap - error handlers may not be wired up.
+      echo "Inconsistent system initialization sequence. Premature access of (" . get_class($this) . ")";
+      CRM_Utils_System::civiExit();
+    }
   }
 
   /**
index 6bf012854ec8125106d3cc6132cd73aedd7035a1..615606eb103182e70431b25fb10a2c8b9d450b35 100644 (file)
@@ -590,7 +590,7 @@ class CRM_Core_Error extends PEAR_ErrorStack {
     }
     $file_log->close();
 
-    if ($config->userFrameworkLogging) {
+    if (!empty($config->userFrameworkLogging)) {
       // should call $config->userSystem->logger($message) here - but I got a situation where userSystem was not an object - not sure why
       if ($config->userSystem->is_drupal and function_exists('watchdog')) {
         watchdog('civicrm', '%message', array('%message' => $message), WATCHDOG_DEBUG);
index 39b97559521059db95494d4cca438a69ca29b891..cc34390e591c6680b25389ba6a82df72dd5bd014 100644 (file)
@@ -335,10 +335,6 @@ class Container {
     );
     $runtime->initialize($loadFromDB);
 
-    if ($loadFromDB && $runtime->dsn) {
-      \CRM_Core_DAO::init($runtime->dsn);
-    }
-
     $bootServices['paths'] = array(
       'class' => 'Civi\Core\Paths',
       'obj' => new \Civi\Core\Paths(),
@@ -377,6 +373,7 @@ class Container {
     );
 
     if ($loadFromDB && $runtime->dsn) {
+      \CRM_Core_DAO::init($runtime->dsn);
       \CRM_Utils_Hook::singleton(TRUE);
       \CRM_Extension_System::singleton(TRUE);