Skip to content

Commit 59553d6

Browse files
committed
Add QM collector and outputter for SQLite query data
Register a custom QM collector that extracts SQLite queries from $wpdb->queries, re-indexed to match QM's rendered row order, and a client-side HTML outputter that emits the inline JS module used by the QM 4.0 shadow DOM integration. QM auto-serializes the collector data into window.QueryMonitorData.data.sqlite.
1 parent 9866af6 commit 59553d6

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

  • packages/plugin-sqlite-database-integration/integrations/query-monitor
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php // phpcs:disable WordPress.Files.FileName.InvalidClassFileName, Generic.Files.OneObjectStructurePerFile.MultipleFound
2+
3+
if ( ! class_exists( 'QM_Collector' ) ) {
4+
return;
5+
}
6+
7+
/**
8+
* Collector for SQLite query data.
9+
*
10+
* Extracts SQLite queries from $wpdb->queries and stores them
11+
* indexed by query position for the QM 4.0+ JS integration.
12+
*/
13+
class SQLite_QM_Collector extends QM_Collector {
14+
/** @var string */
15+
public $id = 'sqlite';
16+
17+
public function process(): void {
18+
global $wpdb;
19+
20+
if ( empty( $wpdb->queries ) ) {
21+
return;
22+
}
23+
24+
// Extract SQLite queries, indexed to match Query Monitor's row order.
25+
$mapped = array();
26+
$row_index = 0;
27+
foreach ( $wpdb->queries as $query ) {
28+
// Query Monitor skips queries with 'wp_admin_bar' in the stack.
29+
$stack = $query[2] ?? '';
30+
if ( false !== strpos( $stack, 'wp_admin_bar' ) ) {
31+
continue;
32+
}
33+
if ( ! empty( $query['sqlite_queries'] ) ) {
34+
$mapped[ $row_index ] = array_column( $query['sqlite_queries'], 'sql' );
35+
}
36+
$row_index += 1;
37+
}
38+
$this->data->queries = $mapped;
39+
}
40+
}
41+
42+
/**
43+
* HTML outputter for SQLite query data.
44+
*
45+
* With $client_side_rendered = true, QM auto-serializes the collector data
46+
* into "window.QueryMonitorData.data.sqlite". This outputter's only job is to
47+
* emit the inline JS module that reads that data and injects SQLite query
48+
* details into QM 4.0's shadow DOM DB queries panel.
49+
*/
50+
class SQLite_QM_Output_Html extends QM_Output_Html {
51+
/** @var bool */
52+
public static $client_side_rendered = true;
53+
54+
public function name(): string {
55+
return 'SQLite';
56+
}
57+
58+
public function output(): void {
59+
if ( empty( $this->get_collector()->get_data()->queries ) ) {
60+
return;
61+
}
62+
63+
$js_path = __DIR__ . '/query-monitor-sqlite.js';
64+
if ( is_readable( $js_path ) ) {
65+
echo '<script type="module">';
66+
include $js_path;
67+
echo '</script>';
68+
}
69+
}
70+
}
71+
72+
/**
73+
* Register the SQLite collector.
74+
*/
75+
function register_sqlite_qm_collector( array $collectors ): array {
76+
$collectors['sqlite'] = new SQLite_QM_Collector();
77+
return $collectors;
78+
}
79+
80+
add_filter( 'qm/collectors', 'register_sqlite_qm_collector', 20 );
81+
82+
/**
83+
* Register the SQLite HTML outputter.
84+
*/
85+
function register_sqlite_qm_output_html( array $output, QM_Collectors $collectors ): array {
86+
$collector = QM_Collectors::get( 'sqlite' );
87+
if ( $collector ) {
88+
$output['sqlite'] = new SQLite_QM_Output_Html( $collector );
89+
}
90+
return $output;
91+
}
92+
93+
add_filter( 'qm/outputter/html', 'register_sqlite_qm_output_html', 30, 2 );

0 commit comments

Comments
 (0)