summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2021-03-04 09:22:24 +0300
committerAndrew Dolgov <[email protected]>2021-03-04 09:22:24 +0300
commit5eb0f3d640374a82a026164942adc79bb1262576 (patch)
tree1227d76bb1184b4e505ea53ca49ea3252ac9512d
parente19570f422df8e4ba0d604b517efad111def9a23 (diff)
bring back web dbupdate using new migrations system
-rw-r--r--backend.php2
-rw-r--r--classes/config.php11
-rw-r--r--classes/db/migrations.php2
-rw-r--r--classes/db/updater.php82
-rwxr-xr-xclasses/handler/public.php150
-rw-r--r--classes/opml.php6
-rwxr-xr-xclasses/rpc.php2
-rwxr-xr-xclasses/rssutils.php2
-rw-r--r--include/functions.php4
-rw-r--r--include/sessions.php24
-rw-r--r--schema/ttrss_schema_mysql.sql0
-rw-r--r--schema/ttrss_schema_pgsql.sql0
-rwxr-xr-xupdate.php48
-rwxr-xr-xupdate_daemon2.php2
14 files changed, 117 insertions, 218 deletions
diff --git a/backend.php b/backend.php
index ef1184068..98c8eace6 100644
--- a/backend.php
+++ b/backend.php
@@ -51,7 +51,7 @@
UserHelper::load_user_plugins($_SESSION["uid"]);
}
- if (Db_Updater::is_update_required()) {
+ if (Config::is_migration_needed()) {
print Errors::to_json(Errors::E_SCHEMA_MISMATCH);
return;
}
diff --git a/classes/config.php b/classes/config.php
index 30b65305a..d0c59fbbd 100644
--- a/classes/config.php
+++ b/classes/config.php
@@ -6,6 +6,8 @@ class Config {
const T_STRING = 2;
const T_INT = 3;
+ const SCHEMA_VERSION = 142;
+
// override defaults, defined below in _DEFAULTS[], via environment: DB_TYPE becomes TTRSS_DB_TYPE, etc
const DB_TYPE = "DB_TYPE";
@@ -228,7 +230,7 @@ class Config {
private function _get_migrations() : Db_Migrations {
if (empty($this->migrations)) {
$this->migrations = new Db_Migrations();
- $this->migrations->initialize(dirname(__DIR__) . "/sql", "ttrss_version", true);
+ $this->migrations->initialize(dirname(__DIR__) . "/sql", "ttrss_version", true, self::SCHEMA_VERSION);
}
return $this->migrations;
@@ -336,7 +338,7 @@ class Config {
$pdo = Db::pdo();
- $errors = array();
+ $errors = [];
if (strpos(self::get(Config::PLUGINS), "auth_") === false) {
array_push($errors, "Please enable at least one authentication module via PLUGINS");
@@ -373,6 +375,11 @@ class Config {
}
if (php_sapi_name() != "cli") {
+
+ if (self::get_schema_version() < 0) {
+ array_push($errors, "Base database schema is missing. Either load it manually or perform a migration (<code>update.php --update-schema</code>)");
+ }
+
$ref_self_url_path = self::make_self_url();
if ($ref_self_url_path) {
diff --git a/classes/db/migrations.php b/classes/db/migrations.php
index e77904f60..e5133ddf6 100644
--- a/classes/db/migrations.php
+++ b/classes/db/migrations.php
@@ -89,7 +89,7 @@ class Db_Migrations {
try {
$this->pdo->query($line);
} catch (PDOException $e) {
- Debug::log("Failed on line: $line");
+ Debug::log("Failed on line: $line", Debug::LOG_VERBOSE);
throw $e;
}
}
diff --git a/classes/db/updater.php b/classes/db/updater.php
deleted file mode 100644
index 9d27c94d9..000000000
--- a/classes/db/updater.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-class Db_Updater {
- const SCHEMA_VERSION = 142;
-
- private $pdo;
- private $db_type;
-
- function __construct($pdo, $db_type) {
- $this->pdo = $pdo;
- $this->db_type = $db_type;
- }
-
- /** always returns actual (=uncached) value */
- private static function get_schema_version() {
- return Config::get_schema_version(true);
- }
-
- static function is_update_required() {
- return self::get_schema_version() < self::SCHEMA_VERSION;
- }
-
- function get_schema_lines($version) {
- $filename = "schema/versions/".$this->db_type."/$version.sql";
-
- if (file_exists($filename)) {
- return explode(";", (string)preg_replace("/[\r\n]/", "", (string)file_get_contents($filename)));
- } else {
- user_error("DB Updater: schema file for version $version is not found.");
- return false;
- }
- }
-
- function update_to($version, $html_output = true) {
- if ($this->get_schema_version() == $version - 1) {
-
- $lines = $this->get_schema_lines($version);
-
- if (is_array($lines)) {
-
- $this->pdo->beginTransaction();
-
- foreach ($lines as $line) {
- if (strpos($line, "--") !== 0 && $line) {
-
- if ($html_output)
- print "<pre>$line</pre>";
- else
- Debug::log("> $line");
-
- try {
- $this->pdo->query($line); // PDO returns errors as exceptions now
- } catch (PDOException $e) {
- if ($html_output) {
- print "<div class='text-error'>Error: " . $e->getMessage() . "</div>";
- } else {
- Debug::log("Error: " . $e->getMessage());
- }
-
- $this->pdo->rollBack();
- return false;
- }
- }
- }
-
- $db_version = self::get_schema_version();
-
- if ($db_version == $version) {
- $this->pdo->commit();
- return true;
- } else {
- $this->pdo->rollBack();
- return false;
- }
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
-}
diff --git a/classes/handler/public.php b/classes/handler/public.php
index 08df7bbc1..0e82b6469 100755
--- a/classes/handler/public.php
+++ b/classes/handler/public.php
@@ -623,33 +623,57 @@ class Handler_Public extends Handler {
<!DOCTYPE html>
<html>
<head>
- <title>Database Updater</title>
+ <title>Tiny Tiny RSS: Database Updater</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <?= stylesheet_tag("themes/light.css") ?>
- <link rel="shortcut icon" type="image/png" href="images/favicon.png">
<link rel="icon" type="image/png" sizes="72x72" href="images/favicon-72px.png">
+ <link rel="shortcut icon" type="image/png" href="images/favicon.png">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<?php
- echo stylesheet_tag("themes/light.css");
- echo javascript_tag("lib/dojo/dojo.js");
- echo javascript_tag("lib/dojo/tt-rss-layer.js");
- ?>
+ foreach (["lib/dojo/dojo.js",
+ "lib/dojo/tt-rss-layer.js",
+ "js/common.js",
+ "js/utility.js"] as $jsfile) {
+
+ echo javascript_tag($jsfile);
+
+ } ?>
+
+ <?php if (theme_exists(Config::get(Config::LOCAL_OVERRIDE_STYLESHEET))) {
+ echo stylesheet_tag(get_theme_path(Config::get(Config::LOCAL_OVERRIDE_STYLESHEET)));
+ } ?>
+
<style type="text/css">
- span.ok { color : #009000; font-weight : bold; }
- span.err { color : #ff0000; font-weight : bold; }
+ @media (prefers-color-scheme: dark) {
+ body {
+ background : #303030;
+ }
+ }
+
+ body.css_loading * {
+ display : none;
+ }
</style>
+
+ <script type="text/javascript">
+ require({cache:{}});
+ </script>
</head>
- <body class="flat ttrss_utility">
+ <body class="flat ttrss_utility css_loading">
<script type="text/javascript">
- require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox', 'dijit/form/Form',
- 'dijit/form/Select','dijit/form/TextBox','dijit/form/ValidationTextBox'],function(parser, ready){
- ready(function() {
- parser.parse();
- });
- });
-
- function confirmOP() {
- return confirm("Update the database?");
+ const UtilityApp = {
+ init: function() {
+ require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox', 'dijit/form/Form',
+ 'dijit/form/Select','dijit/form/TextBox','dijit/form/ValidationTextBox'],function(parser, ready){
+ ready(function() {
+ parser.parse();
+ });
+ });
+ }
+ }
+
+ function confirmDbUpdate() {
+ return confirm(__("Proceed with update?"));
}
</script>
@@ -660,72 +684,66 @@ class Handler_Public extends Handler {
<?php
@$op = clean($_REQUEST["subop"] ?? "");
- $updater = new Db_Updater(Db::pdo(), Config::get(Config::DB_TYPE));
-
- if ($op == "performupdate") {
- if (Db_Updater::is_update_required()) {
-
- print "<h2>" . T_sprintf("Performing updates to version %d", Db_Updater::SCHEMA_VERSION) . "</h2>";
- for ($i = Config::get_schema_version(true) + 1; $i <= Db_Updater::SCHEMA_VERSION; $i++) {
- print "<ul>";
+ $migrations = Config::get_migrations();
- print "<li class='text-info'>" . T_sprintf("Updating to version %d", $i) . "</li>";
+ if ($op == "performupdate") {
+ if ($migrations->is_migration_needed()) {
+ ?>
- print "<li>";
- $result = $updater->update_to($i, true);
- print "</li>";
+ <h2><?= T_sprintf("Performing updates to version %d", Config::SCHEMA_VERSION) ?></h2>
- if (!$result) {
- print "</ul>";
+ <code><pre class="small pre-wrap"><?php
+ Debug::set_enabled(true);
+ Debug::set_loglevel(Debug::LOG_VERBOSE);
+ $result = $migrations->migrate();
+ Debug::set_loglevel(Debug::LOG_NORMAL);
+ Debug::set_enabled(false);
+ ?></pre></code>
- print_error("One of the updates failed. Either retry the process or perform updates manually.");
+ <?php if (!$result) { ?>
+ <?= format_error("One of migrations failed. Either retry the process or perform updates manually.") ?>
- print "<form method='POST'>
- <input type='hidden' name='subop' value='performupdate'>
- <button type='submit' dojoType='dijit.form.Button' class='alt-danger' onclick='return confirmOP()'>".__("Try again")."</button>
- <a href='index.php'>".__("Return to Tiny Tiny RSS")."</a>
- </form>";
+ <form method="post">
+ <?= \Controls\hidden_tag('subop', 'performupdate') ?>
+ <?= \Controls\submit_tag(__("Update"), ["onclick" => "return confirmDbUpdate()"]) ?>
+ </form>
+ <?php } else { ?>
+ <?= format_notice("Update successful.") ?>
- return;
- } else {
- print "<li class='text-success'>" . __("Completed.") . "</li>";
- print "</ul>";
- }
- }
+ <a href="index.php"><?= __("Return to Tiny Tiny RSS") ?></a>
+ <?php }
- print_notice("Your Tiny Tiny RSS database is now updated to the latest version.");
+ } else { ?>
- print "<a href='index.php'>".__("Return to Tiny Tiny RSS")."</a>";
+ <?= format_notice("Database is already up to date.") ?>
- } else {
- print_notice("Tiny Tiny RSS database is up to date.");
+ <a href="index.php"><?= __("Return to Tiny Tiny RSS") ?></a>
- print "<a href='index.php'>".__("Return to Tiny Tiny RSS")."</a>";
+ <?php
}
} else {
- if (Db_Updater::is_update_required()) {
+ if ($migrations->is_migration_needed()) {
- print "<h2>".T_sprintf("Tiny Tiny RSS database needs update to the latest version (%d to %d).",
- Config::get_schema_version(true), Db_Updater::SCHEMA_VERSION)."</h2>";
+ ?>
+ <h2><?= T_sprintf("Database schema needs update to the latest version (%d to %d).",
+ Config::get_schema_version(), Config::SCHEMA_VERSION) ?></h2>
- if (Config::get(Config::DB_TYPE) == "mysql") {
- print_error("<strong>READ THIS:</strong> Due to MySQL limitations, your database is not completely protected while updating. ".
- "Errors may put it in an inconsistent state requiring manual rollback. <strong>BACKUP YOUR DATABASE BEFORE CONTINUING.</strong>");
- } else {
- print_warning("Please backup your database before proceeding.");
- }
+ <?= format_warning("Please backup your database before proceeding.") ?>
- print "<form method='POST'>
- <input type='hidden' name='subop' value='performupdate'>
- <button type='submit' dojoType='dijit.form.Button' class='alt-danger' onclick='return confirmOP()'>".__("Perform updates")."</button>
- </form>";
+ <form method="post">
+ <?= \Controls\hidden_tag('subop', 'performupdate') ?>
+ <?= \Controls\submit_tag(__("Update"), ["onclick" => "return confirmDbUpdate()"]) ?>
+ </form>
- } else {
+ <?php
+ } else { ?>
+
+ <?= format_notice("Database is already up to date.") ?>
- print_notice("Tiny Tiny RSS database is up to date.");
+ <a href="index.php"><?= __("Return to Tiny Tiny RSS") ?></a>
- print "<a href='index.php'>".__("Return to Tiny Tiny RSS")."</a>";
+ <?php
}
}
?>
diff --git a/classes/opml.php b/classes/opml.php
index 1a223788f..f8e9f6728 100644
--- a/classes/opml.php
+++ b/classes/opml.php
@@ -151,7 +151,7 @@ class OPML extends Handler_Protected {
# export tt-rss settings
if ($include_settings) {
- $out .= "<outline text=\"tt-rss-prefs\" schema-version=\"".Db_Updater::SCHEMA_VERSION."\">";
+ $out .= "<outline text=\"tt-rss-prefs\" schema-version=\"".Config::SCHEMA_VERSION."\">";
$sth = $this->pdo->prepare("SELECT pref_name, value FROM ttrss_user_prefs2 WHERE
profile IS NULL AND owner_uid = ? ORDER BY pref_name");
@@ -166,7 +166,7 @@ class OPML extends Handler_Protected {
$out .= "</outline>";
- $out .= "<outline text=\"tt-rss-labels\" schema-version=\"".Db_Updater::SCHEMA_VERSION."\">";
+ $out .= "<outline text=\"tt-rss-labels\" schema-version=\"".Config::SCHEMA_VERSION."\">";
$sth = $this->pdo->prepare("SELECT * FROM ttrss_labels2 WHERE
owner_uid = ?");
@@ -183,7 +183,7 @@ class OPML extends Handler_Protected {
$out .= "</outline>";
- $out .= "<outline text=\"tt-rss-filters\" schema-version=\"".Db_Updater::SCHEMA_VERSION."\">";
+ $out .= "<outline text=\"tt-rss-filters\" schema-version=\"".Config::SCHEMA_VERSION."\">";
$sth = $this->pdo->prepare("SELECT * FROM ttrss_filters2
WHERE owner_uid = ? ORDER BY id");
diff --git a/classes/rpc.php b/classes/rpc.php
index 90c2c762a..054b711bc 100755
--- a/classes/rpc.php
+++ b/classes/rpc.php
@@ -181,7 +181,7 @@ class RPC extends Handler_Protected {
$client_scheme = parse_url($client_location, PHP_URL_SCHEME);
$server_scheme = parse_url(Config::get_self_url(), PHP_URL_SCHEME);
- if (Db_Updater::is_update_required()) {
+ if (Config::is_migration_needed()) {
$error = Errors::E_SCHEMA_MISMATCH;
} else if ($client_scheme != $server_scheme) {
$error = Errors::E_URL_SCHEME_MISMATCH;
diff --git a/classes/rssutils.php b/classes/rssutils.php
index 0d78e0ec7..9480c0b0b 100755
--- a/classes/rssutils.php
+++ b/classes/rssutils.php
@@ -55,7 +55,7 @@ class RSSUtils {
static function update_daemon_common($limit = null, $options = []) {
if (!$limit) $limit = Config::get(Config::DAEMON_FEED_LIMIT);
- if (Config::get_schema_version() != Db_Updater::SCHEMA_VERSION) {
+ if (Config::get_schema_version() != Config::SCHEMA_VERSION) {
die("Schema version is wrong, please upgrade the database.\n");
}
diff --git a/include/functions.php b/include/functions.php
index 4d11ea31f..5e75439cf 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -2,8 +2,8 @@
define('LABEL_BASE_INDEX', -1024);
define('PLUGIN_FEED_BASE_INDEX', -128);
- /** constant is @deprecated, use Db_Updater::SCHEMA_VERSION instead */
- define('SCHEMA_VERSION', Db_Updater::SCHEMA_VERSION);
+ /** constant is @deprecated, use Config::SCHEMA_VERSION instead */
+ define('SCHEMA_VERSION', Config::SCHEMA_VERSION);
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
libxml_disable_entity_loader(true);
diff --git a/include/sessions.php b/include/sessions.php
index 3a1a3b8cd..cda42f52b 100644
--- a/include/sessions.php
+++ b/include/sessions.php
@@ -122,17 +122,19 @@
return true;
}
- if (!\Config::get(\Config::SINGLE_USER_MODE)) {
- session_set_save_handler('\Sessions\ttrss_open',
- '\Sessions\ttrss_close', '\Sessions\ttrss_read',
- '\Sessions\ttrss_write', '\Sessions\ttrss_destroy',
- '\Sessions\ttrss_gc');
- register_shutdown_function('session_write_close');
- }
+ if (\Config::get_schema_version() >= 0) {
+ if (!\Config::get(\Config::SINGLE_USER_MODE)) {
+ session_set_save_handler('\Sessions\ttrss_open',
+ '\Sessions\ttrss_close', '\Sessions\ttrss_read',
+ '\Sessions\ttrss_write', '\Sessions\ttrss_destroy',
+ '\Sessions\ttrss_gc');
+ register_shutdown_function('session_write_close');
+ }
- if (!defined('NO_SESSION_AUTOSTART')) {
- if (isset($_COOKIE[session_name()])) {
- if (session_status() != PHP_SESSION_ACTIVE)
- session_start();
+ if (!defined('NO_SESSION_AUTOSTART')) {
+ if (isset($_COOKIE[session_name()])) {
+ if (session_status() != PHP_SESSION_ACTIVE)
+ session_start();
+ }
}
}
diff --git a/schema/ttrss_schema_mysql.sql b/schema/ttrss_schema_mysql.sql
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/schema/ttrss_schema_mysql.sql
diff --git a/schema/ttrss_schema_pgsql.sql b/schema/ttrss_schema_pgsql.sql
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/schema/ttrss_schema_pgsql.sql
diff --git a/update.php b/update.php
index d19c5f823..ad5704a7d 100755
--- a/update.php
+++ b/update.php
@@ -378,7 +378,7 @@
if (read_stdin() != 'yes')
exit;
} else {
- Debug::log("Proceeding to update without confirmation...");
+ Debug::log("Proceeding to update without confirmation.");
}
if (!isset($options["log-level"])) {
@@ -386,57 +386,11 @@
}
$migrations = Config::get_migrations();
-
- Debug::log("Migrating schema to version " . $migrations->get_max_version());
-
$migrations->migrate();
} else {
Debug::log("Database schema is already at latest version.");
}
-
- /*Debug::log("Checking for updates (" . Config::get(Config::DB_TYPE) . ")...");
-
- $updater = new Db_Updater(Db::pdo(), Config::get(Config::DB_TYPE));
-
- if (Db_Updater::is_update_required()) {
- Debug::log("Schema update required, version " . Config::get_schema_version(true) . " to " . Db_Updater::SCHEMA_VERSION);
-
- if (Config::get(Config::DB_TYPE) == "mysql")
- Debug::Log("READ THIS: Due to MySQL limitations, your database is not completely protected while updating.\n".
- "Errors may put it in an inconsistent state requiring manual rollback.\nBACKUP YOUR DATABASE BEFORE CONTINUING.");
- else
- Debug::log("WARNING: please backup your database before continuing.");
-
- if ($options["update-schema"] != "force-yes") {
- Debug::log("Type 'yes' to continue.");
-
- if (read_stdin() != 'yes')
- exit;
- } else {
- Debug::log("Proceeding to update without confirmation...");
- }
-
- Debug::log("Performing updates to version " . Db_Updater::SCHEMA_VERSION . "...");
-
- for ($i = Config::get_schema_version(true) + 1; $i <= Db_Updater::SCHEMA_VERSION; $i++) {
- Debug::log("* Updating to version $i...");
-
- $result = $updater->update_to($i, false);
-
- if ($result) {
- Debug::log("* Completed.");
- } else {
- Debug::log("One of the updates failed. Either retry the process or perform updates manually.");
- return;
- }
- }
-
- Debug::log("All done.");
- } else {
- Debug::log("Database schema is already at latest version.");
- } */
-
}
if (isset($options["gen-search-idx"])) {
diff --git a/update_daemon2.php b/update_daemon2.php
index 17bca48ee..8931813ff 100755
--- a/update_daemon2.php
+++ b/update_daemon2.php
@@ -189,7 +189,7 @@
"Maybe another daemon is already running.\n");
}
- if (Db_Updater::is_update_required()) {
+ if (Config::is_migration_needed()) {
die("Schema version is wrong, please upgrade the database.\n");
}