1+ <?php
2+ /**
3+ * @copyright Copyright (c) 2018 Robin Appelman <[email protected] > 4+ *
5+ * @license GNU AGPL version 3 or any later version
6+ *
7+ * This program is free software: you can redistribute it and/or modify
8+ * it under the terms of the GNU Affero General Public License as
9+ * published by the Free Software Foundation, either version 3 of the
10+ * License, or (at your option) any later version.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU Affero General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Affero General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ *
20+ */
21+
22+ namespace OCA \DAV \Paginate ;
23+
24+
25+ use OCP \AppFramework \Utility \ITimeFactory ;
26+ use OCP \DB \QueryBuilder \IQueryBuilder ;
27+ use OCP \IDBConnection ;
28+ use OCP \Security \ISecureRandom ;
29+
30+ class PaginateCache {
31+ const TTL = 3600 ;
32+
33+ /** @var IDBConnection */
34+ private $ database ;
35+ /** @var ISecureRandom */
36+ private $ random ;
37+ /** @var ITimeFactory */
38+ private $ timeFactory ;
39+
40+ public function __construct (
41+ IDBConnection $ database ,
42+ ISecureRandom $ random ,
43+ ITimeFactory $ timeFactory
44+ ) {
45+ $ this ->database = $ database ;
46+ $ this ->random = $ random ;
47+ $ this ->timeFactory = $ timeFactory ;
48+ }
49+
50+ public function store (string $ uri , \Iterator $ items ): array {
51+ $ token = $ this ->random ->generate (32 );
52+ $ now = $ this ->timeFactory ->getTime ();
53+
54+ $ query = $ this ->database ->getQueryBuilder ();
55+ $ query ->insert ('dav_page_cache ' )
56+ ->values ([
57+ 'url_hash ' => $ query ->createNamedParameter (md5 ($ uri ), IQueryBuilder::PARAM_STR ),
58+ 'token ' => $ query ->createNamedParameter ($ token , IQueryBuilder::PARAM_STR ),
59+ 'insert_time ' => $ query ->createNamedParameter ($ now , IQueryBuilder::PARAM_INT ),
60+ 'result_index ' => $ query ->createParameter ('index ' ),
61+ 'result_value ' => $ query ->createParameter ('value ' ),
62+ ]);
63+
64+ $ count = 0 ;
65+ foreach ($ items as $ item ) {
66+ $ value = json_encode ($ item );
67+ $ query ->setParameter ('index ' , $ count , IQueryBuilder::PARAM_INT );
68+ $ query ->setParameter ('value ' , $ value );
69+ $ query ->execute ();
70+ $ count ++;
71+ }
72+
73+ return [$ token , $ count ];
74+ }
75+
76+ /**
77+ * @param string $url
78+ * @param string $token
79+ * @param int $offset
80+ * @param int $count
81+ * @return array|\Traversable
82+ */
83+ public function get (string $ url , string $ token , int $ offset , int $ count ) {
84+ $ query = $ this ->database ->getQueryBuilder ();
85+ $ query ->select (['result_value ' ])
86+ ->from ('dav_page_cache ' )
87+ ->where ($ query ->expr ()->eq ('token ' , $ query ->createNamedParameter ($ token )))
88+ ->andWhere ($ query ->expr ()->eq ('url_hash ' , $ query ->createNamedParameter (md5 ($ url ))))
89+ ->andWhere ($ query ->expr ()->gte ('result_index ' , $ query ->createNamedParameter ($ offset , IQueryBuilder::PARAM_INT )))
90+ ->andWhere ($ query ->expr ()->lt ('result_index ' , $ query ->createNamedParameter ($ offset + $ count , IQueryBuilder::PARAM_INT )));
91+
92+ $ result = $ query ->execute ();
93+ return array_map (function (string $ entry ) {
94+ return json_decode ($ entry , true );
95+ }, $ result ->fetchAll (\PDO ::FETCH_COLUMN ));
96+ }
97+
98+ public function cleanup () {
99+ $ now = $ this ->timeFactory ->getTime ();
100+
101+ $ query = $ this ->database ->getQueryBuilder ();
102+ $ query ->delete ('dav_page_cache ' )
103+ ->where ($ query ->expr ()->lt ('insert_time ' , $ query ->createNamedParameter ($ now - self ::TTL )));
104+ $ query ->execute ();
105+ }
106+
107+ public function clear () {
108+ $ query = $ this ->database ->getQueryBuilder ();
109+ $ query ->delete ('dav_page_cache ' );
110+ $ query ->execute ();
111+ }
112+ }
0 commit comments