mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-23 08:04:54 +00:00
Add rollbacks in error cases
This commit is contained in:
parent
a67fe30408
commit
557d17ef5d
2 changed files with 62 additions and 55 deletions
|
@ -359,7 +359,7 @@ class Database {
|
||||||
// if no parent is specified, do nothing
|
// if no parent is specified, do nothing
|
||||||
$parent = null;
|
$parent = null;
|
||||||
} else {
|
} else {
|
||||||
// if a parent is specified, make sure it exists and belongs to the user; get its root (first-level) folder if it's a nested folder
|
// if a parent is specified, make sure it exists and belongs to the user
|
||||||
$p = $this->db->prepare(
|
$p = $this->db->prepare(
|
||||||
"WITH RECURSIVE folders(id) as (SELECT id from arsse_folders where owner is ? and id is ? union select arsse_folders.id from arsse_folders join folders on arsse_folders.parent=folders.id) ".
|
"WITH RECURSIVE folders(id) as (SELECT id from arsse_folders where owner is ? and id is ? union select arsse_folders.id from arsse_folders join folders on arsse_folders.parent=folders.id) ".
|
||||||
"SELECT id,(id not in (select id from folders)) as valid from arsse_folders where owner is ? and id is ?",
|
"SELECT id,(id not in (select id from folders)) as valid from arsse_folders where owner is ? and id is ?",
|
||||||
|
@ -372,7 +372,7 @@ class Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$data['parent'] = $parent;
|
$data['parent'] = $parent;
|
||||||
// check to make sure the target folder name/location would not create a duplicate (we must di this check because null is not distinct in SQL)
|
// check to make sure the target folder name/location would not create a duplicate (we must do this check because null is not distinct in SQL)
|
||||||
$existing = $this->db->prepare("SELECT id from arsse_folders where owner is ? and parent is ? and name is ?", "str", "int", "str")->run($user, $data['parent'], $data['name'])->getValue();
|
$existing = $this->db->prepare("SELECT id from arsse_folders where owner is ? and parent is ? and name is ?", "str", "int", "str")->run($user, $data['parent'], $data['name'])->getValue();
|
||||||
if(!is_null($existing) && $existing != $id) {
|
if(!is_null($existing) && $existing != $id) {
|
||||||
throw new Db\ExceptionInput("constraintViolation"); // FIXME: There needs to be a practical message here
|
throw new Db\ExceptionInput("constraintViolation"); // FIXME: There needs to be a practical message here
|
||||||
|
@ -395,23 +395,20 @@ class Database {
|
||||||
if(!$this->userExists($user)) {
|
if(!$this->userExists($user)) {
|
||||||
throw new User\Exception("doesNotExist", ["user" => $user, "action" => __FUNCTION__]);
|
throw new User\Exception("doesNotExist", ["user" => $user, "action" => __FUNCTION__]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->db->begin();
|
$this->db->begin();
|
||||||
|
try {
|
||||||
// If the feed doesn't already exist in the database then add it to the database
|
// If the feed doesn't already exist in the database then add it to the database
|
||||||
// after determining its validity with PicoFeed.
|
// after determining its validity with PicoFeed.
|
||||||
$qFeed = $this->db->prepare("SELECT id from arsse_feeds where url is ? and username is ? and password is ?", "str", "str", "str");
|
$feedID = $this->db->prepare("SELECT id from arsse_feeds where url is ? and username is ? and password is ?", "str", "str", "str")->run($url, $fetchUser, $fetchPassword)->getValue();
|
||||||
$feed = $qFeed->run($url, $fetchUser, $fetchPassword)->getValue();
|
if($feedID === null) {
|
||||||
if($feed === null) {
|
|
||||||
$feed = new Feed($url);
|
$feed = new Feed($url);
|
||||||
$feed->parse();
|
$feed->parse();
|
||||||
|
|
||||||
// Add the feed to the database and return its Id which will be used when adding
|
// Add the feed to the database and return its Id which will be used when adding
|
||||||
// its articles to the database.
|
// its articles to the database.
|
||||||
$feedID = $this->db->prepare(
|
$feedID = $this->db->prepare(
|
||||||
'INSERT INTO arsse_feeds(url,title,favicon,source,updated,modified,etag,username,password)
|
'INSERT INTO arsse_feeds(url,title,favicon,source,updated,modified,etag,username,password) values(?,?,?,?,?,?,?,?,?)',
|
||||||
values(?,?,?,?,?,?,?,?,?)',
|
'str', 'str', 'str', 'str', 'datetime', 'datetime', 'str', 'str', 'str'
|
||||||
'str', 'str', 'str', 'str', 'datetime', 'datetime', 'str', 'str', 'str')->run(
|
)->run(
|
||||||
$url,
|
$url,
|
||||||
$feed->data->title,
|
$feed->data->title,
|
||||||
// Grab the favicon for the feed; returns an empty string if it cannot find one.
|
// Grab the favicon for the feed; returns an empty string if it cannot find one.
|
||||||
|
@ -423,15 +420,17 @@ class Database {
|
||||||
$fetchUser,
|
$fetchUser,
|
||||||
$fetchPassword
|
$fetchPassword
|
||||||
)->lastId();
|
)->lastId();
|
||||||
|
|
||||||
// Add each of the articles to the database.
|
// Add each of the articles to the database.
|
||||||
foreach($feed->data->items as $i) {
|
foreach($feed->data->items as $i) {
|
||||||
$this->articleAdd($feedID, $i);
|
$this->articleAdd($feedID, $i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the feed to the user's subscriptions.
|
// Add the feed to the user's subscriptions.
|
||||||
$sub = $this->db->prepare('INSERT INTO arsse_subscriptions(owner,feed) values(?,?)', 'str', 'int')->run($user, $feedID)->lastId();
|
$sub = $this->db->prepare('INSERT INTO arsse_subscriptions(owner,feed) values(?,?)', 'str', 'int')->run($user, $feedID)->lastId();
|
||||||
|
} catch(\Throwable $e) {
|
||||||
|
$this->db->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
$this->db->commit();
|
$this->db->commit();
|
||||||
return $sub;
|
return $sub;
|
||||||
}
|
}
|
||||||
|
@ -443,10 +442,11 @@ class Database {
|
||||||
|
|
||||||
public function articleAdd(int $feedID, \PicoFeed\Parser\Item $article): int {
|
public function articleAdd(int $feedID, \PicoFeed\Parser\Item $article): int {
|
||||||
$this->db->begin();
|
$this->db->begin();
|
||||||
|
try {
|
||||||
$articleID = $this->db->prepare('INSERT INTO arsse_articles(feed,url,title,author,published,edited,guid,content,url_title_hash,url_content_hash,title_content_hash)
|
$articleID = $this->db->prepare(
|
||||||
values(?,?,?,?,?,?,?,?,?,?,?)',
|
'INSERT INTO arsse_articles(feed,url,title,author,published,edited,guid,content,url_title_hash,url_content_hash,title_content_hash) values(?,?,?,?,?,?,?,?,?,?,?)',
|
||||||
'int', 'str', 'str', 'str', 'datetime', 'datetime', 'str', 'str', 'str', 'str', 'str')->run(
|
'int', 'str', 'str', 'str', 'datetime', 'datetime', 'str', 'str', 'str', 'str', 'str'
|
||||||
|
)->run(
|
||||||
$feedID,
|
$feedID,
|
||||||
$article->url,
|
$article->url,
|
||||||
$article->title,
|
$article->title,
|
||||||
|
@ -459,24 +459,29 @@ class Database {
|
||||||
$article->urlContentHash,
|
$article->urlContentHash,
|
||||||
$article->titleContentHash
|
$article->titleContentHash
|
||||||
)->lastId();
|
)->lastId();
|
||||||
|
|
||||||
// If the article has categories add them into the categories database.
|
// If the article has categories add them into the categories database.
|
||||||
$this->categoriesAdd($articleID, $article);
|
$this->categoriesAdd($articleID, $article);
|
||||||
|
} catch(\Throwable $e) {
|
||||||
|
$this->db->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
$this->db->commit();
|
$this->db->commit();
|
||||||
return 1;
|
return $articleID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function categoriesAdd(int $articleID, \PicoFeed\Parser\Item $article): int {
|
public function categoriesAdd(int $articleID, \PicoFeed\Parser\Item $article): int {
|
||||||
$this->db->begin();
|
|
||||||
|
|
||||||
$categories = $article->getTag('category');
|
$categories = $article->getTag('category');
|
||||||
|
$this->db->begin();
|
||||||
|
try {
|
||||||
if(count($categories) > 0) {
|
if(count($categories) > 0) {
|
||||||
foreach($categories as $c) {
|
foreach($categories as $c) {
|
||||||
$this->db->prepare('INSERT INTO arsse_categories(article,name) values(?,?)', 'int', 'str')->run($articleID, $c);
|
$this->db->prepare('INSERT INTO arsse_categories(article,name) values(?,?)', 'int', 'str')->run($articleID, $c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch(\Throwable $e) {
|
||||||
|
$this->db->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
$this->db->commit();
|
$this->db->commit();
|
||||||
return count($categories);
|
return count($categories);
|
||||||
}
|
}
|
||||||
|
@ -547,13 +552,15 @@ class Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
if($update) {
|
if($update) {
|
||||||
$this->db->prepare('UPDATE arsse_articles SET url = ?, title = ?, author = ?, published = ?, edited = ?, modified = ?, guid = ?, content = ?, url_title_hash = ?, url_content_hash = ?, title_content_hash = ? WHERE id is ?', 'str', 'str', 'str', 'datetime', 'datetime', 'datetime', 'str', 'str', 'str', 'str', 'str', 'int')->run(
|
$this->db->prepare(
|
||||||
|
'UPDATE arsse_articles SET url = ?, title = ?, author = ?, published = ?, edited = ?, modified = CURRENT_TIMESTAMP, guid = ?, content = ?, url_title_hash = ?, url_content_hash = ?, title_content_hash = ? WHERE id is ?',
|
||||||
|
'str', 'str', 'str', 'datetime', 'datetime', 'str', 'str', 'str', 'str', 'str', 'int'
|
||||||
|
)->run(
|
||||||
$i->url,
|
$i->url,
|
||||||
$i->title,
|
$i->title,
|
||||||
$i->author,
|
$i->author,
|
||||||
$i->publishedDate,
|
$i->publishedDate,
|
||||||
$i->updatedDate,
|
$i->updatedDate,
|
||||||
time(),
|
|
||||||
$i->id,
|
$i->id,
|
||||||
$i->content,
|
$i->content,
|
||||||
$i->urlTitleHash,
|
$i->urlTitleHash,
|
||||||
|
|
|
@ -20,4 +20,4 @@ Data::$user->authorizationEnabled(false);
|
||||||
Data::$user->rightsSet($user, User\Driver::RIGHTS_GLOBAL_ADMIN);
|
Data::$user->rightsSet($user, User\Driver::RIGHTS_GLOBAL_ADMIN);
|
||||||
Data::$user->authorizationEnabled(true);
|
Data::$user->authorizationEnabled(true);
|
||||||
Data::$db->folderAdd($user, ['name' => 'ook']);
|
Data::$db->folderAdd($user, ['name' => 'ook']);
|
||||||
Data::$db->subscriptionAdd($user, "http://www.tbray.org/ongoing/ongoing.atom");
|
Data::$db->subscriptionAdd($user, "http://www.pcgamer.com/rss/");
|
Loading…
Reference in a new issue