feat: add settings construct cache

This will avoid the awkward recursive query for
each post by fetching cached post settings if available, and
caching them nicely.
This commit is contained in:
David Bailey 2023-12-20 18:54:31 +01:00
parent 94b65aec8c
commit 6cb60a6652
3 changed files with 56 additions and 35 deletions

View file

@ -10,11 +10,10 @@ CREATE TABLE posts (
post_path_depth INTEGER NOT NULL DEFAULT 0, post_path_depth INTEGER NOT NULL DEFAULT 0,
post_create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, post_create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
post_update_time DATETIME NOT NULL post_update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
post_metadata JSON NOT NULL, post_metadata JSON NOT NULL,
post_settings_cache JSON DEFAULT NULL,
post_content MEDIUMTEXT, post_content MEDIUMTEXT,

View file

@ -144,18 +144,34 @@ class MySQLAdapter {
return $out_data; return $out_data;
} }
function reset_post_settings_cache($post_path) {
$post_path = $this->_sanitize_path($post_path);
$this->_exec("
UPDATE posts
SET post_settings_cache=NULL
WHERE post_path LIKE ?;
", "s", $post_path . "%");
}
function update_or_create_post($post_path, $post_metadata, $post_content) { function update_or_create_post($post_path, $post_metadata, $post_content) {
$post_path = $this->_sanitize_path($post_path); $post_path = $this->_sanitize_path($post_path);
$path_depth = substr_count($post_path, "/"); $path_depth = substr_count($post_path, "/");
$this->make_post_directory(dirname($post_path)); $this->make_post_directory(dirname($post_path));
$this->reset_post_settings_cache($post_path);
$qry = " $qry = "
INSERT INTO posts INSERT INTO posts
(post_path, post_path_depth, post_metadata, post_content) (post_path, post_path_depth, post_metadata, post_content)
VALUES VALUES
( ?, ?, ?, ?) AS new ( ?, ?, ?, ?) AS new
ON DUPLICATE KEY UPDATE post_metadata=new.post_metadata, post_content=new.post_content;"; ON DUPLICATE KEY
UPDATE post_metadata=new.post_metadata,
post_content=new.post_content,
post_update_time=CURRENT_TIMESTAMP;";
$this->_exec($qry, "siss", $this->_exec($qry, "siss",
$post_path, $post_path,
@ -167,39 +183,45 @@ class MySQLAdapter {
function get_settings_for_path($post_path) { function get_settings_for_path($post_path) {
$post_path = $this->_sanitize_path($post_path); $post_path = $this->_sanitize_path($post_path);
$qry = " $post_settings = $this->_exec("
WITH RECURSIVE settings_data (post_path, post_depth, json_settings) AS ( SELECT post_path, post_settings_cache
SELECT post_path, post_path_depth, post_metadata
FROM posts FROM posts
WHERE post_path = ? WHERE post_path = ?
", "s", $post_path)->fetch_assoc();
UNION ALL if(!isset($post_settings)) {
return [];
SELECT posts.post_path, posts.post_path_depth, posts.post_metadata }
FROM posts, settings_data if(isset($post_settings['post_settings_cache'])) {
WHERE posts.post_path = SUBSTRING_INDEX(settings_data.post_path, '/', settings_data.post_depth) return json_decode($post_settings['post_settings_cache'], true);
AND posts.post_path_depth = settings_data.post_depth - 1
)
SELECT post_depth, json_settings
FROM settings_data
ORDER BY post_depth ASC;
";
$out_settings = [];
$settings_list = $this->_exec($qry, "s", $post_path)->fetch_all(MYSQLI_ASSOC);
foreach($settings_list AS $setting) {
$setting = json_decode($setting['json_settings'], true);
if(!isset($setting) || !isset($setting['settings'])) {
continue;
}
$out_settings = array_merge($out_settings, $setting['settings']);
} }
return $out_settings; $parent_settings = [];
if($post_path != "") {
$parent_settings = $this->get_settings_for_path(dirname($post_path));
}
$post_settings = [];
$post_metadata = $this->_exec("
SELECT post_path, post_metadata
FROM posts
WHERE post_path = ?
", "s", $post_path)->fetch_assoc();
if(isset($post_metadata['post_metadata'])) {
$post_metadata = json_decode($post_metadata['post_metadata'], true);
if(isset($post_metadata['settings'])) {
$post_settings = $post_metadata['settings'];
}
}
$post_settings = array_merge($parent_settings, $post_settings);
$this->_exec("UPDATE posts SET post_settings_cache=? WHERE post_path=?", "ss",
json_encode($post_settings), $post_path);
return $post_settings;
} }
function get_post_by_path($post_path, function get_post_by_path($post_path,

View file

@ -71,12 +71,12 @@ class PostHandler extends MySQLAdapter {
if(basename($post_path) == "README.md") { if(basename($post_path) == "README.md") {
$readme_metadata = []; $readme_metadata = [];
if(isset($post_metadata['directory_data'])) {
$readme_metadata = $post_metadata['directory_data'];
}
if(isset($post_metadata['settings'])) { if(isset($post_metadata['settings'])) {
$readme_metadata['settings'] = $post_metadata['settings']; $readme_metadata['settings'] = $post_metadata['settings'];
} }
if(isset($post_metadata['directory_data'])) {
$readme_metadata = $post_metadata['directory_data'];
}
$this->update_or_create_post(dirname($post_path), $this->update_or_create_post(dirname($post_path),
$readme_metadata, $post_content); $readme_metadata, $post_content);