Repository navigation
Conversation
…chema
Allow Dinky metadata tables to be created in a custom PostgreSQL schema
(e.g. 'dinky' instead of the default 'public'). A single configuration
entry controls JDBC URL, Flyway migrations, and MyBatis-Plus table
name resolution.
Configuration:
dinky.metadata.schema: dinky (default: public)
or environment variable DINKY_METADATA_SCHEMA
Changes:
New files:
- DinkyMetadataProperties.java: schema config properties class
- DinkySchemaInnerInterceptor.java: MyBatis-Plus DynamicTableNameInnerInterceptor
that dynamically prepends schema prefix to all dinky_* table names
(uses official setTableNameHandler(TableNameHandler) API with prefix-based
matching, so any future dinky_* tables are automatically covered)
Modified files:
- application-postgresql.yml: added dinky.metadata.schema config,
JDBC URL currentSchema parameter, Flyway default-schema/placeholders
- MybatisPlusConfig.java: register schema interceptor under postgresql
profile (between TenantLine and Pagination interceptors, using
ObjectProvider so non-postgresql profiles are unaffected)
- 10 Flyway migration scripts: replaced hardcoded 'public.' with Flyway
placeholder '\.' and string literals 'public' with
'\'
- V20241205 migration script: 'enabled = 0' -> 'enabled::int = 0' for
PostgreSQL boolean column compatibility during historical SMALLINT
to BOOLEAN data migration
- script/sql/dinky-pg.sql: removed all 'public.' prefixes so the
manual initialization script works with any search_path
Design notes:
- Default schema is 'public', fully backward compatible
- MyBatis-Plus schema interceptor is Profile-gated to postgresql only
- Interceptor order: TenantLine -> DinkySchema -> Pagination, ensuring
tenant ignoreTable matches original table names
- Flyway validate-on-migrate remains false, so checksum changes for
already-executed scripts do not break existing deployments
- All other database profiles (MySQL, etc.) are unaffected
This branch has not been deployed
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.
Feature Overview
Allow Dinky to use a custom PostgreSQL schema (e.g.,
dinky) instead of being forced to use the defaultpublicschema. A single configuration entrydinky.metadata.schemacontrols JDBC URL, Flyway migrations, and MyBatis-Plus SQL generation — all three layers stay in sync.• Default:
public(fully backward-compatible, existing deployments need zero changes)• Config override:
dinky.metadata.schema: dinkyinapplication-postgresql.yml• Env override:
export DINKY_METADATA_SCHEMA=dinkyBackground
When deploying Dinky with PostgreSQL as metadata DB, moving tables from the default
publicschema to a custom schema (e.g.,dinky) causes two failures:public— all migration scripts hardcodepublic.prefixSELECT * FROM dinky_taskinstead ofSELECT * FROM dinky.dinky_taskSolution Architecture
┌──────────────────────────────────────────────────────────────────┐
│ application-postgresql.yml │
│ │
│ dinky.metadata.schema = ${DINKY_METADATA_SCHEMA:public} │
│ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ JDBC URL Flyway MyBatis-Plus │
│ currentSchema=... default-schema=... SchemaInterceptor │
│ schemas=... placeholders=... (@Profile("pg")) │
│ ${dinky_schema}.dinky_task │
│ in migration scripts │
└──────────────────────────────────────────────────────────────────┘
Changes (15 files)
New Files (2)
File
Purpose
DinkyMetadataProperties.java@ConfigurationProperties(prefix = "dinky.metadata"), defaultschema = "public"DinkySchemaInnerInterceptor.javaExtends
DynamicTableNameInnerInterceptor, prefix-matches alldinky_*tables →schema.table_nameModified Files (13)
Configuration:
File
Change
MybatisPlusConfig.javaEnable
DinkyMetadataPropertiesvia@EnableConfigurationProperties; registerDinkySchemaInnerInterceptoras@Profile("postgresql")Bean; useObjectProvider.ifAvailable()for optional registration so non-PostgreSQL profiles are unaffectedapplication-postgresql.ymlAdd
dinky.metadata.schemaconfig key; JDBC URL auto-appendcurrentSchema=${dinky.metadata.schema:public}; override Flyway withdefault-schema,schemas,create-schemas, andplaceholders.dinky_schemaFlyway Migration Scripts (10 files):
File
Pattern
V20240506.1.0.2__baseline.sqlpublic.→${dinky_schema}.;'public'→'${dinky_schema}'V20240708.1.1.0__release.sqlSame
V20240729.1.1.0__release.sqlSame
V20240827.1.2.0__release.sqlSame
V20241203.1.2.0__release.sqlSame
V20241205.1.2.0__release.sqlSame +
enabled = 0→enabled::int = 0(5×, compatibility for historical SMALLINT→BOOLEAN migration backup-tables)V20241217.1.2.0__release.sqlSame
V20250301.1.3.0__release.sqlSame
R20240708.1.1.0__release.sqlSame
R20240729.1.1.0__release.sqlSame
Manual SQL Script:
File
Change
script/sql/dinky-pg.sqlRemove all
public.prefixes → depends oncurrentSchemaconnection param orSET search_pathDesign Decisions & Verification
Decision
Rationale
Verification
Prefix-based match (
dinky_*) instead of explicit table-name mapFuture Dinky tables auto-covered; no list maintenance needed
Code review confirms no missed tables in baseline
@Profile("postgresql")BeanSchema interceptor only active under PostgreSQL
MySQL/H2 profiles unaffected;
ObjectProvider.ifAvailable()ensures graceful no-opInterceptor order: TenantLine → DinkySchema → Pagination
Critical: tenant's
ignoreTable()must see original (un-prefixed) table names to match correctlyComments in code; ordering validated
Flyway placeholder override in
application-postgresql.ymlKeeps
application-flyway.ymlas generic default (placeholder-prefix: '##{',placeholder-replacement: false) so MySQL isn't affectedapplication-flyway.ymlunchanged; Spring Boot profile override mechanism verifiedMyBatis-Plus 3.5.7 API:
setTableNameHandler(TableNameHandler)Decompiled the actual 3.5.7 jar —
setTableNameHandlerMapdoes NOT exist in 3.5.7 (common pitfall from reading newer master docs)Jar decompilation confirmed;
javap -pshows onlysetTableNameHandler(TableNameHandler)APIvalidate-on-migrate: false(pre-existing)Modified migration scripts won't break already-deployed environments
Changes only affect fresh installs
Manual SQL script uses non-qualified names
script/sql/dinky-pg.sqlis a standalone manual-init script (no Flyway placeholders); relies oncurrentSchemaconnection paramCorrect approach for non-Flyway SQL
Non-Goals (Explicitly Out of Scope)
• No MySQL/H2 changes — schema interceptor is PostgreSQL-profile gated
• No
application-flyway.ymlchanges — kept as generic default; PostgreSQL-specific overrides go inapplication-postgresql.yml• No boolean/integer fix — that's in PR1 (separate PR; recommended to merge PR1 first)
Backward Compatibility
• ✅ Default
publicschema: interceptor short-circuits whenschema = "public"(no-op handler); zero behavioral change for existing users• ✅ MySQL/H2 unaffected: schema interceptor Bean only registered under
@Profile("postgresql")• ✅ Flyway checksum:
validate-on-migrate: falsemeans modified migration scripts won't trigger checksum failures on deployed environmentsUsage
Option A — Config file
application-postgresql.yml
dinky:
metadata:
schema: dinky
Option B — Environment variable (recommended for Docker/K8s)
export DINKY_METADATA_SCHEMA=dinky
Database-side preparation
CREATE SCHEMA dinky AUTHORIZATION dinky;
GRANT ALL PRIVILEGES ON SCHEMA dinky TO dinky;
Continue using
public(no changes needed)Simply don't configure
dinky.metadata.schema. The default valuepublicapplies everywhere.Verification Checklist
MyBatis-Plus 3.5.7 jar decompiled —
setTableNameHandlerexists,setTableNameHandlerMapdoes notDinkySchemaInnerInterceptor.javamanualjavaccompilation — PASS (exit code 0)TenantLineinterceptor ordering preserved —ignoreTableuses original un-prefixed table namesFlyway
placeholder-prefix/suffixmatches${dinky_schema}usage in scripts (placeholder-prefix: '${',placeholder-suffix: '}')application-flyway.ymlkept as generic default (placeholder-prefix: '##{') — not modifiedAll 10 PostgreSQL migration scripts updated consistently (same pattern across all)
V20241205.1.2.0__release.sqlcorrectly handles historical SMALLINT→BOOLEAN migration backup-tables withenabled::int = 0Default schema
public→ interceptor returns immediately (no-op), zero behavioral changePrerequisite
This PR does not fix the
operator does not exist: boolean = integererror on startup. Please merge PR1: fix(postgresql): resolve boolean = integer operator error first (or both in any order — they're independent).Change Summary
15 files changed, 1528 insertions(+), 1395 deletions(-)
New:
DinkyMetadataProperties.java (+40 lines)
DinkySchemaInnerInterceptor.java (+60 lines)
Modified:
MybatisPlusConfig.java (profile-gated interceptor wiring)
application-postgresql.yml (schema config + Flyway override)
10 PostgreSQL Flyway migration scripts (public. → ${dinky_schema}.)
script/sql/dinky-pg.sql (remove public. prefixes)