update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
296343bf3b
commit
d885a4baa9
5833 changed files with 418860 additions and 226988 deletions
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -8,8 +8,6 @@
|
|||
*/
|
||||
namespace Piwik\Db;
|
||||
|
||||
|
||||
use Piwik\Loader;
|
||||
use Zend_Db_Table;
|
||||
|
||||
/**
|
||||
|
|
@ -40,9 +38,14 @@ class Adapter
|
|||
}
|
||||
|
||||
$className = self::getAdapterClassName($adapterName);
|
||||
Loader::loadClass($className);
|
||||
|
||||
$adapter = new $className($dbInfos);
|
||||
// make sure not to pass any references otherwise they will modify $dbInfos
|
||||
$infos = array();
|
||||
foreach ($dbInfos as $key => $val) {
|
||||
$infos[$key] = $val;
|
||||
}
|
||||
|
||||
$adapter = new $className($infos);
|
||||
|
||||
if ($connect) {
|
||||
$adapter->getConnection();
|
||||
|
|
@ -60,10 +63,15 @@ class Adapter
|
|||
*
|
||||
* @param string $adapterName
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getAdapterClassName($adapterName)
|
||||
{
|
||||
return 'Piwik\Db\Adapter\\' . str_replace(' ', '\\', ucwords(str_replace(array('_', '\\'), ' ', strtolower($adapterName))));
|
||||
$className = 'Piwik\Db\Adapter\\' . str_replace(' ', '\\', ucwords(str_replace(array('_', '\\'), ' ', strtolower($adapterName))));
|
||||
if (!class_exists($className)) {
|
||||
throw new \Exception("Adapter $adapterName is not valid.");
|
||||
}
|
||||
return $className;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -10,6 +10,7 @@ namespace Piwik\Db\Adapter;
|
|||
|
||||
use Exception;
|
||||
use Piwik\Config;
|
||||
use Piwik\Db;
|
||||
use Piwik\Db\AdapterInterface;
|
||||
use Piwik\Piwik;
|
||||
use Zend_Config;
|
||||
|
|
@ -49,6 +50,17 @@ class Mysqli extends Zend_Db_Adapter_Mysqli implements AdapterInterface
|
|||
return 3306;
|
||||
}
|
||||
|
||||
protected function _connect()
|
||||
{
|
||||
if ($this->_connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::_connect();
|
||||
|
||||
$this->_connection->query('SET sql_mode = "' . Db::SQL_MODE . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check MySQL version
|
||||
*
|
||||
|
|
@ -56,8 +68,9 @@ class Mysqli extends Zend_Db_Adapter_Mysqli implements AdapterInterface
|
|||
*/
|
||||
public function checkServerVersion()
|
||||
{
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$requiredVersion = Config::getInstance()->General['minimum_mysql_version'];
|
||||
|
||||
if (version_compare($serverVersion, $requiredVersion) === -1) {
|
||||
throw new Exception(Piwik::translate('General_ExceptionDatabaseVersion', array('MySQL', $serverVersion, $requiredVersion)));
|
||||
}
|
||||
|
|
@ -72,6 +85,7 @@ class Mysqli extends Zend_Db_Adapter_Mysqli implements AdapterInterface
|
|||
{
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$clientVersion = $this->getClientVersion();
|
||||
|
||||
// incompatible change to DECIMAL implementation in 5.0.3
|
||||
if (version_compare($serverVersion, '5.0.3') >= 0
|
||||
&& version_compare($clientVersion, '5.0.3') < 0
|
||||
|
|
@ -168,10 +182,12 @@ class Mysqli extends Zend_Db_Adapter_Mysqli implements AdapterInterface
|
|||
public function getClientVersion()
|
||||
{
|
||||
$this->_connect();
|
||||
$version = $this->_connection->server_version;
|
||||
$major = (int)($version / 10000);
|
||||
$minor = (int)($version % 10000 / 100);
|
||||
|
||||
$version = $this->_connection->server_version;
|
||||
$major = (int)($version / 10000);
|
||||
$minor = (int)($version % 10000 / 100);
|
||||
$revision = (int)($version % 100);
|
||||
|
||||
return $major . '.' . $minor . '.' . $revision;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -66,7 +66,7 @@ class Mssql extends Zend_Db_Adapter_Pdo_Mssql implements AdapterInterface
|
|||
|
||||
try {
|
||||
$serverName = $this->_config["host"];
|
||||
$database = $this->_config["dbname"];
|
||||
$database = $this->_config["dbname"];
|
||||
if (is_null($database)) {
|
||||
$database = 'master';
|
||||
}
|
||||
|
|
@ -134,8 +134,9 @@ class Mssql extends Zend_Db_Adapter_Pdo_Mssql implements AdapterInterface
|
|||
*/
|
||||
public function checkServerVersion()
|
||||
{
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$requiredVersion = Config::getInstance()->General['minimum_mssql_version'];
|
||||
|
||||
if (version_compare($serverVersion, $requiredVersion) === -1) {
|
||||
throw new Exception(Piwik::translate('General_ExceptionDatabaseVersion', array('MSSQL', $serverVersion, $requiredVersion)));
|
||||
}
|
||||
|
|
@ -149,7 +150,7 @@ class Mssql extends Zend_Db_Adapter_Pdo_Mssql implements AdapterInterface
|
|||
public function getServerVersion()
|
||||
{
|
||||
try {
|
||||
$stmt = $this->query("SELECT CAST(SERVERPROPERTY('productversion') as VARCHAR) as productversion");
|
||||
$stmt = $this->query("SELECT CAST(SERVERPROPERTY('productversion') as VARCHAR) as productversion");
|
||||
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
|
||||
if (count($result)) {
|
||||
return $result[0][0];
|
||||
|
|
@ -169,6 +170,7 @@ class Mssql extends Zend_Db_Adapter_Pdo_Mssql implements AdapterInterface
|
|||
{
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$clientVersion = $this->getClientVersion();
|
||||
|
||||
if (version_compare($serverVersion, '10') >= 0
|
||||
&& version_compare($clientVersion, '10') < 0
|
||||
) {
|
||||
|
|
@ -183,8 +185,7 @@ class Mssql extends Zend_Db_Adapter_Pdo_Mssql implements AdapterInterface
|
|||
*/
|
||||
public static function isEnabled()
|
||||
{
|
||||
$extensions = @get_loaded_extensions();
|
||||
return in_array('PDO', $extensions) && in_array('pdo_sqlsrv', $extensions);
|
||||
return extension_loaded('PDO') && extension_loaded('pdo_sqlsrv');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -224,6 +225,7 @@ class Mssql extends Zend_Db_Adapter_Pdo_Mssql implements AdapterInterface
|
|||
if (preg_match('/(?:\[|\s)([0-9]{4})(?:\]|\s)/', $e->getMessage(), $match)) {
|
||||
return $match[1] == $errno;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -12,6 +12,7 @@ use Exception;
|
|||
use PDO;
|
||||
use PDOException;
|
||||
use Piwik\Config;
|
||||
use Piwik\Db;
|
||||
use Piwik\Db\AdapterInterface;
|
||||
use Piwik\Piwik;
|
||||
use Zend_Config;
|
||||
|
|
@ -61,10 +62,21 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
*/
|
||||
$this->_connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
|
||||
|
||||
return $this->_connection;
|
||||
}
|
||||
|
||||
protected function _connect()
|
||||
{
|
||||
if ($this->_connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::_connect();
|
||||
|
||||
// MYSQL_ATTR_USE_BUFFERED_QUERY will use more memory when enabled
|
||||
// $this->_connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
|
||||
return $this->_connection;
|
||||
$this->_connection->exec('SET sql_mode = "' . Db::SQL_MODE . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,8 +104,9 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
*/
|
||||
public function checkServerVersion()
|
||||
{
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$requiredVersion = Config::getInstance()->General['minimum_mysql_version'];
|
||||
|
||||
if (version_compare($serverVersion, $requiredVersion) === -1) {
|
||||
throw new Exception(Piwik::translate('General_ExceptionDatabaseVersion', array('MySQL', $serverVersion, $requiredVersion)));
|
||||
}
|
||||
|
|
@ -108,6 +121,7 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
{
|
||||
$serverVersion = $this->getServerVersion();
|
||||
$clientVersion = $this->getClientVersion();
|
||||
|
||||
// incompatible change to DECIMAL implementation in 5.0.3
|
||||
if (version_compare($serverVersion, '5.0.3') >= 0
|
||||
&& version_compare($clientVersion, '5.0.3') < 0
|
||||
|
|
@ -123,8 +137,7 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
*/
|
||||
public static function isEnabled()
|
||||
{
|
||||
$extensions = @get_loaded_extensions();
|
||||
return in_array('PDO', $extensions) && in_array('pdo_mysql', $extensions) && in_array('mysql', PDO::getAvailableDrivers());
|
||||
return extension_loaded('PDO') && extension_loaded('pdo_mysql') && in_array('mysql', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,6 +172,7 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
if (preg_match('/(?:\[|\s)([0-9]{4})(?:\]|\s)/', $e->getMessage(), $match)) {
|
||||
return $match[1] == $errno;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -170,9 +184,11 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
public function isConnectionUTF8()
|
||||
{
|
||||
$charsetInfo = $this->fetchAll('SHOW VARIABLES LIKE ?', array('character_set_connection'));
|
||||
|
||||
if (empty($charsetInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$charset = $charsetInfo[0]['Value'];
|
||||
return $charset === 'utf8';
|
||||
}
|
||||
|
|
@ -230,4 +246,19 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
|
|||
$this->cachePreparedStatement[$sql] = $stmt;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override _dsn() to ensure host and port to not be passed along
|
||||
* if unix_socket is set since setting both causes unexpected behaviour
|
||||
* @see http://php.net/manual/en/ref.pdo-mysql.connection.php
|
||||
*/
|
||||
protected function _dsn()
|
||||
{
|
||||
if (!empty($this->_config['unix_socket'])) {
|
||||
unset($this->_config['host']);
|
||||
unset($this->_config['port']);
|
||||
}
|
||||
|
||||
return parent::_dsn();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -47,6 +47,7 @@ class Pgsql extends Zend_Db_Adapter_Pdo_Pgsql implements AdapterInterface
|
|||
{
|
||||
$databaseVersion = $this->getServerVersion();
|
||||
$requiredVersion = Config::getInstance()->General['minimum_pgsql_version'];
|
||||
|
||||
if (version_compare($databaseVersion, $requiredVersion) === -1) {
|
||||
throw new Exception(Piwik::translate('General_ExceptionDatabaseVersion', array('PostgreSQL', $databaseVersion, $requiredVersion)));
|
||||
}
|
||||
|
|
@ -66,8 +67,7 @@ class Pgsql extends Zend_Db_Adapter_Pdo_Pgsql implements AdapterInterface
|
|||
*/
|
||||
public static function isEnabled()
|
||||
{
|
||||
$extensions = @get_loaded_extensions();
|
||||
return in_array('PDO', $extensions) && in_array('pdo_pgsql', $extensions);
|
||||
return extension_loaded('PDO') && extension_loaded('pdo_pgsql');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,6 +146,7 @@ class Pgsql extends Zend_Db_Adapter_Pdo_Pgsql implements AdapterInterface
|
|||
if (preg_match('/([0-9]{2}[0-9P][0-9]{2})/', $e->getMessage(), $match)) {
|
||||
return $match[1] == $map[$errno];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -9,14 +9,12 @@
|
|||
namespace Piwik\Db;
|
||||
|
||||
use Exception;
|
||||
use Piwik\AssetManager;
|
||||
use Piwik\Common;
|
||||
use Piwik\Config;
|
||||
|
||||
use Piwik\Container\StaticContainer;
|
||||
use Piwik\Db;
|
||||
use Piwik\DbHelper;
|
||||
use Piwik\Log;
|
||||
use Piwik\SettingsPiwik;
|
||||
use Piwik\SettingsServer;
|
||||
|
||||
class BatchInsert
|
||||
|
|
@ -34,13 +32,12 @@ class BatchInsert
|
|||
public static function tableInsertBatchIterate($tableName, $fields, $values, $ignoreWhenDuplicate = true)
|
||||
{
|
||||
$fieldList = '(' . join(',', $fields) . ')';
|
||||
$ignore = $ignoreWhenDuplicate ? 'IGNORE' : '';
|
||||
$ignore = $ignoreWhenDuplicate ? 'IGNORE' : '';
|
||||
|
||||
foreach ($values as $row) {
|
||||
$query = "INSERT $ignore
|
||||
INTO " . $tableName . "
|
||||
$fieldList
|
||||
VALUES (" . Common::getSqlStringFieldsArray($row) . ")";
|
||||
$query = "INSERT $ignore INTO " . $tableName . "
|
||||
$fieldList
|
||||
VALUES (" . Common::getSqlStringFieldsArray($row) . ")";
|
||||
Db::query($query, $row);
|
||||
}
|
||||
}
|
||||
|
|
@ -54,18 +51,20 @@ class BatchInsert
|
|||
* @param array $values array of data to be inserted
|
||||
* @param bool $throwException Whether to throw an exception that was caught while trying
|
||||
* LOAD DATA INFILE, or not.
|
||||
* @param string $charset The charset to use, defaults to utf8
|
||||
* @throws Exception
|
||||
* @return bool True if the bulk LOAD was used, false if we fallback to plain INSERTs
|
||||
*/
|
||||
public static function tableInsertBatch($tableName, $fields, $values, $throwException = false)
|
||||
public static function tableInsertBatch($tableName, $fields, $values, $throwException = false, $charset = 'utf8')
|
||||
{
|
||||
$filePath = PIWIK_USER_PATH . '/tmp/assets/' . $tableName . '-' . Common::generateUniqId() . '.csv';
|
||||
$filePath = SettingsPiwik::rewriteTmpPathWithHostname($filePath);
|
||||
|
||||
$loadDataInfileEnabled = Config::getInstance()->General['enable_load_data_infile'];
|
||||
|
||||
if ($loadDataInfileEnabled
|
||||
&& Db::get()->hasBulkLoader()) {
|
||||
|
||||
$path = self::getBestPathForLoadData();
|
||||
$filePath = $path . $tableName . '-' . Common::generateUniqId() . '.csv';
|
||||
|
||||
try {
|
||||
$fileSpec = array(
|
||||
'delim' => "\t",
|
||||
|
|
@ -76,13 +75,9 @@ class BatchInsert
|
|||
},
|
||||
'eol' => "\r\n",
|
||||
'null' => 'NULL',
|
||||
'charset' => $charset
|
||||
);
|
||||
|
||||
// hack for charset mismatch
|
||||
if (!DbHelper::isDatabaseConnectionUTF8() && !isset(Config::getInstance()->database['charset'])) {
|
||||
$fileSpec['charset'] = 'latin1';
|
||||
}
|
||||
|
||||
self::createCSVFile($filePath, $fileSpec, $values);
|
||||
|
||||
if (!is_readable($filePath)) {
|
||||
|
|
@ -95,20 +90,40 @@ class BatchInsert
|
|||
return true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::info("LOAD DATA INFILE failed or not supported, falling back to normal INSERTs... Error was: %s", $e->getMessage());
|
||||
|
||||
if ($throwException) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
// if all else fails, fallback to a series of INSERTs
|
||||
if (file_exists($filePath)) {
|
||||
@unlink($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
// if all else fails, fallback to a series of INSERTs
|
||||
@unlink($filePath);
|
||||
self::tableInsertBatchIterate($tableName, $fields, $values);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function getBestPathForLoadData()
|
||||
{
|
||||
try {
|
||||
$path = Db::fetchOne('SELECT @@secure_file_priv'); // was introduced in 5.0.38
|
||||
} catch (Exception $e) {
|
||||
// we do not rethrow exception as an error is expected if MySQL is < 5.0.38
|
||||
// in this case tableInsertBatch might still work
|
||||
}
|
||||
|
||||
if (empty($path) || !is_dir($path) || !is_writable($path)) {
|
||||
$path = StaticContainer::get('path.tmp') . '/assets/';
|
||||
} elseif (!Common::stringEndsWith($path, '/')) {
|
||||
$path .= '/';
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch insert into table from CSV (or other delimited) file.
|
||||
*
|
||||
|
|
@ -124,7 +139,7 @@ class BatchInsert
|
|||
{
|
||||
// Chroot environment: prefix the path with the absolute chroot path
|
||||
$chrootPath = Config::getInstance()->General['absolute_chroot_path'];
|
||||
if(!empty($chrootPath)) {
|
||||
if (!empty($chrootPath)) {
|
||||
$filePath = $chrootPath . $filePath;
|
||||
}
|
||||
|
||||
|
|
@ -161,19 +176,20 @@ class BatchInsert
|
|||
";
|
||||
|
||||
/*
|
||||
* First attempt: assume web server and MySQL server are on the same machine;
|
||||
* this requires that the db user have the FILE privilege; however, since this is
|
||||
* a global privilege, it may not be granted due to security concerns
|
||||
*/
|
||||
* First attempt: assume web server and MySQL server are on the same machine;
|
||||
* this requires that the db user have the FILE privilege; however, since this is
|
||||
* a global privilege, it may not be granted due to security concerns
|
||||
*/
|
||||
$keywords = array('');
|
||||
|
||||
/*
|
||||
* Second attempt: using the LOCAL keyword means the client reads the file and sends it to the server;
|
||||
* the LOCAL keyword may trigger a known PHP PDO_MYSQL bug when MySQL not built with --enable-local-infile
|
||||
* @see http://bugs.php.net/bug.php?id=54158
|
||||
*/
|
||||
* Second attempt: using the LOCAL keyword means the client reads the file and sends it to the server;
|
||||
* the LOCAL keyword may trigger a known PHP PDO\MYSQL bug when MySQL not built with --enable-local-infile
|
||||
* @see http://bugs.php.net/bug.php?id=54158
|
||||
*/
|
||||
$openBaseDir = ini_get('open_basedir');
|
||||
$safeMode = ini_get('safe_mode');
|
||||
$safeMode = ini_get('safe_mode');
|
||||
|
||||
if (empty($openBaseDir) && empty($safeMode)) {
|
||||
// php 5.x - LOAD DATA LOCAL INFILE is disabled if open_basedir restrictions or safe_mode enabled
|
||||
$keywords[] = 'LOCAL ';
|
||||
|
|
@ -191,22 +207,21 @@ class BatchInsert
|
|||
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
// echo $sql . ' ---- ' . $e->getMessage();
|
||||
$code = $e->getCode();
|
||||
$message = $e->getMessage() . ($code ? "[$code]" : '');
|
||||
if (!Db::get()->isErrNo($e, '1148')) {
|
||||
Log::info("LOAD DATA INFILE failed... Error was: %s", $message);
|
||||
}
|
||||
$exceptions[] = "\n Try #" . (count($exceptions) + 1) . ': ' . $queryStart . ": " . $message;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($exceptions)) {
|
||||
throw new Exception(implode(",", $exceptions));
|
||||
$message = "LOAD DATA INFILE failed... Error was: " . implode(",", $exceptions);
|
||||
Log::info($message);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create CSV (or other delimited) files
|
||||
*
|
||||
|
|
@ -215,13 +230,13 @@ class BatchInsert
|
|||
* @param array $rows Array of array corresponding to rows of values
|
||||
* @throws Exception if unable to create or write to file
|
||||
*/
|
||||
static protected function createCSVFile($filePath, $fileSpec, $rows)
|
||||
protected static function createCSVFile($filePath, $fileSpec, $rows)
|
||||
{
|
||||
// Set up CSV delimiters, quotes, etc
|
||||
$delim = $fileSpec['delim'];
|
||||
$quote = $fileSpec['quote'];
|
||||
$eol = $fileSpec['eol'];
|
||||
$null = $fileSpec['null'];
|
||||
$eol = $fileSpec['eol'];
|
||||
$null = $fileSpec['null'];
|
||||
$escapespecial_cb = $fileSpec['escapespecial_cb'];
|
||||
|
||||
$fp = @fopen($filePath, 'wb');
|
||||
|
|
@ -248,6 +263,7 @@ class BatchInsert
|
|||
throw new Exception('Error writing to the tmp file ' . $filePath);
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
@chmod($filePath, 0777);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -29,7 +29,6 @@ class Schema extends Singleton
|
|||
*/
|
||||
private $schema = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get schema class name
|
||||
*
|
||||
|
|
@ -39,7 +38,7 @@ class Schema extends Singleton
|
|||
private static function getSchemaClassName($schemaName)
|
||||
{
|
||||
// Upgrade from pre 2.0.4
|
||||
if(strtolower($schemaName) == 'myisam'
|
||||
if (strtolower($schemaName) == 'myisam'
|
||||
|| empty($schemaName)) {
|
||||
$schemaName = self::DEFAULT_SCHEMA;
|
||||
}
|
||||
|
|
@ -48,79 +47,17 @@ class Schema extends Singleton
|
|||
return '\Piwik\Db\Schema\\' . $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of schemas
|
||||
*
|
||||
* @param string $adapterName
|
||||
* @return array
|
||||
*/
|
||||
public static function getSchemas($adapterName)
|
||||
{
|
||||
static $allSchemaNames = array(
|
||||
'MYSQL' => array(
|
||||
self::DEFAULT_SCHEMA,
|
||||
// InfiniDB
|
||||
),
|
||||
|
||||
// Microsoft SQL Server
|
||||
// 'MSSQL' => array( 'Mssql' ),
|
||||
|
||||
// PostgreSQL
|
||||
// 'PDO_PGSQL' => array( 'Pgsql' ),
|
||||
|
||||
// IBM DB2
|
||||
// 'IBM' => array( 'Ibm' ),
|
||||
|
||||
// Oracle
|
||||
// 'OCI' => array( 'Oci' ),
|
||||
);
|
||||
|
||||
$adapterName = strtoupper($adapterName);
|
||||
switch ($adapterName) {
|
||||
case 'PDO_MYSQL':
|
||||
case 'MYSQLI':
|
||||
$adapterName = 'MYSQL';
|
||||
break;
|
||||
|
||||
case 'PDO_MSSQL':
|
||||
case 'SQLSRV':
|
||||
$adapterName = 'MSSQL';
|
||||
break;
|
||||
|
||||
case 'PDO_IBM':
|
||||
case 'DB2':
|
||||
$adapterName = 'IBM';
|
||||
break;
|
||||
|
||||
case 'PDO_OCI':
|
||||
case 'ORACLE':
|
||||
$adapterName = 'OCI';
|
||||
break;
|
||||
}
|
||||
$schemaNames = $allSchemaNames[$adapterName];
|
||||
|
||||
$schemas = array();
|
||||
|
||||
foreach ($schemaNames as $schemaName) {
|
||||
$className = __NAMESPACE__ . '\\Schema\\' . $schemaName;
|
||||
if (call_user_func(array($className, 'isAvailable'))) {
|
||||
$schemas[] = $schemaName;
|
||||
}
|
||||
}
|
||||
|
||||
return $schemas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load schema
|
||||
*/
|
||||
private function loadSchema()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$dbInfos = $config->database;
|
||||
$config = Config::getInstance();
|
||||
$dbInfos = $config->database;
|
||||
$schemaName = trim($dbInfos['schema']);
|
||||
|
||||
$className = self::getSchemaClassName($schemaName);
|
||||
$className = self::getSchemaClassName($schemaName);
|
||||
$this->schema = new $className();
|
||||
}
|
||||
|
||||
|
|
@ -134,6 +71,7 @@ class Schema extends Singleton
|
|||
if ($this->schema === null) {
|
||||
$this->loadSchema();
|
||||
}
|
||||
|
||||
return $this->schema;
|
||||
}
|
||||
|
||||
|
|
@ -233,6 +171,18 @@ class Schema extends Singleton
|
|||
return $this->getSchema()->getTablesInstalled($forceReload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of installed columns in a table
|
||||
*
|
||||
* @param string $tableName The name of a table.
|
||||
*
|
||||
* @return array Installed columns indexed by the column name.
|
||||
*/
|
||||
public function getTableColumns($tableName)
|
||||
{
|
||||
return $this->getSchema()->getTableColumns($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Piwik tables exist
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -20,32 +20,7 @@ use Piwik\DbHelper;
|
|||
*/
|
||||
class Mysql implements SchemaInterface
|
||||
{
|
||||
/**
|
||||
* Is this MySQL storage engine available?
|
||||
*
|
||||
* @param string $engineName
|
||||
* @return bool True if available and enabled; false otherwise
|
||||
*/
|
||||
static private function hasStorageEngine($engineName)
|
||||
{
|
||||
$db = Db::get();
|
||||
$allEngines = $db->fetchAssoc('SHOW ENGINES');
|
||||
if (array_key_exists($engineName, $allEngines)) {
|
||||
$support = $allEngines[$engineName]['Support'];
|
||||
return $support == 'DEFAULT' || $support == 'YES';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this schema available?
|
||||
*
|
||||
* @return bool True if schema is available; false otherwise
|
||||
*/
|
||||
static public function isAvailable()
|
||||
{
|
||||
return self::hasStorageEngine('InnoDB');
|
||||
}
|
||||
private $tablesInstalled = null;
|
||||
|
||||
/**
|
||||
* Get the SQL to create Piwik tables
|
||||
|
|
@ -58,284 +33,229 @@ class Mysql implements SchemaInterface
|
|||
$prefixTables = $this->getTablePrefix();
|
||||
|
||||
$tables = array(
|
||||
'user' => "CREATE TABLE {$prefixTables}user (
|
||||
login VARCHAR(100) NOT NULL,
|
||||
password CHAR(32) NOT NULL,
|
||||
alias VARCHAR(45) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
token_auth CHAR(32) NOT NULL,
|
||||
superuser_access TINYINT(2) unsigned NOT NULL DEFAULT '0',
|
||||
date_registered TIMESTAMP NULL,
|
||||
PRIMARY KEY(login),
|
||||
UNIQUE KEY uniq_keytoken(token_auth)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'user' => "CREATE TABLE {$prefixTables}user (
|
||||
login VARCHAR(100) NOT NULL,
|
||||
password CHAR(32) NOT NULL,
|
||||
alias VARCHAR(45) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
token_auth CHAR(32) NOT NULL,
|
||||
superuser_access TINYINT(2) unsigned NOT NULL DEFAULT '0',
|
||||
date_registered TIMESTAMP NULL,
|
||||
PRIMARY KEY(login),
|
||||
UNIQUE KEY uniq_keytoken(token_auth)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'access' => "CREATE TABLE {$prefixTables}access (
|
||||
login VARCHAR(100) NOT NULL,
|
||||
idsite INTEGER UNSIGNED NOT NULL,
|
||||
access VARCHAR(10) NULL,
|
||||
PRIMARY KEY(login, idsite)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'access' => "CREATE TABLE {$prefixTables}access (
|
||||
login VARCHAR(100) NOT NULL,
|
||||
idsite INTEGER UNSIGNED NOT NULL,
|
||||
access VARCHAR(10) NULL,
|
||||
PRIMARY KEY(login, idsite)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'site' => "CREATE TABLE {$prefixTables}site (
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
name VARCHAR(90) NOT NULL,
|
||||
main_url VARCHAR(255) NOT NULL,
|
||||
ts_created TIMESTAMP NULL,
|
||||
ecommerce TINYINT DEFAULT 0,
|
||||
sitesearch TINYINT DEFAULT 1,
|
||||
sitesearch_keyword_parameters TEXT NOT NULL,
|
||||
sitesearch_category_parameters TEXT NOT NULL,
|
||||
timezone VARCHAR( 50 ) NOT NULL,
|
||||
currency CHAR( 3 ) NOT NULL,
|
||||
excluded_ips TEXT NOT NULL,
|
||||
excluded_parameters TEXT NOT NULL,
|
||||
excluded_user_agents TEXT NOT NULL,
|
||||
`group` VARCHAR(250) NOT NULL,
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
keep_url_fragment TINYINT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(idsite)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'site' => "CREATE TABLE {$prefixTables}site (
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
name VARCHAR(90) NOT NULL,
|
||||
main_url VARCHAR(255) NOT NULL,
|
||||
ts_created TIMESTAMP NULL,
|
||||
ecommerce TINYINT DEFAULT 0,
|
||||
sitesearch TINYINT DEFAULT 1,
|
||||
sitesearch_keyword_parameters TEXT NOT NULL,
|
||||
sitesearch_category_parameters TEXT NOT NULL,
|
||||
timezone VARCHAR( 50 ) NOT NULL,
|
||||
currency CHAR( 3 ) NOT NULL,
|
||||
exclude_unknown_urls TINYINT(1) DEFAULT 0,
|
||||
excluded_ips TEXT NOT NULL,
|
||||
excluded_parameters TEXT NOT NULL,
|
||||
excluded_user_agents TEXT NOT NULL,
|
||||
`group` VARCHAR(250) NOT NULL,
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
keep_url_fragment TINYINT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(idsite)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'site_url' => "CREATE TABLE {$prefixTables}site_url (
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL,
|
||||
url VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY(idsite, url)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'site_setting' => "CREATE TABLE {$prefixTables}site_setting (
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`setting_name` VARCHAR(255) NOT NULL,
|
||||
`setting_value` LONGTEXT NOT NULL,
|
||||
PRIMARY KEY(idsite, setting_name)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'goal' => " CREATE TABLE `{$prefixTables}goal` (
|
||||
`idsite` int(11) NOT NULL,
|
||||
`idgoal` int(11) NOT NULL,
|
||||
`name` varchar(50) NOT NULL,
|
||||
`match_attribute` varchar(20) NOT NULL,
|
||||
`pattern` varchar(255) NOT NULL,
|
||||
`pattern_type` varchar(10) NOT NULL,
|
||||
`case_sensitive` tinyint(4) NOT NULL,
|
||||
`allow_multiple` tinyint(4) NOT NULL,
|
||||
`revenue` float NOT NULL,
|
||||
`deleted` tinyint(4) NOT NULL default '0',
|
||||
PRIMARY KEY (`idsite`,`idgoal`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'site_url' => "CREATE TABLE {$prefixTables}site_url (
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL,
|
||||
url VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY(idsite, url)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'logger_message' => "CREATE TABLE {$prefixTables}logger_message (
|
||||
idlogger_message INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
'goal' => "CREATE TABLE `{$prefixTables}goal` (
|
||||
`idsite` int(11) NOT NULL,
|
||||
`idgoal` int(11) NOT NULL,
|
||||
`name` varchar(50) NOT NULL,
|
||||
`match_attribute` varchar(20) NOT NULL,
|
||||
`pattern` varchar(255) NOT NULL,
|
||||
`pattern_type` varchar(10) NOT NULL,
|
||||
`case_sensitive` tinyint(4) NOT NULL,
|
||||
`allow_multiple` tinyint(4) NOT NULL,
|
||||
`revenue` float NOT NULL,
|
||||
`deleted` tinyint(4) NOT NULL default '0',
|
||||
PRIMARY KEY (`idsite`,`idgoal`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'logger_message' => "CREATE TABLE {$prefixTables}logger_message (
|
||||
idlogger_message INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
tag VARCHAR(50) NULL,
|
||||
timestamp TIMESTAMP NULL,
|
||||
timestamp TIMESTAMP NULL,
|
||||
level VARCHAR(16) NULL,
|
||||
message TEXT NULL,
|
||||
PRIMARY KEY(idlogger_message)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
message TEXT NULL,
|
||||
PRIMARY KEY(idlogger_message)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_action' => "CREATE TABLE {$prefixTables}log_action (
|
||||
idaction INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
name TEXT,
|
||||
hash INTEGER(10) UNSIGNED NOT NULL,
|
||||
type TINYINT UNSIGNED NULL,
|
||||
url_prefix TINYINT(2) NULL,
|
||||
PRIMARY KEY(idaction),
|
||||
INDEX index_type_hash (type, hash)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_action' => "CREATE TABLE {$prefixTables}log_action (
|
||||
idaction INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
name TEXT,
|
||||
hash INTEGER(10) UNSIGNED NOT NULL,
|
||||
type TINYINT UNSIGNED NULL,
|
||||
url_prefix TINYINT(2) NULL,
|
||||
PRIMARY KEY(idaction),
|
||||
INDEX index_type_hash (type, hash)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_visit' => "CREATE TABLE {$prefixTables}log_visit (
|
||||
idvisit INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
visitor_localtime TIME NOT NULL,
|
||||
visitor_returning TINYINT(1) NOT NULL,
|
||||
visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visitor_days_since_last SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visit_first_action_time DATETIME NOT NULL,
|
||||
visit_last_action_time DATETIME NOT NULL,
|
||||
visit_exit_idaction_url INTEGER(11) UNSIGNED NULL DEFAULT 0,
|
||||
visit_exit_idaction_name INTEGER(11) UNSIGNED NOT NULL,
|
||||
visit_entry_idaction_url INTEGER(11) UNSIGNED NOT NULL,
|
||||
visit_entry_idaction_name INTEGER(11) UNSIGNED NOT NULL,
|
||||
visit_total_actions SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visit_total_searches SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visit_total_events SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visit_total_time SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visit_goal_converted TINYINT(1) NOT NULL,
|
||||
visit_goal_buyer TINYINT(1) NOT NULL,
|
||||
referer_type TINYINT(1) UNSIGNED NULL,
|
||||
referer_name VARCHAR(70) NULL,
|
||||
referer_url TEXT NOT NULL,
|
||||
referer_keyword VARCHAR(255) NULL,
|
||||
config_id BINARY(8) NOT NULL,
|
||||
config_os CHAR(3) NOT NULL,
|
||||
config_browser_name VARCHAR(10) NOT NULL,
|
||||
config_browser_version VARCHAR(20) NOT NULL,
|
||||
config_resolution VARCHAR(9) NOT NULL,
|
||||
config_pdf TINYINT(1) NOT NULL,
|
||||
config_flash TINYINT(1) NOT NULL,
|
||||
config_java TINYINT(1) NOT NULL,
|
||||
config_director TINYINT(1) NOT NULL,
|
||||
config_quicktime TINYINT(1) NOT NULL,
|
||||
config_realplayer TINYINT(1) NOT NULL,
|
||||
config_windowsmedia TINYINT(1) NOT NULL,
|
||||
config_gears TINYINT(1) NOT NULL,
|
||||
config_silverlight TINYINT(1) NOT NULL,
|
||||
config_cookie TINYINT(1) NOT NULL,
|
||||
location_ip VARBINARY(16) NOT NULL,
|
||||
location_browser_lang VARCHAR(20) NOT NULL,
|
||||
location_country CHAR(3) NOT NULL,
|
||||
location_region char(2) DEFAULT NULL,
|
||||
location_city varchar(255) DEFAULT NULL,
|
||||
location_latitude float(10, 6) DEFAULT NULL,
|
||||
location_longitude float(10, 6) DEFAULT NULL,
|
||||
PRIMARY KEY(idvisit),
|
||||
INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time),
|
||||
INDEX index_idsite_datetime (idsite, visit_last_action_time),
|
||||
INDEX index_idsite_idvisitor (idsite, idvisitor)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'log_visit' => "CREATE TABLE {$prefixTables}log_visit (
|
||||
idvisit INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
idsite INTEGER(10) UNSIGNED NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
visit_last_action_time DATETIME NOT NULL,
|
||||
config_id BINARY(8) NOT NULL,
|
||||
location_ip VARBINARY(16) NOT NULL,
|
||||
PRIMARY KEY(idvisit),
|
||||
INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time),
|
||||
INDEX index_idsite_datetime (idsite, visit_last_action_time),
|
||||
INDEX index_idsite_idvisitor (idsite, idvisitor)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_conversion_item' => "CREATE TABLE `{$prefixTables}log_conversion_item` (
|
||||
idsite int(10) UNSIGNED NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
server_time DATETIME NOT NULL,
|
||||
idvisit INTEGER(10) UNSIGNED NOT NULL,
|
||||
idorder varchar(100) NOT NULL,
|
||||
idsite int(10) UNSIGNED NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
server_time DATETIME NOT NULL,
|
||||
idvisit INTEGER(10) UNSIGNED NOT NULL,
|
||||
idorder varchar(100) NOT NULL,
|
||||
idaction_sku INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_name INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category2 INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category3 INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category4 INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category5 INTEGER(10) UNSIGNED NOT NULL,
|
||||
price FLOAT NOT NULL,
|
||||
quantity INTEGER(10) UNSIGNED NOT NULL,
|
||||
deleted TINYINT(1) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY(idvisit, idorder, idaction_sku),
|
||||
INDEX index_idsite_servertime ( idsite, server_time )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
idaction_sku INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_name INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category2 INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category3 INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category4 INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_category5 INTEGER(10) UNSIGNED NOT NULL,
|
||||
price FLOAT NOT NULL,
|
||||
quantity INTEGER(10) UNSIGNED NOT NULL,
|
||||
deleted TINYINT(1) UNSIGNED NOT NULL,
|
||||
|
||||
PRIMARY KEY(idvisit, idorder, idaction_sku),
|
||||
INDEX index_idsite_servertime ( idsite, server_time )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_conversion' => "CREATE TABLE `{$prefixTables}log_conversion` (
|
||||
idvisit int(10) unsigned NOT NULL,
|
||||
idsite int(10) unsigned NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
server_time datetime NOT NULL,
|
||||
idaction_url int(11) default NULL,
|
||||
idlink_va int(11) default NULL,
|
||||
referer_visit_server_date date default NULL,
|
||||
referer_type int(10) unsigned default NULL,
|
||||
referer_name varchar(70) default NULL,
|
||||
referer_keyword varchar(255) default NULL,
|
||||
visitor_returning tinyint(1) NOT NULL,
|
||||
visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL,
|
||||
visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL,
|
||||
location_country char(3) NOT NULL,
|
||||
location_region char(2) DEFAULT NULL,
|
||||
location_city varchar(255) DEFAULT NULL,
|
||||
location_latitude float(10, 6) DEFAULT NULL,
|
||||
location_longitude float(10, 6) DEFAULT NULL,
|
||||
url text NOT NULL,
|
||||
idgoal int(10) NOT NULL,
|
||||
buster int unsigned NOT NULL,
|
||||
|
||||
idorder varchar(100) default NULL,
|
||||
items SMALLINT UNSIGNED DEFAULT NULL,
|
||||
revenue float default NULL,
|
||||
revenue_subtotal float default NULL,
|
||||
revenue_tax float default NULL,
|
||||
revenue_shipping float default NULL,
|
||||
revenue_discount float default NULL,
|
||||
|
||||
PRIMARY KEY (idvisit, idgoal, buster),
|
||||
UNIQUE KEY unique_idsite_idorder (idsite, idorder),
|
||||
INDEX index_idsite_datetime ( idsite, server_time )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'log_conversion' => "CREATE TABLE `{$prefixTables}log_conversion` (
|
||||
idvisit int(10) unsigned NOT NULL,
|
||||
idsite int(10) unsigned NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
server_time datetime NOT NULL,
|
||||
idaction_url int(11) default NULL,
|
||||
idlink_va int(11) default NULL,
|
||||
idgoal int(10) NOT NULL,
|
||||
buster int unsigned NOT NULL,
|
||||
idorder varchar(100) default NULL,
|
||||
items SMALLINT UNSIGNED DEFAULT NULL,
|
||||
url text NOT NULL,
|
||||
PRIMARY KEY (idvisit, idgoal, buster),
|
||||
UNIQUE KEY unique_idsite_idorder (idsite, idorder),
|
||||
INDEX index_idsite_datetime ( idsite, server_time )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_link_visit_action' => "CREATE TABLE {$prefixTables}log_link_visit_action (
|
||||
idlink_va INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
idsite int(10) UNSIGNED NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
server_time DATETIME NOT NULL,
|
||||
idvisit INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_url INTEGER(10) UNSIGNED DEFAULT NULL,
|
||||
idaction_url_ref INTEGER(10) UNSIGNED NULL DEFAULT 0,
|
||||
idaction_name INTEGER(10) UNSIGNED,
|
||||
idaction_name_ref INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_event_category INTEGER(10) UNSIGNED DEFAULT NULL,
|
||||
idaction_event_action INTEGER(10) UNSIGNED DEFAULT NULL,
|
||||
time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL,
|
||||
idlink_va INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
idsite int(10) UNSIGNED NOT NULL,
|
||||
idvisitor BINARY(8) NOT NULL,
|
||||
idvisit INTEGER(10) UNSIGNED NOT NULL,
|
||||
idaction_url_ref INTEGER(10) UNSIGNED NULL DEFAULT 0,
|
||||
idaction_name_ref INTEGER(10) UNSIGNED NOT NULL,
|
||||
custom_float FLOAT NULL DEFAULT NULL,
|
||||
PRIMARY KEY(idlink_va),
|
||||
INDEX index_idvisit(idvisit)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
custom_float FLOAT NULL DEFAULT NULL,
|
||||
PRIMARY KEY(idlink_va),
|
||||
INDEX index_idvisit(idvisit),
|
||||
INDEX index_idsite_servertime ( idsite, server_time )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'log_profiling' => "CREATE TABLE {$prefixTables}log_profiling (
|
||||
query TEXT NOT NULL,
|
||||
count INTEGER UNSIGNED NULL,
|
||||
sum_time_ms FLOAT NULL,
|
||||
UNIQUE KEY query(query(100))
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'log_profiling' => "CREATE TABLE {$prefixTables}log_profiling (
|
||||
query TEXT NOT NULL,
|
||||
count INTEGER UNSIGNED NULL,
|
||||
sum_time_ms FLOAT NULL,
|
||||
UNIQUE KEY query(query(100))
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'option' => "CREATE TABLE `{$prefixTables}option` (
|
||||
option_name VARCHAR( 255 ) NOT NULL,
|
||||
option_value LONGTEXT NOT NULL,
|
||||
autoload TINYINT NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY ( option_name ),
|
||||
INDEX autoload( autoload )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'option' => "CREATE TABLE `{$prefixTables}option` (
|
||||
option_name VARCHAR( 255 ) NOT NULL,
|
||||
option_value LONGTEXT NOT NULL,
|
||||
autoload TINYINT NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY ( option_name ),
|
||||
INDEX autoload( autoload )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'session' => "CREATE TABLE {$prefixTables}session (
|
||||
id VARCHAR( 255 ) NOT NULL,
|
||||
modified INTEGER,
|
||||
lifetime INTEGER,
|
||||
data TEXT,
|
||||
PRIMARY KEY ( id )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'session' => "CREATE TABLE {$prefixTables}session (
|
||||
id CHAR(32) NOT NULL,
|
||||
modified INTEGER,
|
||||
lifetime INTEGER,
|
||||
data TEXT,
|
||||
PRIMARY KEY ( id )
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'archive_numeric' => "CREATE TABLE {$prefixTables}archive_numeric (
|
||||
idarchive INTEGER UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
idsite INTEGER UNSIGNED NULL,
|
||||
date1 DATE NULL,
|
||||
date2 DATE NULL,
|
||||
period TINYINT UNSIGNED NULL,
|
||||
ts_archived DATETIME NULL,
|
||||
value DOUBLE NULL,
|
||||
PRIMARY KEY(idarchive, name),
|
||||
INDEX index_idsite_dates_period(idsite, date1, date2, period, ts_archived),
|
||||
INDEX index_period_archived(period, ts_archived)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'archive_numeric' => "CREATE TABLE {$prefixTables}archive_numeric (
|
||||
idarchive INTEGER UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
idsite INTEGER UNSIGNED NULL,
|
||||
date1 DATE NULL,
|
||||
date2 DATE NULL,
|
||||
period TINYINT UNSIGNED NULL,
|
||||
ts_archived DATETIME NULL,
|
||||
value DOUBLE NULL,
|
||||
PRIMARY KEY(idarchive, name),
|
||||
INDEX index_idsite_dates_period(idsite, date1, date2, period, ts_archived),
|
||||
INDEX index_period_archived(period, ts_archived)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'archive_blob' => "CREATE TABLE {$prefixTables}archive_blob (
|
||||
idarchive INTEGER UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
idsite INTEGER UNSIGNED NULL,
|
||||
date1 DATE NULL,
|
||||
date2 DATE NULL,
|
||||
period TINYINT UNSIGNED NULL,
|
||||
ts_archived DATETIME NULL,
|
||||
value MEDIUMBLOB NULL,
|
||||
PRIMARY KEY(idarchive, name),
|
||||
INDEX index_period_archived(period, ts_archived)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
|
||||
'archive_blob' => "CREATE TABLE {$prefixTables}archive_blob (
|
||||
idarchive INTEGER UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
idsite INTEGER UNSIGNED NULL,
|
||||
date1 DATE NULL,
|
||||
date2 DATE NULL,
|
||||
period TINYINT UNSIGNED NULL,
|
||||
ts_archived DATETIME NULL,
|
||||
value MEDIUMBLOB NULL,
|
||||
PRIMARY KEY(idarchive, name),
|
||||
INDEX index_period_archived(period, ts_archived)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
'sequence' => "CREATE TABLE {$prefixTables}sequence (
|
||||
`name` VARCHAR(120) NOT NULL,
|
||||
`value` BIGINT(20) UNSIGNED NOT NULL ,
|
||||
PRIMARY KEY(`name`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8
|
||||
",
|
||||
);
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
|
|
@ -365,16 +285,37 @@ class Mysql implements SchemaInterface
|
|||
*/
|
||||
public function getTablesNames()
|
||||
{
|
||||
$aTables = array_keys($this->getTablesCreateSql());
|
||||
$aTables = array_keys($this->getTablesCreateSql());
|
||||
$prefixTables = $this->getTablePrefix();
|
||||
|
||||
$return = array();
|
||||
foreach ($aTables as $table) {
|
||||
$return[] = $prefixTables . $table;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private $tablesInstalled = null;
|
||||
/**
|
||||
* Get list of installed columns in a table
|
||||
*
|
||||
* @param string $tableName The name of a table.
|
||||
*
|
||||
* @return array Installed columns indexed by the column name.
|
||||
*/
|
||||
public function getTableColumns($tableName)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$allColumns = $db->fetchAll("SHOW COLUMNS FROM . $tableName");
|
||||
|
||||
$fields = array();
|
||||
foreach ($allColumns as $column) {
|
||||
$fields[trim($column['Field'])] = $column;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of tables installed
|
||||
|
|
@ -387,13 +328,10 @@ class Mysql implements SchemaInterface
|
|||
if (is_null($this->tablesInstalled)
|
||||
|| $forceReload === true
|
||||
) {
|
||||
$db = Db::get();
|
||||
$prefixTables = $this->getTablePrefix();
|
||||
$db = $this->getDb();
|
||||
$prefixTables = $this->getTablePrefixEscaped();
|
||||
|
||||
// '_' matches any character; force it to be literal
|
||||
$prefixTables = str_replace('_', '\_', $prefixTables);
|
||||
|
||||
$allTables = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "%'");
|
||||
$allTables = $this->getAllExistingTables($prefixTables);
|
||||
|
||||
// all the tables to be installed
|
||||
$allMyTables = $this->getTablesNames();
|
||||
|
|
@ -403,12 +341,13 @@ class Mysql implements SchemaInterface
|
|||
|
||||
// at this point we have the static list of core tables, but let's add the monthly archive tables
|
||||
$allArchiveNumeric = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "archive_numeric%'");
|
||||
$allArchiveBlob = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "archive_blob%'");
|
||||
$allArchiveBlob = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "archive_blob%'");
|
||||
|
||||
$allTablesReallyInstalled = array_merge($tablesInstalled, $allArchiveNumeric, $allArchiveBlob);
|
||||
|
||||
$this->tablesInstalled = $allTablesReallyInstalled;
|
||||
}
|
||||
|
||||
return $this->tablesInstalled;
|
||||
}
|
||||
|
||||
|
|
@ -432,6 +371,7 @@ class Mysql implements SchemaInterface
|
|||
if (is_null($dbName)) {
|
||||
$dbName = $this->getDbName();
|
||||
}
|
||||
|
||||
Db::exec("CREATE DATABASE IF NOT EXISTS " . $dbName . " DEFAULT CHARACTER SET utf8");
|
||||
}
|
||||
|
||||
|
|
@ -454,8 +394,8 @@ class Mysql implements SchemaInterface
|
|||
Db::exec($statement);
|
||||
} catch (Exception $e) {
|
||||
// mysql code error 1050:table already exists
|
||||
// see bug #153 http://dev.piwik.org/trac/ticket/153
|
||||
if (!Db::get()->isErrNo($e, '1050')) {
|
||||
// see bug #153 https://github.com/piwik/piwik/issues/153
|
||||
if (!$this->getDb()->isErrNo($e, '1050')) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
|
@ -475,7 +415,7 @@ class Mysql implements SchemaInterface
|
|||
*/
|
||||
public function createTables()
|
||||
{
|
||||
$db = Db::get();
|
||||
$db = $this->getDb();
|
||||
$prefixTables = $this->getTablePrefix();
|
||||
|
||||
$tablesAlreadyInstalled = $this->getTablesInstalled();
|
||||
|
|
@ -498,9 +438,9 @@ class Mysql implements SchemaInterface
|
|||
{
|
||||
// The anonymous user is the user that is assigned by default
|
||||
// note that the token_auth value is anonymous, which is assigned by default as well in the Login plugin
|
||||
$db = Db::get();
|
||||
$db = $this->getDb();
|
||||
$db->query("INSERT IGNORE INTO " . Common::prefixTable("user") . "
|
||||
VALUES ( 'anonymous', '', 'anonymous', 'anonymous@example.org', 'anonymous', 0, '" . Date::factory('now')->getDatetime() . "' );");
|
||||
VALUES ( 'anonymous', '', 'anonymous', 'anonymous@example.org', 'anonymous', 0, '" . Date::factory('now')->getDatetime() . "' );");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -508,32 +448,51 @@ class Mysql implements SchemaInterface
|
|||
*/
|
||||
public function truncateAllTables()
|
||||
{
|
||||
$tablesAlreadyInstalled = $this->getTablesInstalled($forceReload = true);
|
||||
foreach ($tablesAlreadyInstalled as $table) {
|
||||
$tables = $this->getAllExistingTables();
|
||||
foreach ($tables as $table) {
|
||||
Db::query("TRUNCATE `$table`");
|
||||
}
|
||||
}
|
||||
|
||||
private function getTablePrefix()
|
||||
{
|
||||
$dbInfos = Db::getDatabaseConfig();
|
||||
$prefixTables = $dbInfos['tables_prefix'];
|
||||
|
||||
return $prefixTables;
|
||||
return $this->getDbSettings()->getTablePrefix();
|
||||
}
|
||||
|
||||
private function getTableEngine()
|
||||
{
|
||||
$dbInfos = Db::getDatabaseConfig();
|
||||
$engine = $dbInfos['type'];
|
||||
return $engine;
|
||||
return $this->getDbSettings()->getEngine();
|
||||
}
|
||||
|
||||
private function getDb()
|
||||
{
|
||||
return Db::get();
|
||||
}
|
||||
|
||||
private function getDbSettings()
|
||||
{
|
||||
return new Db\Settings();
|
||||
}
|
||||
|
||||
private function getDbName()
|
||||
{
|
||||
$dbInfos = Db::getDatabaseConfig();
|
||||
$dbName = $dbInfos['dbname'];
|
||||
return $this->getDbSettings()->getDbName();
|
||||
}
|
||||
|
||||
return $dbName;
|
||||
private function getAllExistingTables($prefixTables = false)
|
||||
{
|
||||
if (empty($prefixTables)) {
|
||||
$prefixTables = $this->getTablePrefixEscaped();
|
||||
}
|
||||
|
||||
return Db::get()->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "%'");
|
||||
}
|
||||
|
||||
private function getTablePrefixEscaped()
|
||||
{
|
||||
$prefixTables = $this->getTablePrefix();
|
||||
// '_' matches any character; force it to be literal
|
||||
$prefixTables = str_replace('_', '\_', $prefixTables);
|
||||
return $prefixTables;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -14,13 +14,6 @@ namespace Piwik\Db;
|
|||
*/
|
||||
interface SchemaInterface
|
||||
{
|
||||
/**
|
||||
* Is this schema available?
|
||||
*
|
||||
* @return bool True if schema is available; false otherwise
|
||||
*/
|
||||
static public function isAvailable();
|
||||
|
||||
/**
|
||||
* Get the SQL to create a specific Piwik table
|
||||
*
|
||||
|
|
@ -87,6 +80,15 @@ interface SchemaInterface
|
|||
*/
|
||||
public function getTablesInstalled($forceReload = true);
|
||||
|
||||
/**
|
||||
* Get list of installed columns in a table
|
||||
*
|
||||
* @param string $tableName The name of a table.
|
||||
*
|
||||
* @return array Installed columns indexed by the column name.
|
||||
*/
|
||||
public function getTableColumns($tableName);
|
||||
|
||||
/**
|
||||
* Checks whether any table exists
|
||||
*
|
||||
|
|
|
|||
44
www/analytics/core/Db/Settings.php
Normal file
44
www/analytics/core/Db/Settings.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Db;
|
||||
|
||||
use Piwik\Db;
|
||||
|
||||
/**
|
||||
* Schema abstraction
|
||||
*
|
||||
* Note: no relation to the ZF proposals for Zend_Db_Schema_Manager
|
||||
*
|
||||
* @method static \Piwik\Db\Schema getInstance()
|
||||
*/
|
||||
class Settings
|
||||
{
|
||||
public function getEngine()
|
||||
{
|
||||
return $this->getDbSetting('type');
|
||||
}
|
||||
|
||||
public function getTablePrefix()
|
||||
{
|
||||
return $this->getDbSetting('tables_prefix');
|
||||
}
|
||||
|
||||
public function getDbName()
|
||||
{
|
||||
return $this->getDbSetting('dbname');
|
||||
}
|
||||
|
||||
private function getDbSetting($key)
|
||||
{
|
||||
$dbInfos = Db::getDatabaseConfig();
|
||||
$engine = $dbInfos[$key];
|
||||
|
||||
return $engine;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue