diff options
| author | Damien Regad <dregad@mantisbt.org> | 2025-08-03 18:26:39 +0200 |
|---|---|---|
| committer | Damien Regad <dregad@mantisbt.org> | 2025-08-03 18:26:39 +0200 |
| commit | 29d4a98adf860e3193d6a9edf6fdb19d293a5fc9 (patch) | |
| tree | fb58196b7606192cdfbdd3f12fe582d78c3e90ff /drivers/adodb-sqlite3.inc.php | |
| parent | b32d1eb70a079c78b1d45266b1f442df9e6ffffd (diff) | |
| parent | 38ce257600e67b1e854f2e9054166569cff4bf6b (diff) | |
| download | adodb-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.php | 207 |
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; |
