aboutsummaryrefslogtreecommitdiff
path: root/app/Models
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2019-09-15 21:36:53 +0200
committerGravatar GitHub <noreply@github.com> 2019-09-15 21:36:53 +0200
commitc76a318193cda63064625b2d92c719b7150d7d64 (patch)
treebaf053cea2cccb8fe7472e65a598d6fa60794e8d /app/Models
parentacec70fdbc680cdf035e4cad4942ca9638118900 (diff)
CLI to export/import any database to/from SQLite (#2496)
* CLI to export/import any database to/from SQLite Require PHP 5.5+ https://github.com/FreshRSS/FreshRSS/pull/2495 * Travis * Execution rights * Fix wrong static fields * Fix MySQL bad default buffering https://stackoverflow.com/questions/6895098/pdo-mysql-memory-consumption-with-large-result-set/6935271#6935271 https://php.net/manual/ref.pdo-mysql * Fix count on progression * Avoid static DB information To ease working with two DBs at the same time * Less static, simplify Needs some testing * Small corrections * Special case for SQLite to SQLite * Modify special case for SQLite * Remove special case for SQLite More uniform logic for the 3 databases. Fix wrong DROP TABLE for SQLite. * Drop indexes * Revert "Drop indexes" This reverts commit f28d2bae0935745c1c74ea38f2ee083f3fd4bf9d. * Fix deletion * Fix classic export * Update cli/README.md Co-Authored-By: Marien Fressinaud <dev@marienfressinaud.fr> * Addressing part of review * Remove goto :cry: * Travis * Comment for SQLite case * Fix missing fields when inserting
Diffstat (limited to 'app/Models')
-rw-r--r--app/Models/CategoryDAO.php14
-rw-r--r--app/Models/DatabaseDAO.php170
-rw-r--r--app/Models/EntryDAO.php32
-rw-r--r--app/Models/EntryDAOPGSQL.php4
-rw-r--r--app/Models/EntryDAOSQLite.php8
-rw-r--r--app/Models/Factory.php4
-rw-r--r--app/Models/FeedDAO.php22
-rw-r--r--app/Models/TagDAO.php21
-rw-r--r--app/Models/UserDAO.php71
9 files changed, 300 insertions, 46 deletions
diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php
index 6535adae7..b0fcb5033 100644
--- a/app/Models/CategoryDAO.php
+++ b/app/Models/CategoryDAO.php
@@ -77,6 +77,15 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo implements FreshRSS_Searchable
}
}
+ public function selectAll() {
+ $sql = 'SELECT id, name FROM `' . $this->prefix . 'category`';
+ $stm = $this->bd->prepare($sql);
+ $stm->execute();
+ while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
+ yield $row;
+ }
+ }
+
public function searchById($id) {
$sql = 'SELECT * FROM `' . $this->prefix . 'category` WHERE id=?';
$stm = $this->bd->prepare($sql);
@@ -96,6 +105,9 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo implements FreshRSS_Searchable
public function searchByName($name) {
$sql = 'SELECT * FROM `' . $this->prefix . 'category` WHERE name=?';
$stm = $this->bd->prepare($sql);
+ if ($stm == false) {
+ return false;
+ }
$values = array($name);
@@ -156,7 +168,7 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo implements FreshRSS_Searchable
$cat->_id(self::DEFAULTCATEGORYID);
$sql = 'INSERT INTO `' . $this->prefix . 'category`(id, name) VALUES(?, ?)';
- if (parent::$sharedDbType === 'pgsql') {
+ if ($this->bd->dbType() === 'pgsql') {
//Force call to nextval()
$sql .= ' RETURNING nextval(\'"' . $this->prefix . 'category_id_seq"\');';
}
diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php
index b331eccc3..ec84da664 100644
--- a/app/Models/DatabaseDAO.php
+++ b/app/Models/DatabaseDAO.php
@@ -144,8 +144,7 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
public function ensureCaseInsensitiveGuids() {
$ok = true;
- $db = FreshRSS_Context::$system_conf->db;
- if ($db['type'] === 'mysql') {
+ if ($this->bd->dbType() === 'mysql') {
include_once(APP_PATH . '/SQL/install.sql.mysql.php');
if (defined('SQL_UPDATE_GUID_LATIN1_BIN')) { //FreshRSS 1.12
try {
@@ -154,7 +153,7 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
$ok = $stm->execute();
} catch (Exception $e) {
$ok = false;
- Minz_Log::error('FreshRSS_DatabaseDAO::ensureCaseInsensitiveGuids error: ' . $e->getMessage());
+ Minz_Log::error(__METHOD__ . ' error: ' . $e->getMessage());
}
}
}
@@ -164,4 +163,169 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
public function minorDbMaintenance() {
$this->ensureCaseInsensitiveGuids();
}
+
+ private static function stdError($error) {
+ if (defined('STDERR')) {
+ fwrite(STDERR, $error . "\n");
+ }
+ Minz_Log::error($error);
+ return false;
+ }
+
+ const SQLITE_EXPORT = 1;
+ const SQLITE_IMPORT = 2;
+
+ public function dbCopy($filename, $mode, $clearFirst = false) {
+ $error = '';
+
+ $userDAO = FreshRSS_Factory::createUserDao();
+ $catDAO = FreshRSS_Factory::createCategoryDao();
+ $feedDAO = FreshRSS_Factory::createFeedDao();
+ $entryDAO = FreshRSS_Factory::createEntryDao();
+ $tagDAO = FreshRSS_Factory::createTagDao();
+
+ switch ($mode) {
+ case self::SQLITE_EXPORT:
+ if (@filesize($filename) > 0) {
+ $error = 'Error: SQLite export file already exists: ' . $filename;
+ }
+ break;
+ case self::SQLITE_IMPORT:
+ if (!is_readable($filename)) {
+ $error = 'Error: SQLite import file is not readable: ' . $filename;
+ } elseif ($clearFirst) {
+ $userDAO->deleteUser();
+ if ($this->bd->dbType() === 'sqlite') {
+ //We cannot just delete the .sqlite file otherwise PDO gets buggy.
+ //SQLite is the only one with database-level optimization, instead of at table level.
+ $this->optimize();
+ }
+ } else {
+ $nbEntries = $entryDAO->countUnreadRead();
+ if (!empty($nbEntries['all'])) {
+ $error = 'Error: Destination database already contains some entries!';
+ }
+ }
+ break;
+ default:
+ $error = 'Invalid copy mode!';
+ break;
+ }
+ if ($error != '') {
+ return self::stdError($error);
+ }
+
+ $sqlite = null;
+
+ try {
+ $sqlite = new MinzPDOSQLite('sqlite:' . $filename);
+ $sqlite->exec('PRAGMA foreign_keys = ON;');
+ } catch (Exception $e) {
+ $error = 'Error while initialising SQLite copy: ' . $e->getMessage();
+ return self::stdError($error);
+ }
+
+ Minz_ModelPdo::clean();
+ $userDAOSQLite = new FreshRSS_UserDAO('', '', $sqlite);
+ $categoryDAOSQLite = new FreshRSS_CategoryDAO('', '', $sqlite);
+ $feedDAOSQLite = new FreshRSS_FeedDAOSQLite('', '', $sqlite);
+ $entryDAOSQLite = new FreshRSS_EntryDAOSQLite('', '', $sqlite);
+ $tagDAOSQLite = new FreshRSS_TagDAOSQLite('', '', $sqlite);
+
+ switch ($mode) {
+ case self::SQLITE_EXPORT:
+ $userFrom = $userDAO; $userTo = $userDAOSQLite;
+ $catFrom = $catDAO; $catTo = $categoryDAOSQLite;
+ $feedFrom = $feedDAO; $feedTo = $feedDAOSQLite;
+ $entryFrom = $entryDAO; $entryTo = $entryDAOSQLite;
+ $tagFrom = $tagDAO; $tagTo = $tagDAOSQLite;
+ break;
+ case self::SQLITE_IMPORT:
+ $userFrom = $userDAOSQLite; $userTo = $userDAO;
+ $catFrom = $categoryDAOSQLite; $catTo = $catDAO;
+ $feedFrom = $feedDAOSQLite; $feedTo = $feedDAO;
+ $entryFrom = $entryDAOSQLite; $entryTo = $entryDAO;
+ $tagFrom = $tagDAOSQLite; $tagTo = $tagDAO;
+ break;
+ }
+
+ $idMaps = [];
+
+ if (defined('STDERR')) {
+ fwrite(STDERR, "Start SQL copy…\n");
+ }
+
+ $userTo->createUser();
+
+ $catTo->beginTransaction();
+ foreach ($catFrom->selectAll() as $category) {
+ $cat = $catTo->searchByName($category['name']); //Useful for the default category
+ if ($cat != null) {
+ $catId = $cat->id();
+ } else {
+ $catId = $catTo->addCategory($category);
+ if ($catId == false) {
+ $error = 'Error during SQLite copy of categories!';
+ return self::stdError($error);
+ }
+ }
+ $idMaps['c' . $category['id']] = $catId;
+ }
+ foreach ($feedFrom->selectAll() as $feed) {
+ $feed['category'] = empty($idMaps['c' . $feed['category']]) ? FreshRSS_CategoryDAO::DEFAULTCATEGORYID : $idMaps['c' . $feed['category']];
+ $feedId = $feedTo->addFeed($feed);
+ if ($feedId == false) {
+ $error = 'Error during SQLite copy of feeds!';
+ return self::stdError($error);
+ }
+ $idMaps['f' . $feed['id']] = $feedId;
+ }
+ $catTo->commit();
+
+ $nbEntries = $entryFrom->count();
+ $n = 0;
+ $entryTo->beginTransaction();
+ foreach ($entryFrom->selectAll() as $entry) {
+ $n++;
+ if (!empty($idMaps['f' . $entry['id_feed']])) {
+ $entry['id_feed'] = $idMaps['f' . $entry['id_feed']];
+ if (!$entryTo->addEntry($entry, false)) {
+ $error = 'Error during SQLite copy of entries!';
+ return self::stdError($error);
+ }
+ }
+ if ($n % 100 === 1 && defined('STDERR')) { //Display progression
+ fwrite(STDERR, "\033[0G" . $n . '/' . $nbEntries);
+ }
+ }
+ if (defined('STDERR')) {
+ fwrite(STDERR, "\033[0G" . $n . '/' . $nbEntries . "\n");
+ }
+ $entryTo->commit();
+ $feedTo->updateCachedValues();
+
+ $idMaps = [];
+
+ $tagTo->beginTransaction();
+ foreach ($tagFrom->selectAll() as $tag) {
+ $tagId = $tagTo->addTag($tag);
+ if ($tagId == false) {
+ $error = 'Error during SQLite copy of tags!';
+ return self::stdError($error);
+ }
+ $idMaps['t' . $tag['id']] = $tagId;
+ }
+ foreach ($tagFrom->selectEntryTag() as $entryTag) {
+ if (!empty($idMaps['t' . $entryTag['id_tag']])) {
+ $entryTag['id_tag'] = $idMaps['t' . $entryTag['id_tag']];
+ if (!$tagTo->tagEntry($entryTag['id_tag'], $entryTag['id_entry'])) {
+ $error = 'Error during SQLite copy of entry-tags!';
+ return self::stdError($error);
+ }
+ }
+ }
+ $tagTo->commit();
+
+ return true;
+ }
}
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index 1b2786a6a..b13c83d67 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -3,11 +3,11 @@
class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
public function isCompressed() {
- return parent::$sharedDbType === 'mysql';
+ return true;
}
public function hasNativeHex() {
- return parent::$sharedDbType !== 'sqlite';
+ return true;
}
public function sqlHexDecode($x) {
@@ -64,7 +64,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
}
$this->triedUpdateToUtf8mb4 = true;
$db = FreshRSS_Context::$system_conf->db;
- if ($db['type'] === 'mysql') {
+ if ($this->bd->dbType() === 'mysql') {
include_once(APP_PATH . '/SQL/install.sql.mysql.php');
if (defined('SQL_UPDATE_UTF8MB4')) {
Minz_Log::warning('Updating MySQL to UTF8MB4...'); //v1.5.0
@@ -98,8 +98,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$this->bd->commit();
}
try {
- $db = FreshRSS_Context::$system_conf->db;
- require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
+ require_once(APP_PATH . '/SQL/install.sql.' . $this->bd->dbType() . '.php');
Minz_Log::warning('SQL CREATE TABLE entrytmp...');
if (defined('SQL_CREATE_TABLE_ENTRYTMP')) {
$sql = sprintf(SQL_CREATE_TABLE_ENTRYTMP, $this->prefix);
@@ -152,9 +151,9 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
private $addEntryPrepared = null;
- public function addEntry($valuesTmp) {
+ public function addEntry($valuesTmp, $useTmpTable = true) {
if ($this->addEntryPrepared == null) {
- $sql = 'INSERT INTO `' . $this->prefix . 'entrytmp` (id, guid, title, author, '
+ $sql = 'INSERT INTO `' . $this->prefix . ($useTmpTable ? 'entrytmp' : 'entry') . '` (id, guid, title, author, '
. ($this->isCompressed() ? 'content_bin' : 'content')
. ', link, date, `lastSeen`, hash, is_read, is_favorite, id_feed, tags) '
. 'VALUES(:id, :guid, :title, :author, '
@@ -178,7 +177,9 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$valuesTmp['link'] = safe_ascii($valuesTmp['link']);
$this->addEntryPrepared->bindParam(':link', $valuesTmp['link']);
$this->addEntryPrepared->bindParam(':date', $valuesTmp['date'], PDO::PARAM_INT);
- $valuesTmp['lastSeen'] = time();
+ if (empty($valuesTmp['lastSeen'])) {
+ $valuesTmp['lastSeen'] = time();
+ }
$this->addEntryPrepared->bindParam(':last_seen', $valuesTmp['lastSeen'], PDO::PARAM_INT);
$valuesTmp['is_read'] = $valuesTmp['is_read'] ? 1 : 0;
$this->addEntryPrepared->bindParam(':is_read', $valuesTmp['is_read'], PDO::PARAM_INT);
@@ -637,6 +638,18 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
}
}
+ public function selectAll() {
+ $sql = 'SELECT id, guid, title, author, '
+ . ($this->isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
+ . ', link, date, `lastSeen`, ' . $this->sqlHexEncode('hash') . ' AS hash, is_read, is_favorite, id_feed, tags '
+ . 'FROM `' . $this->prefix . 'entry`';
+ $stm = $this->bd->prepare($sql);
+ $stm->execute();
+ while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
+ yield $row;
+ }
+ }
+
public function searchByGuid($id_feed, $guid) {
// un guid est unique pour un flux donné
$sql = 'SELECT id, guid, title, author, '
@@ -991,6 +1004,9 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE f.priority > 0'
. ' UNION SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE f.priority > 0 AND e.is_read=0';
$stm = $this->bd->prepare($sql);
+ if ($stm == false) {
+ return false;
+ }
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
rsort($res);
diff --git a/app/Models/EntryDAOPGSQL.php b/app/Models/EntryDAOPGSQL.php
index e571e457f..e90aa8332 100644
--- a/app/Models/EntryDAOPGSQL.php
+++ b/app/Models/EntryDAOPGSQL.php
@@ -2,6 +2,10 @@
class FreshRSS_EntryDAOPGSQL extends FreshRSS_EntryDAOSQLite {
+ public function hasNativeHex() {
+ return true;
+ }
+
public function sqlHexDecode($x) {
return 'decode(' . $x . ", 'hex')";
}
diff --git a/app/Models/EntryDAOSQLite.php b/app/Models/EntryDAOSQLite.php
index f8cd14fe6..f53685e35 100644
--- a/app/Models/EntryDAOSQLite.php
+++ b/app/Models/EntryDAOSQLite.php
@@ -2,6 +2,14 @@
class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
+ public function isCompressed() {
+ return false;
+ }
+
+ public function hasNativeHex() {
+ return false;
+ }
+
public function sqlHexDecode($x) {
return $x;
}
diff --git a/app/Models/Factory.php b/app/Models/Factory.php
index 1accb491c..6f2ca2217 100644
--- a/app/Models/Factory.php
+++ b/app/Models/Factory.php
@@ -2,6 +2,10 @@
class FreshRSS_Factory {
+ public static function createUserDao($username = null) {
+ return new FreshRSS_UserDAO($username);
+ }
+
public static function createCategoryDao($username = null) {
return new FreshRSS_CategoryDAO($username);
}
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index c9c9f6301..1dad4a834 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -39,6 +39,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
description,
`lastUpdate`,
priority,
+ `pathEntries`,
`httpAuth`,
error,
keep_history,
@@ -46,11 +47,14 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
attributes
)
VALUES
- (?, ?, ?, ?, ?, ?, 10, ?, 0, ?, ?, ?)';
+ (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
$stm = $this->bd->prepare($sql);
$valuesTmp['url'] = safe_ascii($valuesTmp['url']);
$valuesTmp['website'] = safe_ascii($valuesTmp['website']);
+ if (!isset($valuesTmp['pathEntries'])) {
+ $valuesTmp['pathEntries'] = '';
+ }
$values = array(
substr($valuesTmp['url'], 0, 511),
@@ -59,8 +63,11 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
substr($valuesTmp['website'], 0, 255),
mb_strcut($valuesTmp['description'], 0, 1023, 'UTF-8'),
$valuesTmp['lastUpdate'],
+ isset($valuesTmp['priority']) ? intval($valuesTmp['priority']) : FreshRSS_Feed::PRIORITY_MAIN_STREAM,
+ mb_strcut($valuesTmp['pathEntries'], 0, 511, 'UTF-8'),
base64_encode($valuesTmp['httpAuth']),
- FreshRSS_Feed::KEEP_HISTORY_DEFAULT,
+ isset($valuesTmp['error']) ? intval($valuesTmp['error']) : 0,
+ isset($valuesTmp['keep_history']) ? intval($valuesTmp['keep_history']) : FreshRSS_Feed::KEEP_HISTORY_DEFAULT,
isset($valuesTmp['ttl']) ? intval($valuesTmp['ttl']) : FreshRSS_Feed::TTL_DEFAULT,
isset($valuesTmp['attributes']) ? json_encode($valuesTmp['attributes']) : '',
);
@@ -238,6 +245,17 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
}
}
+ public function selectAll() {
+ $sql = 'SELECT id, url, category, name, website, description, `lastUpdate`, priority, '
+ . '`pathEntries`, `httpAuth`, error, keep_history, ttl, attributes '
+ . 'FROM `' . $this->prefix . 'feed`';
+ $stm = $this->bd->prepare($sql);
+ $stm->execute();
+ while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
+ yield $row;
+ }
+ }
+
public function searchById($id) {
$sql = 'SELECT * FROM `' . $this->prefix . 'feed` WHERE id=?';
$stm = $this->bd->prepare($sql);
diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php
index 297d24c96..11807fc32 100644
--- a/app/Models/TagDAO.php
+++ b/app/Models/TagDAO.php
@@ -13,8 +13,7 @@ class FreshRSS_TagDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$this->bd->commit();
}
try {
- $db = FreshRSS_Context::$system_conf->db;
- require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
+ require_once(APP_PATH . '/SQL/install.sql.' . $this->bd->dbType() . '.php');
Minz_Log::warning('SQL ALTER GUID case sensitivity...');
$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
@@ -139,6 +138,24 @@ class FreshRSS_TagDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
}
}
+ public function selectAll() {
+ $sql = 'SELECT id, name, attributes FROM `' . $this->prefix . 'tag`';
+ $stm = $this->bd->prepare($sql);
+ $stm->execute();
+ while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
+ yield $row;
+ }
+ }
+
+ public function selectEntryTag() {
+ $sql = 'SELECT id_tag, id_entry FROM `' . $this->prefix . 'entrytag`';
+ $stm = $this->bd->prepare($sql);
+ $stm->execute();
+ while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
+ yield $row;
+ }
+ }
+
public function searchById($id) {
$sql = 'SELECT * FROM `' . $this->prefix . 'tag` WHERE id=?';
$stm = $this->bd->prepare($sql);
diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php
index 0cf163bae..6292cc09f 100644
--- a/app/Models/UserDAO.php
+++ b/app/Models/UserDAO.php
@@ -1,21 +1,19 @@
<?php
class FreshRSS_UserDAO extends Minz_ModelPdo {
- public function createUser($username, $new_user_language, $insertDefaultFeeds = true) {
- $db = FreshRSS_Context::$system_conf->db;
- require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
-
- $userPDO = new Minz_ModelPdo($username);
+ public function createUser($new_user_language = null, $insertDefaultFeeds = false) {
+ require_once(APP_PATH . '/SQL/install.sql.' . $this->bd->dbType() . '.php');
$currentLanguage = Minz_Translate::language();
try {
- Minz_Translate::reset($new_user_language);
+ if ($new_user_language != null) {
+ Minz_Translate::reset($new_user_language);
+ }
$ok = false;
- $bd_prefix_user = $db['prefix'] . $username . '_';
if (defined('SQL_CREATE_TABLES')) { //E.g. MySQL
- $sql = sprintf(SQL_CREATE_TABLES . SQL_CREATE_TABLE_ENTRYTMP . SQL_CREATE_TABLE_TAGS, $bd_prefix_user, _t('gen.short.default_category'));
- $stm = $userPDO->bd->prepare($sql);
+ $sql = sprintf(SQL_CREATE_TABLES . SQL_CREATE_TABLE_ENTRYTMP . SQL_CREATE_TABLE_TAGS, $this->prefix, _t('gen.short.default_category'));
+ $stm = $this->bd->prepare($sql);
$ok = $stm && $stm->execute();
} else { //E.g. SQLite
global $SQL_CREATE_TABLES, $SQL_CREATE_TABLE_ENTRYTMP, $SQL_CREATE_TABLE_TAGS;
@@ -23,8 +21,8 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
$instructions = array_merge($SQL_CREATE_TABLES, $SQL_CREATE_TABLE_ENTRYTMP, $SQL_CREATE_TABLE_TAGS);
$ok = !empty($instructions);
foreach ($instructions as $instruction) {
- $sql = sprintf($instruction, $bd_prefix_user, _t('gen.short.default_category'));
- $stm = $userPDO->bd->prepare($sql);
+ $sql = sprintf($instruction, $this->prefix, _t('gen.short.default_category'));
+ $stm = $this->bd->prepare($sql);
$ok &= ($stm && $stm->execute());
}
}
@@ -32,8 +30,8 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
if ($ok && $insertDefaultFeeds) {
$default_feeds = FreshRSS_Context::$system_conf->default_feeds;
foreach ($default_feeds as $feed) {
- $sql = sprintf(SQL_INSERT_FEED, $bd_prefix_user);
- $stm = $userPDO->bd->prepare($sql);
+ $sql = sprintf(SQL_INSERT_FEED, $this->prefix);
+ $stm = $this->bd->prepare($sql);
$parameters = array(
':url' => $feed['url'],
':name' => $feed['name'],
@@ -44,7 +42,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
}
}
} catch (Exception $e) {
- Minz_Log::error('Error while creating user: ' . $e->getMessage());
+ Minz_Log::error('Error while creating database for user: ' . $e->getMessage());
}
Minz_Translate::reset($currentLanguage);
@@ -53,30 +51,43 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
return true;
} else {
$info = empty($stm) ? array(2 => 'syntax error') : $stm->errorInfo();
- Minz_Log::error('SQL error: ' . $info[2]);
+ Minz_Log::error(__METHOD__ . ' error: ' . $info[2]);
return false;
}
}
- public function deleteUser($username) {
- $db = FreshRSS_Context::$system_conf->db;
- require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
+ public function deleteUser() {
+ if (defined('STDERR')) {
+ fwrite(STDERR, 'Deleting SQL data for user “' . $this->current_user . "”…\n");
+ }
- if ($db['type'] === 'sqlite') {
- return unlink(USERS_PATH . '/' . $username . '/db.sqlite');
- } else {
- $userPDO = new Minz_ModelPdo($username);
+ require_once(APP_PATH . '/SQL/install.sql.' . $this->bd->dbType() . '.php');
- $sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
- $stm = $userPDO->bd->prepare($sql);
- if ($stm && $stm->execute()) {
- return true;
- } else {
- $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
- Minz_Log::error('SQL error : ' . $info[2]);
- return false;
+ $ok = false;
+ if (defined('SQL_DROP_TABLES')) { //E.g. MySQL
+ $sql = sprintf(SQL_DROP_TABLES, $this->prefix);
+ $stm = $this->bd->prepare($sql);
+ $ok = $stm && $stm->execute();
+ } else { //E.g. SQLite
+ global $SQL_DROP_TABLES;
+ if (is_array($SQL_DROP_TABLES)) {
+ $instructions = $SQL_DROP_TABLES;
+ $ok = !empty($instructions);
+ foreach ($instructions as $instruction) {
+ $sql = sprintf($instruction, $this->prefix);
+ $stm = $this->bd->prepare($sql);
+ $ok &= ($stm && $stm->execute());
+ }
}
}
+
+ if ($ok) {
+ return true;
+ } else {
+ $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
+ Minz_Log::error(__METHOD__ . ' error: ' . $info[2]);
+ return false;
+ }
}
public static function exists($username) {