Passed
Push — master ( dafac1...9ad278 )
by Dispositif
08:36
created

DbAdapter   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 322
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 17
Bugs 0 Features 0
Metric Value
eloc 120
dl 0
loc 322
ccs 0
cts 94
cp 0
rs 10
c 17
b 0
f 0
wmc 23

11 Methods

Rating   Name   Duplication   Size   Complexity  
A insertPageOuvrages() 0 14 2
A getAllRowsToEdit() 0 43 3
A getNewRaw() 0 17 2
A skipArticle() 0 15 2
A sendCompletedData() 0 15 2
A __construct() 0 7 1
A getMonitor() 0 26 2
A skipRow() 0 15 2
A updateMonitor() 0 19 3
A setLabel() 0 15 2
A sendEditedData() 0 15 2
1
<?php
2
/**
3
 * This file is part of dispositif/wikibot application
4
 * 2019 : Philippe M. <[email protected]>
5
 * For the full copyright and MIT license information, please view the LICENSE file.
6
 */
7
8
declare(strict_types=1);
9
10
namespace App\Infrastructure;
11
12
use App\Application\QueueInterface;
13
use DateInterval;
14
use DateTime;
15
use Exception;
16
use Simplon\Mysql\Mysql;
17
use Simplon\Mysql\MysqlException;
18
use Simplon\Mysql\PDOConnector;
19
use Throwable;
20
21
/**
22
 * Temporary SQL play. https://github.com/fightbulc/simplon_mysql .
23
 * Class DbAdapter.
24
 */
25
class DbAdapter implements QueueInterface
26
{
27
const OPTI_VALID_DATE = '2020-04-05 00:00:00'; // v0.77
28
    protected $db;
29
    protected $pdoConn; // v.34 sous-titre sans maj
30
31
    public function __construct()
32
    {
33
        $pdo = new PDOConnector(
34
            getenv('MYSQL_HOST'), getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'), getenv('MYSQL_DATABASE')
35
        );
36
        $this->pdoConn = $pdo->connect('utf8', ['port' => getenv('MYSQL_PORT')]);
37
        $this->db = new Mysql($this->pdoConn);
38
    }
39
40
    /**
41
     * @param $datas
42
     *
43
     * @return array|bool
44
     * @throws Exception
45
     */
46
    public function insertPageOuvrages(array $datas)
47
    {
48
        // check if article already in db
49
        $page = $datas[0]['page'];
50
        $count = $this->db->fetchRowMany(
51
            'SELECT id from page_ouvrages WHERE page=:page',
52
            ['page' => $page]
53
        );
54
        if (null !== $count) {
55
            return false;
56
        }
57
58
        // add the citations
59
        return $this->db->insertMany('page_ouvrages', $datas);
60
    }
61
62
    /**
63
     * Get one new row (page, raw) to complete.
64
     *
65
     * @return array|null
66
     */
67
    public function getNewRaw(): ?array
68
    {
69
        try {
70
            $row = $this->db->fetchRow(
71
                'SELECT page,raw FROM page_ouvrages 
72
                WHERE raw <> "" AND (opti = "" OR optidate IS NULL OR optidate < :validDate ) AND (edited IS NULL)
73
                ORDER BY priority DESC,id
74
                LIMIT 1',
75
                [
76
                    'validDate' => self::OPTI_VALID_DATE,
77
                ]
78
            );
79
        } catch (Throwable $e) {
80
            echo "SQL : No more queue to process \n";
81
        }
82
83
        return $row ?? null;
84
    }
85
86
    /**
87
     * Update DB with completed data from CompleteProcess.
88
     *
89
     * @param array $finalData
90
     *
91
     * @return bool
92
     */
93
    public function sendCompletedData(array $finalData): bool
94
    {
95
        try {
96
            $result = $this->db->update(
97
                'page_ouvrages',
98
                ['raw' => $finalData['raw']], // condition
99
                $finalData
100
            );
101
        } catch (MysqlException $e) {
102
            dump($e);
103
104
            return false;
105
        }
106
107
        return !empty($result);
108
    }
109
110
    //------------------------------------------------------
111
    //          EDIT QUEUE
112
    //------------------------------------------------------
113
114
    /**
115
     * Get batch of citations(template) for edit process.
116
     *
117
     * @param int|null $limit
118
     *
119
     * @return string|null
120
     * @throws Exception
121
     */
122
    public function getAllRowsToEdit(?int $limit = 100): ?string
123
    {
124
        try {
125
            $pageInfo = $this->pdoConn->query(
126
                '
127
                SELECT A.page FROM page_ouvrages A
128
                WHERE notcosmetic=1. 
129
                AND NOT EXISTS
130
                    (SELECT B.* FROM page_ouvrages B
131
                    WHERE (
132
                        B.edited IS NOT NULL 
133
                        OR B.optidate < "'.self::OPTI_VALID_DATE.'" 
134
                        OR B.optidate IS NULL 
135
                        OR B.opti="" 
136
                        OR B.skip=1
137
                        OR B.raw=""
138
                        )
139
                    AND A.page = B.page
140
                    )
141
                ORDER BY A.priority DESC,RAND()
142
                LIMIT '.$limit.'
143
                '
144
            );
145
146
            // No page to edit
147
            $rows = $pageInfo->fetchAll();
148
            if (empty($rows)) {
149
                return '[]';
150
            }
151
152
            $page = $rows[0]['page'];
153
154
            // Order by optidate for first version in edit commentary ?
155
            $data = $this->db->fetchRowMany(
156
                'SELECT * FROM page_ouvrages WHERE page=:page ORDER BY optidate DESC',
157
                ['page' => $page]
158
            );
159
            $json = json_encode($data);
160
        } catch (Throwable $e) {
161
            throw new Exception('SQL : No more queue to process');
162
        }
163
164
        return $json;
165
    }
166
167
    public function skipArticle(string $title): bool
168
    {
169
        try {
170
            $result = $this->db->update(
171
                'page_ouvrages',
172
                ['page' => $title], // condition
173
                ['skip' => true]
174
            );
175
        } catch (MysqlException $e) {
176
            dump($e);
177
178
            return false;
179
        }
180
181
        return !empty($result);
182
    }
183
184
    public function setLabel(string $title, ?int $val=0): bool
185
    {
186
        try {
187
            $result = $this->db->update(
188
                'page_ouvrages',
189
                ['page' => $title], // condition
190
                ['label' => $val]
191
            );
192
        } catch (MysqlException $e) {
193
            dump($e);
194
195
            return false;
196
        }
197
198
        return !empty($result);
199
    }
200
201
    public function skipRow(int $id): bool
202
    {
203
        try {
204
            $result = $this->db->update(
205
                'page_ouvrages',
206
                ['id' => $id], // condition
207
                ['skip' => true]
208
            );
209
        } catch (MysqlException $e) {
210
            dump($e);
211
212
            return false;
213
        }
214
215
        return !empty($result);
216
    }
217
218
    /**
219
     * Update DB after wiki edition.
220
     *
221
     * @param array $data
222
     *
223
     * @return bool
224
     */
225
    public function sendEditedData(array $data): bool
226
    {
227
        try {
228
            $result = $this->db->update(
229
                'page_ouvrages',
230
                ['id' => $data['id']], // condition
231
                ['edited' => date('Y-m-d H:i:s')]
232
            );
233
        } catch (MysqlException $e) {
234
            dump($e);
235
236
            return false;
237
        }
238
239
        return !empty($result);
240
    }
241
242
    //------------------------------------------------------
243
244
    //    /**
245
    //     * Dirty naive ORM.
246
    //     *
247
    //     * @param object $object
248
    //     *
249
    //     * @return array|bool
250
    //     */
251
    //    public function saveEntity(object $object)
252
    //    {
253
    //        if ($object instanceof App\Infrastructure\unused\DbEditedPage) {
254
    //            /*
255
    //             * @var $object DbEditedPage
256
    //             */
257
    //            try {
258
    //                return $this->db->replace('editedpages', $object->getVars());
259
    //            } catch (MysqlException $e) {
260
    //                unset($e);
261
    //            }
262
    //        }
263
    //
264
    //        return false;
265
    //    }
266
267
    //    /**
268
    //     * Dirty naive ORM.
269
    //     *
270
    //     * @param $table
271
    //     * @param $primary
272
    //     *
273
    //     * @return object|null
274
    //     */
275
    //    public function findEntity($table, $primary): ?object
276
    //    {
277
    //        if ('editedpages' === $table) {
278
    //            /*
279
    //             * @var $object DbEditedPage
280
    //             */
281
    //            try {
282
    //                $res = $this->db->fetchRow('SELECT * FROM editedpages WHERE title = :title', ['title' => $primary]);
283
    //                $obj = new DbEditedPage($this);
284
    //                $obj->setTitle($primary);
285
    //                $obj->setCompleted($res['completed']);
286
    //                $obj->setEdited($res['edited']);
287
    //
288
    //                return $obj;
289
    //            } catch (MysqlException $e) {
290
    //                unset($e);
291
    //            }
292
    //        }
293
    //
294
    //        return null;
295
    //    }
296
297
    /**
298
     * Get a row to monitor edits.
299
     */
300
    public function getMonitor(): ?array
301
    {
302
        $data = null;
303
        // 2 hours ago
304
        $beforeTime = (new DateTime())->sub(new DateInterval('PT3H'));
305
306
        try {
307
            $data = $this->db->fetchRowMany(
308
                'SELECT id,page,raw,opti,optidate,edited,verify,skip FROM page_ouvrages WHERE page = (
309
                    SELECT page FROM page_ouvrages
310
                    WHERE edited IS NOT NULL 
311
                    and edited > :afterDate and edited < :beforeDate
312
                    and (verify is null or verify < :nextVerifyDate )
313
             		ORDER BY verify,edited
314
                    LIMIT 1)',
315
                [
316
                    'afterDate' => '2019-11-26 06:00:00',
317
                    'beforeDate' => $beforeTime->format('Y-m-d H:i:s'),
318
                    'nextVerifyDate' => (new DateTime())->sub(new DateInterval('P2D'))->format('Y-m-d H:i:s'),
319
                ]
320
            );
321
        } catch (Throwable $e) {
322
            echo "SQL : No more queue to process \n";
323
        }
324
325
        return $data;
326
    }
327
328
    public function updateMonitor(array $data): bool
329
    {
330
        if (empty($data['page'])) {
331
            throw new Exception('pas de page');
332
        }
333
334
        try {
335
            $result = $this->db->update(
336
                'page_ouvrages',
337
                ['page' => $data['page']], // condition
338
                $data
339
            );
340
        } catch (MysqlException $e) {
341
            dump($e);
342
343
            return false;
344
        }
345
346
        return !empty($result);
347
    }
348
}
349