summaryrefslogtreecommitdiff
path: root/drivers/adodb-sqlite3.inc.php
diff options
context:
space:
mode:
authorDamien Regad <dregad@mantisbt.org>2025-08-03 18:26:39 +0200
committerDamien Regad <dregad@mantisbt.org>2025-08-03 18:26:39 +0200
commit29d4a98adf860e3193d6a9edf6fdb19d293a5fc9 (patch)
treefb58196b7606192cdfbdd3f12fe582d78c3e90ff /drivers/adodb-sqlite3.inc.php
parentb32d1eb70a079c78b1d45266b1f442df9e6ffffd (diff)
parent38ce257600e67b1e854f2e9054166569cff4bf6b (diff)
downloadadodb-29d4a98adf860e3193d6a9edf6fdb19d293a5fc9.tar.gz
adodb-29d4a98adf860e3193d6a9edf6fdb19d293a5fc9.tar.bz2
adodb-29d4a98adf860e3193d6a9edf6fdb19d293a5fc9.zip
Merge tag 'v5.22.10'
# Conflicts: # adodb.inc.php # docs/changelog.md
Diffstat (limited to 'drivers/adodb-sqlite3.inc.php')
-rw-r--r--drivers/adodb-sqlite3.inc.php207
1 files changed, 78 insertions, 129 deletions
diff --git a/drivers/adodb-sqlite3.inc.php b/drivers/adodb-sqlite3.inc.php
index e6bc9014..27a1562a 100644
--- a/drivers/adodb-sqlite3.inc.php
+++ b/drivers/adodb-sqlite3.inc.php
@@ -19,6 +19,9 @@
*
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
+ *
+ * @TODO Duplicate code is due to the legacy sqlite driver - delete this when removing the old driver
+ * @noinspection DuplicatedCode
*/
// security - hide paths
@@ -95,7 +98,6 @@ class ADODB_sqlite3 extends ADOConnection {
{
$fieldobj = $t;
$t = $fieldobj->type;
- $len = $fieldobj->max_length;
}
$t = strtoupper($t);
@@ -162,28 +164,30 @@ class ADODB_sqlite3 extends ADOConnection {
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
- $false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->fetchMode !== false) {
$savem = $this->SetFetchMode(false);
}
- $rs = $this->Execute("PRAGMA table_info('$table')");
+
+ $rs = $this->execute("PRAGMA table_info(?)", array($table));
+
if (isset($savem)) {
$this->SetFetchMode($savem);
}
+
if (!$rs) {
$ADODB_FETCH_MODE = $save;
- return $false;
+ return false;
}
+
$arr = array();
while ($r = $rs->FetchRow()) {
- $type = explode('(',$r['type']);
+ $type = explode('(', $r['type']);
$size = '';
- if (sizeof($type)==2) {
- $size = trim($type[1],')');
+ if (sizeof($type) == 2) {
+ $size = trim($type[1], ')');
}
- $fn = strtoupper($r['name']);
$fld = new ADOFieldObject;
$fld->name = $r['name'];
$fld->type = $type[0];
@@ -192,7 +196,7 @@ class ADODB_sqlite3 extends ADOConnection {
$fld->default_value = $r['dflt_value'];
$fld->scale = 0;
if (isset($r['pk']) && $r['pk']) {
- $fld->primary_key=1;
+ $fld->primary_key = 1;
}
if ($save == ADODB_FETCH_NUM) {
$arr[] = $fld;
@@ -207,58 +211,44 @@ class ADODB_sqlite3 extends ADOConnection {
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
- global $ADODB_FETCH_MODE;
- if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC
- || $this->fetchMode == ADODB_FETCH_ASSOC)
- $associative = true;
+ global $ADODB_FETCH_MODE;
+ if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) {
+ $associative = true;
+ }
- /*
- * Read sqlite master to find foreign keys
- */
+ // Read sqlite master to find foreign keys
$sql = "SELECT sql
- FROM (
- SELECT sql sql, type type, tbl_name tbl_name, name name
- FROM sqlite_master
- )
- WHERE type != 'meta'
- AND sql NOTNULL
- AND LOWER(name) ='" . strtolower($table) . "'";
+ FROM sqlite_master
+ WHERE sql NOTNULL
+ AND LOWER(name) = ?";
+ $tableSql = $this->getOne($sql, [strtolower($table)]);
- $tableSql = $this->getOne($sql);
+ // Regex will identify foreign keys in both column and table constraints
+ // Reference: https://sqlite.org/syntax/foreign-key-clause.html
+ // Subpatterns: 1/2 = source columns; 3 = parent table; 4 = parent columns.
+ preg_match_all(
+ '/[(,]\s*(?:FOREIGN\s+KEY\s*\(([^)]+)\)|(\w+).*?)\s*REFERENCES\s+(\w+|"[^"]+")\(([^)]+)\)/i',
+ $tableSql,
+ $fkeyMatches,
+ PREG_SET_ORDER
+ );
$fkeyList = array();
- $ylist = preg_split("/,+/",$tableSql);
- foreach ($ylist as $y)
- {
- if (!preg_match('/FOREIGN/',$y))
- continue;
-
- $matches = false;
- preg_match_all('/\((.+?)\)/i',$y,$matches);
- $tmatches = false;
- preg_match_all('/REFERENCES (.+?)\(/i',$y,$tmatches);
+ foreach ($fkeyMatches as $fkey) {
+ $src_col = $fkey[1] ?: $fkey[2];
+ $ref_table = $upper ? strtoupper($fkey[3]) : $fkey[3];
+ $ref_col = $fkey[4];
- if ($associative)
- {
- if (!isset($fkeyList[$tmatches[1][0]]))
- $fkeyList[$tmatches[1][0]] = array();
- $fkeyList[$tmatches[1][0]][$matches[1][0]] = $matches[1][1];
+ if ($associative) {
+ $fkeyList[$ref_table][$src_col] = $ref_col;
+ } else {
+ $fkeyList[$ref_table][] = $src_col . '=' . $ref_col;
}
- else
- $fkeyList[$tmatches[1][0]][] = $matches[1][0] . '=' . $matches[1][1];
}
- if ($associative)
- {
- if ($upper)
- $fkeyList = array_change_key_case($fkeyList,CASE_UPPER);
- else
- $fkeyList = array_change_key_case($fkeyList,CASE_LOWER);
- }
return $fkeyList;
}
-
function _init($parentDriver)
{
$parentDriver->hasTransactions = false;
@@ -369,24 +359,24 @@ class ADODB_sqlite3 extends ADOConnection {
*/
var $_genSeqSQL = "create table %s (id integer)";
- function GenID($seq='adodbseq',$start=1)
+ function GenID($seqname='adodbseq', $startID=1)
{
// if you have to modify the parameter below, your database is overloaded,
// or you need to implement generation of id's yourself!
$MAXLOOPS = 100;
//$this->debug=1;
while (--$MAXLOOPS>=0) {
- @($num = $this->GetOne("select id from $seq"));
+ @($num = $this->GetOne("select id from $seqname"));
if ($num === false) {
- $this->Execute(sprintf($this->_genSeqSQL ,$seq));
- $start -= 1;
+ $this->Execute(sprintf($this->_genSeqSQL ,$seqname));
+ $startID -= 1;
$num = '0';
- $ok = $this->Execute("insert into $seq values($start)");
+ $ok = $this->Execute("insert into $seqname values($startID)");
if (!$ok) {
return false;
}
}
- $this->Execute("update $seq set id=id+1 where id=$num");
+ $this->Execute("update $seqname set id=id+1 where id=$num");
if ($this->affected_rows() > 0) {
$num += 1;
@@ -395,7 +385,7 @@ class ADODB_sqlite3 extends ADOConnection {
}
}
if ($fn = $this->raiseErrorFn) {
- $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
+ $fn($this->databaseType, 'GENID', -32000, "Unable to generate unique id after $MAXLOOPS attempts", $seqname, $num);
}
return false;
}
@@ -428,111 +418,70 @@ class ADODB_sqlite3 extends ADOConnection {
return $this->_connectionID->close();
}
- function metaIndexes($table, $primary = FALSE, $owner = false)
+ function metaIndexes($table, $primary = false, $owner = false)
{
- $false = false;
// save old fetch mode
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- if ($this->fetchMode !== FALSE) {
- $savem = $this->SetFetchMode(FALSE);
+ if ($this->fetchMode !== false) {
+ $savem = $this->SetFetchMode(false);
}
- $pragmaData = array();
+ $table = strtolower($table);
- /*
- * If we want the primary key, we must extract
- * it from the table statement, and the pragma
- */
- if ($primary)
- {
- $sql = sprintf('PRAGMA table_info([%s]);',
- strtolower($table)
- );
- $pragmaData = $this->getAll($sql);
- }
-
- /*
- * Exclude the empty entry for the primary index
- */
- $sqlite = "SELECT name,sql
- FROM sqlite_master
- WHERE type='index'
- AND sql IS NOT NULL
- AND LOWER(tbl_name)='%s'";
-
- $SQL = sprintf($sqlite,
- strtolower($table)
- );
-
- $rs = $this->execute($SQL);
+ // Exclude the empty entry for the primary index
+ $sql = "SELECT name,sql
+ FROM sqlite_master
+ WHERE type='index'
+ AND sql IS NOT NULL
+ AND LOWER(tbl_name)=?";
+ $rs = $this->execute($sql, [$table]);
if (!is_object($rs)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
- return $false;
+ return false;
}
- $indexes = array ();
-
- while ($row = $rs->FetchRow())
- {
+ $indexes = array();
+ while ($row = $rs->FetchRow()) {
if (!isset($indexes[$row[0]])) {
$indexes[$row[0]] = array(
- 'unique' => preg_match("/unique/i",$row[1]),
- 'columns' => array()
+ 'unique' => preg_match("/unique/i", $row[1]),
);
}
- /**
- * The index elements appear in the SQL statement
- * in cols[1] between parentheses
- * e.g CREATE UNIQUE INDEX ware_0 ON warehouse (org,warehouse)
- */
- preg_match_all('/\((.*)\)/',$row[1],$indexExpression);
- $indexes[$row[0]]['columns'] = array_map('trim',explode(',',$indexExpression[1][0]));
+ // Index elements appear in the SQL statement in cols[1] between parentheses
+ // e.g CREATE UNIQUE INDEX ware_0 ON warehouse (org,warehouse)
+ preg_match_all('/\((.*)\)/', $row[1], $indexExpression);
+ $indexes[$row[0]]['columns'] = array_map('trim', explode(',', $indexExpression[1][0]));
}
- if (isset($savem)) {
- $this->SetFetchMode($savem);
- $ADODB_FETCH_MODE = $save;
- }
-
- /*
- * If we want primary, add it here
- */
+ // If we want the primary key, we must extract it from the pragma
if ($primary){
-
- /*
- * Check the previously retrieved pragma to search
- * with a closure
- */
-
+ $pragmaData = $this->getAll('PRAGMA table_info(?);', [$table]);
$pkIndexData = array('unique'=>1,'columns'=>array());
$pkCallBack = function ($value, $key) use (&$pkIndexData) {
-
- /*
- * As we iterate the elements check for pk index and sort
- */
- if ($value[5] > 0)
- {
+ // As we iterate the elements check for pk index
+ if ($value[5] > 0) {
$pkIndexData['columns'][$value[5]] = strtolower($value[1]);
- ksort($pkIndexData['columns']);
}
};
+ array_walk($pragmaData, $pkCallBack);
- array_walk($pragmaData,$pkCallBack);
-
- /*
- * If we found no columns, there is no
- * primary index
- */
- if (count($pkIndexData['columns']) > 0)
+ // If we found no columns, there is no primary index
+ if (count($pkIndexData['columns']) > 0) {
$indexes['PRIMARY'] = $pkIndexData;
+ }
+ }
+
+ if (isset($savem)) {
+ $this->SetFetchMode($savem);
+ $ADODB_FETCH_MODE = $save;
}
return $indexes;