-
Notifications
You must be signed in to change notification settings - Fork 40
Initial support for SQLite database backend, fixes #56 #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This seems to be working pretty well now. |
Hello @AnnoyingTechnology, Sorry for the delay in reply. I'm a bit busy right now, but I promise, I'll take a look at your PR soon. |
no worries |
I don't think you've tested your code with the table prefix option. I'm right? |
Correct. As SQLite isn't a DBMS the file is the database and the need for prefix to avoid collisions when sharing a single database for multiple uses doesn't exist. There is still a real issue though, I removed an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've done a great job. Thank you for the PR. I have a few comments besides ones I left in your code:
- Your code needs to be tested with the table prefix option enabled with one or more other tables without the prefix.
- You have used spaces and tabs for indentation in your php code. Could you use spaces instead of tabs, please? I am sticking to PSR-2 in the php code of this project.
- In all the new files that I saw, you have not been mentioned as the author of the code. Maybe you forgot to change it?
I haven't tested your code on a server with reports yet. Perhaps after these tests I will have some questions and comments.
break; | ||
case 'sqlite': | ||
$type = 'sqlite'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
break; | |
case 'sqlite': | |
$type = 'sqlite'; | |
break; | |
case 'sqlite': | |
$type = 'sqlite'; |
], | ||
'additional' => '', | ||
'table_options' => '', | ||
'sub_queries' => [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may have forgotten to create an unique index on the fqdn field.
); | ||
while ($row = $st->fetch(\PDO::FETCH_ASSOC)) { | ||
$tname = $row['name']; | ||
$rcnt = $this->dbh->query('SELECT COUNT(*) FROM ' . $tname . '')->fetch(\PDO::FETCH_NUM)[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$rcnt = $this->dbh->query('SELECT COUNT(*) FROM ' . $tname . '')->fetch(\PDO::FETCH_NUM)[0]; | |
$rcnt = $this->dbh->query('SELECT COUNT(*) FROM ' . $tname)->fetch(\PDO::FETCH_NUM)[0]; |
$db->query('PRAGMA FOREIGN_KEYS = OFF'); | ||
$st = $db->query($this->sqlShowTablesQuery()); | ||
while ($table = $st->fetchColumn(0)) { | ||
$db->query('DROP TABLE ' . $table . ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$db->query('DROP TABLE ' . $table . ''); | |
$db->query('DROP TABLE ' . $table); |
if ($col_num > 0) { | ||
$query .= ', '; | ||
} | ||
$query .= '' . $column['name'] . ' ' . $column['definition']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$query .= '' . $column['name'] . ' ' . $column['definition']; | |
$query .= $column['name'] . ' ' . $column['definition']; |
try { | ||
|
||
$st = $db->prepare( | ||
'SELECT org, begin_time, end_time, fqdn, external_id, seen, SUM(rcount) AS rcount,' | ||
. ' MIN(dkim_align) AS dkim_align, MIN(spf_align) AS spf_align,' | ||
. ' MIN(disposition) AS disposition FROM ' . $this->connector->tablePrefix('reports') | ||
. ' AS rp LEFT JOIN ' . $this->connector->tablePrefix('rptrecords') | ||
. ' AS rr ON rp.id = rr.report_id' | ||
. ' INNER JOIN ' . $this->connector->tablePrefix('domains') | ||
. ' AS d ON d.id = rp.domain_id' | ||
. ' GROUP BY rp.id' | ||
. $cond_str1 . $order_str . $limit_str | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try { | |
$st = $db->prepare( | |
'SELECT org, begin_time, end_time, fqdn, external_id, seen, SUM(rcount) AS rcount,' | |
. ' MIN(dkim_align) AS dkim_align, MIN(spf_align) AS spf_align,' | |
. ' MIN(disposition) AS disposition FROM ' . $this->connector->tablePrefix('reports') | |
. ' AS rp LEFT JOIN ' . $this->connector->tablePrefix('rptrecords') | |
. ' AS rr ON rp.id = rr.report_id' | |
. ' INNER JOIN ' . $this->connector->tablePrefix('domains') | |
. ' AS d ON d.id = rp.domain_id' | |
. ' GROUP BY rp.id' | |
. $cond_str1 . $order_str . $limit_str | |
); | |
try { | |
$st = $db->prepare( | |
'SELECT org, begin_time, end_time, fqdn, external_id, seen, SUM(rcount) AS rcount,' | |
. ' MIN(dkim_align) AS dkim_align, MIN(spf_align) AS spf_align,' | |
. ' MIN(disposition) AS disposition FROM ' . $this->connector->tablePrefix('reports') | |
. ' AS rp LEFT JOIN ' . $this->connector->tablePrefix('rptrecords') | |
. ' AS rr ON rp.id = rr.report_id' | |
. ' INNER JOIN ' . $this->connector->tablePrefix('domains') | |
. ' AS d ON d.id = rp.domain_id' | |
. ' GROUP BY rp.id' | |
. $cond_str1 . $order_str . $limit_str | |
); |
$st = $this->connector->dbh()->query( | ||
'SELECT DISTINCT strftime("%Y-%m", date) AS month FROM' | ||
. ' (SELECT DISTINCT begin_time AS date FROM ' . $rep_tn | ||
. ' UNION SELECT DISTINCT end_time AS date FROM ' . $rep_tn | ||
. ') AS r ORDER BY month DESC' | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$st = $this->connector->dbh()->query( | |
'SELECT DISTINCT strftime("%Y-%m", date) AS month FROM' | |
. ' (SELECT DISTINCT begin_time AS date FROM ' . $rep_tn | |
. ' UNION SELECT DISTINCT end_time AS date FROM ' . $rep_tn | |
. ') AS r ORDER BY month DESC' | |
); | |
$st = $this->connector->dbh()->query( | |
'SELECT DISTINCT strftime("%Y-%m", date) AS month FROM' | |
. ' (SELECT DISTINCT begin_time AS date FROM ' . $rep_tn | |
. ' UNION SELECT DISTINCT end_time AS date FROM ' . $rep_tn | |
. ') AS r ORDER BY month DESC' | |
); |
$st->closeCursor(); | ||
|
||
$st = $db->prepare( | ||
'SELECT COUNT(*) FROM (SELECT org FROM ' . $this->connector->tablePrefix('reports') . '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'SELECT COUNT(*) FROM (SELECT org FROM ' . $this->connector->tablePrefix('reports') . '' | |
'SELECT COUNT(*) FROM (SELECT org FROM ' . $this->connector->tablePrefix('reports') |
'SELECT ip, SUM(rcount) AS rcount, SUM(CASE WHEN dkim_align = 2 THEN rcount ELSE 0 END) AS dkim_aligned,' | ||
. ' SUM(CASE WHEN spf_align = 2 THEN rcount ELSE 0 END) AS spf_aligned' | ||
. ' FROM ' . $this->connector->tablePrefix('rptrecords') . ' AS rr' | ||
. ' INNER JOIN ' . $this->connector->tablePrefix('reports') | ||
. ' AS rp ON rr.report_id = rp.id' | ||
. $this->sqlCondition($domain ? true : false) . ' GROUP BY ip ORDER BY rcount DESC' | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'SELECT ip, SUM(rcount) AS rcount, SUM(CASE WHEN dkim_align = 2 THEN rcount ELSE 0 END) AS dkim_aligned,' | |
. ' SUM(CASE WHEN spf_align = 2 THEN rcount ELSE 0 END) AS spf_aligned' | |
. ' FROM ' . $this->connector->tablePrefix('rptrecords') . ' AS rr' | |
. ' INNER JOIN ' . $this->connector->tablePrefix('reports') | |
. ' AS rp ON rr.report_id = rp.id' | |
. $this->sqlCondition($domain ? true : false) . ' GROUP BY ip ORDER BY rcount DESC' | |
); | |
'SELECT ip, SUM(rcount) AS rcount, SUM(CASE WHEN dkim_align = 2 THEN rcount ELSE 0 END) AS dkim_aligned,' | |
. ' SUM(CASE WHEN spf_align = 2 THEN rcount ELSE 0 END) AS spf_aligned' | |
. ' FROM ' . $this->connector->tablePrefix('rptrecords') . ' AS rr' | |
. ' INNER JOIN ' . $this->connector->tablePrefix('reports') | |
. ' AS rp ON rr.report_id = rp.id' | |
. $this->sqlCondition($domain ? true : false) . ' GROUP BY ip ORDER BY rcount DESC' | |
); |
private function columnExists($db, string $table, string $column): bool | ||
{ | ||
$st = $db->prepare( | ||
'PRAGMA table_info(?)' | ||
); | ||
$st->bindValue(2, $table, \PDO::PARAM_STR); | ||
$st->execute(); | ||
$res = $st->fetch(\PDO::FETCH_ASSOC); | ||
$st->closeCursor(); | ||
return $res ? true : false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is the column existence tested here?
Yes, I understand you. But different prefixes can be used within the same project. For example, for tests or quick reports. The current code may delete tables beyond the prefix. Added: What about Write-Ahead Logging: https://www.sqlite.org/wal.html ? |
Thanks for the feedback, I'll fix all of this.
What about it ? This is a performance/concurrency per-database setting.
The simplicity of changing the database file path, or copying a database file generally renders this moot. But I'll bring prefixes back. |
At least there is support for prefixes, there is support for sqlite, but nowhere is it stated that the prefixes will not work with sqlite. Your code only creates the appearance of working with prefixes. That's the main problem. If you don't want prefixes to be used with sqlite, it makes sense to EXPLICITLY disable running this configuration. |
If you're OK with that, I'm fine with the application dying with |
Okay. So be it. |
bump rebase merge ? |
Draft