Skip to content

Commit 9c149d7

Browse files
committed
use new SQLiteDB class
This had many changes in how data is quoted in the SQL strings. The SQL building code is an absolute mess and test coverage is super spotty. So it's not 100% clear that this commit is fully correct.
1 parent 7df6d60 commit 9c149d7

File tree

12 files changed

+157
-157
lines changed

12 files changed

+157
-157
lines changed

_test/action_handle.test.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use dokuwiki\plugin\sqlite\SQLiteDB;
4+
35
/**
46
* @group plugin_data
57
* @group plugins
@@ -12,14 +14,14 @@ class action_handle_test extends DokuWikiTest
1214
protected $action;
1315
/** @var helper_plugin_data */
1416
protected $helper;
15-
/** @var helper_plugin_sqlite */
17+
/** @var SQLiteDB */
1618
protected $db;
1719

1820
public function tearDown(): void
1921
{
2022
parent::tearDown();
2123

22-
$this->db->query('DELETE FROM pages WHERE page = ?', 'test');
24+
$this->db->exec('DELETE FROM pages WHERE page = ?', 'test');
2325
}
2426

2527
public function setUp(): void
@@ -30,8 +32,10 @@ public function setUp(): void
3032
$this->helper = plugin_load('helper', 'data');
3133
$this->db = $this->helper->_getDB();
3234

33-
$this->db->query('INSERT INTO pages ( pid, page, title , class , lastmod) VALUES
34-
(?, ?, ?, ?, ?)', 1, 'test', 'title', 'class', time());
35+
$this->db->exec(
36+
'INSERT INTO pages ( pid, page, title , class , lastmod) VALUES (?, ?, ?, ?, ?)',
37+
[1, 'test', 'title', 'class', time()]
38+
);
3539
}
3640

3741
function testHandleStillPresent()
@@ -64,16 +68,14 @@ function testHandleDelete()
6468
$event = new Doku_Event('', $data);
6569
$this->action->_handle($event, null);
6670

67-
$res = $this->db->query('SELECT pid FROM pages WHERE page = ?', 'test');
68-
$pid = $this->db->res2single($res);
71+
$pid = $this->db->queryValue('SELECT pid FROM pages WHERE page = ?', 'test');
6972
$this->assertTrue(!$pid);
7073
}
7174

7275

7376
private function getTestPageId()
7477
{
75-
$res = $this->db->query('SELECT pid FROM pages WHERE page = ?', 'test');
76-
$pid = (int)$this->db->res2single($res);
78+
$pid = (int) $this->db->queryValue('SELECT pid FROM pages WHERE page = ?', 'test');
7779
return $pid;
7880
}
7981
}

_test/helper.test.php

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -227,61 +227,62 @@ protected function createColumnEntry($name, $multi, $key, $origkey, $title, $typ
227227

228228
public function testNoSqlPlugin()
229229
{
230-
$helper = new helper_plugin_data();
231230
plugin_disable('sqlite');
232-
$this->assertFalse($helper->_getDB());
231+
$this->expectException(\Exception::class);
232+
$helper = new helper_plugin_data();
233+
$helper->_getDB();
233234
}
234235

235236
public function testParseFilter()
236237
{
237238
$helper = new helper_plugin_data();
238239

239-
$this->assertEquals($this->createFilterArray('name', 'tom', '=', 'name_some', 'some')
240+
$this->assertEquals($this->createFilterArray('name', "'tom'", '=', 'name_some', 'some')
240241
, $helper->_parse_filter('name_some = tom'));
241242

242-
$this->assertEquals($this->createFilterArray('name', 'tom', '=', 'name', '')
243+
$this->assertEquals($this->createFilterArray('name', "'tom'", '=', 'name', '')
243244
, $helper->_parse_filter('name = tom'));
244245

245-
$this->assertEquals($this->createFilterArray('name', 'tom', '!=', 'name', '')
246+
$this->assertEquals($this->createFilterArray('name', "'tom'", '!=', 'name', '')
246247
, $helper->_parse_filter('name != tom'));
247248

248-
$this->assertEquals($this->createFilterArray('name', 'tom', '!=', 'name', '')
249+
$this->assertEquals($this->createFilterArray('name', "'tom'", '!=', 'name', '')
249250
, $helper->_parse_filter('name <> tom'));
250251

251-
$this->assertEquals($this->createFilterArray('name', 'tom', '<', 'name', '')
252+
$this->assertEquals($this->createFilterArray('name', "'tom'", '<', 'name', '')
252253
, $helper->_parse_filter('name < tom'));
253254

254-
$this->assertEquals($this->createFilterArray('name', 'tom', '>', 'name', '')
255+
$this->assertEquals($this->createFilterArray('name', "'tom'", '>', 'name', '')
255256
, $helper->_parse_filter('name > tom'));
256257

257-
$this->assertEquals($this->createFilterArray('name', 'tom', '<=', 'name', '')
258+
$this->assertEquals($this->createFilterArray('name', "'tom'", '<=', 'name', '')
258259
, $helper->_parse_filter('name <= tom'));
259260

260-
$this->assertEquals($this->createFilterArray('name', 'tom', '>=', 'name', '')
261+
$this->assertEquals($this->createFilterArray('name', "'tom'", '>=', 'name', '')
261262
, $helper->_parse_filter('name >= tom'));
262263

263-
$this->assertEquals($this->createFilterArray('name', 'tom', 'LIKE', 'name', '')
264+
$this->assertEquals($this->createFilterArray('name', "'tom'", 'LIKE', 'name', '')
264265
, $helper->_parse_filter('name ~ tom'));
265266

266-
$this->assertEquals($this->createFilterArray('name', '%tom%', 'LIKE', 'name', '')
267+
$this->assertEquals($this->createFilterArray('name', "'%tom%'", 'LIKE', 'name', '')
267268
, $helper->_parse_filter('name *~ tom'));
268269

269-
$this->assertEquals($this->createFilterArray('name', 'tom', 'NOT LIKE', 'name', '')
270+
$this->assertEquals($this->createFilterArray('name', "'tom'", 'NOT LIKE', 'name', '')
270271
, $helper->_parse_filter('name !~ tom'));
271272

272-
$this->assertEquals($this->createFilterArray('name', '%tom', 'LIKE', 'name', '')
273+
$this->assertEquals($this->createFilterArray('name', "'%tom'", 'LIKE', 'name', '')
273274
, $helper->_parse_filter('name ~ *tom'));
274275

275-
$this->assertEquals($this->createFilterArray('name', 'tom%', 'LIKE', 'name', '')
276+
$this->assertEquals($this->createFilterArray('name', "'tom%'", 'LIKE', 'name', '')
276277
, $helper->_parse_filter('name ~ tom*'));
277278

278-
$this->assertEquals($this->createFilterArray('name', '%tom%', 'LIKE', 'name', '')
279+
$this->assertEquals($this->createFilterArray('name', "'%tom%'", 'LIKE', 'name', '')
279280
, $helper->_parse_filter('name ~ *tom*'));
280281

281-
$this->assertEquals($this->createFilterArray('name', 'tom', 'IN(', 'name', '')
282+
$this->assertEquals($this->createFilterArray('name', "'tom'", 'IN(', 'name', '')
282283
, $helper->_parse_filter('name ~~ tom'));
283284

284-
$this->assertEquals($this->createFilterArray('name', "t''om','john*", 'IN(', 'name', '')
285+
$this->assertEquals($this->createFilterArray('name', "'t''om','john*'", 'IN(', 'name', '')
285286
, $helper->_parse_filter("name ~~ t'om,john*"));
286287

287288
$this->assertEquals(false, $helper->_parse_filter('name is *tom*'));
@@ -306,21 +307,21 @@ public function testGetFilters()
306307
$this->assertEquals(array(), $helper->_get_filters());
307308

308309
$_REQUEST['dataflt'] = 'name = tom';
309-
$this->assertEquals(array($this->createFilterArrayListEntry('name', 'tom', '=', 'name', '', 'AND')),
310+
$this->assertEquals(array($this->createFilterArrayListEntry('name', "'tom'", '=', 'name', '', 'AND')),
310311
$helper->_get_filters());
311312

312313
$_REQUEST['dataflt'] = array();
313314
$_REQUEST['dataflt'][] = 'name = tom';
314-
$this->assertEquals(array($this->createFilterArrayListEntry('name', 'tom', '=', 'name', '', 'AND')),
315+
$this->assertEquals(array($this->createFilterArrayListEntry('name', "'tom'", '=', 'name', '', 'AND')),
315316
$helper->_get_filters());
316317

317318
$_REQUEST['dataflt'] = array();
318319
$_REQUEST['dataflt'][] = 'name = tom';
319320
$_REQUEST['dataflt'][] = 'unit_url = dokuwiki.org';
320321
$this->assertEquals(
321322
array(
322-
$this->createFilterArrayListEntry('name', 'tom', '=', 'name', '', 'AND'),
323-
$this->createFilterArrayListEntry('unit', 'http://dokuwiki.org', '=', 'unit_url', 'url', 'AND')
323+
$this->createFilterArrayListEntry('name', "'tom'", '=', 'name', '', 'AND'),
324+
$this->createFilterArrayListEntry('unit', "'http://dokuwiki.org'", '=', 'unit_url', 'url', 'AND')
324325
),
325326
$helper->_get_filters());
326327
}

_test/helperAliases.test.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ public function testAliases()
1414
$helper = new helper_plugin_data();
1515
$db = $helper->_getDB();
1616
$this->assertTrue($db !== false);
17-
$db->query("INSERT INTO aliases (name, type, prefix, postfix, enum) VALUES (?,?,?,?,?)",
18-
'alias', 'wiki', '[[', ']]', '');
17+
$db->exec(
18+
'INSERT INTO aliases (name, type, prefix, postfix, enum) VALUES (?,?,?,?,?)',
19+
['alias', 'wiki', '[[', ']]', '']
20+
);
1921

2022
$expect = array(
2123
'alias' => array(

_test/syntax_plugin_data_table.test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function testHandle()
5252
'filter' => array(
5353
'0' => array(
5454
'key' => 'type',
55-
'value' => 'web development',
55+
'value' => "'web development'",
5656
'compare' => '=',
5757
'colname' => 'type',
5858
'type' => '',

action.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,11 @@ function _handle(Doku_Event $event, $param)
5555
$id = ltrim($data[1] . ':' . $data[2], ':');
5656

5757
// get page id
58-
$res = $sqlite->query('SELECT pid FROM pages WHERE page = ?', $id);
59-
$pid = (int)$sqlite->res2single($res);
58+
$pid = (int) $sqlite->queryValue('SELECT pid FROM pages WHERE page = ?', $id);
6059
if (!$pid) return; // we have no data for this page
6160

62-
$sqlite->query('DELETE FROM data WHERE pid = ?', $pid);
63-
$sqlite->query('DELETE FROM pages WHERE pid = ?', $pid);
61+
$sqlite->exec('DELETE FROM data WHERE pid = ?', $pid);
62+
$sqlite->exec('DELETE FROM pages WHERE pid = ?', $pid);
6463
}
6564

6665
/**

admin/aliases.php

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,29 +70,30 @@ public function handle()
7070
$sqlite = $this->dthlp->_getDB();
7171
if (!$sqlite) return;
7272

73-
$sqlite->query("BEGIN TRANSACTION");
74-
if (!$sqlite->query("DELETE FROM aliases")) {
75-
$sqlite->query('ROLLBACK TRANSACTION');
76-
return;
77-
}
78-
foreach ($_REQUEST['d'] as $row) {
79-
$row = array_map('trim', $row);
80-
$row['name'] = PHPString::strtolower($row['name']);
81-
$row['name'] = rtrim($row['name'], 's');
82-
if (!$row['name']) continue;
83-
84-
// Clean enum
85-
$arr = preg_split('/\s*,\s*/', $row['enum']);
86-
$arr = array_unique($arr);
87-
$row['enum'] = implode(', ', $arr);
88-
89-
if (!$sqlite->query("INSERT INTO aliases (name, type, prefix, postfix, enum)
90-
VALUES (?,?,?,?,?)", $row)) {
91-
$sqlite->query('ROLLBACK TRANSACTION');
92-
return;
73+
$sqlite->getPdo()->beginTransaction();
74+
try {
75+
$sqlite->exec('DELETE FROM aliases');
76+
77+
foreach ($_REQUEST['d'] as $row) {
78+
$row = array_map('trim', $row);
79+
$row['name'] = PHPString::strtolower($row['name']);
80+
$row['name'] = rtrim($row['name'], 's');
81+
if (!$row['name']) continue;
82+
83+
// Clean enum
84+
$arr = preg_split('/\s*,\s*/', $row['enum']);
85+
$arr = array_unique($arr);
86+
$row['enum'] = implode(', ', $arr);
87+
88+
$sqlite->exec(
89+
'INSERT INTO aliases (name, type, prefix, postfix, enum) VALUES (?,?,?,?,?)',
90+
$row
91+
);
9392
}
93+
$sqlite->getPdo()->commit();
94+
} catch (\Exception $exception) {
95+
$sqlite->getPdo()->rollBack();
9496
}
95-
$sqlite->query("COMMIT TRANSACTION");
9697
}
9798

9899
/**
@@ -105,9 +106,8 @@ public function html()
105106

106107
echo $this->locale_xhtml('admin_intro');
107108

108-
$sql = "SELECT * FROM aliases ORDER BY name";
109-
$res = $sqlite->query($sql);
110-
$rows = $sqlite->res2arr($res);
109+
$sql = 'SELECT * FROM aliases ORDER BY name';
110+
$rows = $sqlite->queryAll($sql);
111111

112112
$form = new Doku_Form(array('method' => 'post'));
113113
$form->addHidden('page', 'data_aliases');
@@ -164,5 +164,3 @@ public function html()
164164
}
165165

166166
}
167-
168-
// vim:ts=4:sw=4:et:enc=utf-8:

admin/clean.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,13 @@ public function handle()
6868
$sqlite = $this->dthlp->_getDB();
6969
if (!$sqlite) return;
7070

71-
$res = $sqlite->query("SELECT pid, page FROM pages");
72-
$rows = $sqlite->res2arr($res);
71+
$rows = $sqlite->queryAll('SELECT pid, page FROM pages');
7372

7473
$count = 0;
7574
foreach ($rows as $row) {
7675
if (!page_exists($row['page'])) {
77-
$sqlite->query('DELETE FROM data WHERE pid = ?', $row['pid']);
78-
$sqlite->query('DELETE FROM pages WHERE pid = ?', $row['pid']);
76+
$sqlite->exec('DELETE FROM data WHERE pid = ?', $row['pid']);
77+
$sqlite->exec('DELETE FROM pages WHERE pid = ?', $row['pid']);
7978
$count++;
8079
}
8180
}
@@ -100,5 +99,3 @@ public function html()
10099
}
101100

102101
}
103-
104-
// vim:ts=4:sw=4:et:enc=utf-8:

helper.php

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* @author Andreas Gohr <andi@splitbrain.org>
55
*/
66

7+
use dokuwiki\ErrorHandler;
8+
use dokuwiki\plugin\sqlite\SQLiteDB;
79
use dokuwiki\Utf8\PhpString;
810

911
/**
@@ -13,7 +15,7 @@ class helper_plugin_data extends DokuWiki_Plugin
1315
{
1416

1517
/**
16-
* @var helper_plugin_sqlite initialized via _getDb()
18+
* @var SQLiteDB initialized via _getDb()
1719
*/
1820
protected $db = null;
1921

@@ -80,21 +82,20 @@ public function ready()
8082
/**
8183
* load the sqlite helper
8284
*
83-
* @return helper_plugin_sqlite|false plugin or false if failed
85+
* @return SQLiteDB|null SQLite class plugin or null if failed
8486
*/
8587
function _getDB()
8688
{
8789
if ($this->db === null) {
88-
$this->db = plugin_load('helper', 'sqlite');
89-
if ($this->db === null) {
90-
msg('The data plugin needs the sqlite plugin', -1);
91-
return false;
92-
}
93-
if (!$this->db->init('data', dirname(__FILE__) . '/db/')) {
94-
$this->db = null;
95-
return false;
90+
try {
91+
$this->db = new SQLiteDB('data', __DIR__ . '/db/');
92+
$this->db->getPdo()->sqliteCreateFunction('DATARESOLVE', [$this, '_resolveData'], 2);
93+
} catch (\Exception $exception) {
94+
if (defined('DOKU_UNITTEST')) throw new \RuntimeException('Could not load SQLite', 0, $exception);
95+
ErrorHandler::logException($exception);
96+
msg('Couldn\'t load sqlite.', -1);
97+
return null;
9698
}
97-
$this->db->create_function('DATARESOLVE', array($this, '_resolveData'), 2);
9899
}
99100
return $this->db;
100101
}
@@ -432,8 +433,7 @@ function _aliases()
432433
if (!$sqlite) return array();
433434

434435
$this->aliases = array();
435-
$res = $sqlite->query("SELECT * FROM aliases");
436-
$rows = $sqlite->res2arr($res);
436+
$rows = $sqlite->queryAll("SELECT * FROM aliases");
437437
foreach ($rows as $row) {
438438
$name = $row['name'];
439439
unset($row['name']);
@@ -492,11 +492,14 @@ function _parse_filter($filterline)
492492
}
493493
$sqlite = $this->_getDB();
494494
if (!$sqlite) return false;
495-
$val = $sqlite->escape_string($val); //pre escape
495+
496496
if ($com == 'IN(') {
497497
$val = explode(',', $val);
498498
$val = array_map('trim', $val);
499-
$val = implode("','", $val);
499+
$val = array_map([$sqlite->getPdo(), 'quote'], $val);
500+
$val = implode(",", $val);
501+
} else {
502+
$val = $sqlite->getPdo()->quote($val);
500503
}
501504

502505
return array(

syntax/cloud.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public function _buildSQL(&$data)
103103
if (!$tables[$col]) {
104104
$tables[$col] = 'T' . (++$cnt);
105105
$from .= ' LEFT JOIN data AS ' . $tables[$col] . ' ON ' . $tables[$col] . '.pid = data.pid';
106-
$from .= ' AND ' . $tables[$col] . ".key = " . $sqlite->quote_string($col);
106+
$from .= ' AND ' . $tables[$col] . ".key = " . $sqlite->getPdo()->quote($col);
107107
}
108108

109109
$where .= ' ' . $filter['logic'] . ' ' . $tables[$col] . '.value ' . $filter['compare'] .
@@ -115,7 +115,7 @@ public function _buildSQL(&$data)
115115
// build query
116116
$sql = "SELECT data.value AS value, COUNT(data.pid) AS cnt
117117
FROM data $from $pagesjoin
118-
WHERE data.key = " . $sqlite->quote_string($ckey) . "
118+
WHERE data.key = " . $sqlite->getPdo()->quote($ckey) . "
119119
$where
120120
GROUP BY data.value";
121121
if (isset($data['min'])) {
@@ -164,8 +164,7 @@ public function render($format, Doku_Renderer $renderer, $data)
164164
$this->dthlp->_replacePlaceholdersInSQL($data);
165165

166166
// build cloud data
167-
$res = $sqlite->query($data['sql']);
168-
$rows = $sqlite->res2arr($res);
167+
$rows = $sqlite->queryAll($data['sql']);
169168
$min = 0;
170169
$max = 0;
171170
$tags = array();

0 commit comments

Comments
 (0)