Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Sqlite3
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
2 / 2
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createTables
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 * The phpMyFAQ instances a database class with CREATE TABLE statements for SQLite3.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2015-2026 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2015-04-16
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Instance\Database;
21
22use phpMyFAQ\Configuration;
23use phpMyFAQ\Instance\Database;
24
25/**
26 * Class Sqlite3
27 *
28 * @package phpMyFAQ\Instance\Database
29 * @deprecated Use PDO instead. Will be removed in the v5.0 release.
30 */
31class Sqlite3 extends Database implements DriverInterface
32{
33    /** @var string[] */
34    private array $createTableStatements = [
35        'faqadminlog' => 'CREATE TABLE %sfaqadminlog (
36            id INTEGER NOT NULL,
37            time INTEGER NOT NULL,
38            usr INTEGER NOT NULL,
39            text VARCHAR(8000) NOT NULL,
40            hash VARCHAR(64) NULL,
41            previous_hash VARCHAR(64) NULL,
42            ip VARCHAR(64) NOT NULL,
43            PRIMARY KEY (id))',
44        'faqattachment' => 'CREATE TABLE %sfaqattachment (
45            id INTEGER NOT NULL,
46            record_id INTEGER NOT NULL,
47            record_lang VARCHAR(5) NOT NULL,
48            real_hash CHAR(32) NOT NULL,
49            virtual_hash CHAR(32) NOT NULL,
50            password_hash CHAR(40) NULL,
51            filename VARCHAR(255) NOT NULL,
52            filesize INTEGER NOT NULL,
53            encrypted INTEGER NOT NULL DEFAULT 0,
54            mime_type VARCHAR(255) NULL,
55            PRIMARY KEY (id))',
56        'faqattachment_file' => 'CREATE TABLE %sfaqattachment_file (
57            virtual_hash CHAR(32) NOT NULL,
58            contents TEXT NOT NULL,
59            PRIMARY KEY (virtual_hash))',
60        'faqbackup' => 'CREATE TABLE %sfaqbackup (
61            id INT(11) NOT NULL,
62            filename VARCHAR(255) NOT NULL,
63            authkey VARCHAR(255) NOT NULL,
64            authcode VARCHAR(255) NOT NULL,
65            created timestamp NOT NULL,
66            PRIMARY KEY (id))',
67        'faqbookmarks' => 'CREATE TABLE %sfaqbookmarks (
68            userid INT(11) DEFAULT NULL,
69            faqid INT(11) DEFAULT NULL)',
70        'faqcaptcha' => 'CREATE TABLE %sfaqcaptcha (
71            id VARCHAR(6) NOT NULL,
72            useragent VARCHAR(255) NOT NULL,
73            language VARCHAR(5) NOT NULL,
74            ip VARCHAR(64) NOT NULL,
75            captcha_time INTEGER NOT NULL,
76            PRIMARY KEY (id))',
77        'faqcategories' => 'CREATE TABLE %sfaqcategories (
78            id INTEGER NOT NULL,
79            lang VARCHAR(5) NOT NULL,
80            parent_id INTEGER NOT NULL,
81            name VARCHAR(255) NOT NULL,
82            description VARCHAR(255) DEFAULT NULL,
83            user_id INTEGER NOT NULL,
84            group_id INTEGER NOT NULL DEFAULT -1,
85            active INTEGER NULL DEFAULT 1,
86            image VARCHAR(255) DEFAULT NULL,
87            show_home INTEGER DEFAULT NULL,
88            PRIMARY KEY (id, lang))',
89        'faqcategoryrelations' => 'CREATE TABLE %sfaqcategoryrelations (
90            category_id INTEGER NOT NULL,
91            category_lang VARCHAR(5) NOT NULL,
92            record_id INTEGER NOT NULL,
93            record_lang VARCHAR(5) NOT NULL,
94            PRIMARY KEY (category_id, category_lang, record_id, record_lang))',
95        'faqcategoryrelations_idx' => 'CREATE INDEX idx_records ON %sfaqcategoryrelations (record_id, record_lang)',
96        'faqcategory_group' => 'CREATE TABLE %sfaqcategory_group (
97            category_id INTEGER NOT NULL,
98            group_id INTEGER NOT NULL,
99            PRIMARY KEY (category_id, group_id))',
100        'faqcategory_news' => 'CREATE TABLE %sfaqcategory_news (
101            category_id INTEGER NOT NULL,
102            news_id INTEGER NOT NULL,
103            PRIMARY KEY (category_id, news_id))',
104        'faqcategory_order' => 'CREATE TABLE %sfaqcategory_order (
105            category_id INTEGER NOT NULL,
106            parent_id INTEGER DEFAULT NULL,
107            position INTEGER NOT NULL,
108            PRIMARY KEY (category_id))',
109        'faqcategory_user' => 'CREATE TABLE %sfaqcategory_user (
110            category_id INTEGER NOT NULL,
111            user_id INTEGER NOT NULL,
112            PRIMARY KEY (category_id, user_id))',
113        'faqchanges' => 'CREATE TABLE %sfaqchanges (
114            id INTEGER NOT NULL,
115            beitrag SMALLINT NOT NULL,
116            lang VARCHAR(5) NOT NULL,
117            revision_id INTEGER NOT NULL DEFAULT 0,
118            usr INTEGER NOT NULL ,
119            datum INTEGER NOT NULL,
120            what text DEFAULT NULL,
121            PRIMARY KEY (id, lang))',
122        'faqcomments' => 'CREATE TABLE %sfaqcomments (
123            id_comment INTEGER NOT NULL,
124            id INTEGER NOT NULL,
125            type VARCHAR(10) NOT NULL,
126            usr VARCHAR(255) NOT NULL,
127            email VARCHAR(255) NOT NULL,
128            comment text NOT NULL,
129            datum VARCHAR(64) NOT NULL,
130            helped text DEFAULT NULL,
131            PRIMARY KEY (id_comment))',
132        'faqconfig' => 'CREATE TABLE %sfaqconfig (
133            config_name VARCHAR(255) NOT NULL default \'\',
134            config_value TEXT DEFAULT NULL,
135            PRIMARY KEY (config_name))',
136        'faqdata' => 'CREATE TABLE %sfaqdata (
137            id INTEGER NOT NULL,
138            lang VARCHAR(5) NOT NULL,
139            solution_id INTEGER NOT NULL,
140            revision_id INTEGER NOT NULL DEFAULT 0,
141            active char(3) NOT NULL,
142            sticky INTEGER NOT NULL,
143            keywords text DEFAULT NULL,
144            thema text NOT NULL,
145            content text DEFAULT NULL,
146            author VARCHAR(255) NOT NULL,
147            email VARCHAR(255) NOT NULL,
148            comment char(1) default \'y\',
149            updated VARCHAR(15) NOT NULL,
150            date_start VARCHAR(14) NOT NULL DEFAULT \'00000000000000\',
151            date_end VARCHAR(14) NOT NULL DEFAULT \'99991231235959\',
152            created DATETIME DEFAULT CURRENT_TIMESTAMP,
153            notes text DEFAULT NULL,
154            sticky_order INTEGER DEFAULT NULL,
155            PRIMARY KEY (id, lang))',
156        'faqdata_revisions' => 'CREATE TABLE %sfaqdata_revisions (
157            id INTEGER NOT NULL,
158            lang VARCHAR(5) NOT NULL,
159            solution_id INTEGER NOT NULL,
160            revision_id INTEGER NOT NULL DEFAULT 0,
161            active char(3) NOT NULL,
162            sticky INTEGER NOT NULL,
163            keywords text DEFAULT NULL,
164            thema text NOT NULL,
165            content text DEFAULT NULL,
166            author VARCHAR(255) NOT NULL,
167            email VARCHAR(255) NOT NULL,
168            comment char(1) default \'y\',
169            updated VARCHAR(15) NOT NULL,
170            date_start VARCHAR(14) NOT NULL DEFAULT \'00000000000000\',
171            date_end VARCHAR(14) NOT NULL DEFAULT \'99991231235959\',
172            created DATETIME DEFAULT CURRENT_TIMESTAMP,
173            notes text DEFAULT NULL,
174            sticky_order INTEGER DEFAULT NULL,
175            PRIMARY KEY (id, lang, solution_id, revision_id))',
176        'faqdata_group' => 'CREATE TABLE %sfaqdata_group (
177            record_id INTEGER NOT NULL,
178            group_id INTEGER NOT NULL,
179            PRIMARY KEY (record_id, group_id))',
180        'faqdata_tags' => 'CREATE TABLE %sfaqdata_tags (
181            record_id INTEGER NOT NULL,
182            tagging_id INTEGER NOT NULL,
183            PRIMARY KEY (record_id, tagging_id))',
184        'faqdata_user' => 'CREATE TABLE %sfaqdata_user (
185            record_id INTEGER NOT NULL,
186            user_id INTEGER NOT NULL,
187            PRIMARY KEY (record_id, user_id))',
188        'faqforms' => 'CREATE TABLE %sfaqforms (
189            form_id INTEGER NOT NULL,
190            input_id INTEGER NOT NULL,
191            input_type VARCHAR(1000) NOT NULL,
192            input_label VARCHAR(500) NOT NULL,
193            input_active INTEGER NOT NULL,
194            input_required INTEGER NOT NULL,
195            input_lang VARCHAR(11) NOT NULL)',
196        'faqglossary' => 'CREATE TABLE %sfaqglossary (
197            id INTEGER NOT NULL ,
198            lang VARCHAR(5) NOT NULL ,
199            item VARCHAR(255) NOT NULL ,
200            definition text NOT NULL,
201            PRIMARY KEY (id, lang))',
202        'faqgroup' => 'CREATE TABLE %sfaqgroup (
203            group_id INTEGER NOT NULL,
204            name VARCHAR(25) NULL,
205            description text NULL,
206            auto_join INTEGER NULL,
207            PRIMARY KEY(group_id))',
208        'faqgroup_idx' => 'CREATE UNIQUE INDEX idx_name ON %sfaqgroup (name)',
209        'faqgroup_right' => 'CREATE TABLE %sfaqgroup_right (
210            group_id INTEGER NOT NULL,
211            right_id INTEGER NOT NULL,
212            PRIMARY KEY(group_id, right_id))',
213        'faqinstances' => 'CREATE TABLE %sfaqinstances (
214            id INT NOT NULL,
215            url VARCHAR(255) NOT NULL,
216            instance VARCHAR(255) NOT NULL,
217            comment TEXT NULL,
218            created DATETIME NOT NULL,
219            modified DATETIME NOT NULL,
220            PRIMARY KEY (id))',
221        'faqinstances_config' => 'CREATE TABLE %sfaqinstances_config (
222            instance_id INT NOT NULL,
223            config_name VARCHAR(255) NOT NULL default \'\',
224            config_value VARCHAR(255) DEFAULT NULL,
225            PRIMARY KEY (instance_id, config_name))',
226        'faqnews' => 'CREATE TABLE %sfaqnews (
227            id INTEGER NOT NULL,
228            lang VARCHAR(5) NOT NULL,
229            header VARCHAR(255) NOT NULL,
230            artikel text NOT NULL,
231            datum VARCHAR(14) NOT NULL,
232            author_name  VARCHAR(255) NULL,
233            author_email VARCHAR(255) NULL,
234            active char(1) default \'y\',
235            comment char(1) default \'n\',
236            link VARCHAR(255) DEFAULT NULL,
237            linktitel VARCHAR(255) DEFAULT NULL,
238            target VARCHAR(255) NOT NULL,
239            PRIMARY KEY (id))',
240        'faqcustompages' => 'CREATE TABLE %sfaqcustompages (
241            id INTEGER NOT NULL,
242            lang VARCHAR(5) NOT NULL,
243            page_title VARCHAR(255) NOT NULL,
244            slug VARCHAR(255) NOT NULL,
245            content TEXT NOT NULL,
246            author_name VARCHAR(255) NOT NULL,
247            author_email VARCHAR(255) NOT NULL,
248            active CHAR(1) NOT NULL DEFAULT \'n\',
249            created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
250            updated TIMESTAMP NULL,
251            seo_title VARCHAR(60) NULL,
252            seo_description VARCHAR(160) NULL,
253            seo_robots VARCHAR(50) NOT NULL DEFAULT \'index,follow\',
254            PRIMARY KEY (id, lang))',
255        'faqquestions' => 'CREATE TABLE %sfaqquestions (
256            id INTEGER NOT NULL,
257            lang VARCHAR(5) NOT NULL,
258            username VARCHAR(100) NOT NULL,
259            email VARCHAR(100) NOT NULL,
260            category_id INTEGER NOT NULL,
261            question text NOT NULL,
262            created VARCHAR(20) NOT NULL,
263            is_visible char(1) default \'Y\',
264            answer_id INTEGER NOT NULL DEFAULT 0,
265            PRIMARY KEY (id))',
266        'faqright' => 'CREATE TABLE %sfaqright (
267            right_id INTEGER NOT NULL,
268            name VARCHAR(50) NULL,
269            description text NULL,
270            for_users INTEGER NULL DEFAULT 1,
271            for_groups INTEGER NULL DEFAULT 1,
272            for_sections INTEGER NULL DEFAULT 1,
273            PRIMARY KEY (right_id))',
274        'faqsearches' => 'CREATE TABLE %sfaqsearches (
275            id INTEGER NOT NULL ,
276            lang VARCHAR(5) NOT NULL ,
277            searchterm VARCHAR(255) NOT NULL ,
278            searchdate DATETIME,
279            PRIMARY KEY (id, lang))',
280        'faqseo' => 'CREATE TABLE %sfaqseo (
281            id INT NOT NULL,
282            type VARCHAR(32) NOT NULL,
283            reference_id INT NOT NULL,
284            reference_language VARCHAR(5) NOT NULL,
285            title TEXT NULL,
286            description TEXT NULL,
287            slug TEXT NULL,
288            created DATE NOT NULL DEFAULT (date(\'now\')),
289            PRIMARY KEY (id))',
290        'faqsessions' => 'CREATE TABLE %sfaqsessions (
291            sid INTEGER NOT NULL,
292            user_id INTEGER NOT NULL,
293            ip VARCHAR(64) NOT NULL,
294            time INTEGER NOT NULL,
295            PRIMARY KEY (sid))',
296        'faqsessions_idx' => 'CREATE INDEX idx_time ON %sfaqsessions (time)',
297        'faqsearches_searchterm_idx' => 'CREATE INDEX idx_faqsearches_searchterm ON %sfaqsearches (searchterm)',
298        'faqsearches_date_term_idx' => 'CREATE INDEX idx_faqsearches_date_term ON %sfaqsearches (searchdate, searchterm)',
299        'faqsearches_date_term_lang_idx' => 'CREATE INDEX idx_faqsearches_date_term_lang ON %sfaqsearches (searchdate, searchterm, lang)',
300        'faqstopwords' => 'CREATE TABLE %sfaqstopwords (
301            id INTEGER NOT NULL,
302            lang VARCHAR(5) NOT NULL,
303            stopword VARCHAR(64) NOT NULL,
304            PRIMARY KEY (id, lang))',
305        'faqtags' => 'CREATE TABLE %sfaqtags (
306            tagging_id INTEGER NOT NULL,
307            tagging_name VARCHAR(255) NOT NULL ,
308            PRIMARY KEY (tagging_id, tagging_name))',
309        'faquser' => 'CREATE TABLE %sfaquser (
310            user_id INTEGER NOT NULL,
311            login VARCHAR(128) NOT NULL,
312            session_id VARCHAR(150) NULL,
313            session_timestamp INTEGER NULL,
314            ip VARCHAR(64) NULL,
315            account_status VARCHAR(50) NULL,
316            last_login VARCHAR(14) NULL,
317            auth_source VARCHAR(100) NULL,
318            member_since VARCHAR(14) NULL,
319            remember_me VARCHAR(150) NULL,
320            success INT(1) NULL DEFAULT 1,
321            is_superadmin INT(1) NULL DEFAULT 0,
322            login_attempts INT(1) NULL DEFAULT 0,
323            refresh_token TEXT NULL DEFAULT NULL,
324            access_token TEXT NULL DEFAULT NULL,
325            code_verifier VARCHAR(255) NULL DEFAULT NULL,
326            jwt TEXT NULL DEFAULT NULL,
327            webauthnkeys TEXT NULL DEFAULT NULL,
328            PRIMARY KEY (user_id))',
329        'faquserdata' => 'CREATE TABLE %sfaquserdata (
330            user_id INTEGER NOT NULL,
331            last_modified VARCHAR(14) NULL,
332            display_name VARCHAR(128) NULL,
333            email VARCHAR(128) NULL,
334            keycloak_sub VARCHAR(255) NULL,
335            is_visible INT(1) NULL DEFAULT 0,
336            twofactor_enabled INT(1) NULL DEFAULT 0,
337            secret VARCHAR(128) NULL DEFAULT NULL)',
338        'faquserlogin' => 'CREATE TABLE %sfaquserlogin (
339            login VARCHAR(128) NOT NULL,
340            pass VARCHAR(80) NULL,
341            domain VARCHAR(255) NULL,
342            PRIMARY KEY (login))',
343        'faquser_group' => 'CREATE TABLE %sfaquser_group (
344            user_id INTEGER NOT NULL,
345            group_id INTEGER NOT NULL,
346            PRIMARY KEY (user_id, group_id))',
347        'faquser_right' => 'CREATE TABLE %sfaquser_right (
348            user_id INTEGER NOT NULL,
349            right_id INTEGER NOT NULL,
350            PRIMARY KEY (user_id, right_id))',
351        'faqvisits' => 'CREATE TABLE %sfaqvisits (
352            id INTEGER NOT NULL,
353            lang VARCHAR(5) NOT NULL,
354            visits INTEGER NOT NULL,
355            last_visit INTEGER NOT NULL,
356            PRIMARY KEY (id, lang))',
357        'faqvoting' => 'CREATE TABLE %sfaqvoting (
358            id INTEGER NOT NULL,
359            artikel SMALLINT NOT NULL,
360            vote SMALLINT NOT NULL,
361            usr SMALLINT NOT NULL,
362            datum VARCHAR(20) DEFAULT \'\',
363            ip VARCHAR(15) DEFAULT \'\',
364            PRIMARY KEY (id))',
365        'faqchat_messages' => 'CREATE TABLE %sfaqchat_messages (
366            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
367            sender_id INTEGER NOT NULL,
368            recipient_id INTEGER NOT NULL,
369            message TEXT NOT NULL,
370            is_read INTEGER NOT NULL DEFAULT 0,
371            created_at DATETIME DEFAULT CURRENT_TIMESTAMP)',
372        'faqchat_messages_idx_sender' => 'CREATE INDEX idx_chat_sender ON %sfaqchat_messages (sender_id)',
373        'faqchat_messages_idx_recipient' => 'CREATE INDEX idx_chat_recipient ON %sfaqchat_messages (recipient_id)',
374        'faqchat_messages_idx_conversation' => 'CREATE INDEX idx_chat_conversation ON %sfaqchat_messages (sender_id, recipient_id)',
375        'faqchat_messages_idx_created' => 'CREATE INDEX idx_chat_created ON %sfaqchat_messages (created_at)',
376    ];
377
378    /**
379     * Constructor.
380     */
381    public function __construct(Configuration $configuration)
382    {
383        $this->configuration = $configuration;
384    }
385
386    /**
387     * Executes all CREATE TABLE and CREATE INDEX statements.
388     *
389     *
390     */
391    public function createTables(string $prefix = '', ?string $schema = null): bool
392    {
393        // SQLite does not support schema-based isolation; use separate database files instead.
394
395        foreach ($this->createTableStatements as $createTableStatement) {
396            $result = $this->configuration->getDb()->query(sprintf($createTableStatement, $prefix));
397
398            if (!$result) {
399                return false;
400            }
401        }
402
403        return true;
404    }
405}