Skip to content

Query Monitor support #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open

Query Monitor support #212

wants to merge 5 commits into from

Conversation

JanJakes
Copy link
Collaborator

@JanJakes JanJakes commented Jul 7, 2025

This PR integrates Query Monitor so that it can be used together with the SQLite Database Integration plugin, and it extends the Query Monitor panel to include SQLite query information.

This implementation uses some tricks and workarounds to achieve this functionality. We could improve the integration by proposing upstream changes to the Query Monitor plugin.

The wp-content/db.php issue

The main issue to overcome was that both plugins rely on the usage of the wp-content/db.php database drop-in file. To resolve this, I’ve enabled the SQLite plugin to override the db.php file created by Query Monitor while also ensuring it eagerly boots Query Monitor when needed. The behavior depends on which plugin is activated first:

  1. If the SQLite plugin is activated first, its db.php file will never be replaced by Query Monitor. The SQLite plugin will detect when Query Monitor is active and boot it eagerly while also storing detailed query information for Query Monitor to consume.
  2. If Query Monitor is activated first, the SQLite plugin will detect that on its activation, it will replace the existing db.php file, and it will retain the eager boot logic for Query Monitor. The user will be notified about the db.php file replacement.

screenshot-2025-07-09-at-12 25 04

Extended query information for Query Monitor

The SQLite plugin now stores enhanced query information for Query Monitor when it’s active, effectively mirroring a tiny portion of the Query Monitor code. To reduce duplication, we can propose changes to the Query Monitor codebase that would allow this logic to be reused rather than reimplemented.

Extending the Query Monitor panel

The Query Monitor panel was extended to provide information about the executed SQLite queries for each MySQL query. This makes it easy to inspect and debug which SQLite queries correspond to each MySQL statement.

Currently, Query Monitor doesn’t offer a way to customize the rendered query information. To overcome this limitation, I implemented this by capturing the generated HTML and modifying it before it is sent to the browser. This is another area where we could improve integration by proposing upstream changes to the Query Monitor plugin.

sqlite-query-monitor

Playground support

Playground loads the SQLite Database Integration differently, without creating a db.php file. As a result, third-party plugins can still inject their db.php drop-in. For Query Monitor, I’ve added a simple fix. Setting the QM_DB_SYMLINK constant to false prevents it from using the db.php drop-in, and the SQLite plugin will boot it as needed.

@JanJakes JanJakes force-pushed the query-monitor-support branch 3 times, most recently from 81c83c2 to 4dfca33 Compare July 8, 2025 15:02
@JanJakes JanJakes force-pushed the query-monitor-support branch 2 times, most recently from 2e03007 to 09cdd0f Compare July 9, 2025 09:22
@JanJakes JanJakes force-pushed the query-monitor-support branch from 09cdd0f to 5c2265e Compare July 9, 2025 12:12
@JanJakes JanJakes marked this pull request as ready for review July 9, 2025 13:07
@JanJakes JanJakes requested a review from adamziel July 9, 2025 13:12
@@ -478,6 +487,35 @@ public function query( $query ) {
$return_val = $num_rows;
}

// Query monitor integration:
if ( $query_monitor_active && class_exists( 'QM_Backtrace' ) ) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there any way we could use the QM_DB class directly without recreating its logic here? I see it's class QM_DB extends wpdb. Perhaps we could provide it with a version of wpdb that uses SQLite?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@adamziel Inspired by what WP CLI does with wp-config.php, I guess we could try to read the QB_DB contents, change the extends ... clause, and then eval it 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

nono, that will break on plugin update. I've meant not including the root wpdb and providing our own class with that name.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@adamziel Oh, but we're extending wpdb, we need to load it, at least under a different name — and I guess that's not really doable without actually rewriting it at some point.

What I meant is adjusting QM_DB on the fly. This could be fine, as when QM is active, we don't expect performance to be critical anyway. Something like:

$contents = file_get_contents( '.../QM_DB.php' );
$contents = str_replace( '<?php', '', $contents );
$contents = str_replace( 'extends wpdb', 'extends WP_SQLite_DB', $contents );
eval( $contents );
$wpdb = new QM_DB( ... );

But maybe it's better to suggest some improvements upstream so we can reuse some code without the hacks? For example, I think that making the inheritance configurable can be done pretty simply:

$wpdb_class = defined( 'WPDB_CLASS' ) && class_exists( WPDB_CLASS ) ? WPDB_CLASS : 'wpdb';
class_alias( $wpdb_class, 'QM_WPDB' );

class QM_DB extends QM_WPDB { ... }

Copy link
Collaborator

Choose a reason for hiding this comment

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

The upstream improvement sound like a great idea. Until then, this PR looks solid. Thank you 👍

Copy link
Collaborator

@adamziel adamziel left a comment

Choose a reason for hiding this comment

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

I left one idea but otherwise I think it's a good solution. Thank you @JanJakes! Is there any way we could add this to our test suite? Ideally not via Playground, just to separate the tool from its testing infrastructure.

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.

2 participants