diff --git a/includes/cache.inc b/includes/cache.inc index 207bf66..8af7fd8 100644 --- a/includes/cache.inc +++ b/includes/cache.inc @@ -460,10 +460,25 @@ class DrupalDatabaseCache implements DrupalCacheInterface { } try { - db_merge($this->bin) - ->key(array('cid' => $cid)) - ->fields($fields) - ->execute(); + if (function_exists('drupal_mysqli_get_object')) { + $mysqli = drupal_mysqli_get_object(); + } + if (empty($mysqli)) { + db_merge($this->bin) + ->key(array('cid' => $cid)) + ->fields($fields) + ->execute(); + } + else { + // Flush the async buffer. + @$mysqli->reap_async_query(); + + // Run query. + $escaped_cid = $mysqli->real_escape_string($cid); + $escaped_data = $mysqli->real_escape_string($fields['data']); + $query = "INSERT IGNORE INTO {$this->bin} (cid, serialized, created, expire, data) VALUES ('$escaped_cid', '{$fields['serialized']}', '{$fields['created']}', '{$fields['expire']}', '$escaped_data');"; + $mysqli->query($query, MYSQLI_ASYNC); + } } catch (Exception $e) { // The database may not be available, so we'll ignore cache_set requests. diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc index 4907a39..b3dfd4d 100644 --- a/includes/database/mysql/database.inc +++ b/includes/database/mysql/database.inc @@ -5,6 +5,61 @@ * Database interface code for MySQL database servers. */ +function drupal_mysqli_get_object() { + // Bail out if not mysql that is async capable. + $db_type = Database::getConnection()->databaseType(); + if ($db_type !== 'mysql' || !function_exists('mysqli_init') || !defined('MYSQLI_ASYNC')) { + return FALSE; + } + + $db_connections = &drupal_static(__FUNCTION__); + $connection_info = Database::getConnectionInfo(); + + $default_name = key($connection_info); + if (!isset($db_connections[$default_name])) { + if (!isset($GLOBALS['databases'][$default_name]['default'])) { + return FALSE; + } + $default_info = $GLOBALS['databases'][$default_name]['default']; + + if (empty($default_info['port'])) { + $default_info['port'] = NULL; + } + if (empty($default_info['unix_socket'])) { + $default_info['unix_socket'] = NULL; + } + $mysqli = new mysqli($default_info['host'], $default_info['username'], $default_info['password'], $default_info['database'], $default_info['port'], $default_info['unix_socket']); + + if (empty($mysqli) || !empty($mysqli->connect_errno)) { + unset($mysqli); + $mysqli = FALSE; + } + if (!empty($mysqli)) { + $mysqli->set_charset('utf8'); + + if (!isset($default_info['init_commands'])) { + $default_info['init_commands'] = array(); + } + $default_info['init_commands'] += array( + 'sql_mode' => "SET sql_mode = 'ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'", + 'isolation' => "SET SESSION tx_isolation='READ-UNCOMMITTED'", + ); + foreach ($default_info['init_commands'] as $query) { + $mysqli->query($query); + } + } + $db_connections[$default_name] = $mysqli; + register_shutdown_function('drupal_mysqli_async_flush_buffer'); + } + + return $db_connections[$default_name]; +} + +function drupal_mysqli_async_flush_buffer() { + $mysqli = drupal_mysqli_get_object(); + return @$mysqli->reap_async_query(); +} + /** * @addtogroup database * @{