-
Notifications
You must be signed in to change notification settings - Fork 345
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
daos: break daos depending on Database
The structure of DAOs is pretty convoluted: sqlite and pgsql items/sources/tags inherit from the corresponding mysql classes to facilitate code reuse. Additionally, the mysql classes inherited from mysql\database, which instantiated statements helper based on the database type. We move the statements initalization to each individual class to allow us break the dependency on database. Late static binding allows us to do this pretty conveniently while retaining the inheritance as code deduplication hack (to be fixed later).
- Loading branch information
Showing
12 changed files
with
63 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,10 +12,13 @@ | |
* @author Tobias Zeising <[email protected]> | ||
* @author Harald Lapp <[email protected]> | ||
*/ | ||
class Items extends Database { | ||
class Items { | ||
/** @var bool indicates whether last run has more results or not */ | ||
protected $hasMore = false; | ||
|
||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
|
||
/** | ||
* mark item as read | ||
* | ||
|
@@ -182,7 +185,7 @@ public function findAll($itemsInFeed, $sourceId) { | |
*/ | ||
public function updateLastSeen(array $itemIds) { | ||
\F3::get('db')->exec('UPDATE ' . \F3::get('db_prefix') . 'items SET lastseen = CURRENT_TIMESTAMP | ||
WHERE ' . $this->stmt->intRowMatches('id', $itemIds)); | ||
WHERE ' . static::$stmt::intRowMatches('id', $itemIds)); | ||
} | ||
|
||
/** | ||
|
@@ -198,7 +201,7 @@ public function cleanup(DateTime $date = null) { | |
SELECT id FROM ' . \F3::get('db_prefix') . 'sources)'); | ||
if ($date !== null) { | ||
\F3::get('db')->exec('DELETE FROM ' . \F3::get('db_prefix') . 'items | ||
WHERE ' . $this->stmt->isFalse('starred') . ' AND lastseen<:date', | ||
WHERE ' . static::$stmt::isFalse('starred') . ' AND lastseen<:date', | ||
[':date' => $date->format('Y-m-d') . ' 00:00:00'] | ||
); | ||
} | ||
|
@@ -213,17 +216,17 @@ public function cleanup(DateTime $date = null) { | |
*/ | ||
public function get($options = []) { | ||
$params = []; | ||
$where = [$this->stmt->bool(true)]; | ||
$where = [static::$stmt::bool(true)]; | ||
$order = 'DESC'; | ||
|
||
// only starred | ||
if (isset($options['type']) && $options['type'] === 'starred') { | ||
$where[] = $this->stmt->isTrue('starred'); | ||
$where[] = static::$stmt::isTrue('starred'); | ||
} | ||
|
||
// only unread | ||
elseif (isset($options['type']) && $options['type'] === 'unread') { | ||
$where[] = $this->stmt->isTrue('unread'); | ||
$where[] = static::$stmt::isTrue('unread'); | ||
if (\F3::get('unread_order') === 'asc') { | ||
$order = 'ASC'; | ||
} | ||
|
@@ -240,7 +243,7 @@ public function get($options = []) { | |
if (isset($options['tag']) && strlen($options['tag']) > 0) { | ||
$params[':tag'] = $options['tag']; | ||
$where[] = 'items.source=sources.id'; | ||
$where[] = $this->stmt->csvRowMatches('sources.tags', ':tag'); | ||
$where[] = static::$stmt::csvRowMatches('sources.tags', ':tag'); | ||
} | ||
// source filter | ||
elseif (isset($options['source']) && strlen($options['source']) > 0) { | ||
|
@@ -263,7 +266,7 @@ public function get($options = []) { | |
// with seek pagination. | ||
$options['offset'] = 0; | ||
|
||
$offset_from_datetime_sql = $this->stmt->datetime($options['fromDatetime']); | ||
$offset_from_datetime_sql = static::$stmt::datetime($options['fromDatetime']); | ||
$params[':offset_from_datetime'] = [ | ||
$offset_from_datetime_sql, \PDO::PARAM_STR | ||
]; | ||
|
@@ -294,7 +297,7 @@ public function get($options = []) { | |
&& count($options['extraIds']) > 0 | ||
// limit the query to a sensible max | ||
&& count($options['extraIds']) <= \F3::get('items_perpage')) { | ||
$extra_ids_stmt = $this->stmt->intRowMatches('items.id', $options['extraIds']); | ||
$extra_ids_stmt = static::$stmt::intRowMatches('items.id', $options['extraIds']); | ||
if ($extra_ids_stmt !== null) { | ||
$where_ids = $extra_ids_stmt; | ||
} | ||
|
@@ -346,7 +349,7 @@ public function get($options = []) { | |
$query = "$select $where_sql $order_sql LIMIT " . $options['items'] . ' OFFSET ' . $options['offset']; | ||
} | ||
|
||
return $this->stmt->ensureRowTypes(\F3::get('db')->exec($query, $params), [ | ||
return static::$stmt::ensureRowTypes(\F3::get('db')->exec($query, $params), [ | ||
'id' => \daos\PARAM_INT, | ||
'unread' => \daos\PARAM_BOOL, | ||
'starred' => \daos\PARAM_BOOL, | ||
|
@@ -380,8 +383,8 @@ public function sync($sinceId, DateTime $notBefore, DateTime $since, $howMany) { | |
items.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tags | ||
FROM ' . \F3::get('db_prefix') . 'items AS items, ' . \F3::get('db_prefix') . 'sources AS sources | ||
WHERE items.source=sources.id | ||
AND (' . $this->stmt->isTrue('unread') . | ||
' OR ' . $this->stmt->isTrue('starred') . | ||
AND (' . static::$stmt::isTrue('unread') . | ||
' OR ' . static::$stmt::isTrue('starred') . | ||
' OR datetime >= :notBefore | ||
) | ||
AND (items.id > :sinceId OR | ||
|
@@ -395,7 +398,7 @@ public function sync($sinceId, DateTime $notBefore, DateTime $since, $howMany) { | |
'since' => [$since->format(\DateTime::ATOM), \PDO::PARAM_STR] | ||
]; | ||
|
||
return $this->stmt->ensureRowTypes(\F3::get('db')->exec($query, $params), [ | ||
return static::$stmt::ensureRowTypes(\F3::get('db')->exec($query, $params), [ | ||
'id' => \daos\PARAM_INT, | ||
'unread' => \daos\PARAM_BOOL, | ||
'starred' => \daos\PARAM_BOOL, | ||
|
@@ -409,11 +412,11 @@ public function sync($sinceId, DateTime $notBefore, DateTime $since, $howMany) { | |
* @return int lowest id of interest | ||
*/ | ||
public function lowestIdOfInterest() { | ||
$lowest = $this->stmt->ensureRowTypes( | ||
$lowest = static::$stmt::ensureRowTypes( | ||
\F3::get('db')->exec( | ||
'SELECT id FROM ' . \F3::get('db_prefix') . 'items AS items | ||
WHERE ' . $this->stmt->isTrue('unread') . | ||
' OR ' . $this->stmt->isTrue('starred') . | ||
WHERE ' . static::$stmt::isTrue('unread') . | ||
' OR ' . static::$stmt::isTrue('starred') . | ||
' ORDER BY id LIMIT 1'), | ||
['id' => \daos\PARAM_INT] | ||
); | ||
|
@@ -430,7 +433,7 @@ public function lowestIdOfInterest() { | |
* @return int last id in db | ||
*/ | ||
public function lastId() { | ||
$lastId = $this->stmt->ensureRowTypes( | ||
$lastId = static::$stmt::ensureRowTypes( | ||
\F3::get('db')->exec( | ||
'SELECT id FROM ' . \F3::get('db_prefix') . 'items AS items | ||
ORDER BY id DESC LIMIT 1'), | ||
|
@@ -572,7 +575,7 @@ public function getLastIcon($sourceid) { | |
public function numberOfUnread() { | ||
$res = \F3::get('db')->exec('SELECT count(*) AS amount | ||
FROM ' . \F3::get('db_prefix') . 'items | ||
WHERE ' . $this->stmt->isTrue('unread')); | ||
WHERE ' . static::$stmt::isTrue('unread')); | ||
|
||
return $res[0]['amount']; | ||
} | ||
|
@@ -585,10 +588,10 @@ public function numberOfUnread() { | |
public function stats() { | ||
$res = \F3::get('db')->exec('SELECT | ||
COUNT(*) AS total, | ||
' . $this->stmt->sumBool('unread') . ' AS unread, | ||
' . $this->stmt->sumBool('starred') . ' AS starred | ||
' . static::$stmt::sumBool('unread') . ' AS unread, | ||
' . static::$stmt::sumBool('starred') . ' AS starred | ||
FROM ' . \F3::get('db_prefix') . 'items;'); | ||
$res = $this->stmt->ensureRowTypes($res, [ | ||
$res = static::$stmt::ensureRowTypes($res, [ | ||
'total' => \daos\PARAM_INT, | ||
'unread' => \daos\PARAM_INT, | ||
'starred' => \daos\PARAM_INT | ||
|
@@ -622,7 +625,7 @@ public function statuses(DateTime $since) { | |
FROM ' . \F3::get('db_prefix') . 'items | ||
WHERE ' . \F3::get('db_prefix') . 'items.updatetime > :since;', | ||
[':since' => [$since->format(DateTime::ATOM), \PDO::PARAM_STR]]); | ||
$res = $this->stmt->ensureRowTypes($res, [ | ||
$res = static::$stmt::ensureRowTypes($res, [ | ||
'id' => \daos\PARAM_INT, | ||
'unread' => \daos\PARAM_BOOL, | ||
'starred' => \daos\PARAM_BOOL | ||
|
@@ -652,12 +655,12 @@ public function bulkStatusUpdate(array $statuses) { | |
if ($status[$sk] == 'true') { | ||
$statusUpdate = [ | ||
'sk' => $sk, | ||
'sql' => $this->stmt->isTrue($sk) | ||
'sql' => static::$stmt::isTrue($sk) | ||
]; | ||
} elseif ($status[$sk] == 'false') { | ||
$statusUpdate = [ | ||
'sk' => $sk, | ||
'sql' => $this->stmt->isFalse($sk) | ||
'sql' => static::$stmt::isFalse($sk) | ||
]; | ||
} | ||
} | ||
|
@@ -712,7 +715,7 @@ public function bulkStatusUpdate(array $statuses) { | |
// statuses. | ||
\F3::get('db')->exec( | ||
'UPDATE ' . \F3::get('db_prefix') . 'items | ||
SET ' . $this->stmt->rowTouch('updatetime') . ' | ||
SET ' . static::$stmt::rowTouch('updatetime') . ' | ||
WHERE id = :id', [':id' => [$id, \PDO::PARAM_INT]]); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,10 @@ | |
* @license GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html) | ||
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Sources extends Database { | ||
class Sources { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
|
||
/** | ||
* add new source | ||
* | ||
|
@@ -22,9 +25,9 @@ class Sources extends Database { | |
* @return int new id | ||
*/ | ||
public function add($title, array $tags, $filter, $spout, array $params) { | ||
return $this->stmt->insert('INSERT INTO ' . \F3::get('db_prefix') . 'sources (title, tags, filter, spout, params) VALUES (:title, :tags, :filter, :spout, :params)', [ | ||
return static::$stmt::insert('INSERT INTO ' . \F3::get('db_prefix') . 'sources (title, tags, filter, spout, params) VALUES (:title, :tags, :filter, :spout, :params)', [ | ||
':title' => trim($title), | ||
':tags' => $this->stmt->csvRow($tags), | ||
':tags' => static::$stmt::csvRow($tags), | ||
':filter' => $filter, | ||
':spout' => $spout, | ||
':params' => htmlentities(json_encode($params)) | ||
|
@@ -46,7 +49,7 @@ public function add($title, array $tags, $filter, $spout, array $params) { | |
public function edit($id, $title, array $tags, $filter, $spout, array $params) { | ||
\F3::get('db')->exec('UPDATE ' . \F3::get('db_prefix') . 'sources SET title=:title, tags=:tags, filter=:filter, spout=:spout, params=:params WHERE id=:id', [ | ||
':title' => trim($title), | ||
':tags' => $this->stmt->csvRow($tags), | ||
':tags' => static::$stmt::csvRow($tags), | ||
':filter' => $filter, | ||
':spout' => $spout, | ||
':params' => htmlentities(json_encode($params)), | ||
|
@@ -140,15 +143,15 @@ public function get($id = null) { | |
// select source by id if specified or return all sources | ||
if (isset($id)) { | ||
$ret = \F3::get('db')->exec('SELECT id, title, tags, spout, params, filter, error FROM ' . \F3::get('db_prefix') . 'sources WHERE id=:id', [':id' => $id]); | ||
$ret = $this->stmt->ensureRowTypes($ret, ['id' => \daos\PARAM_INT]); | ||
$ret = static::$stmt::ensureRowTypes($ret, ['id' => \daos\PARAM_INT]); | ||
if (isset($ret[0])) { | ||
$ret = $ret[0]; | ||
} else { | ||
$ret = null; | ||
} | ||
} else { | ||
$ret = \F3::get('db')->exec('SELECT id, title, tags, spout, params, filter, error FROM ' . \F3::get('db_prefix') . 'sources ORDER BY error DESC, lower(title) ASC'); | ||
$ret = $this->stmt->ensureRowTypes($ret, [ | ||
$ret = static::$stmt::ensureRowTypes($ret, [ | ||
'id' => \daos\PARAM_INT, | ||
'tags' => \daos\PARAM_CSV | ||
]); | ||
|
@@ -167,11 +170,11 @@ public function getWithUnread() { | |
sources.id, sources.title, COUNT(items.id) AS unread | ||
FROM ' . \F3::get('db_prefix') . 'sources AS sources | ||
LEFT OUTER JOIN ' . \F3::get('db_prefix') . 'items AS items | ||
ON (items.source=sources.id AND ' . $this->stmt->isTrue('items.unread') . ') | ||
ON (items.source=sources.id AND ' . static::$stmt::isTrue('items.unread') . ') | ||
GROUP BY sources.id, sources.title | ||
ORDER BY lower(sources.title) ASC'); | ||
|
||
return $this->stmt->ensureRowTypes($ret, [ | ||
return static::$stmt::ensureRowTypes($ret, [ | ||
'id' => \daos\PARAM_INT, | ||
'unread' => \daos\PARAM_INT | ||
]); | ||
|
@@ -198,9 +201,9 @@ public function getWithIcon() { | |
WHERE items.id=icons.maxid AND items.source=icons.source | ||
) AS sourceicons | ||
ON sources.id=sourceicons.source | ||
ORDER BY ' . $this->stmt->nullFirst('sources.error', 'DESC') . ', lower(sources.title)'); | ||
ORDER BY ' . static::$stmt::nullFirst('sources.error', 'DESC') . ', lower(sources.title)'); | ||
|
||
return $this->stmt->ensureRowTypes($ret, [ | ||
return static::$stmt::ensureRowTypes($ret, [ | ||
'id' => \daos\PARAM_INT, | ||
'tags' => \daos\PARAM_CSV | ||
]); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,10 @@ | |
* @license GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html) | ||
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Tags extends Database { | ||
class Tags { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
|
||
/** | ||
* save given tag color | ||
* | ||
|
@@ -82,12 +85,12 @@ public function getWithUnread() { | |
FROM ' . \F3::get('db_prefix') . 'tags AS tags, | ||
' . \F3::get('db_prefix') . 'sources AS sources | ||
LEFT OUTER JOIN ' . \F3::get('db_prefix') . 'items AS items | ||
ON (items.source=sources.id AND ' . $this->stmt->isTrue('items.unread') . ') | ||
WHERE ' . $this->stmt->csvRowMatches('sources.tags', 'tags.tag') . ' | ||
ON (items.source=sources.id AND ' . static::$stmt::isTrue('items.unread') . ') | ||
WHERE ' . static::$stmt::csvRowMatches('sources.tags', 'tags.tag') . ' | ||
GROUP BY tags.tag, tags.color | ||
ORDER BY LOWER(tags.tag);'; | ||
|
||
return $this->stmt->ensureRowTypes(\F3::get('db')->exec($select), ['unread' => \daos\PARAM_INT]); | ||
return static::$stmt::ensureRowTypes(\F3::get('db')->exec($select), ['unread' => \daos\PARAM_INT]); | ||
} | ||
|
||
/** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,6 @@ | |
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Items extends \daos\mysql\Items { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,6 @@ | |
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Sources extends \daos\mysql\Sources { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,6 @@ | |
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Tags extends \daos\mysql\Tags { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
* @author Harald Lapp <[email protected]> | ||
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
// class Items extends Database { | ||
class Items extends \daos\mysql\Items { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,6 @@ | |
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Sources extends \daos\mysql\Sources { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,6 @@ | |
* @author Tobias Zeising <[email protected]> | ||
*/ | ||
class Tags extends \daos\mysql\Tags { | ||
/** @var class-string SQL helper */ | ||
protected static $stmt = Statements::class; | ||
} |