diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d9018e5261..6450aaabdb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -124,8 +124,8 @@ jobs: db: "mysql:8.0" - php: '8.0' db: "mysql:5.7" - - php: '8.1' - db: "mysql:5.7" + #- php: '8.1' + # db: "mysql:5.7" name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }} @@ -243,6 +243,16 @@ jobs: db: "postgres:12" - php: '7.1' db: "postgres:13" + - php: '7.2' + db: "postgres:13" + - php: '7.3' + db: "postgres:13" + - php: '7.4' + db: "postgres:13" + - php: '8.0' + db: "postgres:12" + - php: '8.0' + db: "postgres:13" name: PHP ${{ matrix.php }} - ${{ matrix.db }} diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php index 52a5b6b546..7541d1e6b6 100644 --- a/phpBB/phpbb/db/driver/postgres.php +++ b/phpBB/phpbb/db/driver/postgres.php @@ -277,9 +277,10 @@ class postgres extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + $safe_query_id = $this->clean_query_id($query_id); + if ($cache && $cache->sql_exists($safe_query_id)) { - return $cache->sql_fetchrow($query_id); + return $cache->sql_fetchrow($safe_query_id); } return ($query_id) ? pg_fetch_assoc($query_id, null) : false; @@ -297,14 +298,47 @@ class postgres extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + $safe_query_id = $this->clean_query_id($query_id); + if ($cache && $cache->sql_exists($safe_query_id)) { - return $cache->sql_rowseek($rownum, $query_id); + return $cache->sql_rowseek($rownum, $safe_query_id); } return ($query_id) ? @pg_result_seek($query_id, $rownum) : false; } + /** + * {@inheritDoc} + */ + function sql_fetchfield($field, $rownum = false, $query_id = false) + { + global $cache; + + if ($query_id === false) + { + $query_id = $this->query_result; + } + + if ($query_id) + { + if ($rownum !== false) + { + $this->sql_rowseek($rownum, $query_id); + } + + $safe_query_id = $this->clean_query_id($query_id); + if ($cache && !is_object($query_id) && $cache->sql_exists($safe_query_id)) + { + return $cache->sql_fetchfield($safe_query_id, $field); + } + + $row = $this->sql_fetchrow($query_id); + return (isset($row[$field])) ? $row[$field] : false; + } + + return false; + } + /** * {@inheritDoc} */ @@ -346,14 +380,15 @@ class postgres extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) + $safe_query_id = $this->clean_query_id($query_id); + if ($cache && !is_object($query_id) && $cache->sql_exists($safe_query_id)) { - return $cache->sql_freeresult($query_id); + return $cache->sql_freeresult($safe_query_id); } - if (isset($this->open_queries[(int) $query_id])) + if (isset($this->open_queries[$safe_query_id])) { - unset($this->open_queries[(int) $query_id]); + unset($this->open_queries[$safe_query_id]); return pg_free_result($query_id); } @@ -431,6 +466,11 @@ class postgres extends \phpbb\db\driver\driver */ function _sql_close() { + // Released resources are already closed, return true in this case + if (!is_resource($this->db_connect_id)) + { + return true; + } return @pg_close($this->db_connect_id); } @@ -505,4 +545,16 @@ class postgres extends \phpbb\db\driver\driver { return '"' . $msg . '"'; } + + /** + * Ensure query ID can be used by cache + * + * @param resource|int|string $query_id Mixed type query id + * + * @return int|string Query id in string or integer format + */ + private function clean_query_id($query_id) + { + return is_resource($query_id) ? (int) $query_id : $query_id; + } } diff --git a/phpBB/phpbb/db/tools/postgres.php b/phpBB/phpbb/db/tools/postgres.php index 7cb024d4f6..573b40fe5d 100644 --- a/phpBB/phpbb/db/tools/postgres.php +++ b/phpBB/phpbb/db/tools/postgres.php @@ -96,6 +96,24 @@ class postgres extends tools return $tables; } + /** + * {@inheritDoc} + */ + function sql_table_exists($table_name) + { + $sql = "SELECT CAST(EXISTS( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = '" . $this->db->sql_escape($table_name) . "' + ) AS INTEGER)"; + $result = $this->db->sql_query_limit($sql, 1); + $row = $this->db->sql_fetchrow($result); + $table_exists = (booL) $row['exists']; + $this->db->sql_freeresult($result); + + return $table_exists; + } + /** * {@inheritDoc} */ diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index ebaf573753..c46bbe11c3 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -29,7 +29,7 @@ abstract class phpbb_database_test_case extends TestCase static protected $install_schema_file; - static protected $phpunit_version; + static protected $phpunit_version; public function __construct($name = NULL, array $data = [], $dataName = '') {