Skip to content

Defaults Configuration#27

Merged
ez-plugins merged 5 commits intodev/1.0.5from
feature/public-configuration
Apr 18, 2026
Merged

Defaults Configuration#27
ez-plugins merged 5 commits intodev/1.0.5from
feature/public-configuration

Conversation

@ez-plugins
Copy link
Copy Markdown
Contributor

New: QueryBuilderDefaults — configure dialect and query defaults upfront

Introduces an immutable QueryBuilderDefaults class that centralises the default
values applied by every builder. Configure once at application startup; all builders
constructed afterward pick it up automatically. Each builder also accepts a
per-instance override via withDefaults() without touching the global.

Configurable defaults

Setting Default Description
dialect SqlDialect.STANDARD Dialect used when none is passed to buildSql() / build()
defaultColumns "*" Column expression rendered when no .select() columns are specified
defaultLimit -1 (none) LIMIT applied when no .limit() call is made
defaultOffset -1 (none) OFFSET applied when no .offset() call is made
likePrefix "%" Prepended to values in LIKE / NOT LIKE conditions
likeSuffix "%" Appended to values in LIKE / NOT LIKE conditions

Explicit per-call values always win over configured defaults.

Builders updated

  • QueryBuilder — gains withDefaults() and applies dialect/defaults in buildSql()
  • DeleteBuilder — gains withDefaults() and applies dialect in build()
  • SelectBuilder — gains withDefaults() and applies all defaults in build()
    • Note: whereLike() now auto-wraps the value using likePrefix/likeSuffix,
      consistent with QueryBuilder and AbstractSqlDialect. Previously no wrapping was applied.

Breaking changes

  • SelectBuilder.whereLike(column, value) — pass the raw value (e.g. "bob");
    % wrapping is now applied automatically. If your code was passing "%bob%" manually,
    remove the manual wrapping.
  • AbstractSqlDialect.appendConditionFragment gains a Query parameter.
    Custom subclasses that override this protected method must update their signature.

Immutable config holder with JVM-wide global (volatile static) and
per-instance override support (builder.withDefaults(...)). Configures:
- SQL dialect (default: STANDARD)
- Default SELECT column expression (default: "*")
- Default LIMIT / OFFSET (default: -1, i.e. none)
- LIKE prefix / suffix (default: "%" / "%")

Global is captured at builder construction time so behaviour is
predictable across concurrent updates.
Three new fields propagated from QueryBuilderDefaults into the Query
data object at build() time so dialect-agnostic renderers can read them:
- defaultSelectColumns  (fallback when selectColumns is empty)
- likePrefix            (prepended to LIKE / NOT LIKE values)
- likeSuffix            (appended  to LIKE / NOT LIKE values)

All fields default to the existing hardcoded behaviour ("*", "%", "%")
so there is no change to query output without an explicit configuration.
AbstractSqlDialect now reads from the Query object instead of using
hardcoded literals:
- appendSelectColumns: uses query.getDefaultSelectColumns() instead of "*"
- LIKE / NOT LIKE params: uses query.getLikePrefix()/getLikeSuffix()
  instead of hardcoded "%" + val + "%"

appendConditionFragment gains a Query parameter to pass the hints
through to appendNonComparisonFragment.
QueryBuilder, DeleteBuilder, and SelectBuilder each gain:
- A queryBuilderDefaults field initialised from QueryBuilderDefaults.global()
  at construction time (snapshot semantics — not live).
- A withDefaults(QueryBuilderDefaults) fluent method for per-instance
  override without touching the global.

Behavioural changes when a non-default QueryBuilderDefaults is active:
- Dialect: buildSql() / build() null-fallback now routes to the
  configured dialect instead of hardcoded SqlDialect.STANDARD.
- Default columns: rendered when no explicit select() columns are set.
- Default limit / offset: applied when builder sentinel (-1) is present
  and the defaults carry a non-negative value (explicit wins).
- LIKE wrapping: SelectBuilder.whereLike() now honours likePrefix /
  likeSuffix (previously had no wrapping at all — aligned with
  AbstractSqlDialect behaviour).
…ping

QueryBuilderDefaultsTest (23 tests) covers:
- Canonical global defaults (STANDARD, "*", -1, -1, "%", "%")
- builder() and builder(source) factory methods
- setGlobal(null) NPE guard
- withDefaults(null) NPE guard on all three builders
- Global dialect applied to newly created QueryBuilder
- Per-instance withDefaults() overrides global for that instance only
- Explicit buildSql(table, dialect) parameter wins over configured default
- defaultColumns / explicit select() winner semantics
- defaultLimit / defaultOffset applied and overridden correctly
- Custom likePrefix / likeSuffix applied (QueryBuilder + SelectBuilder)
- DeleteBuilder dialect routing via withDefaults()
- SelectBuilder defaultColumns, defaultLimit, LIKE wrapping

SelectBuilderTest.testWhereLike: updated to pass the raw value ("bob")
instead of pre-wrapped "%bob%" now that SelectBuilder auto-wraps using
the configured likePrefix/likeSuffix (consistent with QueryBuilder).
@ez-plugins ez-plugins merged commit f20fa26 into dev/1.0.5 Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant