summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Regad <dregad@mantisbt.org>2025-07-21 00:55:27 +0200
committerDamien Regad <dregad@mantisbt.org>2025-08-03 18:05:05 +0200
commitbe6033941f6fbe1f4058b669fd0e6462bb627a36 (patch)
tree67c6fd7ae7b04e4b74cf07d39fd920d5df8a72c4
parent5fe4fc8e5c6cd1e202d540203106f483f3aa45c2 (diff)
downloadadodb-be6033941f6fbe1f4058b669fd0e6462bb627a36.tar.gz
adodb-be6033941f6fbe1f4058b669fd0e6462bb627a36.tar.bz2
adodb-be6033941f6fbe1f4058b669fd0e6462bb627a36.zip
Refactor metaForeignKeys() method
Use a single, more advanced regex to parse the table SQL, allowing identification of foreign key definitions with a single pass, instead of several preg_split/preg_match calls. The new regex recognizes both column and table constraints, and allows composite keys too. Case conversion (when $upper parameter is true) is performed within the foreach loop that builds the return array, instead of calling array_change_key_case() at the end. Fixes #1078, #1079, #1080
-rw-r--r--drivers/adodb-sqlite3.inc.php36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/adodb-sqlite3.inc.php b/drivers/adodb-sqlite3.inc.php
index 171a6c76..026e0392 100644
--- a/drivers/adodb-sqlite3.inc.php
+++ b/drivers/adodb-sqlite3.inc.php
@@ -221,33 +221,31 @@ class ADODB_sqlite3 extends ADOConnection {
FROM sqlite_master
WHERE sql NOTNULL
AND LOWER(name) = ?";
-
$tableSql = $this->getOne($sql, [strtolower($table)]);
- $fkeyList = array();
- $ylist = preg_split("/,+/", $tableSql);
- foreach ($ylist as $y) {
- if (!preg_match('/FOREIGN/i', $y)) {
- continue;
- }
- $matches = false;
- preg_match_all('/\((.+?)\)/i', $y, $matches);
- $tmatches = false;
- preg_match_all('/REFERENCES (.+?)\(/i', $y, $tmatches);
+ // 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();
+ 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];
+ $fkeyList[$ref_table][$src_col] = $ref_col;
} else {
- $fkeyList[$tmatches[1][0]][] = $matches[1][0] . '=' . $matches[1][1];
+ $fkeyList[$ref_table][] = $src_col . '=' . $ref_col;
}
}
- if ($associative) {
- $fkeyList = array_change_key_case($fkeyList, $upper ? CASE_UPPER : CASE_LOWER);
- }
return $fkeyList;
}