mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-24 18:25:04 +08:00
#8506: Adapting MySqlCommandInterpreter to 767 character length limitation (#8826)
Some checks failed
Compile / Compile .NET solution (push) Has been cancelled
Compile / Compile Client-side Assets (push) Has been cancelled
SpecFlow Tests / Define Strategy Matrix (push) Has been cancelled
SpecFlow Tests / SpecFlow Tests (push) Has been cancelled
Build Crowdin Translation Packages / build-crowdin-translation-packages (push) Has been cancelled
Some checks failed
Compile / Compile .NET solution (push) Has been cancelled
Compile / Compile Client-side Assets (push) Has been cancelled
SpecFlow Tests / Define Strategy Matrix (push) Has been cancelled
SpecFlow Tests / SpecFlow Tests (push) Has been cancelled
Build Crowdin Translation Packages / build-crowdin-translation-packages (push) Has been cancelled
* Update MySqlCommandInterpreter.cs https://github.com/OrchardCMS/Orchard/issues/8056 767 length limitation in mysql * Fixing typo * Code styling and simplifications in MySqlCommandInterpreter --------- Co-authored-by: Benedek Farkas <benedek.farkas@lombiq.com>
This commit is contained in:
@@ -21,9 +21,7 @@ namespace Orchard.Data.Migration.Interpreters {
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public string DataProvider {
|
||||
get { return "MySql"; }
|
||||
}
|
||||
public string DataProvider => "MySql";
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
@@ -40,32 +38,37 @@ namespace Orchard.Data.Migration.Interpreters {
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendFormat("alter table {0} modify column {1} ",
|
||||
_dialectLazy.Value.QuoteForTableName(PrefixTableName(command.TableName)),
|
||||
_dialectLazy.Value.QuoteForColumnName(command.ColumnName));
|
||||
_dialectLazy.Value.QuoteForTableName(PrefixTableName(command.TableName)),
|
||||
_dialectLazy.Value.QuoteForColumnName(command.ColumnName));
|
||||
var initLength = builder.Length;
|
||||
|
||||
// type
|
||||
// Type.
|
||||
if (command.DbType != DbType.Object) {
|
||||
builder.Append(DefaultDataMigrationInterpreter.GetTypeName(_dialectLazy.Value, command.DbType, command.Length, command.Precision, command.Scale));
|
||||
} else {
|
||||
if (command.Length > 0 || command.Precision > 0 || command.Scale > 0) {
|
||||
throw new OrchardException(T("Error while executing data migration: you need to specify the field's type in order to change its properties"));
|
||||
}
|
||||
builder.Append(DefaultDataMigrationInterpreter.GetTypeName(
|
||||
_dialectLazy.Value,
|
||||
command.DbType,
|
||||
command.Length,
|
||||
command.Precision,
|
||||
command.Scale));
|
||||
}
|
||||
else if (command.Length > 0 || command.Precision > 0 || command.Scale > 0) {
|
||||
throw new OrchardException(
|
||||
T("Error while executing data migration: You need to specify the field's type in order to change its properties."));
|
||||
}
|
||||
|
||||
// [default value]
|
||||
// Default value.
|
||||
var builder2 = new StringBuilder();
|
||||
|
||||
builder2.AppendFormat("alter table {0} alter column {1} ",
|
||||
_dialectLazy.Value.QuoteForTableName(PrefixTableName(command.TableName)),
|
||||
_dialectLazy.Value.QuoteForColumnName(command.ColumnName));
|
||||
_dialectLazy.Value.QuoteForTableName(PrefixTableName(command.TableName)),
|
||||
_dialectLazy.Value.QuoteForColumnName(command.ColumnName));
|
||||
var initLength2 = builder2.Length;
|
||||
|
||||
if (command.Default != null) {
|
||||
builder2.Append(" set default ").Append(_dataMigrationInterpreter.ConvertToSqlValue(command.Default)).Append(" ");
|
||||
}
|
||||
|
||||
// result
|
||||
// Result.
|
||||
var result = new List<string>();
|
||||
|
||||
if (builder.Length > initLength) {
|
||||
@@ -79,40 +82,68 @@ namespace Orchard.Data.Migration.Interpreters {
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private string PrefixTableName(string tableName) {
|
||||
if (string.IsNullOrEmpty(_shellSettings.DataTablePrefix))
|
||||
return tableName;
|
||||
return _shellSettings.DataTablePrefix + "_" + tableName;
|
||||
}
|
||||
private string PrefixTableName(string tableName) =>
|
||||
string.IsNullOrEmpty(_shellSettings.DataTablePrefix) ? tableName : $"{_shellSettings.DataTablePrefix}_{tableName}";
|
||||
|
||||
public string[] CreateStatements(AddIndexCommand command) {
|
||||
var session = _transactionManager.GetSession();
|
||||
|
||||
using (var sqlCommand = session.Connection.CreateCommand()) {
|
||||
var columnNames = String.Join(", ", command.ColumnNames.Select(c => string.Format("'{0}'", c)));
|
||||
var columnNames = String.Join(", ", command.ColumnNames.Select(column => $"'{column}'"));
|
||||
var tableName = PrefixTableName(command.TableName);
|
||||
// check whether the index contains big nvarchar columns or text fields
|
||||
string sql = @"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = '{1}' AND COLUMN_NAME in ({0}) AND TABLE_SCHEMA = '{2}' AND
|
||||
((Data_type = 'varchar' and CHARACTER_MAXIMUM_LENGTH > 767) OR data_type= 'text');";
|
||||
|
||||
sql = string.Format(sql, columnNames, tableName, session.Connection.Database);
|
||||
sqlCommand.CommandText = sql;
|
||||
|
||||
var columnList = command.ColumnNames.ToList();
|
||||
var indexMaximumLength = 767;
|
||||
var longColumnNames = new List<string>();
|
||||
|
||||
if (columnList.Count > 1) {
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT SUM(CHARACTER_MAXIMUM_LENGTH)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = '{tableName}'
|
||||
AND COLUMN_NAME in ({columnNames})
|
||||
AND TABLE_SCHEMA = '{session.Connection.Database}'
|
||||
AND (Data_type = 'varchar');";
|
||||
|
||||
using (var reader = sqlCommand.ExecuteReader()) {
|
||||
reader.Read();
|
||||
if (!reader.IsDBNull(0)) {
|
||||
var characterMaximumLength = reader.GetInt32(0);
|
||||
indexMaximumLength -= characterMaximumLength;
|
||||
if (indexMaximumLength < 0) {
|
||||
throw new InvalidOperationException("Cannot create index because indexMaximumLength is less than 0!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check whether the index contains big nvarchar columns or text fields.
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = '{tableName}'
|
||||
AND COLUMN_NAME in ({columnNames})
|
||||
AND TABLE_SCHEMA = '{session.Connection.Database}'
|
||||
AND ((Data_type = 'varchar' and CHARACTER_MAXIMUM_LENGTH > {indexMaximumLength}) OR data_type= 'text');";
|
||||
|
||||
using (var reader = sqlCommand.ExecuteReader()) {
|
||||
// Provide prefix for string columns with length longer than 767
|
||||
// Provide prefix for string columns with length more than 767.
|
||||
while (reader.Read()) {
|
||||
var columnName = reader.GetString(0);
|
||||
columnList[columnList.IndexOf(columnName)] = string.Format("{0}(767)", columnName);
|
||||
longColumnNames.Add(reader.GetString(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (longColumnNames.Count > 0) {
|
||||
var columnPrefixKeyPartLength = indexMaximumLength / longColumnNames.Count;
|
||||
foreach (var columnName in longColumnNames) {
|
||||
columnList[columnList.IndexOf(columnName)] = $"{columnName}({columnPrefixKeyPartLength})";
|
||||
}
|
||||
}
|
||||
|
||||
return new[] {string.Format("create index {1} on {0} ({2}) ",
|
||||
_dialectLazy.Value.QuoteForTableName(tableName),
|
||||
_dialectLazy.Value.QuoteForTableName(PrefixTableName(command.IndexName)),
|
||||
String.Join(", ", columnList))};
|
||||
|
||||
return new[] {
|
||||
string.Format("create index {1} on {0} ({2}) ",
|
||||
_dialectLazy.Value.QuoteForTableName(tableName),
|
||||
_dialectLazy.Value.QuoteForTableName(PrefixTableName(command.IndexName)),
|
||||
string.Join(", ", columnList))};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user