Skip to content
This repository has been archived by the owner on Sep 11, 2021. It is now read-only.

Commit

Permalink
✨ pragmas, transactions
Browse files Browse the repository at this point in the history
Signed-off-by: Bruno Meilick <b@bnomei.com>
  • Loading branch information
bnomei committed Sep 5, 2020
1 parent a8729e0 commit c59b8b9
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 33 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ $checkIfContentFileIsSQLiteCached = $page->isSQLitePage(); // bool
| bnomei.page-sqlite. | Default | Description |
|---------------------------|----------------|---------------------------|
| file | `callback` | |
| wal | `true` | sqlite WAL for faster IO |


## Dependencies
Expand Down
86 changes: 60 additions & 26 deletions classes/SQLitePagesDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,68 @@

use Kirby\Cache\FileCache;
use Kirby\Toolkit\A;
use Kirby\Toolkit\F;
use Kirby\Toolkit\Obj;
use SQLite3;

final class SQLitePagesDatabase
{
/** @var \SQLite3 */
private $database;
private $transactionsCount = 0;
private $options;

public function __construct(array $options = [])
{
$this->options = array_merge([
'file' => \option('bnomei.page-sqlite.file'),
], $options);
$this->setOptions($options);
$this->loadDatabase();

foreach ($this->options as $key => $call) {
if (!is_string($call) && is_callable($call) && in_array($key, ['file'])) {
$this->options[$key] = $call();
}
}

$target = $this->options['file'];
$this->database = new \SQLite3($target);
if (\SQLite3::version() >= 3007001 && \option('bnomei.page-sqlite.wal')) {
$this->database->exec("PRAGMA busy_timeout=1000");
$this->database->exec("PRAGMA journal_mode = WAL");
}
$this->database->exec("CREATE TABLE IF NOT EXISTS pages (id TEXT primary key unique, modified_at INTEGER, data TEXT)");

if (\option('debug')) {
if ($this->options['debug']) {
$this->flush();
}

$this->beginTransaction();
}

public function __destruct()
{
if (\SQLite3::version() >= 3007001 && \option('bnomei.page-sqlite.wal')) {
$this->database()->exec('PRAGMA main.wal_checkpoint(TRUNCATE);');
$this->endTransaction();
$this->applyPragmas('pragmas-destruct');
$this->database->close();
}

private function loadDatabase()
{
$file = $this->options['file'];
try {
$this->database = new SQLite3($file);
} catch (\Exception $exception) {
F::remove($file);
F::remove($file . '-wal');
F::remove($file . '-shm');
$this->database = new SQLite3($file);
throw new \Exception($exception->getMessage());
}
}

private function applyPragmas(string $pragmas)
{
foreach ($this->options[$pragmas] as $pragma) {
$this->database->exec($pragma);
}
$this->database()->close();
}

public function databaseFile(): string
private function beginTransaction()
{
return $this->options['file'];
$this->database->exec("BEGIN TRANSACTION;");
$this->transactionsCount++;
}

private function endTransaction()
{
$this->database->exec("END TRANSACTION;");
}

public function database(): \SQLite3
Expand Down Expand Up @@ -128,11 +147,6 @@ public function flush(): bool
return $this->database->exec("DELETE FROM pages WHERE id != ''") !== false;
}

public function root(): string
{
return realpath(__DIR__ . '/../') . '/cache';
}

public static function cacheFolder(): string
{
$cache = kirby()->cache('bnomei.page-sqlite');
Expand All @@ -143,4 +157,24 @@ public static function cacheFolder(): string
return kirby()->roots()->cache();
// @codeCoverageIgnoreEnd
}

private function setOptions(array $options): void
{
$this->options = array_merge([
'file' => \option('bnomei.page-sqlite.file'),
'debug' => \option('debug'),
'pragmas-construct' => \option('bnomei.page-sqlite.pragmas-construct'),
'pragmas-destruct' => \option('bnomei.page-sqlite.pragmas-destruct'),
], $options);

foreach ($this->options as $key => $call) {
if (!is_string($call) && is_callable($call) && in_array($key, [
'file',
'pragmas-construct',
'pragmas-destruct',
])) {
$this->options[$key] = $call();
}
}
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "bnomei/kirby3-page-sqlite",
"type": "kirby-plugin",
"version": "1.1.4",
"version": "1.2.0",
"description": "Kirby 3 Plugin to cache the content file using SQLite",
"license": "MIT",
"authors": [
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 37 additions & 2 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,45 @@
Kirby::plugin('bnomei/page-sqlite', [
'options' => [
'cache' => true,
'wal' => true,
'file' => function () {
return \Bnomei\SQLitePagesDatabase::cacheFolder() . '/page-sqlite-v1-0-1.sqlite';
}
},
// https://sqlite.org/pragma.html
'pragmas-construct' => function () {
$defaults = [
'PRAGMA main.cache_size = 10000;',
'PRAGMA case_sensitive_like = false',
'PRAGMA main.auto_vacuum = INCREMENTAL;',
'PRAGMA main.locking_mode = EXCLUSIVE;',
'PRAGMA main.page_size = 4096;',
'PRAGMA temp_store = MEMORY;',
];
if (SQLite3::version() >= 3007001) {
return array_merge($defaults, [
'PRAGMA main.synchronous = NORMAL;',
'PRAGMA main.journal_mode = WAL;',
]);
} else {
return array_merge($defaults, [
'PRAGMA main.synchronous = OFF;',
'PRAGMA main.journal_mode = MEMORY;',
]);
}
},
'pragmas-destruct' => function () {
$defaults = [
'PRAGMA main.incremental_vacuum;',
];
if (SQLite3::version() >= 3007001) {
return array_merge($defaults, [
'PRAGMA main.wal_checkpoint(TRUNCATE);',
'PRAGMA main.synchronous = NORMAL;',
'PRAGMA main.locking_mode = NORMAL;',
]);
} else {
return array_merge($defaults, []);
}
},
],
'pageMethods' => [
'isSQLitePage' => function () {
Expand Down
4 changes: 2 additions & 2 deletions tests/content/home/default.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Title: Home 1599160794
Title: Home 1599344942

----

Text:
Text:

0 comments on commit c59b8b9

Please sign in to comment.