Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
Driver
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
5 / 5
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getDbs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTables
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getFks
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 insertBatch
n/a
0 / 0
n/a
0 / 0
5
 returning
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php declare(strict_types=1);
2/**
3 * Query
4 *
5 * SQL Query Builder / Database Abstraction Layer
6 *
7 * PHP version 8.1
8 *
9 * @package     Query
10 * @author      Timothy J. Warren <tim@timshome.page>
11 * @copyright   2012 - 2023 Timothy J. Warren
12 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13 * @link        https://git.timshomepage.net/aviat/Query
14 * @version     4.0.0
15 */
16
17namespace Query\Drivers\Sqlite;
18
19use InvalidArgumentException;
20
21use PDO;
22use Query\Drivers\AbstractDriver;
23use function is_array;
24
25/**
26 * SQLite specific class
27 */
28class Driver extends AbstractDriver
29{
30    /**
31     * SQLite has a truncate optimization,
32     * but no support for the actual keyword
33     */
34    protected bool $hasTruncate = FALSE;
35
36    /**
37     * Open SQLite Database
38     */
39    public function __construct(string $dsn, ?string $user=NULL, ?string $pass=NULL, array $driverOptions=[])
40    {
41        if ( ! str_contains($dsn, 'sqlite:'))
42        {
43            $dsn = "sqlite:{$dsn}";
44        }
45
46        parent::__construct($dsn, $user, $pass);
47    }
48
49    /**
50     * Return list of dbs for the current connection, if possible. Meaningless for SQLite.
51     */
52    public function getDbs(): ?array
53    {
54        return NULL;
55    }
56
57    /**
58     * List tables for the current database
59     */
60    public function getTables(): array
61    {
62        $sql = $this->getSql()->tableList();
63        $res = $this->query($sql);
64
65        return dbFilter($res->fetchAll(PDO::FETCH_ASSOC), 'name');
66    }
67
68    /**
69     * Retrieve foreign keys for the table
70     */
71    public function getFks(string $table): array
72    {
73        $returnRows = [];
74
75        foreach (parent::getFks($table) as $row)
76        {
77            $returnRows[] = [
78                'child_column' => $row['from'],
79                'parent_table' => $row['table'],
80                'parent_column' => $row['to'],
81                'update' => $row['on_update'],
82                'delete' => $row['on_delete'],
83            ];
84        }
85
86        return $returnRows;
87    }
88
89    /**
90     * Create sql for batch insert
91     *
92     * @codeCoverageIgnore
93     * @return array[]|null[]|string[]
94     */
95    public function insertBatch(string $table, array $data=[]): array
96    {
97        // If greater than version 3.7.11, supports the same syntax as
98        // MySQL and Postgres
99        if (version_compare($this->getVersion(), '3.7.11', '>='))
100        {
101            return parent::insertBatch($table, $data);
102        }
103
104        // --------------------------------------------------------------------------
105        // Otherwise, do a union query as an analogue to a 'proper' batch insert
106        // --------------------------------------------------------------------------
107
108        // Each member of the data array needs to be an array
109        if ( ! is_array(current($data)))
110        {
111            throw new InvalidArgumentException('$data must be an array of arrays');
112        }
113
114        // Start the block of sql statements
115        $table = $this->quoteTable($table);
116        $sql = "INSERT INTO {$table} \n";
117
118        // Create a key-value mapping for each field
119        $first = array_shift($data);
120        $cols = [];
121
122        foreach ($first as $colName => $datum)
123        {
124            $cols[] = $this->_quote($datum) . ' AS ' . $this->quoteIdent($colName);
125        }
126        $sql .= 'SELECT ' . implode(', ', $cols) . "\n";
127
128        foreach ($data as $union)
129        {
130            $vals = array_map([$this, 'quote'], $union);
131            $sql .= 'UNION SELECT ' . implode(',', $vals) . "\n";
132        }
133
134        return [$sql, NULL];
135    }
136
137    /**
138     * Generate the returning clause for the current database
139     */
140    public function returning(string $query, string $select): string
141    {
142        // Return the same query, as the returning clause is not supported
143        return $query;
144    }
145}