Repository navigation
Keep schema apply from dropping the tables of a plugin the host does not register - #3123
Merged
Merged
Conversation
…rve core's stream names
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3072
fluentcms schema apply --allow-destructiveno longer drops the tables of a plugin that the host does not register. A history tablecms_{plugin}__migrationsin the database markscms_{plugin}_as a plugin's prefix. The tables under it are left alone and listed in the plan underLeft alone:, with the history table as the reason, and--scriptlists them as comments. A stale content table is still dropped. Schema sync shares the comparison, so it no longer reports such a table as dropped.Schema apply knows a removed type by the newest row of the schema history. For a host without content migrations, that row is now written only by what brings the content tables up to the schema: schema apply and schema sync, never
migrateor a start. Before,migrateand a start recorded the new schema when no column was missing. Schema apply then lost sight of a removed type, and a block field renamed withformerNamespassed as "Nothing to apply", with its values left under the old key.The PR also fixes the two Low items of the review of #3084. On SQLite a renamed JSON field's check takes the new name, and a rename plus a column change now has a data test. From the review of this PR:
systemandcontentare refused;Spec 4.3 and 6.1,
docs/docker.md,docs/content-migrations.mdanddocs/plugin-migrations.mdsay what was built.Decisions
cms_{name}__migrationswhere the name is a plugin name with underscores. The system'scms__migrationsand the content stream'scms_content__migrationsare left out, socms_andcms_content_never spare a content table. The prefix keeps its trailing underscore, socms_demonstrationis not undercms_demo_. When several prefixes match, the plan names the longest.seo-metagivescms_seo_metaundercms_seo_, and a localizedseogivescms_seo_i18n. Names cannot tell these apart, and neither can columns, since the search plugin'scms_search_entryhas the content tables'id,document_id,site_id,stateandlocale. So schema apply reads the newest row of the schema history. The table of one of its collections or singletons is a content table under any prefix, and so is the locale table of a localized one, and a stale one is dropped. Only the newest row counts, so a plugin table that later took the name of an older type is not mistaken for content. With no row, or a row that cannot be read, the safer choice holds: every table under a plugin's prefix is left alone.migrateand a start that migrates record when no column is missing.migrateand a start that migrates no longer record. A start now logs the drift (9315) instead, and 9314 and 9315 ask such a host to runfluentcms schema apply.--allow-destructive. A host with content migrations records after every sync that left nothing undone, as before: schema apply refuses that host, so nothing else would ever record past the loss.schema diff --appliednamesfluentcms schema applyfor an empty history of such a host (FCMS3323). When the history cannot be read (FCMS3324), it asks to runmigrateand thenschema apply. Themigratehelp says it records only for a host with content migrations.schema apply, which records one even with nothing to apply, or from schema sync's first start.schema applyaftermigrate, so all three keep their first row.SchemaHistory.Losses.systemandcontentare refused withFCMS1502, both inPluginHost.Readand for a stream registered throughIPluginMigrations, whichMigrationRunnerchecks when it is created.Operations:andLeft alone:lines and the script's comments go throughPrintableText.Escape(from CLI, backup and restore follow-ups from the review of M4 and M6 #3068, merged from main). A stale table whose name has a control character is left alone and listed, never dropped. No content table has such a name, and aGOline in one would split a SQL Server script.Declined
None. The second Low item, a rename plus a change of store type, now has a data test that applies it on every provider.
Dependencies
None.
Acceptance
schema apply --allow-destructive, and the plan says whyTests
SchemaApplyTests.TheTablesOfAPluginTheHostDoesNotRegisterAreLeftAloneAndARemovedTypesTablesAreDropped: the demo plugin is migrated, then left out of the host. Its table is kept and listed in the plan and in the script. The removed types' tables are dropped, includingcms_demo_postandcms_demo_i18nundercms_demo_, and so are the hand-madecms_demonstrationandcms_content_extra, the latter next to an empty content history. A host that registers the plugin again lists nothing.SchemaApplyTests.MigrateAndAStartBeforeSchemaApplyLeaveItTheRowThatNamesARemovedType:migrateand a start that migrates run with the new schema beforeapply.demo-post, under the prefix of the registered plugin demo, is then still refused and is dropped with--allow-destructive. Fails on the previous code.SchemaApplyTests.ABlockFieldRenamedBeforeMigrateAndAStartIsStillALoss: the same steps with a block field renamed;applystill stops withFCMS3337. Fails on the previous code.SchemaSyncTests.ABlockFieldRenamedIsNotRecordedSinceItsValuesStayUnderTheFormerName: sync keeps the row and logs the drift, asking forfluentcms schema apply. Fails on the previous code.SchemaApplyTests.WithoutAReadableHistoryRowEveryTableUnderAPluginsPrefixIsLeftAlone: withsnapshot = '[]', and then with no row,--allow-destructiveleavescms_demo_postalone.SchemaApplyTests.ATableWhoseNameHasAControlCharacterIsLeftAloneAndItsNameEscaped, with a table namedcms_bad\nGO\nname.SchemaSyncTests.AHostWithContentMigrationsRecordsASyncThatRemovesABlockField: 2 rows. Fails on the previous round's code.SchemaSyncTests.ASyncWhoseHistoryCannotBeReadIsNotRecordedAndDoesNotFail.SchemaHistoryTests.AStartOfAHostWithoutContentMigrationsRecordsNothingAndAsksForSchemaApply, for both start paths: the 9314 advice with an empty history, then the 9315 advice.SchemaApplyTests.ADiffFromAnEmptyOrUnreadableHistoryNamesWhatRecordsItForTheHost(FCMS3323for both kinds of host, andFCMS3324), andSchemaCommandTestschecks the new advice.MigrationRunnerTests.AStreamNamedAfterOneOfCoresIsRefusedandPluginValidationTests.ABadManifestStopsTheHostforsystemandcontent.SchemaApplyTests.ARenamedJsonFieldKeepsItsValuesAndItsCheckTakesTheNewNamenow checks the check's name on SQLite, and fails without the fix.SchemaApplyTests.ARenamedFieldWhoseColumnAlsoChangesKeepsItsValues: a rename and then anAlterColumn, applied, with the values kept.SchemaSyncTests.ATableOfAPluginTheHostNoLongerRegistersIsNotAStaleContentTableandSchemaSnapshotTestsforContentTypesOf.-warnaserror, and markdownlint. PostgreSQL and SQL Server ran in the full CI run.Full CI run: 43731667867, passed, on 8419100 after merging main. The earlier runs were 43724851071, which passed after the rerun of a timing-bound job test on SQL Server 2019, and 43659302666.