SleekDB middleware

Tillreetree
SleekDB middleware
Tillreetree@fc7e1f5a Tuesday 26th July 2022, 09:25:20

the first step to unifying core and plug-in development



Note

This middleware is a Alpha version which, when configured, is comparable to the original Flatboard in terms of stability, but is not recommended for use on production sites.

This middleware solves the following difficulties
  • No need to implement your own CRUD (Create, Read, Update, Delete) process
  • Slight performance improvements

Features
  • True JSON storage
  • Perfectly reproduces the CRUD functions in the FlatDB class (without the deleteDir function)
  • Almost no modification to the original Flatboard files (except for FlatDB.lib.php)
  • Built-in caching mechanism (provided by SleekDB) (as fast as 0.065 seconds, but needs more testing)
  • Better search mechanism (provided by SleekDB)

Changes relative to the original version
Database entries

Added "_fileid" field for this middleware to emulate the original query method.
Added "_id" field (provided by SleekDB) as a numeric ID, which will work well in some cases.

saveEntry()

Added $forceDeleteCache parameter: if true, the entire cache of the modified part is cleared after saving. For example, if this parameter is true, the full topic cache will be cleared after editing the topic, so that the user sees the latest modified topic.

readEntry()

Added $raw parameter: if true, the "_fileid" and "_id" are not removed. For compatibility, readEntry does not provide "_fileid" and "_id" by default.

Other
  • The readEntry, saveEntry, deleteEntry and isValidEntry functions all support "_id" and "_fileid" queries.
  • The search page has not been changed, so you can modify the implementation yourself.

Installation
  1. Download Flatboard and upload it to the server.
  2. Download SleekDB.
  3. Visit your website for unzipping Flatboard.
  4. Unzip the downloaded package, find the "src folder" and upload it to the "lib" folder on the server.
  5. Rename the src to "sleekdb".
  6. Open Flatdb.lib.php and replace the contents with the following code.
  7. Visit your website again and install Flatboard.

Code
[pre]

<?php defined('FLATBOARD') or die('Flatboard Community.');

/*
* Project name: Flatboard
* Project URL: https://flatboard.org
* Author: Frédéric Kaplon and contributors
* All Flatboard code is released under the MIT license.
*/
require_once "sleekdb/SleekDB.php";
require_once "sleekdb/Store.php";
if (!defined('DATA_DIR')) {
define('DATA_DIR', "../data");
}

/**
* SleekDB Middleware
*/
class flatDB
{
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}

/**
* @var array $SleekDB_config SleekDB Configuration
*/
static $SleekDB_config = array(
"auto_cache" => true,
"cache_lifetime" => 1,
"timeout" => false,
"primary_key" => "_id"
);

/**
* List files in the specified directory without suffixes
*
* @param string $dir Directory
* @return array
*/
public static function fdir($dir)
{
$ignored = array('.', '..', '.svn', '.git', 'Thumbs.db', 'index.html', '.DS_Store');
$files = array();
$dh = opendir($dir);
while (false !== ($file = readdir($dh))) {
if (in_array($file, $ignored)) continue;
$file = explode('.', $file, 2);
$files[] = $file[0];
}
closedir($dh);
return $files;
}

/**
* Whether the specified file exists in the specified directory
*
* @param string $file name
* @param string $dir directory
* @param string $ext suffix
* @return bool
*/
public static function indir($file, $dir, $ext = '')
{
return strpos($file, DS) === false && strpos($file, '.') === false && strpos($file, "\0") === false && file_exists($dir . DS . $file . $ext);
}

/**
* Read the specified row of the specified table
*
* @param string $type table
* @param string $file row
* @Param string $raw without removing "_fileid" and "_id" columns
* @return mixed
*/
public static function readEntry($type, $file, $raw = false)
{
$table_this = new \SleekDB\Store($type, DATA_DIR, self::$SleekDB_config);
if (is_array($file)) {
$_id = $file['_id'];
} else {
$_id = $file;
}
if (is_numeric($_id)) {
$r = $table_this->findById($_id);
} else {
$r = $table_this->findOneBy(["_fileid", "=", $_id]);
}
if (!$raw) {
if (isset($r['_fileid'])) {
unset($r['_fileid']);
}
if (isset($r['_id'])) {
unset($r['_id']);
}
}
if (is_null($r)) {
return array();
}
//var_dump($r);
return $r;
}

/**
* Save the specified row of the specified table
*
* @param string $type table
* @param string $file row
* @param $data content
* @param bool $forceDeleteCache cleans up all caches after saving
*/
public static function saveEntry($type, $file, $data, $forceDeleteCache = false)
{
$table_this = new \SleekDB\Store($type, DATA_DIR, self::$SleekDB_config);
$r = self::readEntry($type, $file, true);
if (is_null($r) || empty($r)) {
$r = array('_fileid' => $file);
}
$r = array_merge($r, $data);
if ($forceDeleteCache) {
//cache clean up
$cacheCtrl = new \SleekDB\SleekDB($type, DATA_DIR, self::$SleekDB_config);
$cacheCtrl->deleteAllCache();
unset($cacheCtrl);
}
return $table_this->updateOrInsert($r);
}

/**
* Delete the specified row of the specified table
*
* @param string $type table
* @param string $file row
*/
public static function deleteEntry($type, $file)
{
$table_this = new \SleekDB\Store($type, DATA_DIR, self::$SleekDB_config);
if (is_numeric($file)) {
return $table_this->deleteById($file);
} else {
return $table_this->deleteBy(["_fileid", "=", $file]);
}
}

/**
* Query the IDs of all rows of the specified table
*
* @param string $type table
*/
public static function listEntry($type)
{
$table_this = new \SleekDB\Store($type, DATA_DIR, self::$SleekDB_config);
$r = $table_this->findAll();
if (is_null($r)) {
return array();
} elseif (isset($r[0]['_fileid'])) {
return array_column($r, '_fileid');
} else {
return array_column($r, '_id');
}
}

/**
* Query whether the specified table has the specified row
*
* @param string $type table
* @param string $file row
* @return bool
*/
public static function isValidEntry($type, $file)
{
$table_this = new \SleekDB\Store($type, DATA_DIR, self::$SleekDB_config);
if (is_numeric($file)) {
$r = $table_this->findById($file);
} else {
$r = $table_this->findBy(["_fileid", "=", $file]);
}
//var_dump($r);
if (!is_null($r) && !empty($r)) {
return true;
}
return false;
/*
return flatDB::indir($file, DATA_DIR . $type, '.dat.php');
*/
}

/**
* ID (filename) required to create a new row
* @return string
*/
public static function newEntry()
{
return date('Y-m-dHis') . substr(uniqid(), -5);
}

/**
* Recursively delete files in the specified directory and subdirectories [Danger]
*
* @param string $dir directory
*/
public static function deleteDir($dir)
{
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..') {
if (is_dir($dir . $file)) {
if (!rmdir($dir . $file)) // Empty directory? Remove it
{
flatDB::deleteDir($dir . '/' . $file . '/'); // Not empty? Delete the files inside it
}
} else {
unlink($dir . $file);
}
}
}
closedir($handle);
@rmdir($dir);
}
}
}
[/pre]

Translated with www.DeepL.com/Translator (free version)

Last modified by Tillreetree@fc7e1f5a on Tuesday 26th July 2022, 09:25:00

Replies 5
SurveyBuilder-Admin
XHiddenProjects  Sunday 31st July 2022, 14:00:39

Why would you do that, when the software already makes a database, it would just use up more storage and a waste of time going through the whole thing to change. I think it’s unnecessary to install a software when it’s not needed.
Software engineer, creates plugins for Flatboard, checks source codes, and answers any software errors questions and contributes on the GitHub page as well

Tillreetree
Tillreetree@fc7e1f5a  Monday 1st August 2022, 06:29:55

  Maybe you're right, this is more of an interesting attempt.

Tillreetree
Tillreetree@fc7e1f5a  Monday 1st August 2022, 06:48:31

I also noticed that some plugins use their own database implementations, leading to data "fragmentation"
(e.g. the Notification plugin, which uses JSON - rather than FlatDB - to store notifications, and saves them in the plugin's folder - not the data folder)
There are no standards to speak of.

Last modified by Tillreetree@fc7e1f5a on Monday 1st August 2022, 06:48:00

Fred
Fred  Sunday 7th August 2022, 18:10:04

@Tillreetree@fc7e1f5a Just download an official plugin to discover its structure.
So if there is a standard to respect, especially in saving data with flatDB::saveEntry and for reading them with flatDB::readEntry

Last modified by Fred on Sunday 7th August 2022, 18:11:00
  • Before ask a question, read the documentation.
  • 🎉  Featured as #1 product of the day on Product Hunt
  • Please like in alternativeto.net 👍🏻
  • ╰☆╮Flatboard╰☆╮ is a open source and community contributions are essential to project success!
  • <TextField>, my new CMS project designed by a passionate developer, for developers!
  • I am currently busy 😫.

SurveyBuilder-Admin
XHiddenProjects  Monday 8th August 2022, 12:21:09

@Tillreetree@fc7e1f5a I do that, just because it just makes it easier for me to just grab data, even though I could use
flatDB::saveEntry()
and
flatDB:readEntry()
, but I never really got into the library during those times.

Last modified by XHiddenProjects on Monday 8th August 2022, 12:23:00
Software engineer, creates plugins for Flatboard, checks source codes, and answers any software errors questions and contributes on the GitHub page as well