Skip to content

refactor: burn down wave 2 — adapter type maps, ORM dynamic methods, URLFor, form/migrator helpers - #3437

Merged
bpamiri merged 7 commits into
developfrom
peter/complexity-burn-down-2
Aug 28, 2026
Merged

refactor: burn down wave 2 — adapter type maps, ORM dynamic methods, URLFor, form/migrator helpers#3437
bpamiri merged 7 commits into
developfrom
peter/complexity-burn-down-2

Conversation

@bpamiri

@bpamiri bpamiri commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Second burn-down wave on the framework's complexity hotspots. Extract-method / table-driven refactors only — no behavior change.

Before → after (cyclomatic complexity)

Function Before After
$getType H2 adapter 66 2
$getType PostgreSQL adapter 56 2
$getType MySQL adapter 43 6 (keeps the unsigned branch)
$getType MSSQL adapter 34 2
$dbTypeToMigrationType (AutoMigrator) 52 2
$associationMethod (onmissingmethod) 61 11
onMissingMethod 46 7
URLFor (routing.cfm) 45 11
$checkMinimumVersion (plugins.cfm) 37 8
startFormTag (forms.cfc) 39 14
$expandedAssociations (sql.cfc) 35 14
migrateTo (Migrator.cfc) 35 25

Repo-wide: functions over complexity 50 drop 7 → 3 (remaining are .cfm templates + $createSQLFieldList); functions at 10 or under rise to 2429.

How it was verified

  • Four parallel subagents (one per file group), extract-method only, with the round-1 lessons as hard rules: no typed returns that could receive a cfcatch (Adobe return-type validation), struct-by-reference for arguments mutation, public $-prefixed mixin helpers, hardener-spec awareness.
  • Independent parity audit of the adapter maps: every original switch case label present exactly once with identical result (65/55/38/33/51 entries; the only delta is H2 UUIDuuid covered by the LCase-normalized lookup, matching the case-insensitive original switch).
  • Local Lucee 7 + SQLite area suites — global 219/0, view 581/0, database 105/0, security 290/0, dispatch 168/0, controller 529/0, events 87/0, hardener 247/0, interfaces 58/0, internal 92/0, channel 43/0, model 979/0, migrator 292/0 — all green.
  • Adapter maps proven non-regressive on Adobe 2023 + MySQL: database specs 101/0; model specs identical to develop's baseline (the 8 fail / 2 error there are a pre-existing Adobe+MySQL leg issue, reproduced byte-for-byte with develop's original adapters).
  • Complexity gate PASS on both trees.

Also fixed along the way (separate PR #3436, already merged)

  • Adobe compile break in DatabaseAdapterHardenerSpec.cfc (var abstract, default = named args, unquoted default: keys)
  • wheels_events.id widened to varchar(255) for MySQL channel specs

No changelog fragment: internal refactor, no user-facing change.

Three Adobe-only parser traps in the S6 optionsIncludeDefault describe:
- a variable named `abstract` (reserved word on Adobe CF) — rename to abstractMigrator
- `default` passed as a named argument to optionsIncludeDefault — use positional args
- unquoted `default:` struct-literal keys — quote them

Verified on Adobe 2023 + MySQL: database specs 101/0/0 (previously the whole
leg failed at compile time with MissingNameException).

Signed-off-by: Peter Amiri <peter@alurium.com>
The id column was varchar(36) (UUID-sized) but channel event ids can be
arbitrarily long (spec ids like "test.hard.s1.<36 chars>" are 42+ chars),
which made MySQL legs fail with "Data too long for column 'id'". Matches
the channel/event columns' 255 width. Verified on Adobe 2023 + MySQL:
channel specs 43/0/0.

Signed-off-by: Peter Amiri <peter@alurium.com>
…2/2/6/2/2)

Converts the constant switch cases in the four adapter $getType
functions and AutoMigrator's $dbTypeToMigrationType into variables-scoped
lookup structs. Lookups normalize with LCase (original switches are
case-insensitive); conditional branches (MySQL unsigned) and default
fallthroughs are preserved verbatim. Independent parity audit: every
original case label present with identical result.

Signed-off-by: Peter Amiri <peter@alurium.com>
…ionMethod (46/61 to 7/11)

Named-scope/enum/property/finder resolvers on the onMissingMethod side;
polymorphic belongsTo, hasOne, hasMany, and belongsTo dispatch on the
association side. Helpers return {handled, rv} so rv-may-be-unset semantics
and the MethodNotFound throw guard survive; missingMethodArguments is
mutated via struct-by-reference. No hardener source-pins on these functions.

Signed-off-by: Peter Amiri <peter@alurium.com>
…n (45/37 to 11/8)

URLFor: route memo resolution, controller/action fallback, and route
variable substitution helpers. $checkMinimumVersion: version-part parsing,
BoxLang message, and shared/per-major floor helpers. Argument mutation via
struct-by-reference; IncorrectRoutingArguments/IncorrectArguments throws
and the BoxLang lazy Len(minimumBuild) semantics preserved.

Signed-off-by: Peter Amiri <peter@alurium.com>
Route lookup + method matching + non-get/post rewrite move into a
helper that mutates the args struct by reference and returns the original
verb (empty string sentinel replaces the unset local — exactly equivalent
because the original never set method to an empty string).

Signed-off-by: Peter Amiri <peter@alurium.com>
…35 to 14/25)

$expandedAssociations: metadata fill (double-checked lock, marker
written last) and per-variant JOIN fragment construction extracted verbatim.
migrateTo: down/up iteration loops extracted; transaction/lock boundaries
live in untouched $runMigrationStep.

Signed-off-by: Peter Amiri <peter@alurium.com>
@bpamiri
bpamiri merged commit a8e2fe2 into develop Aug 28, 2026
11 checks passed
@bpamiri
bpamiri deleted the peter/complexity-burn-down-2 branch August 28, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant