@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/portfolio/lh-block-and-shortcode-auditor/>
  a sioc:Post ;
  dc:title "Database schema" ;
  dcterms:identifier 147632 ;
  dc:modified "2026-10-16T09:22:31Z"^^xsd:dateTime ;
  dc:created "2026-09-16T22:49:53Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-block-and-shortcode-auditor/database-schema/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<ul class="lh_portfolio-meta"><li><strong>Part of:</strong> <a href="https://lhero.org/portfolio/lh-block-and-shortcode-auditor/">LH Block and Shortcode Auditor</a></li></ul>
<p class="wp-block-paragraph">Two network-wide tables on the base prefix (<code>{base_prefix}lh_bsa_summary</code> and <code>{base_prefix}lh_bsa_usage</code>, both names filterable), scoped per site by <code>blog_id</code>. Created and upgraded with <code>dbDelta</code> on <code>init</code> whenever the network option <code>lh_block_and_shortcode_auditor_db_version</code> differs from the code&#8217;s schema version (currently 1). Both are dropped on uninstall; everything in them can be regenerated by rescanning.</p>



<h2 class="wp-block-heading">lh_bsa_summary</h2>



<p class="wp-block-paragraph">One row per site, tag type and tag: every registered tag plus every used tag that is not registered. Rewritten as a whole on each registry capture or count refresh.</p>



<figure class="wp-block-table"><table><thead><tr><th>Column</th><th>Type</th><th>Notes</th></tr></thead><tbody><tr><td>id</td><td>bigint unsigned</td><td>Primary key</td></tr><tr><td>blog_id</td><td>bigint unsigned</td><td>Site</td></tr><tr><td>tag_type</td><td>varchar(20)</td><td><code>block</code> or <code>shortcode</code></td></tr><tr><td>tag</td><td>varchar(191)</td><td>Block name or shortcode tag</td></tr><tr><td>is_registered</td><td>tinyint(1)</td><td>1 if registered at the last capture</td></tr><tr><td>provider</td><td>varchar(191)</td><td><code>plugin:slug</code>, <code>theme:slug</code>, <code>core</code>, <code>namespace:name</code> or empty</td></tr><tr><td>usage_count</td><td>bigint unsigned</td><td>Total occurrences in content</td></tr><tr><td>object_count</td><td>bigint unsigned</td><td>Posts or widgets using it</td></tr><tr><td>scanned_at</td><td>datetime, GMT</td><td>When the row was written</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Keys: unique <code>blog_tag (blog_id, tag_type, tag)</code>; <code>blog_registered (blog_id, is_registered)</code>.</p>



<h2 class="wp-block-heading">lh_bsa_usage</h2>



<p class="wp-block-paragraph">One row per site, object, tag type and tag. Keyed by tag type, not registration state, so a registry change only needs the summary rebuilt, never a content rescan. Rows for one object are deleted and reinserted on each scan; rows not rewritten during a full sweep are removed when it finishes.</p>



<figure class="wp-block-table"><table><thead><tr><th>Column</th><th>Type</th><th>Notes</th></tr></thead><tbody><tr><td>id</td><td>bigint unsigned</td><td>Primary key</td></tr><tr><td>blog_id</td><td>bigint unsigned</td><td>Site</td></tr><tr><td>tag_type</td><td>varchar(20)</td><td><code>block</code> or <code>shortcode</code></td></tr><tr><td>tag</td><td>varchar(191)</td><td>Block name or shortcode tag</td></tr><tr><td>object_type</td><td>varchar(20)</td><td><code>post</code>, or <code>widget_{id_base}</code></td></tr><tr><td>object_id</td><td>bigint unsigned</td><td>Post ID or widget number</td></tr><tr><td>object_subtype</td><td>varchar(64)</td><td>Post type or widget id_base</td></tr><tr><td>object_status</td><td>varchar(20)</td><td>Post status; empty for widgets</td></tr><tr><td>occurrences</td><td>int unsigned</td><td>Uses in that object</td></tr><tr><td>scanned_at</td><td>datetime, GMT</td><td>When the row was written</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Keys: unique <code>object_tag (blog_id, object_type, object_id, tag_type, tag)</code>; <code>blog_tag (blog_id, tag_type, tag)</code>.</p>



<h2 class="wp-block-heading">Per-site options and transients</h2>



<ul class="wp-block-list"><li><code>lh_block_and_shortcode_auditor_registry_signature</code>, <code>_registry_captured_at</code>, <code>_registry_requested</code>: registry capture state.</li><li><code>lh_block_and_shortcode_auditor_scanner_sweep_started</code>, <code>_scanner_sweep_completed</code> (GMT), <code>_scanner_scanner_version</code>: sweep state. Clearing the scanner version forces a sweep on the site&#8217;s next request.</li><li><code>lh_block_and_shortcode_auditor_scanner_sweep_token</code> (since 0.1.13): random token for the current sweep, passed to every batch job. A batch whose token no longer matches exits, so a superseded sweep cannot race a new one.</li><li><code>lh_block_and_shortcode_auditor_scanner_sweep_progress</code> (since 0.1.17): array of <code>cursor</code> (last post ID scanned), <code>token</code> and <code>time</code>, written when a sweep starts and after every batch. The watchdog reads it to detect and resume a stalled sweep.</li><li>Transient <code>lh_block_and_shortcode_auditor_scanner_schedule_checked</code>: throttles the daily-sweep schedule check to every 12 hours.</li></ul>



<p class="wp-block-paragraph">All are removed per site on uninstall, along with the plugin&#8217;s jobs in both Action Scheduler and WP-Cron.</p>
"""^^rdf:XMLLiteral ;
  sioc:content """Part of: LH Block and Shortcode Auditor
Two network-wide tables on the base prefix ({base_prefix}lh_bsa_summary and {base_prefix}lh_bsa_usage, both names filterable), scoped per site by blog_id. Created and upgraded with dbDelta on init whenever the network option lh_block_and_shortcode_auditor_db_version differs from the code&#8217;s schema version (currently 1). Both are dropped on uninstall; everything in them can be regenerated by rescanning.



lh_bsa_summary



One row per site, tag type and tag: every registered tag plus every used tag that is not registered. Rewritten as a whole on each registry capture or count refresh.



ColumnTypeNotesidbigint unsignedPrimary keyblog_idbigint unsignedSitetag_typevarchar(20)block or shortcodetagvarchar(191)Block name or shortcode tagis_registeredtinyint(1)1 if registered at the last captureprovidervarchar(191)plugin:slug, theme:slug, core, namespace:name or emptyusage_countbigint unsignedTotal occurrences in contentobject_countbigint unsignedPosts or widgets using itscanned_atdatetime, GMTWhen the row was written



Keys: unique blog_tag (blog_id, tag_type, tag); blog_registered (blog_id, is_registered).



lh_bsa_usage



One row per site, object, tag type and tag. Keyed by tag type, not registration state, so a registry change only needs the summary rebuilt, never a content rescan. Rows for one object are deleted and reinserted on each scan; rows not rewritten during a full sweep are removed when it finishes.



ColumnTypeNotesidbigint unsignedPrimary keyblog_idbigint unsignedSitetag_typevarchar(20)block or shortcodetagvarchar(191)Block name or shortcode tagobject_typevarchar(20)post, or widget_{id_base}object_idbigint unsignedPost ID or widget numberobject_subtypevarchar(64)Post type or widget id_baseobject_statusvarchar(20)Post status; empty for widgetsoccurrencesint unsignedUses in that objectscanned_atdatetime, GMTWhen the row was written



Keys: unique object_tag (blog_id, object_type, object_id, tag_type, tag); blog_tag (blog_id, tag_type, tag).



Per-site options and transients



lh_block_and_shortcode_auditor_registry_signature, _registry_captured_at, _registry_requested: registry capture state.lh_block_and_shortcode_auditor_scanner_sweep_started, _scanner_sweep_completed (GMT), _scanner_scanner_version: sweep state. Clearing the scanner version forces a sweep on the site&#8217;s next request.lh_block_and_shortcode_auditor_scanner_sweep_token (since 0.1.13): random token for the current sweep, passed to every batch job. A batch whose token no longer matches exits, so a superseded sweep cannot race a new one.lh_block_and_shortcode_auditor_scanner_sweep_progress (since 0.1.17): array of cursor (last post ID scanned), token and time, written when a sweep starts and after every batch. The watchdog reads it to detect and resume a stalled sweep.Transient lh_block_and_shortcode_auditor_scanner_schedule_checked: throttles the daily-sweep schedule check to every 12 hours.



All are removed per site on uninstall, along with the plugin&#8217;s jobs in both Action Scheduler and WP-Cron.
""" ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
