Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1486121ffa | ||
|
|
0908586e89 | ||
|
|
e6f53b9d30 | ||
|
|
87e12b9ee2 | ||
|
|
6ad2a17c09 |
+28
-9
@@ -1,6 +1,8 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NPoco;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_17_3_0;
|
||||
|
||||
@@ -12,15 +14,28 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_17_3_0;
|
||||
/// </summary>
|
||||
public class RetrustForeignKeyAndCheckConstraints : AsyncMigrationBase
|
||||
{
|
||||
private readonly IUmbracoDatabaseFactory _databaseFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RetrustForeignKeyAndCheckConstraints"/> class.
|
||||
/// </summary>
|
||||
/// <param name="context">The migration context.</param>
|
||||
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public RetrustForeignKeyAndCheckConstraints(IMigrationContext context)
|
||||
: base(context)
|
||||
: this(
|
||||
context,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IUmbracoDatabaseFactory>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RetrustForeignKeyAndCheckConstraints"/> class.
|
||||
/// </summary>
|
||||
/// <param name="context">The migration context.</param>
|
||||
/// <param name="databaseFactory">The database factory used to create separate connections for constraint validation.</param>
|
||||
public RetrustForeignKeyAndCheckConstraints(IMigrationContext context, IUmbracoDatabaseFactory databaseFactory)
|
||||
: base(context) => _databaseFactory = databaseFactory;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task MigrateAsync()
|
||||
{
|
||||
@@ -67,17 +82,21 @@ public class RetrustForeignKeyAndCheckConstraints : AsyncMigrationBase
|
||||
|
||||
Logger.LogInformation("Found {Count} untrusted constraint(s) to re-trust.", untrustedConstraints.Count);
|
||||
|
||||
// Ensure we have a long command timeout, in case the migration targets a huge table.
|
||||
EnsureLongCommandTimeout(Database);
|
||||
|
||||
// ALTER TABLE ... WITH CHECK CHECK CONSTRAINT is executed on a separate database connection
|
||||
// to isolate failures from the migration scope's transaction. When constraint validation fails
|
||||
// (e.g. orphaned FK rows), the error can zombie the .NET SqlTransaction even when caught by
|
||||
// T-SQL TRY...CATCH, because the transaction state change propagates through the TDS (Tabular
|
||||
// Data Stream) protocol layer that underlies SQL Server client-server communication.
|
||||
// Using a separate connection (which has no explicit transaction) avoids this entirely —
|
||||
// TRY...CATCH works correctly and no SqlException is thrown to the .NET layer.
|
||||
var retrusted = 0;
|
||||
var failed = 0;
|
||||
|
||||
using IUmbracoDatabase db = _databaseFactory.CreateDatabase();
|
||||
EnsureLongCommandTimeout(db);
|
||||
|
||||
foreach (UntrustedConstraintDto constraint in untrustedConstraints)
|
||||
{
|
||||
// Use T-SQL TRY...CATCH to handle errors at the SQL level. This prevents a constraint
|
||||
// validation failure from dooming the .NET SqlTransaction, which would cause all
|
||||
// subsequent operations to fail with "This SqlTransaction has completed".
|
||||
// Leading semicolon prevents NPoco's auto-select from prepending
|
||||
// "SELECT ... FROM []" based on the empty [TableName("")] attribute.
|
||||
var sql = $@";
|
||||
@@ -89,7 +108,7 @@ BEGIN CATCH
|
||||
SELECT CAST(0 AS BIT) AS Success, ERROR_MESSAGE() AS ErrorMessage;
|
||||
END CATCH";
|
||||
|
||||
RetrustResultDto result = Database.Single<RetrustResultDto>(sql);
|
||||
RetrustResultDto result = db.Single<RetrustResultDto>(sql);
|
||||
|
||||
if (result.Success)
|
||||
{
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@umbraco-cms/backoffice",
|
||||
"version": "17.3.3",
|
||||
"version": "17.3.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@umbraco-cms/backoffice",
|
||||
"version": "17.3.0-rc",
|
||||
"version": "17.3.5",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"./src/libs/*",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@umbraco-cms/backoffice",
|
||||
"license": "MIT",
|
||||
"version": "17.3.3",
|
||||
"version": "17.3.5",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": null,
|
||||
|
||||
-2
@@ -582,7 +582,6 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper
|
||||
}
|
||||
|
||||
#renderEditAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return html`
|
||||
${when(
|
||||
this._showContentEdit && this._workspaceEditContentPath,
|
||||
@@ -616,7 +615,6 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper
|
||||
}
|
||||
|
||||
#renderEditSettingsAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return html`
|
||||
${this._hasSettings && this._workspaceEditSettingsPath
|
||||
? html`
|
||||
|
||||
-2
@@ -455,7 +455,6 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
|
||||
}
|
||||
|
||||
#renderEditContentAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return this._showContentEdit && this._workspaceEditContentPath
|
||||
? html`<uui-button
|
||||
label="edit"
|
||||
@@ -479,7 +478,6 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
|
||||
}
|
||||
|
||||
#renderEditSettingsAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return html`
|
||||
${this._hasSettings && this._workspaceEditSettingsPath
|
||||
? html`<uui-button
|
||||
|
||||
-2
@@ -371,7 +371,6 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert
|
||||
}
|
||||
|
||||
#renderEditAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return this._showContentEdit && this._workspaceEditContentPath
|
||||
? html`<uui-button
|
||||
label="edit"
|
||||
@@ -394,7 +393,6 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert
|
||||
}
|
||||
|
||||
#renderEditSettingsAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return html`
|
||||
${this._hasSettings && this._workspaceEditSettingsPath
|
||||
? html`<uui-button
|
||||
|
||||
-2
@@ -441,7 +441,6 @@ export class UmbBlockSingleEntryElement extends UmbLitElement implements UmbProp
|
||||
}
|
||||
|
||||
#renderEditContentAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return this._showContentEdit && this._workspaceEditContentPath
|
||||
? html`<uui-button
|
||||
label="edit"
|
||||
@@ -464,7 +463,6 @@ export class UmbBlockSingleEntryElement extends UmbLitElement implements UmbProp
|
||||
}
|
||||
|
||||
#renderEditSettingsAction() {
|
||||
if (this._isReadOnly) return nothing;
|
||||
return html`
|
||||
${this._hasSettings && this._workspaceEditSettingsPath
|
||||
? html`<uui-button
|
||||
|
||||
-4
@@ -212,12 +212,8 @@ export class UmbBlockWorkspaceContext<LayoutDataType extends UmbBlockLayoutBaseM
|
||||
};
|
||||
|
||||
this.readOnlyGuard?.addRule(rule);
|
||||
this.content.propertyWriteGuard.addRule({ unique, permitted: false });
|
||||
this.settings.propertyWriteGuard.addRule({ unique, permitted: false });
|
||||
} else {
|
||||
this.readOnlyGuard?.removeRule(unique);
|
||||
this.content.propertyWriteGuard.removeRule(unique);
|
||||
this.settings.propertyWriteGuard.removeRule(unique);
|
||||
}
|
||||
},
|
||||
'observeIsReadOnly',
|
||||
|
||||
@@ -26,10 +26,6 @@ export const manifests: Array<UmbExtensionManifest> = [
|
||||
alias: 'Umb.Condition.BlockWorkspaceIsExposed',
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
alias: 'Umb.Condition.BlockWorkspaceIsReadOnly',
|
||||
match: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -51,10 +47,6 @@ export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
alias: 'Umb.Condition.BlockWorkspaceIsExposed',
|
||||
},
|
||||
{
|
||||
alias: 'Umb.Condition.BlockWorkspaceIsReadOnly',
|
||||
match: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@umbraco/acceptance-test-helpers",
|
||||
"version": "17.3.3",
|
||||
"version": "17.3.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@umbraco-cms/acceptance-test-helpers",
|
||||
"version": "17.3.3",
|
||||
"version": "17.3.5",
|
||||
"description": "Test helpers and builders for making Playwright tests for Umbraco solutions",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json",
|
||||
"version": "17.3.3",
|
||||
"version": "17.3.5",
|
||||
"assemblyVersion": {
|
||||
"precision": "build"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user