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_create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
post_update_time DATETIME NOT NULL
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
post_update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
post_metadata JSON NOT NULL,
post_settings_cache JSON DEFAULT NULL,
post_content MEDIUMTEXT,

View file

@ -144,18 +144,34 @@ class MySQLAdapter {
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) {
$post_path = $this->_sanitize_path($post_path);
$path_depth = substr_count($post_path, "/");
$this->make_post_directory(dirname($post_path));
$this->reset_post_settings_cache($post_path);
$qry = "
INSERT INTO posts
(post_path, post_path_depth, post_metadata, post_content)
VALUES
( ?, ?, ?, ?) 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",
$post_path,
@ -167,39 +183,45 @@ class MySQLAdapter {
function get_settings_for_path($post_path) {
$post_path = $this->_sanitize_path($post_path);
$qry = "
WITH RECURSIVE settings_data (post_path, post_depth, json_settings) AS (
SELECT post_path, post_path_depth, post_metadata
$post_settings = $this->_exec("
SELECT post_path, post_settings_cache
FROM posts
WHERE post_path = ?
", "s", $post_path)->fetch_assoc();
UNION ALL
SELECT posts.post_path, posts.post_path_depth, posts.post_metadata
FROM posts, settings_data
WHERE posts.post_path = SUBSTRING_INDEX(settings_data.post_path, '/', settings_data.post_depth)
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']);
if(!isset($post_settings)) {
return [];
}
if(isset($post_settings['post_settings_cache'])) {
return json_decode($post_settings['post_settings_cache'], true);
}
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,

View file

@ -71,12 +71,12 @@ class PostHandler extends MySQLAdapter {
if(basename($post_path) == "README.md") {
$readme_metadata = [];
if(isset($post_metadata['directory_data'])) {
$readme_metadata = $post_metadata['directory_data'];
}
if(isset($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),
$readme_metadata, $post_content);