mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #8880 from tractorcow/pulls/4.2/enum-schema-shifting
BUG Resolve issue where schema changes between enum / non-enum types
This commit is contained in:
commit
67d88c824b
@ -86,9 +86,9 @@ class GridFieldLevelup implements GridField_HTMLProvider
|
|||||||
));
|
));
|
||||||
|
|
||||||
$template = SSViewer::get_templates_by_class($this, '', __CLASS__);
|
$template = SSViewer::get_templates_by_class($this, '', __CLASS__);
|
||||||
return array(
|
return [
|
||||||
'before' => $forTemplate->renderWith($template),
|
'before' => $forTemplate->renderWith($template),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAttributes($attrs)
|
public function setAttributes($attrs)
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
namespace SilverStripe\ORM\Connect;
|
namespace SilverStripe\ORM\Connect;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\ORM\FieldType\DBPrimaryKey;
|
use SilverStripe\ORM\DB;
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
use Exception;
|
use SilverStripe\ORM\FieldType\DBPrimaryKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents and handles all schema management for a database
|
* Represents and handles all schema management for a database
|
||||||
@ -710,33 +711,33 @@ MESSAGE
|
|||||||
} elseif ($fieldValue != $specValue) {
|
} elseif ($fieldValue != $specValue) {
|
||||||
// If enums/sets are being modified, then we need to fix existing data in the table.
|
// If enums/sets are being modified, then we need to fix existing data in the table.
|
||||||
// Update any records where the enum is set to a legacy value to be set to the default.
|
// Update any records where the enum is set to a legacy value to be set to the default.
|
||||||
foreach (array('enum', 'set') as $enumtype) {
|
$enumValuesExpr = "/^(enum|set)\\s*\\(['\"](?<values>[^'\"]+)['\"]\\).*/i";
|
||||||
if (preg_match("/^$enumtype/i", $specValue)) {
|
if (preg_match($enumValuesExpr, $specValue, $specMatches)
|
||||||
$newStr = preg_replace("/(^$enumtype\\s*\\(')|('\\).*)/i", "", $spec_orig);
|
&& preg_match($enumValuesExpr, $spec_orig, $oldMatches)
|
||||||
$new = preg_split("/'\\s*,\\s*'/", $newStr);
|
) {
|
||||||
|
$new = preg_split("/'\\s*,\\s*'/", $specMatches['values']);
|
||||||
|
$old = preg_split("/'\\s*,\\s*'/", $oldMatches['values']);
|
||||||
|
|
||||||
$oldStr = preg_replace("/(^$enumtype\\s*\\(')|('\\).*)/i", "", $fieldValue);
|
$holder = array();
|
||||||
$old = preg_split("/'\\s*,\\s*'/", $oldStr);
|
foreach ($old as $check) {
|
||||||
|
if (!in_array($check, $new)) {
|
||||||
$holder = array();
|
$holder[] = $check;
|
||||||
foreach ($old as $check) {
|
|
||||||
if (!in_array($check, $new)) {
|
|
||||||
$holder[] = $check;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (count($holder)) {
|
}
|
||||||
|
|
||||||
|
if (count($holder)) {
|
||||||
|
// Get default pre-escaped for SQL. We just use this directly, as we don't have a real way to
|
||||||
|
// de-encode SQL values
|
||||||
$default = explode('default ', $spec_orig);
|
$default = explode('default ', $spec_orig);
|
||||||
$default = $default[1];
|
$defaultSQL = isset($default[1]) ? $default[1] : 'NULL';
|
||||||
$query = "UPDATE \"$table\" SET $field=$default WHERE $field IN (";
|
// Reset to default any value in that is in the old enum, but not the new one
|
||||||
for ($i = 0; $i + 1 < count($holder); $i++) {
|
$placeholders = DB::placeholders($holder);
|
||||||
$query .= "'{$holder[$i]}', ";
|
$query = "UPDATE \"{$table}\" SET \"{$field}\" = {$defaultSQL} WHERE \"{$field}\" IN ({$placeholders})";
|
||||||
}
|
$this->preparedQuery($query, $holder);
|
||||||
$query .= "'{$holder[$i]}')";
|
|
||||||
$this->query($query);
|
|
||||||
$amount = $this->database->affectedRows();
|
$amount = $this->database->affectedRows();
|
||||||
$this->alterationMessage("Changed $amount rows to default value of field $field"
|
$this->alterationMessage(
|
||||||
. " (Value: $default)");
|
"Changed $amount rows to default value of field $field (Value: $defaultSQL)"
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->transAlterField($table, $field, $spec_orig);
|
$this->transAlterField($table, $field, $spec_orig);
|
||||||
|
@ -41,11 +41,12 @@ if (!defined('BASE_PATH')) {
|
|||||||
define('BASE_PATH', call_user_func(function () {
|
define('BASE_PATH', call_user_func(function () {
|
||||||
// Determine BASE_PATH based on the composer autoloader
|
// Determine BASE_PATH based on the composer autoloader
|
||||||
foreach (debug_backtrace() as $backtraceItem) {
|
foreach (debug_backtrace() as $backtraceItem) {
|
||||||
if (isset($backtraceItem['file']) && preg_match(
|
if (isset($backtraceItem['file'])
|
||||||
'#^(?<base>.*)(/|\\\\)vendor(/|\\\\)composer(/|\\\\)autoload_real.php#',
|
&& preg_match(
|
||||||
$backtraceItem['file'],
|
'#^(?<base>.*)(/|\\\\)vendor(/|\\\\)composer(/|\\\\)autoload_real.php#',
|
||||||
$matches
|
$backtraceItem['file'],
|
||||||
)) {
|
$matches
|
||||||
|
)) {
|
||||||
return realpath($matches['base']) ?: DIRECTORY_SEPARATOR;
|
return realpath($matches['base']) ?: DIRECTORY_SEPARATOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,23 +133,24 @@ if (!defined('BASE_URL')) {
|
|||||||
|
|
||||||
// When htaccess redirects from /base to /base/public folder, we need to only include /public
|
// When htaccess redirects from /base to /base/public folder, we need to only include /public
|
||||||
// in the BASE_URL if it's also present in the request
|
// in the BASE_URL if it's also present in the request
|
||||||
if ($baseURL
|
if (!$baseURL
|
||||||
&& PUBLIC_DIR
|
|| !PUBLIC_DIR
|
||||||
&& isset($_SERVER['REQUEST_URI'])
|
|| !isset($_SERVER['REQUEST_URI'])
|
||||||
&& substr($baseURL, -strlen(PUBLIC_DIR)) === PUBLIC_DIR
|
|| substr($baseURL, -strlen(PUBLIC_DIR)) !== PUBLIC_DIR
|
||||||
) {
|
) {
|
||||||
$requestURI = $_SERVER['REQUEST_URI'];
|
return $baseURL;
|
||||||
// Check if /base/public or /base are in the request
|
|
||||||
foreach ([$baseURL, dirname($baseURL)] as $candidate) {
|
|
||||||
if (stripos($requestURI, $candidate) === 0) {
|
|
||||||
return $candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Ambiguous
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $baseURL;
|
$requestURI = $_SERVER['REQUEST_URI'];
|
||||||
|
// Check if /base/public or /base are in the request
|
||||||
|
foreach ([$baseURL, dirname($baseURL)] as $candidate) {
|
||||||
|
if (stripos($requestURI, $candidate) === 0) {
|
||||||
|
return $candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambiguous
|
||||||
|
return '';
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user