Merge branch 'w04_MDL-43761_m27_sqlinstall' of https://github.com/skodak/moodle
This commit is contained in:
@@ -69,26 +69,21 @@ class database_manager {
|
||||
/**
|
||||
* This function will execute an array of SQL commands.
|
||||
*
|
||||
* @param array $sqlarr Array of sql statements to execute.
|
||||
* @throws ddl_exception This exception is thrown if any error is found.
|
||||
* @param string[] $sqlarr Array of sql statements to execute.
|
||||
* @throws ddl_change_structure_exception This exception is thrown if any error is found.
|
||||
*/
|
||||
protected function execute_sql_arr(array $sqlarr) {
|
||||
foreach ($sqlarr as $sql) {
|
||||
$this->execute_sql($sql);
|
||||
}
|
||||
$this->mdb->change_database_structure($sqlarr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a given sql command string.
|
||||
*
|
||||
* @param string $sql The sql string you wish to be executed.
|
||||
* @throws ddl_exception This exception is thrown if any error is found.
|
||||
* @throws ddl_change_structure_exception This exception is thrown if any error is found.
|
||||
*/
|
||||
protected function execute_sql($sql) {
|
||||
if (!$this->mdb->change_database_structure($sql)) {
|
||||
// in case driver does not throw exceptions yet ;-)
|
||||
throw new ddl_change_structure_exception($this->mdb->get_last_error(), $sql);
|
||||
}
|
||||
$this->mdb->change_database_structure($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -124,22 +124,66 @@ class mysql_sql_generator extends sql_generator {
|
||||
|
||||
$sqlarr = parent::getCreateTableSQL($xmldb_table);
|
||||
|
||||
// Let's inject the extra MySQL tweaks.
|
||||
foreach ($sqlarr as $i=>$sql) {
|
||||
if (strpos($sql, 'CREATE TABLE ') === 0) {
|
||||
// This is a very nasty hack that tries to use just one query per created table
|
||||
// because MySQL is stupidly slow when modifying empty tables.
|
||||
// Note: it is safer to inject everything on new lines because there might be some trailing -- comments.
|
||||
$sqls = array();
|
||||
$prevcreate = null;
|
||||
$matches = null;
|
||||
foreach ($sqlarr as $sql) {
|
||||
if (preg_match('/^CREATE TABLE ([^ ]+)/', $sql, $matches)) {
|
||||
$prevcreate = $matches[1];
|
||||
$sql = preg_replace('/\s*\)\s*$/s', '/*keyblock*/)', $sql);
|
||||
// Let's inject the extra MySQL tweaks here.
|
||||
if ($engine) {
|
||||
$sqlarr[$i] .= " ENGINE = $engine";
|
||||
$sql .= "\n ENGINE = $engine";
|
||||
}
|
||||
if ($collation) {
|
||||
if (strpos($collation, 'utf8_') === 0) {
|
||||
$sqlarr[$i] .= " DEFAULT CHARACTER SET utf8";
|
||||
$sql .= "\n DEFAULT CHARACTER SET utf8";
|
||||
}
|
||||
$sql .= "\n DEFAULT COLLATE = $collation";
|
||||
}
|
||||
$sqls[] = $sql;
|
||||
continue;
|
||||
}
|
||||
if ($prevcreate) {
|
||||
if (preg_match('/^ALTER TABLE '.$prevcreate.' COMMENT=(.*)$/s', $sql, $matches)) {
|
||||
$prev = array_pop($sqls);
|
||||
$prev .= "\n COMMENT=$matches[1]";
|
||||
$sqls[] = $prev;
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^CREATE INDEX ([^ ]+) ON '.$prevcreate.' (.*)$/s', $sql, $matches)) {
|
||||
$prev = array_pop($sqls);
|
||||
if (strpos($prev, '/*keyblock*/')) {
|
||||
$prev = str_replace('/*keyblock*/', "\n, KEY $matches[1] $matches[2]/*keyblock*/", $prev);
|
||||
$sqls[] = $prev;
|
||||
continue;
|
||||
} else {
|
||||
$sqls[] = $prev;
|
||||
}
|
||||
}
|
||||
if (preg_match('/^CREATE UNIQUE INDEX ([^ ]+) ON '.$prevcreate.' (.*)$/s', $sql, $matches)) {
|
||||
$prev = array_pop($sqls);
|
||||
if (strpos($prev, '/*keyblock*/')) {
|
||||
$prev = str_replace('/*keyblock*/', "\n, UNIQUE KEY $matches[1] $matches[2]/*keyblock*/", $prev);
|
||||
$sqls[] = $prev;
|
||||
continue;
|
||||
} else {
|
||||
$sqls[] = $prev;
|
||||
}
|
||||
$sqlarr[$i] .= " DEFAULT COLLATE = $collation";
|
||||
}
|
||||
}
|
||||
$prevcreate = null;
|
||||
$sqls[] = $sql;
|
||||
}
|
||||
|
||||
return $sqlarr;
|
||||
foreach ($sqls as $key => $sql) {
|
||||
$sqls[$key] = str_replace('/*keyblock*/', "\n", $sql);
|
||||
}
|
||||
|
||||
return $sqls;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1092,9 +1092,9 @@ abstract class moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, this is for use by database_manager only!
|
||||
* @param string $sql query
|
||||
* @param string|array $sql query or array of queries
|
||||
* @return bool true
|
||||
* @throws dml_exception A DML specific exception is thrown for any errors.
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public abstract function change_database_structure($sql);
|
||||
|
||||
|
||||
@@ -595,17 +595,26 @@ class mssql_native_moodle_database extends moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, to be used by database_manager only!
|
||||
* @param string $sql query
|
||||
* @param string|array $sql query
|
||||
* @return bool true
|
||||
* @throws dml_exception A DML specific exception is thrown for any errors.
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public function change_database_structure($sql) {
|
||||
$this->get_manager(); // Includes DDL exceptions classes ;-)
|
||||
$sqls = (array)$sql;
|
||||
|
||||
try {
|
||||
foreach ($sqls as $sql) {
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = mssql_query($sql, $this->mssql);
|
||||
$this->query_end($result);
|
||||
}
|
||||
} catch (ddl_change_structure_exception $e) {
|
||||
$this->reset_caches();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->reset_caches();
|
||||
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = mssql_query($sql, $this->mssql);
|
||||
$this->query_end($result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ require_once(__DIR__.'/mysqli_native_moodle_temptables.php');
|
||||
*/
|
||||
class mysqli_native_moodle_database extends moodle_database {
|
||||
|
||||
/** @var mysqli $mysqli */
|
||||
protected $mysqli = null;
|
||||
|
||||
private $transactions_supported = null;
|
||||
@@ -821,17 +822,38 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, to be used by database_manager only!
|
||||
* @param string $sql query
|
||||
* @param string|array $sql query
|
||||
* @return bool true
|
||||
* @throws dml_exception A DML specific exception is thrown for any errors.
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public function change_database_structure($sql) {
|
||||
$this->get_manager(); // Includes DDL exceptions classes ;-)
|
||||
if (is_array($sql)) {
|
||||
$sql = implode("\n;\n", $sql);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = $this->mysqli->multi_query($sql);
|
||||
if ($result === false) {
|
||||
$this->query_end(false);
|
||||
}
|
||||
while ($this->mysqli->more_results()) {
|
||||
$result = $this->mysqli->next_result();
|
||||
if ($result === false) {
|
||||
$this->query_end(false);
|
||||
}
|
||||
}
|
||||
$this->query_end(true);
|
||||
} catch (ddl_change_structure_exception $e) {
|
||||
while (@$this->mysqli->more_results()) {
|
||||
@$this->mysqli->next_result();
|
||||
}
|
||||
$this->reset_caches();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->reset_caches();
|
||||
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = $this->mysqli->query($sql);
|
||||
$this->query_end($result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -888,19 +888,28 @@ class oci_native_moodle_database extends moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, to be used by database_manager only!
|
||||
* @param string $sql query
|
||||
* @param string|array $sql query
|
||||
* @return bool true
|
||||
* @throws dml_exception A DML specific exception is thrown for any errors.
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public function change_database_structure($sql) {
|
||||
$this->get_manager(); // Includes DDL exceptions classes ;-)
|
||||
$sqls = (array)$sql;
|
||||
|
||||
try {
|
||||
foreach ($sqls as $sql) {
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$stmt = $this->parse_query($sql);
|
||||
$result = oci_execute($stmt, $this->commit_status);
|
||||
$this->query_end($result, $stmt);
|
||||
oci_free_statement($stmt);
|
||||
}
|
||||
} catch (ddl_change_structure_exception $e) {
|
||||
$this->reset_caches();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->reset_caches();
|
||||
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$stmt = $this->parse_query($sql);
|
||||
$result = oci_execute($stmt, $this->commit_status);
|
||||
$this->query_end($result, $stmt);
|
||||
oci_free_statement($stmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,22 +174,34 @@ abstract class pdo_moodle_database extends moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, to be used by database_manager only!
|
||||
* @param string $sql query
|
||||
* @return bool success
|
||||
* @param string|array $sql query
|
||||
* @return bool true
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public function change_database_structure($sql) {
|
||||
$result = true;
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$this->get_manager(); // Includes DDL exceptions classes ;-)
|
||||
$sqls = (array)$sql;
|
||||
|
||||
try {
|
||||
$this->pdb->exec($sql);
|
||||
foreach ($sqls as $sql) {
|
||||
$result = true;
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
|
||||
try {
|
||||
$this->pdb->exec($sql);
|
||||
} catch (PDOException $ex) {
|
||||
$this->lastError = $ex->getMessage();
|
||||
$result = false;
|
||||
}
|
||||
$this->query_end($result);
|
||||
}
|
||||
} catch (ddl_change_structure_exception $e) {
|
||||
$this->reset_caches();
|
||||
} catch (PDOException $ex) {
|
||||
$this->lastError = $ex->getMessage();
|
||||
$result = false;
|
||||
throw $e;
|
||||
}
|
||||
$this->query_end($result);
|
||||
return $result;
|
||||
|
||||
$this->reset_caches();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete_records_select($table, $select, array $params=null) {
|
||||
|
||||
@@ -37,6 +37,7 @@ require_once(__DIR__.'/pgsql_native_moodle_temptables.php');
|
||||
*/
|
||||
class pgsql_native_moodle_database extends moodle_database {
|
||||
|
||||
/** @var resource $pgsql database resource */
|
||||
protected $pgsql = null;
|
||||
protected $bytea_oid = null;
|
||||
|
||||
@@ -625,18 +626,35 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, to be used by database_manager only!
|
||||
* @param string $sql query
|
||||
* @param string|array $sql query
|
||||
* @return bool true
|
||||
* @throws dml_exception A DML specific exception is thrown for any errors.
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public function change_database_structure($sql) {
|
||||
$this->get_manager(); // Includes DDL exceptions classes ;-)
|
||||
if (is_array($sql)) {
|
||||
$sql = implode("\n;\n", $sql);
|
||||
}
|
||||
if (!$this->is_transaction_started()) {
|
||||
// It is better to do all or nothing, this helps with recovery...
|
||||
$sql = "BEGIN ISOLATION LEVEL SERIALIZABLE;\n$sql\n; COMMIT";
|
||||
}
|
||||
|
||||
try {
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = pg_query($this->pgsql, $sql);
|
||||
$this->query_end($result);
|
||||
pg_free_result($result);
|
||||
} catch (ddl_change_structure_exception $e) {
|
||||
if (!$this->is_transaction_started()) {
|
||||
$result = @pg_query($this->pgsql, "ROLLBACK");
|
||||
@pg_free_result($result);
|
||||
}
|
||||
$this->reset_caches();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->reset_caches();
|
||||
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = pg_query($this->pgsql, $sql);
|
||||
$this->query_end($result);
|
||||
|
||||
pg_free_result($result);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -669,17 +669,26 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||
|
||||
/**
|
||||
* Do NOT use in code, to be used by database_manager only!
|
||||
* @param string $sql query
|
||||
* @param string|array $sql query
|
||||
* @return bool true
|
||||
* @throws dml_exception A DML specific exception is thrown for any errors.
|
||||
* @throws ddl_change_structure_exception A DDL specific exception is thrown for any errors.
|
||||
*/
|
||||
public function change_database_structure($sql) {
|
||||
$this->get_manager(); // Includes DDL exceptions classes ;-)
|
||||
$sqls = (array)$sql;
|
||||
|
||||
try {
|
||||
foreach ($sqls as $sql) {
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = sqlsrv_query($this->sqlsrv, $sql);
|
||||
$this->query_end($result);
|
||||
}
|
||||
} catch (ddl_change_structure_exception $e) {
|
||||
$this->reset_caches();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->reset_caches();
|
||||
|
||||
$this->query_start($sql, null, SQL_QUERY_STRUCTURE);
|
||||
$result = sqlsrv_query($this->sqlsrv, $sql);
|
||||
$this->query_end($result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user