Skip to content

Comments

Feature/add postgres rmdbs support#245

Merged
KofTwentyTwo merged 4 commits intodevelopfrom
feature/add-postgres-rmdbs-support
Oct 3, 2025
Merged

Feature/add postgres rmdbs support#245
KofTwentyTwo merged 4 commits intodevelopfrom
feature/add-postgres-rmdbs-support

Conversation

@KofTwentyTwo
Copy link
Member

Pull Request

📝 Description

What does this PR do?
This PR adds comprehensive PostgreSQL database support to the QQQ framework as a new backend module (qqq-backend-module-postgres). The module provides full CRUD operations with feature parity to the existing SQLite module, making PostgreSQL a true drop-in replacement for any RDBMS backend. It includes PostgreSQL-specific optimizations such as the RETURNING clause for generated IDs, proper NULL type handling, and Java 8 temporal type support. The implementation also enhances the base RDBMS module with improved identifier quoting logic to support multiple database dialects.

Related Issue:
Closes #244

🔍 Type of Change

  • Bug Fix - Fixes an existing issue
  • New Feature - Adds new functionality
  • Breaking Change - Fix or feature that would cause existing functionality to not work as expected
  • Documentation Update - Updates documentation
  • Refactoring - Code change that neither fixes a bug nor adds a feature
  • Performance Improvement - Code change that improves performance
  • Test Addition - Adding missing tests or correcting existing tests

🧪 Testing

How has this been tested?

  • Unit Tests: All unit tests pass
  • Integration Tests: Integration tests pass (71/71 tests passing using Testcontainers with PostgreSQL 16)
  • Coverage: Meets QQQ's coverage requirements (82% instructions, 77% branches, 81% lines - exceeds 80% requirement)
  • Manual Testing: Tested manually in development environment

Test Commands:

# Run PostgreSQL module tests
mvn test -pl qqq-backend-module-postgres

# Run full verification
mvn verify

# Generate coverage report
mvn test jacoco:report -pl qqq-backend-module-postgres

Test Coverage:

  • ✅ 5 Insert tests (single, batch, associations, generated IDs)
  • ✅ 40 Query tests (filters, joins, expressions, record security)
  • ✅ 9 Update tests (batch operations, audit fields)
  • ✅ 7 Delete tests (by ID, by filter, FK constraints)
  • ✅ 9 Count tests (with joins and filters)
  • ✅ 1 Metadata test

📋 Checklist

Before submitting this PR, please ensure:

  • Code Style: Follows QQQ's Code Review Standards
  • Tests: All tests pass with required coverage (82% instructions, exceeds 80% requirement)
  • Documentation: Updated relevant wiki pages and code comments (README.md and postgres-module.md included)
  • Breaking Changes: No breaking changes
  • Commit Messages: Follow conventional commit format
  • Self Review: Code has been reviewed by the author

🔗 Related Resources

Documentation:

📊 Additional Information

New PostgreSQL Backend Module

Module Structure:

  • PostgreSQLBackendModule.java - Module registration
  • PostgreSQLBackendMetaData.java - Connection configuration
  • PostgreSQLTableBackendDetails.java - Table metadata
  • PostgreSQLRDBMSActionStrategy.java - PostgreSQL-specific SQL generation and type handling

PostgreSQL-Specific Optimizations:

  1. RETURNING Clause: Uses PostgreSQL's RETURNING clause for generated IDs instead of JDBC's getGeneratedKeys() - single database round-trip
  2. NULL Type Binding: Uses Types.OTHER for NULL values to allow proper type inference
  3. Temporal Type Handling: Explicit binding for Java 8 temporal types (Instant, LocalDate, LocalDateTime)
  4. Identifier Quoting: No identifier quoting (PostgreSQL prefers unquoted identifiers)

Migration Path:
PostgreSQL is a drop-in replacement - only backend configuration needs to change. All existing QQQ code (CRUD operations, filters, joins, record security, associations) works identically.

Dependencies Added:

  • postgresql:42.7.2 - PostgreSQL JDBC driver
  • testcontainers:1.19.3 (test scope) - Integration testing with real PostgreSQL

Other Features in This Branch:
This feature branch also includes several merged features from develop:

  • Row Builder Widget for dynamic form creation
  • Enhanced audit customization capabilities
  • Javalin POST endpoint support for widgets (larger parameter sets)
  • Table export capabilities
  • API-aware middleware improvements for exposed joins
  • Various bug fixes and enhancements

Build Status:

  • ✅ All 71 PostgreSQL module tests passing
  • ✅ Full project builds successfully
  • ✅ Code coverage: 82% instructions, 77% branches, 81% lines
  • ✅ Checkstyle: 0 violations

Performance Impact:
Positive - PostgreSQL-specific optimizations (RETURNING clause) reduce database round-trips compared to generic JDBC approach.


Thank you for contributing to QQQ! 🚀

…dule

- Improved `escapeIdentifier` method to dynamically retrieve quote characters from RDBMS strategies.
- Added default `getIdentifierQuoteString` method to `RDBMSActionStrategyInterface`.
- Updated `RDBMSInsertAction` to use enhanced quoting for identifiers.
- Made `resetConnectionProviders` in `ConnectionManager` public.
- Included `qqq-backend-module-postgres` in the build.
- Updated IntelliJ configuration to ignore specific files.
- Introduced `qqq-backend-module-postgres` with full support for PostgreSQL database.
- Implemented PostgreSQL-specific backend metadata, table details, and action strategies.
- Integrated PostgreSQL JDBC driver and Testcontainers for testing.
- Achieved 100% test pass rate with 82% code coverage.
@KofTwentyTwo KofTwentyTwo added the enhancement New feature or request label Oct 2, 2025
@KofTwentyTwo KofTwentyTwo linked an issue Oct 2, 2025 that may be closed by this pull request
@KofTwentyTwo KofTwentyTwo self-assigned this Oct 2, 2025
@KofTwentyTwo KofTwentyTwo moved this to In review in QQQ Roadmap Oct 2, 2025
@github-actions
Copy link

github-actions bot commented Oct 2, 2025

🔒 Security Scan Complete

Dependency vulnerability scan completed for this PR. View full report

update tests to rename order_table just "order" (which is the point of being able to quote identifiers)
@github-actions
Copy link

github-actions bot commented Oct 2, 2025

🔒 Security Scan Complete

Dependency vulnerability scan completed for this PR. View full report

darinkelkhoff
darinkelkhoff previously approved these changes Oct 2, 2025
Copy link
Contributor

@darinkelkhoff darinkelkhoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my first reaction was "why a new module for this, rather than just adding it to rdbms module" (and sorry, maybe we discussed before?)? based on the idea of, mysql is within rdbms, so wouldn't all vendors be there?

but upon further reflection, ya, i think i like keeping them separate. I wonder if the base rdbms should become basically abstract, and the mysql parts of it should move out into their own module as well (so mysql isn't special)?

anyway +1

@Override
public String getIdentifierQuoteString()
{
return "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm curious, if postgres doesn't "require" a quoting character, does that mean that it doesn't allow one at all, and/or, that it never needs one?

like, for mysql, you only need to quote an identifier if it conflicts with a keyword. e.g., SELECT * FROM order ORDER BY - the table order needs quoted.

in a quick query on this, i'm being told that postgres would need identifiers to be quoted if they matched keywords, e.g., CREATE TABLE "select" (id INT);, and that " would be the quote char (that's from an LLM, so, don't 100% trust it - which, i realized i should just check this out myself and test it - which i just did, and i just pushed an update wherein i renamed the test table from order_table, then changed this method to return ", and, so, I think better now)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah… this one’s on me. I let the LLM crank out the Postgres tests by copy-pasting the SQLite ones, squinted at them, and said “looks good.” bad-programmer.

Thanks for catching it.

more verify… especially when the author is half AI, half really lazy human.

@KofTwentyTwo
Copy link
Member Author

my first reaction was "why a new module for this, rather than just adding it to rdbms module" (and sorry, maybe we discussed before?)? based on the idea of, mysql is within rdbms, so wouldn't all vendors be there?

but upon further reflection, ya, i think i like keeping them separate. I wonder if the base rdbms should become basically abstract, and the mysql parts of it should move out into their own module as well (so mysql isn't special)?

anyway +1

Thanks — yes, this matches what I recall us chatting about few months ago: the rdbms module acting as the abstract/base layer, with each vendor (MySQL, SQLite, Postgres, etc.) implemented as its own qbit instead of MySQL being “special.” and everything else being spliced into that.

With your comment, I think the bigger architectural question is whether these vendor things should even live in the core platform. Right now, adding or updating support for an external service requires cutting a new core release, which tightly couples integration cadence to the platform.

In other ecosystems (e.g. Apache HTTPD with mod_*, Kubernetes with storage/network plugins, Terraform providers, etc.), the model is:
• a stable core with abstract extension points
• integrations implemented as external modules that can be versioned and released independently

Framing it in our terms: if someone wanted to build support for DB2, would they need write access to the core platform to add a new external service (db, filesystem, s3, queue hanlder, etc), or should they be able to write and publish their own DB2 qbit independently?

This seems like a good moment to step back and decide whether database vendor qbits belong in core, or whether they should be first-class extensions managed outside the platform release cycle. And how we would like to expand this to other parts? Keeping the core "core" or?

…ity and license checks - integrating with circleci orb
@KofTwentyTwo KofTwentyTwo merged commit f20c83d into develop Oct 3, 2025
5 of 6 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in QQQ Roadmap Oct 3, 2025
@KofTwentyTwo KofTwentyTwo deleted the feature/add-postgres-rmdbs-support branch October 3, 2025 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Add Postgres RDBMS Support

2 participants