primo commit
This commit is contained in:
		
							
								
								
									
										177
									
								
								libraries/vendor/joomla/database/src/Command/ExportCommand.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								libraries/vendor/joomla/database/src/Command/ExportCommand.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,177 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Command; | ||||
|  | ||||
| use Joomla\Archive\Archive; | ||||
| use Joomla\Archive\Zip; | ||||
| use Joomla\Console\Command\AbstractCommand; | ||||
| use Joomla\Database\DatabaseDriver; | ||||
| use Joomla\Database\Exception\UnsupportedAdapterException; | ||||
| use Joomla\Filesystem\File; | ||||
| use Symfony\Component\Console\Input\InputInterface; | ||||
| use Symfony\Component\Console\Input\InputOption; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
| use Symfony\Component\Console\Style\SymfonyStyle; | ||||
|  | ||||
| /** | ||||
|  * Console command for exporting the database | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class ExportCommand extends AbstractCommand | ||||
| { | ||||
|     /** | ||||
|      * The default command name | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected static $defaultName = 'database:export'; | ||||
|  | ||||
|     /** | ||||
|      * Database connector | ||||
|      * | ||||
|      * @var    DatabaseDriver | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $db; | ||||
|  | ||||
|     /** | ||||
|      * Instantiate the command. | ||||
|      * | ||||
|      * @param   DatabaseDriver  $db  Database connector | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __construct(DatabaseDriver $db) | ||||
|     { | ||||
|         $this->db = $db; | ||||
|  | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Internal function to execute the command. | ||||
|      * | ||||
|      * @param   InputInterface   $input   The input to inject into the command. | ||||
|      * @param   OutputInterface  $output  The output to inject into the command. | ||||
|      * | ||||
|      * @return  integer  The command exit code | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function doExecute(InputInterface $input, OutputInterface $output): int | ||||
|     { | ||||
|         $symfonyStyle = new SymfonyStyle($input, $output); | ||||
|  | ||||
|         $symfonyStyle->title('Exporting Database'); | ||||
|  | ||||
|         $totalTime = microtime(true); | ||||
|  | ||||
|         if (!class_exists(File::class)) { | ||||
|             $symfonyStyle->error('The "joomla/filesystem" Composer package is not installed, cannot create an export.'); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         // Make sure the database supports exports before we get going | ||||
|         try { | ||||
|             $exporter = $this->db->getExporter() | ||||
|                 ->withStructure(); | ||||
|         } catch (UnsupportedAdapterException $e) { | ||||
|             $symfonyStyle->error(sprintf('The "%s" database driver does not support exporting data.', $this->db->getName())); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         $folderPath = $input->getOption('folder'); | ||||
|         $tableName  = $input->getOption('table'); | ||||
|         $zip        = $input->getOption('zip'); | ||||
|  | ||||
|         $zipFile = $folderPath . '/data_exported_' . date("Y-m-d\TH-i-s") . '.zip'; | ||||
|         $tables  = $this->db->getTableList(); | ||||
|         $prefix  = $this->db->getPrefix(); | ||||
|  | ||||
|         if ($tableName) { | ||||
|             if (!\in_array($tableName, $tables)) { | ||||
|                 $symfonyStyle->error(sprintf('The %s table does not exist in the database.', $tableName)); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             $tables = [$tableName]; | ||||
|         } | ||||
|  | ||||
|         if ($zip) { | ||||
|             if (!class_exists(Archive::class)) { | ||||
|                 $symfonyStyle->error('The "joomla/archive" Composer package is not installed, cannot create ZIP files.'); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             /** @var Zip $zipArchive */ | ||||
|             $zipArchive = (new Archive())->getAdapter('zip'); | ||||
|  | ||||
|             $filenames = []; | ||||
|             $zipFilesArray = []; | ||||
|         } | ||||
|  | ||||
|         foreach ($tables as $table) { | ||||
|             // If an empty prefix is in use then we will dump all tables, otherwise the prefix must match | ||||
|             if (strlen($prefix) === 0 || strpos(substr($table, 0, strlen($prefix)), $prefix) !== false) { | ||||
|                 $taskTime = microtime(true); | ||||
|                 $filename = $folderPath . '/' . $table . '.xml'; | ||||
|  | ||||
|                 $symfonyStyle->text(sprintf('Processing the %s table', $table)); | ||||
|  | ||||
|                 $data = (string) $exporter->from($table)->withData(true); | ||||
|  | ||||
|                 if (file_exists($filename)) { | ||||
|                     File::delete($filename); | ||||
|                 } | ||||
|  | ||||
|                 File::write($filename, $data); | ||||
|  | ||||
|                 if ($zip) { | ||||
|                     $zipFilesArray[] = ['name' => $table . '.xml', 'data' => $data]; | ||||
|                     $filenames[] = $filename; | ||||
|                 } | ||||
|  | ||||
|                 $symfonyStyle->text(sprintf('Exported data for %s in %d seconds', $table, round(microtime(true) - $taskTime, 3))); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($zip) { | ||||
|             $zipArchive->create($zipFile, $zipFilesArray); | ||||
|             foreach ($filenames as $fname) { | ||||
|                 File::delete($fname); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $symfonyStyle->success(sprintf('Export completed in %d seconds', round(microtime(true) - $totalTime, 3))); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Configure the command. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function configure(): void | ||||
|     { | ||||
|         $this->setDescription('Export the database'); | ||||
|         $this->addOption('folder', null, InputOption::VALUE_OPTIONAL, 'Path to write the export files to', '.'); | ||||
|         $this->addOption('table', null, InputOption::VALUE_REQUIRED, 'The name of the database table to export'); | ||||
|         $this->addOption('zip', null, InputOption::VALUE_NONE, 'Flag indicating the export will be saved to a ZIP archive'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										251
									
								
								libraries/vendor/joomla/database/src/Command/ImportCommand.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								libraries/vendor/joomla/database/src/Command/ImportCommand.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,251 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| // phpcs:disable Generic.PHP.DeprecatedFunctions.Deprecated | ||||
|  | ||||
| namespace Joomla\Database\Command; | ||||
|  | ||||
| use Joomla\Archive\Archive; | ||||
| use Joomla\Archive\Exception\UnknownArchiveException; | ||||
| use Joomla\Console\Command\AbstractCommand; | ||||
| use Joomla\Database\DatabaseDriver; | ||||
| use Joomla\Database\Exception\ExecutionFailureException; | ||||
| use Joomla\Database\Exception\UnsupportedAdapterException; | ||||
| use Joomla\Filesystem\Exception\FilesystemException; | ||||
| use Joomla\Filesystem\File; | ||||
| use Joomla\Filesystem\Folder; | ||||
| use Symfony\Component\Console\Input\InputInterface; | ||||
| use Symfony\Component\Console\Input\InputOption; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
| use Symfony\Component\Console\Style\SymfonyStyle; | ||||
|  | ||||
| /** | ||||
|  * Console command for importing the database | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class ImportCommand extends AbstractCommand | ||||
| { | ||||
|     /** | ||||
|      * The default command name | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected static $defaultName = 'database:import'; | ||||
|  | ||||
|     /** | ||||
|      * Database connector | ||||
|      * | ||||
|      * @var    DatabaseDriver | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $db; | ||||
|  | ||||
|     /** | ||||
|      * Instantiate the command. | ||||
|      * | ||||
|      * @param   DatabaseDriver  $db  Database connector | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __construct(DatabaseDriver $db) | ||||
|     { | ||||
|         $this->db = $db; | ||||
|  | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks if the zip file contains database export files | ||||
|      * | ||||
|      * @param   string  $archive  A zip archive to analyze | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     private function checkZipFile(string $archive): void | ||||
|     { | ||||
|         if (!extension_loaded('zip')) { | ||||
|             throw new \RuntimeException('The PHP zip extension is not installed or is disabled'); | ||||
|         } | ||||
|  | ||||
|         $zip = zip_open($archive); | ||||
|  | ||||
|         if (!\is_resource($zip)) { | ||||
|             throw new \RuntimeException('Unable to open archive'); | ||||
|         } | ||||
|  | ||||
|         while ($file = @zip_read($zip)) { | ||||
|             if (strpos(zip_entry_name($file), $this->db->getPrefix()) === false) { | ||||
|                 zip_entry_close($file); | ||||
|                 @zip_close($zip); | ||||
|  | ||||
|                 throw new \RuntimeException('Unable to find table matching database prefix'); | ||||
|             } | ||||
|  | ||||
|             zip_entry_close($file); | ||||
|         } | ||||
|  | ||||
|         @zip_close($zip); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Internal function to execute the command. | ||||
|      * | ||||
|      * @param   InputInterface   $input   The input to inject into the command. | ||||
|      * @param   OutputInterface  $output  The output to inject into the command. | ||||
|      * | ||||
|      * @return  integer  The command exit code | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function doExecute(InputInterface $input, OutputInterface $output): int | ||||
|     { | ||||
|         $symfonyStyle = new SymfonyStyle($input, $output); | ||||
|  | ||||
|         $symfonyStyle->title('Importing Database'); | ||||
|  | ||||
|         $totalTime = microtime(true); | ||||
|  | ||||
|         // Make sure the database supports imports before we get going | ||||
|         try { | ||||
|             $importer = $this->db->getImporter() | ||||
|                 ->withStructure() | ||||
|                 ->asXml(); | ||||
|         } catch (UnsupportedAdapterException $e) { | ||||
|             $symfonyStyle->error(sprintf('The "%s" database driver does not support importing data.', $this->db->getName())); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         $folderPath = $input->getOption('folder'); | ||||
|         $tableName  = $input->getOption('table'); | ||||
|         $zipFile    = $input->getOption('zip'); | ||||
|  | ||||
|         if ($zipFile) { | ||||
|             if (!class_exists(File::class)) { | ||||
|                 $symfonyStyle->error('The "joomla/filesystem" Composer package is not installed, cannot process ZIP files.'); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             if (!class_exists(Archive::class)) { | ||||
|                 $symfonyStyle->error('The "joomla/archive" Composer package is not installed, cannot process ZIP files.'); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             $zipPath = $folderPath . '/' . $zipFile; | ||||
|  | ||||
|             try { | ||||
|                 $this->checkZipFile($zipPath); | ||||
|             } catch (\RuntimeException $e) { | ||||
|                 $symfonyStyle->error($e->getMessage()); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             $folderPath .= File::stripExt($zipFile); | ||||
|  | ||||
|             try { | ||||
|                 Folder::create($folderPath); | ||||
|             } catch (FilesystemException $e) { | ||||
|                 $symfonyStyle->error($e->getMessage()); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 (new Archive())->extract($zipPath, $folderPath); | ||||
|             } catch (UnknownArchiveException $e) { | ||||
|                 $symfonyStyle->error($e->getMessage()); | ||||
|                 Folder::delete($folderPath); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($tableName) { | ||||
|             $tables = [$tableName . '.xml']; | ||||
|         } else { | ||||
|             $tables = Folder::files($folderPath, '\.xml$'); | ||||
|         } | ||||
|  | ||||
|         foreach ($tables as $table) { | ||||
|             $taskTime = microtime(true); | ||||
|             $percorso = $folderPath . '/' . $table; | ||||
|  | ||||
|             // Check file | ||||
|             if (!file_exists($percorso)) { | ||||
|                 $symfonyStyle->error(sprintf('The %s file does not exist.', $table)); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             $tableName = str_replace('.xml', '', $table); | ||||
|             $symfonyStyle->text(sprintf('Importing %1$s from %2$s', $tableName, $table)); | ||||
|  | ||||
|             $importer->from(file_get_contents($percorso)); | ||||
|  | ||||
|             $symfonyStyle->text(sprintf('Processing the %s table', $tableName)); | ||||
|  | ||||
|             try { | ||||
|                 $this->db->dropTable($tableName, true); | ||||
|             } catch (ExecutionFailureException $e) { | ||||
|                 $symfonyStyle->error(sprintf('Error executing the DROP TABLE statement for %1$s: %2$s', $tableName, $e->getMessage())); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 $importer->mergeStructure(); | ||||
|             } catch (\Exception $e) { | ||||
|                 $symfonyStyle->error(sprintf('Error merging the structure for %1$s: %2$s', $tableName, $e->getMessage())); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 $importer->importData(); | ||||
|             } catch (\Exception $e) { | ||||
|                 $symfonyStyle->error(sprintf('Error importing the data for %1$s: %2$s', $tableName, $e->getMessage())); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|  | ||||
|             $symfonyStyle->text(sprintf('Imported data for %s in %d seconds', $table, round(microtime(true) - $taskTime, 3))); | ||||
|         } | ||||
|  | ||||
|         if ($zipFile) { | ||||
|             Folder::delete($folderPath); | ||||
|         } | ||||
|  | ||||
|         $symfonyStyle->success(sprintf('Import completed in %d seconds', round(microtime(true) - $totalTime, 3))); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Configure the command. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function configure(): void | ||||
|     { | ||||
|         $this->setDescription('Import the database'); | ||||
|         $this->addOption('folder', null, InputOption::VALUE_OPTIONAL, 'Path to the folder containing files to import', '.'); | ||||
|         $this->addOption('zip', null, InputOption::VALUE_REQUIRED, 'The name of a ZIP file to import'); | ||||
|         $this->addOption('table', null, InputOption::VALUE_REQUIRED, 'The name of the database table to import'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										29
									
								
								libraries/vendor/joomla/database/src/DatabaseAwareInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								libraries/vendor/joomla/database/src/DatabaseAwareInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2022 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Defines the interface for a DatabaseInterface aware class. | ||||
|  * | ||||
|  * @since  2.1.0 | ||||
|  */ | ||||
| interface DatabaseAwareInterface | ||||
| { | ||||
|     /** | ||||
|      * Set the database. | ||||
|      * | ||||
|      * @param   DatabaseInterface  $db  The database. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.1.0 | ||||
|      */ | ||||
|     public function setDatabase(DatabaseInterface $db): void; | ||||
| } | ||||
							
								
								
									
										59
									
								
								libraries/vendor/joomla/database/src/DatabaseAwareTrait.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								libraries/vendor/joomla/database/src/DatabaseAwareTrait.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2022 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| use Joomla\Database\Exception\DatabaseNotFoundException; | ||||
|  | ||||
| /** | ||||
|  * Defines the trait for a Database Aware Class. | ||||
|  * | ||||
|  * @since  2.1.0 | ||||
|  */ | ||||
| trait DatabaseAwareTrait | ||||
| { | ||||
|     /** | ||||
|      * Database | ||||
|      * | ||||
|      * @var    DatabaseInterface | ||||
|      * @since  2.1.0 | ||||
|      */ | ||||
|     private $databaseAwareTraitDatabase; | ||||
|  | ||||
|     /** | ||||
|      * Get the database. | ||||
|      * | ||||
|      * @return  DatabaseInterface | ||||
|      * | ||||
|      * @since   2.1.0 | ||||
|      * @throws  DatabaseNotFoundException May be thrown if the database has not been set. | ||||
|      */ | ||||
|     protected function getDatabase(): DatabaseInterface | ||||
|     { | ||||
|         if ($this->databaseAwareTraitDatabase) { | ||||
|             return $this->databaseAwareTraitDatabase; | ||||
|         } | ||||
|  | ||||
|         throw new DatabaseNotFoundException('Database not set in ' . \get_class($this)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the database. | ||||
|      * | ||||
|      * @param   DatabaseInterface  $db  The database. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.1.0 | ||||
|      */ | ||||
|     public function setDatabase(DatabaseInterface $db): void | ||||
|     { | ||||
|         $this->databaseAwareTraitDatabase = $db; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										1896
									
								
								libraries/vendor/joomla/database/src/DatabaseDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1896
									
								
								libraries/vendor/joomla/database/src/DatabaseDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										47
									
								
								libraries/vendor/joomla/database/src/DatabaseEvents.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								libraries/vendor/joomla/database/src/DatabaseEvents.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Class defining the events dispatched by the database API | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| final class DatabaseEvents | ||||
| { | ||||
|     /** | ||||
|      * Private constructor to prevent instantiation of this class | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function __construct() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Database event which is dispatched after the connection to the database server is opened. | ||||
|      * | ||||
|      * Listeners to this event receive a `Joomla\Database\Event\ConnectionEvent` object. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const POST_CONNECT = 'onAfterConnect'; | ||||
|  | ||||
|     /** | ||||
|      * Database event which is dispatched after the connection to the database server is closed. | ||||
|      * | ||||
|      * Listeners to this event receive a `Joomla\Database\Event\ConnectionEvent` object. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const POST_DISCONNECT = 'onAfterDisconnect'; | ||||
| } | ||||
							
								
								
									
										308
									
								
								libraries/vendor/joomla/database/src/DatabaseExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								libraries/vendor/joomla/database/src/DatabaseExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,308 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework Database Exporter Class | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| abstract class DatabaseExporter | ||||
| { | ||||
|     /** | ||||
|      * The type of output format. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $asFormat = 'xml'; | ||||
|  | ||||
|     /** | ||||
|      * An array of cached data. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $cache = ['columns' => [], 'keys' => []]; | ||||
|  | ||||
|     /** | ||||
|      * The database connector to use for exporting structure and/or data. | ||||
|      * | ||||
|      * @var    DatabaseInterface | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $db; | ||||
|  | ||||
|     /** | ||||
|      * An array input sources (table names). | ||||
|      * | ||||
|      * @var    string[] | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $from = []; | ||||
|  | ||||
|     /** | ||||
|      * An array of options for the exporter. | ||||
|      * | ||||
|      * @var    \stdClass | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $options; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * Sets up the default options for the exporter. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->options = new \stdClass(); | ||||
|  | ||||
|         // Set up the class defaults: | ||||
|  | ||||
|         // Export not only structure | ||||
|         $this->withStructure(); | ||||
|         $this->withData(); | ||||
|  | ||||
|         // Export as xml. | ||||
|         $this->asXml(); | ||||
|  | ||||
|         // Default destination is a string using $output = (string) $exporter; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Magic function to exports the data to a string. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __toString() | ||||
|     { | ||||
|         $buffer = ''; | ||||
|  | ||||
|         try { | ||||
|             // Check everything is ok to run first. | ||||
|             $this->check(); | ||||
|  | ||||
|             // Get the format. | ||||
|             switch ($this->asFormat) { | ||||
|                 case 'xml': | ||||
|                 default: | ||||
|                     $buffer = $this->buildXml(); | ||||
|  | ||||
|                     break; | ||||
|             } | ||||
|         } catch (\Exception $e) { | ||||
|             // Do nothing | ||||
|         } | ||||
|  | ||||
|         return $buffer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the output option for the exporter to XML format. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function asXml() | ||||
|     { | ||||
|         $this->asFormat = 'xml'; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML data for the tables to export. | ||||
|      * | ||||
|      * @return  string  An XML string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     abstract protected function buildXml(); | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML structure to export. | ||||
|      * | ||||
|      * @return  array  An array of XML lines (strings). | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     abstract protected function buildXmlStructure(); | ||||
|  | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error is encountered. | ||||
|      */ | ||||
|     abstract public function check(); | ||||
|  | ||||
|     /** | ||||
|      * Specifies a list of table names to export. | ||||
|      * | ||||
|      * @param   string[]|string  $from  The name of a single table, or an array of the table names to export. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \InvalidArgumentException | ||||
|      */ | ||||
|     public function from($from) | ||||
|     { | ||||
|         if (\is_string($from)) { | ||||
|             $this->from = [$from]; | ||||
|         } elseif (\is_array($from)) { | ||||
|             $this->from = $from; | ||||
|         } else { | ||||
|             throw new \InvalidArgumentException('The exporter requires either a single table name or array of table names'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the generic name of the table, converting the database prefix to the wildcard string. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table. | ||||
|      * | ||||
|      * @return  string  The name of the table with the database prefix replaced with #__. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getGenericTableName($table) | ||||
|     { | ||||
|         $prefix = $this->db->getPrefix(); | ||||
|  | ||||
|         // Replace the magic prefix if found. | ||||
|         return preg_replace("|^$prefix|", '#__', $table); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the database connector to use for importing structure and/or data. | ||||
|      * | ||||
|      * @param   DatabaseInterface  $db  The database connector. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function setDbo(DatabaseInterface $db) | ||||
|     { | ||||
|         $this->db = $db; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets an internal option to export the structure of the input table(s). | ||||
|      * | ||||
|      * @param   boolean  $setting  True to export the structure, false to not. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function withStructure($setting = true) | ||||
|     { | ||||
|         $this->options->withStructure = (bool) $setting; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets an internal option to export the data of the input table(s). | ||||
|      * | ||||
|      * @param   boolean  $setting  True to export the data, false to not. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function withData($setting = false) | ||||
|     { | ||||
|         $this->options->withData = (bool) $setting; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML data to export. | ||||
|      * | ||||
|      * @return  array  An array of XML lines (strings). | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXmlData() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         foreach ($this->from as $table) { | ||||
|             // Replace the magic prefix if found. | ||||
|             $table = $this->getGenericTableName($table); | ||||
|  | ||||
|             // Get the details columns information. | ||||
|             $fields  = $this->db->getTableColumns($table, false); | ||||
|             $colblob = []; | ||||
|  | ||||
|             foreach ($fields as $field) { | ||||
|                 // Catch blob for conversion xml | ||||
|                 if ($field->Type == 'mediumblob') { | ||||
|                     $colblob[] = $field->Field; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $this->db->setQuery( | ||||
|                 $this->db->getQuery(true) | ||||
|                     ->select($this->db->quoteName(array_keys($fields))) | ||||
|                     ->from($this->db->quoteName($table)) | ||||
|             ); | ||||
|  | ||||
|             $rows = $this->db->loadObjectList(); | ||||
|  | ||||
|             if (!count($rows)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  <table_data name="' . $table . '">'; | ||||
|  | ||||
|             foreach ($rows as $row) { | ||||
|                 $buffer[] = '   <row>'; | ||||
|  | ||||
|                 foreach ($row as $key => $value) { | ||||
|                     if (!in_array($key, $colblob)) { | ||||
|                         if (is_null($value)) { | ||||
|                             $buffer[] = '    <field name="' . $key . '" value_is_null></field>'; | ||||
|                         } else { | ||||
|                             $buffer[] = '    <field name="' . $key . '">' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '</field>'; | ||||
|                         } | ||||
|                     } else { | ||||
|                         $buffer[] = '    <field name="' . $key . '">' . base64_encode($value) . '</field>'; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 $buffer[] = '   </row>'; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  </table_data>'; | ||||
|         } | ||||
|  | ||||
|         return $buffer; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										171
									
								
								libraries/vendor/joomla/database/src/DatabaseFactory.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								libraries/vendor/joomla/database/src/DatabaseFactory.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,171 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework Database Factory class | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class DatabaseFactory | ||||
| { | ||||
|     /** | ||||
|      * Method to return a database driver based on the given options. | ||||
|      * | ||||
|      * There are three global options and then the rest are specific to the database driver. The 'database' option determines which database is to | ||||
|      * be used for the connection. The 'select' option determines whether the connector should automatically select the chosen database. | ||||
|      * | ||||
|      * @param   string  $name     Name of the database driver you'd like to instantiate | ||||
|      * @param   array   $options  Parameters to be passed to the database driver. | ||||
|      * | ||||
|      * @return  DatabaseInterface | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  Exception\UnsupportedAdapterException if there is not a compatible database driver | ||||
|      */ | ||||
|     public function getDriver(string $name = 'mysqli', array $options = []): DatabaseInterface | ||||
|     { | ||||
|         // Sanitize the database connector options. | ||||
|         $options['driver']   = preg_replace('/[^A-Z0-9_\.-]/i', '', $name); | ||||
|         $options['database'] = $options['database'] ?? null; | ||||
|         $options['select']   = $options['select'] ?? true; | ||||
|         $options['factory']  = $options['factory'] ?? $this; | ||||
|  | ||||
|         // Derive the class name from the driver. | ||||
|         $class = __NAMESPACE__ . '\\' . ucfirst(strtolower($options['driver'])) . '\\' . ucfirst(strtolower($options['driver'])) . 'Driver'; | ||||
|  | ||||
|         // If the class still doesn't exist we have nothing left to do but throw an exception.  We did our best. | ||||
|         if (!class_exists($class)) { | ||||
|             throw new Exception\UnsupportedAdapterException(sprintf('Unable to load Database Driver: %s', $options['driver'])); | ||||
|         } | ||||
|  | ||||
|         return new $class($options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets an exporter class object. | ||||
|      * | ||||
|      * @param   string                  $name  Name of the driver you want an exporter for. | ||||
|      * @param   DatabaseInterface|null  $db    Optional database driver to inject into the query object. | ||||
|      * | ||||
|      * @return  DatabaseExporter | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  Exception\UnsupportedAdapterException if there is not a compatible database exporter | ||||
|      */ | ||||
|     public function getExporter(string $name, ?DatabaseInterface $db = null): DatabaseExporter | ||||
|     { | ||||
|         // Derive the class name from the driver. | ||||
|         $class = __NAMESPACE__ . '\\' . ucfirst(strtolower($name)) . '\\' . ucfirst(strtolower($name)) . 'Exporter'; | ||||
|  | ||||
|         // Make sure we have an exporter class for this driver. | ||||
|         if (!class_exists($class)) { | ||||
|             // If it doesn't exist we are at an impasse so throw an exception. | ||||
|             throw new Exception\UnsupportedAdapterException('Database Exporter not found.'); | ||||
|         } | ||||
|  | ||||
|         /** @var DatabaseExporter $o */ | ||||
|         $o = new $class(); | ||||
|  | ||||
|         if ($db) { | ||||
|             $o->setDbo($db); | ||||
|         } | ||||
|  | ||||
|         return $o; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets an importer class object. | ||||
|      * | ||||
|      * @param   string                  $name  Name of the driver you want an importer for. | ||||
|      * @param   DatabaseInterface|null  $db    Optional database driver to inject into the query object. | ||||
|      * | ||||
|      * @return  DatabaseImporter | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  Exception\UnsupportedAdapterException if there is not a compatible database importer | ||||
|      */ | ||||
|     public function getImporter(string $name, ?DatabaseInterface $db = null): DatabaseImporter | ||||
|     { | ||||
|         // Derive the class name from the driver. | ||||
|         $class = __NAMESPACE__ . '\\' . ucfirst(strtolower($name)) . '\\' . ucfirst(strtolower($name)) . 'Importer'; | ||||
|  | ||||
|         // Make sure we have an importer class for this driver. | ||||
|         if (!class_exists($class)) { | ||||
|             // If it doesn't exist we are at an impasse so throw an exception. | ||||
|             throw new Exception\UnsupportedAdapterException('Database importer not found.'); | ||||
|         } | ||||
|  | ||||
|         /** @var DatabaseImporter $o */ | ||||
|         $o = new $class(); | ||||
|  | ||||
|         if ($db) { | ||||
|             $o->setDbo($db); | ||||
|         } | ||||
|  | ||||
|         return $o; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a new iterator on the current query. | ||||
|      * | ||||
|      * @param   string              $name       Name of the driver you want an iterator for. | ||||
|      * @param   StatementInterface  $statement  Statement holding the result set to be iterated. | ||||
|      * @param   string|null         $column     An optional column to use as the iterator key. | ||||
|      * @param   string              $class      The class of object that is returned. | ||||
|      * | ||||
|      * @return  DatabaseIterator | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getIterator( | ||||
|         string $name, | ||||
|         StatementInterface $statement, | ||||
|         ?string $column = null, | ||||
|         string $class = \stdClass::class | ||||
|     ): DatabaseIterator { | ||||
|         // Derive the class name from the driver. | ||||
|         $iteratorClass = __NAMESPACE__ . '\\' . ucfirst($name) . '\\' . ucfirst($name) . 'Iterator'; | ||||
|  | ||||
|         // Make sure we have an iterator class for this driver. | ||||
|         if (!class_exists($iteratorClass)) { | ||||
|             // We can work with the base iterator class so use that | ||||
|             $iteratorClass = DatabaseIterator::class; | ||||
|         } | ||||
|  | ||||
|         // Return a new iterator | ||||
|         return new $iteratorClass($statement, $column, $class); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the current query object or a new Query object. | ||||
|      * | ||||
|      * @param   string                  $name  Name of the driver you want an query object for. | ||||
|      * @param   DatabaseInterface|null  $db    Optional database driver to inject into the query object. | ||||
|      * | ||||
|      * @return  QueryInterface | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  Exception\UnsupportedAdapterException if there is not a compatible database query object | ||||
|      */ | ||||
|     public function getQuery(string $name, ?DatabaseInterface $db = null): QueryInterface | ||||
|     { | ||||
|         // Derive the class name from the driver. | ||||
|         $class = __NAMESPACE__ . '\\' . ucfirst(strtolower($name)) . '\\' . ucfirst(strtolower($name)) . 'Query'; | ||||
|  | ||||
|         // Make sure we have a query class for this driver. | ||||
|         if (!class_exists($class)) { | ||||
|             // If it doesn't exist we are at an impasse so throw an exception. | ||||
|             throw new Exception\UnsupportedAdapterException('Database Query class not found'); | ||||
|         } | ||||
|  | ||||
|         return new $class($db); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										376
									
								
								libraries/vendor/joomla/database/src/DatabaseImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										376
									
								
								libraries/vendor/joomla/database/src/DatabaseImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,376 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework Database Importer Class | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| abstract class DatabaseImporter | ||||
| { | ||||
|     /** | ||||
|      * An array of cached data. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $cache = ['columns' => [], 'keys' => []]; | ||||
|  | ||||
|     /** | ||||
|      * The database connector to use for exporting structure and/or data. | ||||
|      * | ||||
|      * @var    DatabaseInterface | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $db; | ||||
|  | ||||
|     /** | ||||
|      * The input source. | ||||
|      * | ||||
|      * @var    mixed | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $from = []; | ||||
|  | ||||
|     /** | ||||
|      * The type of input format. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $asFormat = 'xml'; | ||||
|  | ||||
|     /** | ||||
|      * An array of options for the exporter. | ||||
|      * | ||||
|      * @var    \stdClass | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $options; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * Sets up the default options for the importer. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->options = new \stdClass(); | ||||
|  | ||||
|         // Set up the class defaults: | ||||
|  | ||||
|         // Import with only structure | ||||
|         $this->withStructure(); | ||||
|  | ||||
|         // Export as XML. | ||||
|         $this->asXml(); | ||||
|  | ||||
|         // Default destination is a string using $output = (string) $importer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the output option for the importer to XML format. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function asXml() | ||||
|     { | ||||
|         $this->asFormat = 'xml'; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to importer. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     abstract public function check(); | ||||
|  | ||||
|     /** | ||||
|      * Specifies the data source to import. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement|string  $from  The data source to import, either as a SimpleXMLElement object or XML string. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function from($from) | ||||
|     { | ||||
|         $this->from = $from; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a column. | ||||
|      * | ||||
|      * @param   string             $table  The table name. | ||||
|      * @param   \SimpleXMLElement  $field  The XML field definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAddColumnSql($table, \SimpleXMLElement $field) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ADD COLUMN ' . $this->getColumnSQL($field); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get alters for table if there is a difference. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $structure  The XML structure of the table. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     abstract protected function getAlterTableSql(\SimpleXMLElement $structure); | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to alter a column. | ||||
|      * | ||||
|      * @param   string             $table  The name of the database table to alter. | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the field. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getChangeColumnSql($table, \SimpleXMLElement $field) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' CHANGE COLUMN ' . $this->db->quoteName((string) $field['Field']) . ' ' | ||||
|             . $this->getColumnSQL($field); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a single column that would be included in a table create or alter statement. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML field definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     abstract protected function getColumnSql(\SimpleXMLElement $field); | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a column. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   string  $name   The name of the field to drop. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropColumnSql($table, $name) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP COLUMN ' . $this->db->quoteName($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   array  $keys  An array of objects that comprise the keys for the table. | ||||
|      * | ||||
|      * @return  array  The lookup array. array({key name} => array(object, ...)) | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getKeyLookup($keys) | ||||
|     { | ||||
|         // First pass, create a lookup of the keys. | ||||
|         $lookup = []; | ||||
|  | ||||
|         foreach ($keys as $key) { | ||||
|             if ($key instanceof \SimpleXMLElement) { | ||||
|                 $kName = (string) $key['Key_name']; | ||||
|             } else { | ||||
|                 $kName = $key->Key_name; | ||||
|             } | ||||
|  | ||||
|             if (empty($lookup[$kName])) { | ||||
|                 $lookup[$kName] = []; | ||||
|             } | ||||
|  | ||||
|             $lookup[$kName][] = $key; | ||||
|         } | ||||
|  | ||||
|         return $lookup; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the real name of the table, converting the prefix wildcard string if present. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table. | ||||
|      * | ||||
|      * @return  string  The real name of the table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getRealTableName($table) | ||||
|     { | ||||
|         $prefix = $this->db->getPrefix(); | ||||
|  | ||||
|         // Replace the magic prefix if found. | ||||
|         $table = preg_replace('|^#__|', $prefix, $table); | ||||
|  | ||||
|         return $table; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Import the data from the source into the existing tables. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @note    Currently only supports XML format. | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException on error. | ||||
|      */ | ||||
|     public function importData() | ||||
|     { | ||||
|         if ($this->from instanceof \SimpleXMLElement) { | ||||
|             $xml = $this->from; | ||||
|         } else { | ||||
|             $xml = new \SimpleXMLElement($this->from); | ||||
|         } | ||||
|  | ||||
|         // Get all the table definitions. | ||||
|         $xmlTables = $xml->xpath('database/table_data'); | ||||
|  | ||||
|         foreach ($xmlTables as $table) { | ||||
|             // Convert the magic prefix into the real table name. | ||||
|             $tableName = $this->getRealTableName((string) $table['name']); | ||||
|  | ||||
|             $rows = $table->children(); | ||||
|  | ||||
|             foreach ($rows as $row) { | ||||
|                 if ($row->getName() == 'row') { | ||||
|                     $entry = new \stdClass(); | ||||
|  | ||||
|                     foreach ($row->children() as $data) { | ||||
|                         if (isset($data['value_is_null'])) { | ||||
|                             $entry->{(string) $data['name']} = null; | ||||
|                         } else { | ||||
|                             $entry->{(string) $data['name']} = (string) $data; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     $this->db->insertObject($tableName, $entry); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Merges the incoming structure definition with the existing structure. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @note    Currently only supports XML format. | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException on error. | ||||
|      */ | ||||
|     public function mergeStructure() | ||||
|     { | ||||
|         $tables = $this->db->getTableList(); | ||||
|  | ||||
|         if ($this->from instanceof \SimpleXMLElement) { | ||||
|             $xml = $this->from; | ||||
|         } else { | ||||
|             $xml = new \SimpleXMLElement($this->from); | ||||
|         } | ||||
|  | ||||
|         // Get all the table definitions. | ||||
|         $xmlTables = $xml->xpath('database/table_structure'); | ||||
|  | ||||
|         foreach ($xmlTables as $table) { | ||||
|             // Convert the magic prefix into the real table name. | ||||
|             $tableName = $this->getRealTableName((string) $table['name']); | ||||
|  | ||||
|             if (\in_array($tableName, $tables, true)) { | ||||
|                 // The table already exists. Now check if there is any difference. | ||||
|                 if ($queries = $this->getAlterTableSql($table)) { | ||||
|                     // Run the queries to upgrade the data structure. | ||||
|                     foreach ($queries as $query) { | ||||
|                         $this->db->setQuery((string) $query); | ||||
|                         $this->db->execute(); | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 // This is a new table. | ||||
|                 $sql     = $this->xmlToCreate($table); | ||||
|                 $queries = explode(';', (string) $sql); | ||||
|  | ||||
|                 foreach ($queries as $query) { | ||||
|                     if (!empty($query)) { | ||||
|                         $this->db->setQuery((string) $query); | ||||
|                         $this->db->execute(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the database connector to use for exporting structure and/or data. | ||||
|      * | ||||
|      * @param   DatabaseInterface  $db  The database connector. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function setDbo(DatabaseInterface $db) | ||||
|     { | ||||
|         $this->db = $db; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets an internal option to merge the structure based on the input data. | ||||
|      * | ||||
|      * @param   boolean  $setting  True to import the structure, false to not. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function withStructure($setting = true) | ||||
|     { | ||||
|         $this->options->withStructure = (bool) $setting; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a table. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $table  The table information. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     abstract protected function xmlToCreate(\SimpleXMLElement $table); | ||||
| } | ||||
							
								
								
									
										619
									
								
								libraries/vendor/joomla/database/src/DatabaseInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										619
									
								
								libraries/vendor/joomla/database/src/DatabaseInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,619 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework Database Interface | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| interface DatabaseInterface | ||||
| { | ||||
|     /** | ||||
|      * Connects to the database if needed. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function connect(); | ||||
|  | ||||
|     /** | ||||
|      * Determines if the connection to the server is active. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function connected(); | ||||
|  | ||||
|     /** | ||||
|      * Create a new database using information from $options object. | ||||
|      * | ||||
|      * @param   \stdClass  $options  Object used to pass user and database name to database driver. This object must have "db_name" and "db_user" set. | ||||
|      * @param   boolean    $utf      True if the database supports the UTF-8 character set. | ||||
|      * | ||||
|      * @return  boolean|resource | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function createDatabase($options, $utf = true); | ||||
|  | ||||
|     /** | ||||
|      * Replace special placeholder representing binary field with the original string. | ||||
|      * | ||||
|      * @param   string|resource  $data  Encoded string or resource. | ||||
|      * | ||||
|      * @return  string  The original string. | ||||
|      * | ||||
|      * @since   1.7.0 | ||||
|      */ | ||||
|     public function decodeBinary($data); | ||||
|  | ||||
|     /** | ||||
|      * Disconnects the database. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function disconnect(); | ||||
|  | ||||
|     /** | ||||
|      * Drops a table from the database. | ||||
|      * | ||||
|      * @param   string   $table     The name of the database table to drop. | ||||
|      * @param   boolean  $ifExists  Optionally specify that the table must exist before it is dropped. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function dropTable($table, $ifExists = true); | ||||
|  | ||||
|     /** | ||||
|      * Escapes a string for usage in an SQL statement. | ||||
|      * | ||||
|      * @param   string   $text   The string to be escaped. | ||||
|      * @param   boolean  $extra  Optional parameter to provide extra escaping. | ||||
|      * | ||||
|      * @return  string   The escaped string. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function escape($text, $extra = false); | ||||
|  | ||||
|     /** | ||||
|      * Execute the SQL statement. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function execute(); | ||||
|  | ||||
|     /** | ||||
|      * Get the number of affected rows for the previous executed SQL statement. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getAffectedRows(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database or boolean false if not supported. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getCollation(); | ||||
|  | ||||
|     /** | ||||
|      * Method that provides access to the underlying database connection. | ||||
|      * | ||||
|      * @return  resource  The underlying database connection resource. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getConnection(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database connection collation, as reported by the driver. | ||||
|      * | ||||
|      * If the connector doesn't support reporting this value please return an empty string. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getConnectionCollation(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database encryption details (cipher and protocol) in use. | ||||
|      * | ||||
|      * @return  string  The database encryption details. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getConnectionEncryption(): string; | ||||
|  | ||||
|     /** | ||||
|      * Method to test if the database TLS connections encryption are supported. | ||||
|      * | ||||
|      * @return  boolean  Whether the database supports TLS connections encryption. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isConnectionEncryptionSupported(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Method to check whether the installed database version is supported by the database driver | ||||
|      * | ||||
|      * @return  boolean  True if the database version is supported | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isMinimumVersion(); | ||||
|  | ||||
|     /** | ||||
|      * Get the total number of SQL statements executed by the database driver. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getCount(); | ||||
|  | ||||
|     /** | ||||
|      * Returns a PHP date() function compliant date format for the database driver. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getDateFormat(); | ||||
|  | ||||
|     /** | ||||
|      * Get the minimum supported database version. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getMinimum(); | ||||
|  | ||||
|     /** | ||||
|      * Get the name of the database driver. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getName(); | ||||
|  | ||||
|     /** | ||||
|      * Get the null or zero representation of a timestamp for the database driver. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getNullDate(); | ||||
|  | ||||
|     /** | ||||
|      * Get the common table prefix for the database driver. | ||||
|      * | ||||
|      * @return  string  The common database table prefix. | ||||
|      * | ||||
|      * @since   3.0 | ||||
|      */ | ||||
|     public function getPrefix(); | ||||
|  | ||||
|     /** | ||||
|      * Get the number of returned rows for the previous executed SQL statement. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getNumRows(); | ||||
|  | ||||
|     /** | ||||
|      * Get the current query object or a new QueryInterface object. | ||||
|      * | ||||
|      * @param   boolean  $new  False to return the current query object, True to return a new QueryInterface object. | ||||
|      * | ||||
|      * @return  QueryInterface | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getQuery($new = false); | ||||
|  | ||||
|     /** | ||||
|      * Get the server family type. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getServerType(); | ||||
|  | ||||
|     /** | ||||
|      * Retrieves field information about the given tables. | ||||
|      * | ||||
|      * @param   string   $table     The name of the database table. | ||||
|      * @param   boolean  $typeOnly  True (default) to only return field types. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableColumns($table, $typeOnly = true); | ||||
|  | ||||
|     /** | ||||
|      * Retrieves field information about the given tables. | ||||
|      * | ||||
|      * @param   mixed  $tables  A table name or a list of table names. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableKeys($tables); | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of all tables in the database. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableList(); | ||||
|  | ||||
|     /** | ||||
|      * Get the version of the database connector. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getVersion(); | ||||
|  | ||||
|     /** | ||||
|      * Determine whether or not the database engine supports UTF-8 character encoding. | ||||
|      * | ||||
|      * @return  boolean  True if the database engine supports UTF-8 character encoding. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function hasUtfSupport(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the auto-incremented value from the last INSERT statement. | ||||
|      * | ||||
|      * @return  mixed  The value of the auto-increment field from the last inserted row. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function insertid(); | ||||
|  | ||||
|     /** | ||||
|      * Inserts a row into a table based on an object's properties. | ||||
|      * | ||||
|      * @param   string  $table   The name of the database table to insert into. | ||||
|      * @param   object  $object  A reference to an object whose public properties match the table fields. | ||||
|      * @param   string  $key     The name of the primary key. If provided the object property is updated. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function insertObject($table, &$object, $key = null); | ||||
|  | ||||
|     /** | ||||
|      * Test to see if the connector is available. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function isSupported(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the first row of the result set from the database query as an associative array of ['field_name' => 'row_value']. | ||||
|      * | ||||
|      * @return  mixed  The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadAssoc(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of the result set rows from the database query where each row is an associative array | ||||
|      * of ['field_name' => 'row_value'].  The array of rows can optionally be keyed by a field name, but defaults to | ||||
|      * a sequential numeric array. | ||||
|      * | ||||
|      * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted | ||||
|      * behavior and should be avoided. | ||||
|      * | ||||
|      * @param   string  $key     The name of a field on which to key the result array. | ||||
|      * @param   string  $column  An optional column name. Instead of the whole row, only this column value will be in the result array. | ||||
|      * | ||||
|      * @return  mixed   The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadAssocList($key = null, $column = null); | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of values from the <var>$offset</var> field in each row of the result set from the database query. | ||||
|      * | ||||
|      * @param   integer  $offset  The row offset to use to build the result array. | ||||
|      * | ||||
|      * @return  mixed  The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadColumn($offset = 0); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the first row of the result set from the database query as an object. | ||||
|      * | ||||
|      * @param   string  $class  The class name to use for the returned row object. | ||||
|      * | ||||
|      * @return  mixed  The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadObject($class = \stdClass::class); | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of the result set rows from the database query where each row is an object.  The array | ||||
|      * of objects can optionally be keyed by a field name, but defaults to a sequential numeric array. | ||||
|      * | ||||
|      * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted behavior and should be avoided. | ||||
|      * | ||||
|      * @param   string  $key    The name of a field on which to key the result array. | ||||
|      * @param   string  $class  The class name to use for the returned row objects. | ||||
|      * | ||||
|      * @return  mixed  The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadObjectList($key = '', $class = \stdClass::class); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the first field of the first row of the result set from the database query. | ||||
|      * | ||||
|      * @return  mixed  The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadResult(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get the first row of the result set from the database query as an array. | ||||
|      * | ||||
|      * Columns are indexed numerically so the first column in the result set would be accessible via <var>$row[0]</var>, etc. | ||||
|      * | ||||
|      * @return  mixed  The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadRow(); | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of the result set rows from the database query where each row is an array.  The array | ||||
|      * of objects can optionally be keyed by a field offset, but defaults to a sequential numeric array. | ||||
|      * | ||||
|      * NOTE: Choosing to key the result array by a non-unique field can result in unwanted behavior and should be avoided. | ||||
|      * | ||||
|      * @param   string  $key  The name of a field on which to key the result array. | ||||
|      * | ||||
|      * @return  mixed   The return value or null if the query failed. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function loadRowList($key = null); | ||||
|  | ||||
|     /** | ||||
|      * Locks a table in the database. | ||||
|      * | ||||
|      * @param   string  $tableName  The name of the table to unlock. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function lockTable($tableName); | ||||
|  | ||||
|     /** | ||||
|      * Quotes and optionally escapes a string to database requirements for use in database queries. | ||||
|      * | ||||
|      * @param   array|string  $text    A string or an array of strings to quote. | ||||
|      * @param   boolean       $escape  True (default) to escape the string, false to leave it unchanged. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function quote($text, $escape = true); | ||||
|  | ||||
|     /** | ||||
|      * Quotes a binary string to database requirements for use in database queries. | ||||
|      * | ||||
|      * @param   string  $data  A binary string to quote. | ||||
|      * | ||||
|      * @return  string  The binary quoted input string. | ||||
|      * | ||||
|      * @since   1.7.0 | ||||
|      */ | ||||
|     public function quoteBinary($data); | ||||
|  | ||||
|     /** | ||||
|      * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection | ||||
|      * risks and reserved word conflicts. | ||||
|      * | ||||
|      * @param   array|string  $name  The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. | ||||
|      *                               Each type supports dot-notation name. | ||||
|      * @param   array|string  $as    The AS query part associated to $name. It can be string or array, in latter case it has to be | ||||
|      *                               same length of $name; if is null there will not be any AS part for string or array element. | ||||
|      * | ||||
|      * @return  array|string  The quote wrapped name, same type of $name. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function quoteName($name, $as = null); | ||||
|  | ||||
|     /** | ||||
|      * Renames a table in the database. | ||||
|      * | ||||
|      * @param   string  $oldTable  The name of the table to be renamed | ||||
|      * @param   string  $newTable  The new name for the table. | ||||
|      * @param   string  $backup    Table prefix | ||||
|      * @param   string  $prefix    For the table - used to rename constraints in non-mysql databases | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function renameTable($oldTable, $newTable, $backup = null, $prefix = null); | ||||
|  | ||||
|     /** | ||||
|      * This function replaces a string identifier with the configured table prefix. | ||||
|      * | ||||
|      * @param   string  $sql     The SQL statement to prepare. | ||||
|      * @param   string  $prefix  The table prefix. | ||||
|      * | ||||
|      * @return  string  The processed SQL statement. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function replacePrefix($sql, $prefix = '#__'); | ||||
|  | ||||
|     /** | ||||
|      * Select a database for use. | ||||
|      * | ||||
|      * @param   string  $database  The name of the database to select for use. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function select($database); | ||||
|  | ||||
|     /** | ||||
|      * Sets the SQL statement string for later execution. | ||||
|      * | ||||
|      * @param   mixed    $query   The SQL statement to set either as a Query object or a string. | ||||
|      * @param   integer  $offset  The affected row offset to set. {@deprecated 3.0 Use LimitableInterface::setLimit() instead} | ||||
|      * @param   integer  $limit   The maximum affected rows to set. {@deprecated 3.0 Use LimitableInterface::setLimit() instead} | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function setQuery($query, $offset = 0, $limit = 0); | ||||
|  | ||||
|     /** | ||||
|      * Method to commit a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, commit to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionCommit($toSavepoint = false); | ||||
|  | ||||
|     /** | ||||
|      * Method to roll back a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, rollback to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionRollback($toSavepoint = false); | ||||
|  | ||||
|     /** | ||||
|      * Method to initialize a transaction. | ||||
|      * | ||||
|      * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionStart($asSavepoint = false); | ||||
|  | ||||
|     /** | ||||
|      * Method to truncate a table. | ||||
|      * | ||||
|      * @param   string  $table  The table to truncate | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function truncateTable($table); | ||||
|  | ||||
|     /** | ||||
|      * Unlocks tables in the database. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function unlockTables(); | ||||
|  | ||||
|     /** | ||||
|      * Updates a row in a table based on an object's properties. | ||||
|      * | ||||
|      * @param   string        $table   The name of the database table to update. | ||||
|      * @param   object        $object  A reference to an object whose public properties match the table fields. | ||||
|      * @param   array|string  $key     The name of the primary key. | ||||
|      * @param   boolean       $nulls   True to update null fields or false to ignore them. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function updateObject($table, &$object, $key, $nulls = false); | ||||
| } | ||||
							
								
								
									
										246
									
								
								libraries/vendor/joomla/database/src/DatabaseIterator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								libraries/vendor/joomla/database/src/DatabaseIterator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,246 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework Database Driver Class | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class DatabaseIterator implements \Countable, \Iterator | ||||
| { | ||||
|     /** | ||||
|      * The class of object to create. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $class; | ||||
|  | ||||
|     /** | ||||
|      * The name of the column to use for the key of the database record. | ||||
|      * | ||||
|      * @var    mixed | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     private $column; | ||||
|  | ||||
|     /** | ||||
|      * The current database record. | ||||
|      * | ||||
|      * @var    mixed | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     private $current; | ||||
|  | ||||
|     /** | ||||
|      * A numeric or string key for the current database record. | ||||
|      * | ||||
|      * @var    scalar | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     private $key; | ||||
|  | ||||
|     /** | ||||
|      * The number of fetched records. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     private $fetched = 0; | ||||
|  | ||||
|     /** | ||||
|      * The statement holding the result set to iterate. | ||||
|      * | ||||
|      * @var    StatementInterface | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $statement; | ||||
|  | ||||
|     /** | ||||
|      * Database iterator constructor. | ||||
|      * | ||||
|      * @param   StatementInterface  $statement  The statement holding the result set to iterate. | ||||
|      * @param   string              $column     An option column to use as the iterator key. | ||||
|      * @param   string              $class      The class of object that is returned. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \InvalidArgumentException | ||||
|      */ | ||||
|     public function __construct(StatementInterface $statement, $column = null, $class = \stdClass::class) | ||||
|     { | ||||
|         if (!class_exists($class)) { | ||||
|             throw new \InvalidArgumentException(sprintf('new %s(*%s*, cursor)', \get_class($this), \gettype($class))); | ||||
|         } | ||||
|  | ||||
|         if ($statement) { | ||||
|             $fetchMode = $class === \stdClass::class ? FetchMode::STANDARD_OBJECT : FetchMode::CUSTOM_OBJECT; | ||||
|  | ||||
|             // PDO doesn't allow extra arguments for \PDO::FETCH_CLASS, so only forward the class for the custom object mode | ||||
|             if ($fetchMode === FetchMode::STANDARD_OBJECT) { | ||||
|                 $statement->setFetchMode($fetchMode); | ||||
|             } else { | ||||
|                 $statement->setFetchMode($fetchMode, $class); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->statement = $statement; | ||||
|         $this->class     = $class; | ||||
|         $this->column    = $column; | ||||
|         $this->fetched   = 0; | ||||
|         $this->next(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Database iterator destructor. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __destruct() | ||||
|     { | ||||
|         if ($this->statement) { | ||||
|             $this->freeResult(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the number of rows in the result set for the executed SQL given by the cursor. | ||||
|      * | ||||
|      * @return  integer  The number of rows in the result set. | ||||
|      * | ||||
|      * @see     Countable::count() | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     #[\ReturnTypeWillChange] | ||||
|     public function count() | ||||
|     { | ||||
|         if ($this->statement) { | ||||
|             return $this->statement->rowCount(); | ||||
|         } | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The current element in the iterator. | ||||
|      * | ||||
|      * @return  object | ||||
|      * | ||||
|      * @see     Iterator::current() | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     #[\ReturnTypeWillChange] | ||||
|     public function current() | ||||
|     { | ||||
|         return $this->current; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The key of the current element in the iterator. | ||||
|      * | ||||
|      * @return  scalar | ||||
|      * | ||||
|      * @see     Iterator::key() | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     #[\ReturnTypeWillChange] | ||||
|     public function key() | ||||
|     { | ||||
|         return $this->key; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Moves forward to the next result from the SQL query. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @see     Iterator::next() | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     #[\ReturnTypeWillChange] | ||||
|     public function next() | ||||
|     { | ||||
|         // Set the default key as being the number of fetched object | ||||
|         $this->key = $this->fetched; | ||||
|  | ||||
|         // Try to get an object | ||||
|         $this->current = $this->fetchObject(); | ||||
|  | ||||
|         // If an object has been found | ||||
|         if ($this->current) { | ||||
|             // Set the key as being the indexed column (if it exists) | ||||
|             if ($this->column && isset($this->current->{$this->column})) { | ||||
|                 $this->key = $this->current->{$this->column}; | ||||
|             } | ||||
|  | ||||
|             // Update the number of fetched object | ||||
|             $this->fetched++; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Rewinds the iterator. | ||||
|      * | ||||
|      * This iterator cannot be rewound. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @see     Iterator::rewind() | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     #[\ReturnTypeWillChange] | ||||
|     public function rewind() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks if the current position of the iterator is valid. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @see     Iterator::valid() | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     #[\ReturnTypeWillChange] | ||||
|     public function valid() | ||||
|     { | ||||
|         return (bool) $this->current; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to fetch a row from the result set cursor as an object. | ||||
|      * | ||||
|      * @return  mixed  Either the next row from the result set or false if there are no more rows. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function fetchObject() | ||||
|     { | ||||
|         if ($this->statement) { | ||||
|             return $this->statement->fetch(); | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to free up the memory used for the result set. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function freeResult() | ||||
|     { | ||||
|         if ($this->statement) { | ||||
|             $this->statement->closeCursor(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										2370
									
								
								libraries/vendor/joomla/database/src/DatabaseQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2370
									
								
								libraries/vendor/joomla/database/src/DatabaseQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										56
									
								
								libraries/vendor/joomla/database/src/Event/ConnectionEvent.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								libraries/vendor/joomla/database/src/Event/ConnectionEvent.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Event; | ||||
|  | ||||
| use Joomla\Database\DatabaseInterface; | ||||
| use Joomla\Event\Event; | ||||
|  | ||||
| /** | ||||
|  * Database connection event | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class ConnectionEvent extends Event | ||||
| { | ||||
|     /** | ||||
|      * DatabaseInterface object for this event | ||||
|      * | ||||
|      * @var    DatabaseInterface | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $driver; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   string             $name    The event name. | ||||
|      * @param   DatabaseInterface  $driver  The DatabaseInterface object for this event. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __construct(string $name, DatabaseInterface $driver) | ||||
|     { | ||||
|         parent::__construct($name); | ||||
|  | ||||
|         $this->driver = $driver; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retrieve the DatabaseInterface object attached to this event. | ||||
|      * | ||||
|      * @return  DatabaseInterface | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getDriver(): DatabaseInterface | ||||
|     { | ||||
|         return $this->driver; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								libraries/vendor/joomla/database/src/Exception/ConnectionFailureException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								libraries/vendor/joomla/database/src/Exception/ConnectionFailureException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * Exception class defining an error connecting to the database platform | ||||
|  * | ||||
|  * @since  1.5.0 | ||||
|  */ | ||||
| class ConnectionFailureException extends \RuntimeException | ||||
| { | ||||
|     /** | ||||
|      * Construct the exception | ||||
|      * | ||||
|      * @param   string       $message   The Exception message to throw. [optional] | ||||
|      * @param   integer      $code      The Exception code. [optional] | ||||
|      * @param   ?\Exception  $previous  The previous exception used for the exception chaining. [optional] | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __construct($message = '', $code = 0, ?\Exception $previous = null) | ||||
|     { | ||||
|         // PDO uses strings for exception codes, PHP forces numeric codes, so "force" the string code to be used | ||||
|         parent::__construct($message, 0, $previous); | ||||
|  | ||||
|         $this->code = $code; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/DatabaseNotFoundException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/DatabaseNotFoundException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2022 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * No database is available. | ||||
|  * | ||||
|  * @since  2.1.0 | ||||
|  */ | ||||
| class DatabaseNotFoundException extends \RuntimeException | ||||
| { | ||||
| } | ||||
							
								
								
									
										57
									
								
								libraries/vendor/joomla/database/src/Exception/ExecutionFailureException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								libraries/vendor/joomla/database/src/Exception/ExecutionFailureException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * Exception class defining an error executing a statement | ||||
|  * | ||||
|  * @since  1.5.0 | ||||
|  */ | ||||
| class ExecutionFailureException extends \RuntimeException | ||||
| { | ||||
|     /** | ||||
|      * The SQL statement that was executed. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.5.0 | ||||
|      */ | ||||
|     private $query; | ||||
|  | ||||
|     /** | ||||
|      * Construct the exception | ||||
|      * | ||||
|      * @param   string       $query     The SQL statement that was executed. | ||||
|      * @param   string       $message   The Exception message to throw. [optional] | ||||
|      * @param   integer      $code      The Exception code. [optional] | ||||
|      * @param   ?\Exception  $previous  The previous exception used for the exception chaining. [optional] | ||||
|      * | ||||
|      * @since   1.5.0 | ||||
|      */ | ||||
|     public function __construct($query, $message = '', $code = 0, ?\Exception $previous = null) | ||||
|     { | ||||
|         // PDO uses strings for exception codes, PHP forces numeric codes, so "force" the string code to be used | ||||
|         parent::__construct($message, 0, $previous); | ||||
|  | ||||
|         $this->code  = $code; | ||||
|         $this->query = $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL statement that was executed | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.5.0 | ||||
|      */ | ||||
|     public function getQuery() | ||||
|     { | ||||
|         return $this->query; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								libraries/vendor/joomla/database/src/Exception/PrepareStatementFailureException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								libraries/vendor/joomla/database/src/Exception/PrepareStatementFailureException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * Exception class defining an error preparing the SQL statement for execution | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class PrepareStatementFailureException extends \RuntimeException | ||||
| { | ||||
|     /** | ||||
|      * Construct the exception | ||||
|      * | ||||
|      * @param   string       $message   The Exception message to throw. [optional] | ||||
|      * @param   integer      $code      The Exception code. [optional] | ||||
|      * @param   ?\Exception  $previous  The previous exception used for the exception chaining. [optional] | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __construct($message = '', $code = 0, ?\Exception $previous = null) | ||||
|     { | ||||
|         // PDO uses strings for exception codes, PHP forces numeric codes, so "force" the string code to be used | ||||
|         parent::__construct($message, 0, $previous); | ||||
|  | ||||
|         $this->code = $code; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/QueryTypeAlreadyDefinedException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/QueryTypeAlreadyDefinedException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * Exception class defining an exception when attempting to change a query type | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class QueryTypeAlreadyDefinedException extends \RuntimeException | ||||
| { | ||||
| } | ||||
							
								
								
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/UnknownTypeException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/UnknownTypeException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * Class representing an unknown type for a given database driver. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class UnknownTypeException extends \InvalidArgumentException | ||||
| { | ||||
| } | ||||
							
								
								
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/UnsupportedAdapterException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								libraries/vendor/joomla/database/src/Exception/UnsupportedAdapterException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Exception; | ||||
|  | ||||
| /** | ||||
|  * Exception class defining an unsupported database object | ||||
|  * | ||||
|  * @since  1.5.0 | ||||
|  */ | ||||
| class UnsupportedAdapterException extends \RuntimeException | ||||
| { | ||||
| } | ||||
							
								
								
									
										88
									
								
								libraries/vendor/joomla/database/src/FetchMode.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								libraries/vendor/joomla/database/src/FetchMode.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Class defining the fetch mode for prepared statements | ||||
|  * | ||||
|  * The values of the constants in this class match the `PDO::FETCH_*` constants. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| final class FetchMode | ||||
| { | ||||
|     /** | ||||
|      * Specifies that the fetch method shall return each row as an array indexed by column name as returned in the corresponding result set. | ||||
|      * | ||||
|      * If the result set contains multiple columns with the same name, the statement returns only a single value per column name. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      * @see    \PDO::FETCH_ASSOC | ||||
|      */ | ||||
|     public const ASSOCIATIVE = 2; | ||||
|  | ||||
|     /** | ||||
|      * Specifies that the fetch method shall return each row as an array indexed by column number as returned in the corresponding result set, | ||||
|      * starting at column 0. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      * @see    \PDO::FETCH_NUM | ||||
|      */ | ||||
|     public const NUMERIC = 3; | ||||
|  | ||||
|     /** | ||||
|      * Specifies that the fetch method shall return each row as an array indexed by both column name and number as returned in the corresponding | ||||
|      * result set, starting at column 0. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      * @see    \PDO::FETCH_BOTH | ||||
|      */ | ||||
|     public const MIXED = 4; | ||||
|  | ||||
|     /** | ||||
|      * Specifies that the fetch method shall return each row as an object with property names that correspond to the column names returned in the | ||||
|      * result set. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      * @see    \PDO::FETCH_OBJ | ||||
|      */ | ||||
|     public const STANDARD_OBJECT = 5; | ||||
|  | ||||
|     /** | ||||
|      * Specifies that the fetch method shall return only a single requested column from the next row in the result set. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      * @see    \PDO::FETCH_COLUMN | ||||
|      */ | ||||
|     public const COLUMN = 7; | ||||
|  | ||||
|     /** | ||||
|      * Specifies that the fetch method shall return a new instance of the requested class, mapping the columns to named properties in the class. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      * @see    \PDO::FETCH_CLASS | ||||
|      */ | ||||
|     public const CUSTOM_OBJECT = 8; | ||||
|  | ||||
|     /** | ||||
|      * Private constructor to prevent instantiation of this class | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function __construct() | ||||
|     { | ||||
|     } | ||||
| } | ||||
							
								
								
									
										77
									
								
								libraries/vendor/joomla/database/src/FetchOrientation.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								libraries/vendor/joomla/database/src/FetchOrientation.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Class defining the fetch orientation for prepared statements | ||||
|  * | ||||
|  * The values of the constants in this class match the `PDO::FETCH_ORI_*` constants. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| final class FetchOrientation | ||||
| { | ||||
|     /** | ||||
|      * Fetch the next row in the result set. Valid only for scrollable cursors. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const NEXT = 0; | ||||
|  | ||||
|     /** | ||||
|      * Fetch the previous row in the result set. Valid only for scrollable cursors. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const PRIOR = 1; | ||||
|  | ||||
|     /** | ||||
|      * Fetch the first row in the result set. Valid only for scrollable cursors. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const FIRST = 2; | ||||
|  | ||||
|     /** | ||||
|      * Fetch the last row in the result set. Valid only for scrollable cursors. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const LAST = 3; | ||||
|  | ||||
|     /** | ||||
|      * Fetch the requested row by row number from the result set. Valid only for scrollable cursors. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const ABS = 4; | ||||
|  | ||||
|     /** | ||||
|      * Fetch the requested row by relative position from the current position of the cursor in the result set. Valid only for scrollable cursors. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const REL = 5; | ||||
|  | ||||
|     /** | ||||
|      * Private constructor to prevent instantiation of this class | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function __construct() | ||||
|     { | ||||
|     } | ||||
| } | ||||
							
								
								
									
										74
									
								
								libraries/vendor/joomla/database/src/Monitor/ChainedMonitor.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								libraries/vendor/joomla/database/src/Monitor/ChainedMonitor.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Monitor; | ||||
|  | ||||
| use Joomla\Database\QueryMonitorInterface; | ||||
|  | ||||
| /** | ||||
|  * Chained query monitor allowing multiple monitors to be executed. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class ChainedMonitor implements QueryMonitorInterface | ||||
| { | ||||
|     /** | ||||
|      * The query monitors stored to this chain | ||||
|      * | ||||
|      * @var    QueryMonitorInterface[] | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $monitors = []; | ||||
|  | ||||
|     /** | ||||
|      * Register a monitor to the chain. | ||||
|      * | ||||
|      * @param   QueryMonitorInterface  $monitor  The monitor to add. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function addMonitor(QueryMonitorInterface $monitor): void | ||||
|     { | ||||
|         $this->monitors[] = $monitor; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being started. | ||||
|      * | ||||
|      * @param   string         $sql           The SQL to be executed. | ||||
|      * @param   object[]|null  $boundParams   List of bound params, used with the query. | ||||
|      *                                        Each item is an object that holds: value, dataType | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function startQuery(string $sql, ?array $boundParams = null): void | ||||
|     { | ||||
|         foreach ($this->monitors as $monitor) { | ||||
|             $monitor->startQuery($sql, $boundParams); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being stopped. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function stopQuery(): void | ||||
|     { | ||||
|         foreach ($this->monitors as $monitor) { | ||||
|             $monitor->stopQuery(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										156
									
								
								libraries/vendor/joomla/database/src/Monitor/DebugMonitor.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								libraries/vendor/joomla/database/src/Monitor/DebugMonitor.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Monitor; | ||||
|  | ||||
| use Joomla\Database\QueryMonitorInterface; | ||||
|  | ||||
| /** | ||||
|  * Query monitor handling logging of queries. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| final class DebugMonitor implements QueryMonitorInterface | ||||
| { | ||||
|     /** | ||||
|      * The log of executed SQL statements call stacks by the database driver. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $callStacks = []; | ||||
|  | ||||
|     /** | ||||
|      * The log of executed SQL statements by the database driver. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $logs = []; | ||||
|  | ||||
|     /** | ||||
|      * List of bound params, used with the query. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $boundParams = []; | ||||
|  | ||||
|     /** | ||||
|      * The log of executed SQL statements memory usage (start and stop memory_get_usage) by the database driver. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $memoryLogs = []; | ||||
|  | ||||
|     /** | ||||
|      * The log of executed SQL statements timings (start and stop microtimes) by the database driver. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $timings = []; | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being started. | ||||
|      * | ||||
|      * @param   string         $sql           The SQL to be executed. | ||||
|      * @param   object[]|null  $boundParams   List of bound params, used with the query. | ||||
|      *                                        Each item is an object that holds: value, dataType | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function startQuery(string $sql, ?array $boundParams = null): void | ||||
|     { | ||||
|         $this->logs[]        = $sql; | ||||
|  | ||||
|         // Dereference bound parameters to prevent reporting wrong value when reusing the same query object. | ||||
|         $this->boundParams[] = unserialize(serialize($boundParams)); | ||||
|  | ||||
|         $this->callStacks[]  = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); | ||||
|         $this->memoryLogs[]  = memory_get_usage(); | ||||
|         $this->timings[]     = microtime(true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being stopped. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function stopQuery(): void | ||||
|     { | ||||
|         $this->timings[]    = microtime(true); | ||||
|         $this->memoryLogs[] = memory_get_usage(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the logged call stacks. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getCallStacks(): array | ||||
|     { | ||||
|         return $this->callStacks; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the logged queries. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getLogs(): array | ||||
|     { | ||||
|         return $this->logs; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the logged bound params. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getBoundParams(): array | ||||
|     { | ||||
|         return $this->boundParams; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the logged memory logs. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getMemoryLogs(): array | ||||
|     { | ||||
|         return $this->memoryLogs; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the logged timings. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getTimings(): array | ||||
|     { | ||||
|         return $this->timings; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										57
									
								
								libraries/vendor/joomla/database/src/Monitor/LoggingMonitor.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								libraries/vendor/joomla/database/src/Monitor/LoggingMonitor.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Monitor; | ||||
|  | ||||
| use Joomla\Database\QueryMonitorInterface; | ||||
| use Psr\Log\LoggerAwareInterface; | ||||
| use Psr\Log\LoggerAwareTrait; | ||||
|  | ||||
| /** | ||||
|  * Query monitor handling logging of queries. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class LoggingMonitor implements QueryMonitorInterface, LoggerAwareInterface | ||||
| { | ||||
|     use LoggerAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being started. | ||||
|      * | ||||
|      * @param   string         $sql          The SQL to be executed. | ||||
|      * @param   object[]|null  $boundParams  List of bound params, used with the query. | ||||
|      *                                       Each item is an object that holds: value, dataType | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function startQuery(string $sql, ?array $boundParams = null): void | ||||
|     { | ||||
|         if ($this->logger) { | ||||
|             // Add the query to the object queue. | ||||
|             $this->logger->info( | ||||
|                 'Query Executed: {sql}', | ||||
|                 ['sql' => $sql, 'trace' => debug_backtrace()] | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being stopped. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function stopQuery(): void | ||||
|     { | ||||
|         // Nothing to do | ||||
|     } | ||||
| } | ||||
							
								
								
									
										807
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										807
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,807 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysql; | ||||
|  | ||||
| use Joomla\Database\Exception\ConnectionFailureException; | ||||
| use Joomla\Database\Pdo\PdoDriver; | ||||
| use Joomla\Database\UTF8MB4SupportInterface; | ||||
|  | ||||
| /** | ||||
|  * MySQL database driver supporting PDO based connections | ||||
|  * | ||||
|  * @link   https://www.php.net/manual/en/ref.pdo-mysql.php | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqlDriver extends PdoDriver implements UTF8MB4SupportInterface | ||||
| { | ||||
|     /** | ||||
|      * The name of the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $name = 'mysql'; | ||||
|  | ||||
|     /** | ||||
|      * The character(s) used to quote SQL statement names such as table names or field names, etc. | ||||
|      * | ||||
|      * If a single character string the same character is used for both sides of the quoted name, else the first character will be used for the | ||||
|      * opening quote and the second for the closing quote. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nameQuote = '`'; | ||||
|  | ||||
|     /** | ||||
|      * The null or zero representation of a timestamp for the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nullDate = '0000-00-00 00:00:00'; | ||||
|  | ||||
|     /** | ||||
|      * True if the database engine supports UTF-8 Multibyte (utf8mb4) character encoding. | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @since  1.4.0 | ||||
|      */ | ||||
|     protected $utf8mb4 = false; | ||||
|  | ||||
|     /** | ||||
|      * True if the database engine is MariaDB. | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $mariadb = false; | ||||
|  | ||||
|     /** | ||||
|      * The minimum supported database version. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected static $dbMinimum = '5.6'; | ||||
|  | ||||
|     /** | ||||
|      * The minimum supported MariaDB database version. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected static $dbMinMariadb = '10.0'; | ||||
|  | ||||
|     /** | ||||
|      * The default cipher suite for TLS connections. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected static $defaultCipherSuite = [ | ||||
|         'AES128-GCM-SHA256', | ||||
|         'AES256-GCM-SHA384', | ||||
|         'AES128-CBC-SHA256', | ||||
|         'AES256-CBC-SHA384', | ||||
|         'DES-CBC3-SHA', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * The default charset. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public $charset = 'utf8'; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array  $options  Array of database options with keys: host, user, password, database, select. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct(array $options) | ||||
|     { | ||||
|         /** | ||||
|          * sql_mode to MySql 5.7.8+ default strict mode minus ONLY_FULL_GROUP_BY | ||||
|          * | ||||
|          * @link https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-8.html#mysqld-5-7-8-sql-mode | ||||
|          */ | ||||
|         $sqlModes = [ | ||||
|             'STRICT_TRANS_TABLES', | ||||
|             'ERROR_FOR_DIVISION_BY_ZERO', | ||||
|             'NO_ENGINE_SUBSTITUTION', | ||||
|         ]; | ||||
|  | ||||
|         // Get some basic values from the options. | ||||
|         $options['driver']   = 'mysql'; | ||||
|         $options['charset']  = $options['charset'] ?? 'utf8'; | ||||
|         $options['sqlModes'] = isset($options['sqlModes']) ? (array) $options['sqlModes'] : $sqlModes; | ||||
|  | ||||
|         $this->charset = $options['charset']; | ||||
|  | ||||
|         /* | ||||
|          * Pre-populate the UTF-8 Multibyte compatibility flag. Unfortunately PDO won't report the server version unless we're connected to it, | ||||
|          * and we cannot connect to it unless we know if it supports utf8mb4, which requires us knowing the server version. Because of this | ||||
|          * chicken and egg issue, we _assume_ it's supported and we'll just catch any problems at connection time. | ||||
|          */ | ||||
|         $this->utf8mb4 = $options['charset'] === 'utf8mb4'; | ||||
|  | ||||
|         // Finalize initialisation. | ||||
|         parent::__construct($options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Connects to the database if needed. | ||||
|      * | ||||
|      * @return  void  Returns void if the database connected successfully. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function connect() | ||||
|     { | ||||
|         if ($this->getConnection()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // For SSL/TLS connection encryption. | ||||
|         if ($this->options['ssl'] !== [] && $this->options['ssl']['enable'] === true) { | ||||
|             $sslContextIsNull = true; | ||||
|  | ||||
|             // If customised, add cipher suite, ca file path, ca path, private key file path and certificate file path to PDO driver options. | ||||
|             foreach (['cipher', 'ca', 'capath', 'key', 'cert'] as $key => $value) { | ||||
|                 if ($this->options['ssl'][$value] !== null) { | ||||
|                     $this->options['driverOptions'][constant('\PDO::MYSQL_ATTR_SSL_' . strtoupper($value))] = $this->options['ssl'][$value]; | ||||
|                     $sslContextIsNull                                                                       = false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // PDO, if no cipher, ca, capath, cert and key are set, can't start TLS one-way connection, set a common ciphers suite to force it. | ||||
|             if ($sslContextIsNull === true) { | ||||
|                 $this->options['driverOptions'][\PDO::MYSQL_ATTR_SSL_CIPHER] = implode(':', static::$defaultCipherSuite); | ||||
|             } | ||||
|  | ||||
|             // If customised, for capable systems (PHP 7.0.14+ and 7.1.4+) verify certificate chain and Common Name to driver options. | ||||
|             if ($this->options['ssl']['verify_server_cert'] !== null && defined('\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')) { | ||||
|                 $this->options['driverOptions'][\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = $this->options['ssl']['verify_server_cert']; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // Try to connect to MySQL | ||||
|             parent::connect(); | ||||
|         } catch (ConnectionFailureException $e) { | ||||
|             // If the connection failed, but not because of the wrong character set, then bubble up the exception. | ||||
|             if (!$this->utf8mb4) { | ||||
|                 throw $e; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * Otherwise, try connecting again without using utf8mb4 and see if maybe that was the problem. If the connection succeeds, then we | ||||
|              * will have learned that the client end of the connection does not support utf8mb4. | ||||
|                */ | ||||
|             $this->utf8mb4            = false; | ||||
|             $this->options['charset'] = 'utf8'; | ||||
|  | ||||
|             parent::connect(); | ||||
|         } | ||||
|  | ||||
|         $serverVersion = $this->getVersion(); | ||||
|  | ||||
|         $this->mariadb = stripos($serverVersion, 'mariadb') !== false; | ||||
|  | ||||
|         if ($this->utf8mb4) { | ||||
|             // At this point we know the client supports utf8mb4.  Now we must check if the server supports utf8mb4 as well. | ||||
|             $this->utf8mb4 = version_compare($serverVersion, '5.5.3', '>='); | ||||
|  | ||||
|             if ($this->mariadb && version_compare($serverVersion, '10.0.0', '<')) { | ||||
|                 $this->utf8mb4 = false; | ||||
|             } | ||||
|  | ||||
|             if (!$this->utf8mb4) { | ||||
|                 // Reconnect with the utf8 character set. | ||||
|                 parent::disconnect(); | ||||
|                 $this->options['charset'] = 'utf8'; | ||||
|                 parent::connect(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // If needed, set the sql modes. | ||||
|         if ($this->options['sqlModes'] !== []) { | ||||
|             $this->connection->query('SET @@SESSION.sql_mode = \'' . implode(',', $this->options['sqlModes']) . '\';'); | ||||
|         } | ||||
|  | ||||
|         $this->setOption(\PDO::ATTR_EMULATE_PREPARES, true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Automatically downgrade a CREATE TABLE or ALTER TABLE query from utf8mb4 (UTF-8 Multibyte) to plain utf8. | ||||
|      * | ||||
|      * Used when the server doesn't support UTF-8 Multibyte. | ||||
|      * | ||||
|      * @param   string  $query  The query to convert | ||||
|      * | ||||
|      * @return  string  The converted query | ||||
|      * | ||||
|      * @since   1.4.0 | ||||
|      */ | ||||
|     public function convertUtf8mb4QueryToUtf8($query) | ||||
|     { | ||||
|         if ($this->hasUTF8mb4Support()) { | ||||
|             return $query; | ||||
|         } | ||||
|  | ||||
|         // If it's not an ALTER TABLE or CREATE TABLE command there's nothing to convert | ||||
|         $beginningOfQuery = substr($query, 0, 12); | ||||
|         $beginningOfQuery = strtoupper($beginningOfQuery); | ||||
|  | ||||
|         if (!\in_array($beginningOfQuery, ['ALTER TABLE ', 'CREATE TABLE'], true)) { | ||||
|             return $query; | ||||
|         } | ||||
|  | ||||
|         // Replace utf8mb4 with utf8 | ||||
|         return str_replace('utf8mb4', 'utf8', $query); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Test to see if the MySQL connector is available. | ||||
|      * | ||||
|      * @return  boolean  True on success, false otherwise. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function isSupported() | ||||
|     { | ||||
|         return class_exists('\\PDO') && \in_array('mysql', \PDO::getAvailableDrivers(), true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Select a database for use. | ||||
|      * | ||||
|      * @param   string  $database  The name of the database to select for use. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function select($database) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $this->setQuery('USE ' . $this->quoteName($database)) | ||||
|             ->execute(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Return the query string to alter the database character set. | ||||
|      * | ||||
|      * @param   string  $dbName  The database name | ||||
|      * | ||||
|      * @return  string  The query that alter the database query string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getAlterDbCharacterSet($dbName) | ||||
|     { | ||||
|         $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; | ||||
|  | ||||
|         return 'ALTER DATABASE ' . $this->quoteName($dbName) . ' CHARACTER SET `' . $charset . '`'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database (string) or boolean false if not supported. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getCollation() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->setQuery('SELECT @@collation_database;')->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database connection collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database connection (string) or boolean false if not supported. | ||||
|      * | ||||
|      * @since   1.6.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getConnectionCollation() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->setQuery('SELECT @@collation_connection;')->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database encryption details (cipher and protocol) in use. | ||||
|      * | ||||
|      * @return  string  The database encryption details. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getConnectionEncryption(): string | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $variables = $this->setQuery('SHOW SESSION STATUS WHERE `Variable_name` IN (\'Ssl_version\', \'Ssl_cipher\')') | ||||
|             ->loadObjectList('Variable_name'); | ||||
|  | ||||
|         if (!empty($variables['Ssl_cipher']->Value)) { | ||||
|             return $variables['Ssl_version']->Value . ' (' . $variables['Ssl_cipher']->Value . ')'; | ||||
|         } | ||||
|  | ||||
|         return ''; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to test if the database TLS connections encryption are supported. | ||||
|      * | ||||
|      * @return  boolean  Whether the database supports TLS connections encryption. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isConnectionEncryptionSupported(): bool | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $variables = $this->setQuery('SHOW SESSION VARIABLES WHERE `Variable_name` IN (\'have_ssl\')')->loadObjectList('Variable_name'); | ||||
|  | ||||
|         return !empty($variables['have_ssl']->Value) && $variables['have_ssl']->Value === 'YES'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Return the query string to create new Database. | ||||
|      * | ||||
|      * @param   \stdClass  $options  Object used to pass user and database name to database driver. This object must have "db_name" and "db_user" set. | ||||
|      * @param   boolean    $utf      True if the database supports the UTF-8 character set. | ||||
|      * | ||||
|      * @return  string  The query that creates database | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function getCreateDatabaseQuery($options, $utf) | ||||
|     { | ||||
|         if ($utf) { | ||||
|             $charset   = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; | ||||
|             $collation = $charset . '_unicode_ci'; | ||||
|  | ||||
|             return 'CREATE DATABASE ' . $this->quoteName($options->db_name) . ' CHARACTER SET `' . $charset . '` COLLATE `' . $collation . '`'; | ||||
|         } | ||||
|  | ||||
|         return 'CREATE DATABASE ' . $this->quoteName($options->db_name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the table CREATE statement that creates the given tables. | ||||
|      * | ||||
|      * @param   array|string  $tables  A table name or a list of table names. | ||||
|      * | ||||
|      * @return  array  A list of the create SQL for the tables. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableCreate($tables) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Initialise variables. | ||||
|         $result = []; | ||||
|  | ||||
|         // Sanitize input to an array and iterate over the list. | ||||
|         $tables = (array) $tables; | ||||
|  | ||||
|         foreach ($tables as $table) { | ||||
|             $row = $this->setQuery('SHOW CREATE TABLE ' . $this->quoteName($table))->loadRow(); | ||||
|  | ||||
|             // Populate the result array based on the create statements. | ||||
|             $result[$table] = $row[1]; | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retrieves field information about a given table. | ||||
|      * | ||||
|      * @param   string   $table     The name of the database table. | ||||
|      * @param   boolean  $typeOnly  True to only return field types. | ||||
|      * | ||||
|      * @return  array  An array of fields for the database table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableColumns($table, $typeOnly = true) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $result = []; | ||||
|  | ||||
|         // Set the query to get the table fields statement. | ||||
|         $fields = $this->setQuery('SHOW FULL COLUMNS FROM ' . $this->quoteName($table))->loadObjectList(); | ||||
|  | ||||
|         // If we only want the type as the value add just that to the list. | ||||
|         if ($typeOnly) { | ||||
|             foreach ($fields as $field) { | ||||
|                 $result[$field->Field] = preg_replace('/[(0-9)]/', '', $field->Type); | ||||
|             } | ||||
|         } else { | ||||
|             // If we want the whole field data object add that to the list. | ||||
|             foreach ($fields as $field) { | ||||
|                 $result[$field->Field] = $field; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table. | ||||
|      * | ||||
|      * @return  array  An array of the column specification for the table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableKeys($table) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Get the details columns information. | ||||
|         return $this->setQuery('SHOW KEYS FROM ' . $this->quoteName($table))->loadObjectList(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of all tables in the database. | ||||
|      * | ||||
|      * @return  array  An array of all the tables in the database. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableList() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Set the query to get the tables statement and not the views. | ||||
|         return $this->setQuery('SHOW FULL TABLES WHERE table_type="BASE TABLE"')->loadColumn(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the version of the database connector. | ||||
|      * | ||||
|      * @return  string  The database connector version. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getVersion() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $version = $this->getOption(\PDO::ATTR_SERVER_VERSION); | ||||
|  | ||||
|         if (stripos($version, 'mariadb') !== false) { | ||||
|             // MariaDB: Strip off any leading '5.5.5-', if present | ||||
|             return preg_replace('/^5\.5\.5-/', '', $version); | ||||
|         } | ||||
|  | ||||
|         return $version; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the minimum supported database version. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getMinimum() | ||||
|     { | ||||
|         return $this->mariadb ? static::$dbMinMariadb : static::$dbMinimum; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the null or zero representation of a timestamp for the database driver. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getNullDate() | ||||
|     { | ||||
|         // Check the session sql mode; | ||||
|         if (\in_array('NO_ZERO_DATE', $this->options['sqlModes']) !== false) { | ||||
|             $this->nullDate = '1000-01-01 00:00:00'; | ||||
|         } | ||||
|  | ||||
|         return $this->nullDate; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Determine whether the database engine support the UTF-8 Multibyte (utf8mb4) character encoding. | ||||
|      * | ||||
|      * @return  boolean  True if the database engine supports UTF-8 Multibyte. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function hasUTF8mb4Support() | ||||
|     { | ||||
|         return $this->utf8mb4; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Determine if the database engine is MariaDB. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isMariaDb(): bool | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->mariadb; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Locks a table in the database. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table to unlock. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function lockTable($table) | ||||
|     { | ||||
|         $this->setQuery('LOCK TABLES ' . $this->quoteName($table) . ' WRITE') | ||||
|             ->execute(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renames a table in the database. | ||||
|      * | ||||
|      * @param   string  $oldTable  The name of the table to be renamed | ||||
|      * @param   string  $newTable  The new name for the table. | ||||
|      * @param   string  $backup    Not used by MySQL. | ||||
|      * @param   string  $prefix    Not used by MySQL. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) | ||||
|     { | ||||
|         $this->setQuery('RENAME TABLE ' . $this->quoteName($oldTable) . ' TO ' . $this->quoteName($newTable)) | ||||
|             ->execute(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Inserts a row into a table based on an object's properties. | ||||
|      * | ||||
|      * @param   string  $table   The name of the database table to insert into. | ||||
|      * @param   object  $object  A reference to an object whose public properties match the table fields. | ||||
|      * @param   string  $key     The name of the primary key. If provided the object property is updated. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function insertObject($table, &$object, $key = null) | ||||
|     { | ||||
|         $fields       = []; | ||||
|         $values       = []; | ||||
|         $tableColumns = $this->getTableColumns($table); | ||||
|  | ||||
|         // Iterate over the object variables to build the query fields and values. | ||||
|         foreach (get_object_vars($object) as $k => $v) { | ||||
|             // Skip columns that don't exist in the table. | ||||
|             if (!array_key_exists($k, $tableColumns)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Only process non-null scalars. | ||||
|             if (\is_array($v) || \is_object($v) || $v === null) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Ignore any internal fields. | ||||
|             if ($k[0] === '_') { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Ignore null datetime fields. | ||||
|             if ($tableColumns[$k] === 'datetime' && empty($v)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Ignore null integer fields. | ||||
|             if (stristr($tableColumns[$k], 'int') !== false && $v === '') { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Prepare and sanitize the fields and values for the database query. | ||||
|             $fields[] = $this->quoteName($k); | ||||
|             $values[] = $this->quote($v); | ||||
|         } | ||||
|  | ||||
|         // Create the base insert statement. | ||||
|         $query = $this->createQuery() | ||||
|             ->insert($this->quoteName($table)) | ||||
|             ->columns($fields) | ||||
|             ->values(implode(',', $values)); | ||||
|  | ||||
|         // Set the query and execute the insert. | ||||
|         $this->setQuery($query)->execute(); | ||||
|  | ||||
|         // Update the primary key if it exists. | ||||
|         $id = $this->insertid(); | ||||
|  | ||||
|         if ($key && $id && \is_string($key)) { | ||||
|             $object->$key = $id; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to escape a string for usage in an SQL statement. | ||||
|      * | ||||
|      * Oracle escaping reference: | ||||
|      * http://www.orafaq.com/wiki/SQL_FAQ#How_does_one_escape_special_characters_when_writing_SQL_queries.3F | ||||
|      * | ||||
|      * SQLite escaping notes: | ||||
|      * http://www.sqlite.org/faq.html#q14 | ||||
|      * | ||||
|      * Method body is as implemented by the Zend Framework | ||||
|      * | ||||
|      * Note: Using query objects with bound variables is preferable to the below. | ||||
|      * | ||||
|      * @param   string   $text   The string to be escaped. | ||||
|      * @param   boolean  $extra  Unused optional parameter to provide extra escaping. | ||||
|      * | ||||
|      * @return  string  The escaped string. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function escape($text, $extra = false) | ||||
|     { | ||||
|         if (\is_int($text)) { | ||||
|             return $text; | ||||
|         } | ||||
|  | ||||
|         if (\is_float($text)) { | ||||
|             // Force the dot as a decimal point. | ||||
|             return str_replace(',', '.', (string) $text); | ||||
|         } | ||||
|  | ||||
|         $this->connect(); | ||||
|  | ||||
|         $result = substr($this->connection->quote($text), 1, -1); | ||||
|  | ||||
|         if ($extra) { | ||||
|             $result = addcslashes($result, '%_'); | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Unlocks tables in the database. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function unlockTables() | ||||
|     { | ||||
|         $this->setQuery('UNLOCK TABLES') | ||||
|             ->execute(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to commit a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, commit to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionCommit($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth <= 1) { | ||||
|             parent::transactionCommit($toSavepoint); | ||||
|         } else { | ||||
|             $this->transactionDepth--; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to roll back a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, rollback to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionRollback($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth <= 1) { | ||||
|             parent::transactionRollback($toSavepoint); | ||||
|         } else { | ||||
|             $savepoint = 'SP_' . ($this->transactionDepth - 1); | ||||
|             $this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint)); | ||||
|  | ||||
|             if ($this->execute()) { | ||||
|                 $this->transactionDepth--; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to initialize a transaction. | ||||
|      * | ||||
|      * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionStart($asSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$asSavepoint || !$this->transactionDepth) { | ||||
|             parent::transactionStart($asSavepoint); | ||||
|         } else { | ||||
|             $savepoint = 'SP_' . $this->transactionDepth; | ||||
|             $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); | ||||
|  | ||||
|             if ($this->execute()) { | ||||
|                 $this->transactionDepth++; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										116
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysql; | ||||
|  | ||||
| use Joomla\Database\DatabaseExporter; | ||||
|  | ||||
| /** | ||||
|  * MySQL Database Exporter. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqlExporter extends DatabaseExporter | ||||
| { | ||||
|     /** | ||||
|      * Builds the XML data for the tables to export. | ||||
|      * | ||||
|      * @return  string  An XML string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXml() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         $buffer[] = '<?xml version="1.0"?>'; | ||||
|         $buffer[] = '<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'; | ||||
|         $buffer[] = ' <database name="">'; | ||||
|  | ||||
|         if ($this->options->withStructure) { | ||||
|             $buffer = array_merge($buffer, $this->buildXmlStructure()); | ||||
|         } | ||||
|  | ||||
|         if ($this->options->withData) { | ||||
|             $buffer = array_merge($buffer, $this->buildXmlData()); | ||||
|         } | ||||
|  | ||||
|         $buffer[] = ' </database>'; | ||||
|         $buffer[] = '</mysqldump>'; | ||||
|  | ||||
|         return implode("\n", $buffer); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML structure to export. | ||||
|      * | ||||
|      * @return  array  An array of XML lines (strings). | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXmlStructure() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         foreach ($this->from as $table) { | ||||
|             // Replace the magic prefix if found. | ||||
|             $table = $this->getGenericTableName($table); | ||||
|  | ||||
|             // Get the details columns information. | ||||
|             $fields = $this->db->getTableColumns($table, false); | ||||
|             $keys   = $this->db->getTableKeys($table); | ||||
|  | ||||
|             $buffer[] = '  <table_structure name="' . $table . '">'; | ||||
|  | ||||
|             foreach ($fields as $field) { | ||||
|                 $buffer[] = '   <field Field="' . $field->Field . '" Type="' . $field->Type . '" Null="' . $field->Null . '" Key="' . | ||||
|                     $field->Key . '"' . (isset($field->Default) ? ' Default="' . $field->Default . '"' : '') . ' Extra="' . $field->Extra . '"' . | ||||
|                     ' />'; | ||||
|             } | ||||
|  | ||||
|             foreach ($keys as $key) { | ||||
|                 $buffer[] = '   <key Table="' . $table . '" Non_unique="' . $key->Non_unique . '" Key_name="' . $key->Key_name . '"' . | ||||
|                     ' Seq_in_index="' . $key->Seq_in_index . '" Column_name="' . $key->Column_name . '" Collation="' . $key->Collation . '"' . | ||||
|                     ' Null="' . $key->Null . '" Index_type="' . $key->Index_type . '"' . | ||||
|                     ' Sub_part="' . $key->Sub_part . '"' . | ||||
|                     ' Comment="' . htmlspecialchars($key->Comment, \ENT_COMPAT, 'UTF-8') . '"' . | ||||
|                     ' />'; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  </table_structure>'; | ||||
|         } | ||||
|  | ||||
|         return $buffer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         // Check if the db connector has been set. | ||||
|         if (!($this->db instanceof MysqlDriver)) { | ||||
|             throw new \RuntimeException('Database connection wrong type.'); | ||||
|         } | ||||
|  | ||||
|         // Check if the tables have been specified. | ||||
|         if (empty($this->from)) { | ||||
|             throw new \RuntimeException('ERROR: No Tables Specified'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										398
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,398 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysql; | ||||
|  | ||||
| use Joomla\Database\DatabaseImporter; | ||||
|  | ||||
| /** | ||||
|  * MySQL Database Importer. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqlImporter extends DatabaseImporter | ||||
| { | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         // Check if the db connector has been set. | ||||
|         if (!($this->db instanceof MysqlDriver)) { | ||||
|             throw new \RuntimeException('Database connection wrong type.'); | ||||
|         } | ||||
|  | ||||
|         // Check if the tables have been specified. | ||||
|         if (empty($this->from)) { | ||||
|             throw new \RuntimeException('ERROR: No Tables Specified'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   array   $keys   An array of the fields pertaining to this key. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAddKeySql($table, $keys) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ADD ' . $this->getKeySql($keys); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get alters for table if there is a difference. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $structure  The XML structure of the table. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAlterTableSql(\SimpleXMLElement $structure) | ||||
|     { | ||||
|         // Initialise variables. | ||||
|         $table     = $this->getRealTableName($structure['name']); | ||||
|         $oldFields = $this->db->getTableColumns($table); | ||||
|         $oldKeys   = $this->db->getTableKeys($table); | ||||
|         $alters    = []; | ||||
|  | ||||
|         // Get the fields and keys from the XML that we are aiming for. | ||||
|         $newFields = $structure->xpath('field'); | ||||
|         $newKeys   = $structure->xpath('key'); | ||||
|  | ||||
|         // Loop through each field in the new structure. | ||||
|         foreach ($newFields as $field) { | ||||
|             $fName = (string) $field['Field']; | ||||
|  | ||||
|             if (isset($oldFields[$fName])) { | ||||
|                 // The field exists, check it's the same. | ||||
|                 $column = $oldFields[$fName]; | ||||
|  | ||||
|                 // Test whether there is a change. | ||||
|                 $change = ((string) $field['Type'] !== $column->Type) || ((string) $field['Null'] !== $column->Null) | ||||
|                     || ((string) $field['Default'] !== $column->Default) || ((string) $field['Extra'] !== $column->Extra); | ||||
|  | ||||
|                 if ($change) { | ||||
|                     $alters[] = $this->getChangeColumnSql($table, $field); | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldFields[$fName]); | ||||
|             } else { | ||||
|                 // The field is new. | ||||
|                 $alters[] = $this->getAddColumnSql($table, $field); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any columns left are orphans | ||||
|         foreach ($oldFields as $name => $column) { | ||||
|             // Delete the column. | ||||
|             $alters[] = $this->getDropColumnSql($table, $name); | ||||
|         } | ||||
|  | ||||
|         // Get the lookups for the old and new keys. | ||||
|         $oldLookup = $this->getKeyLookup($oldKeys); | ||||
|         $newLookup = $this->getKeyLookup($newKeys); | ||||
|  | ||||
|         // Loop through each key in the new structure. | ||||
|         foreach ($newLookup as $name => $keys) { | ||||
|             // Check if there are keys on this field in the existing table. | ||||
|             if (isset($oldLookup[$name])) { | ||||
|                 $same     = true; | ||||
|                 $newCount = \count($newLookup[$name]); | ||||
|                 $oldCount = \count($oldLookup[$name]); | ||||
|  | ||||
|                 // There is a key on this field in the old and new tables. Are they the same? | ||||
|                 if ($newCount === $oldCount) { | ||||
|                     // Need to loop through each key and do a fine grained check. | ||||
|                     for ($i = 0; $i < $newCount; $i++) { | ||||
|                         $same = (((string) $newLookup[$name][$i]['Non_unique'] === $oldLookup[$name][$i]->Non_unique) | ||||
|                             && ((string) $newLookup[$name][$i]['Column_name'] === $oldLookup[$name][$i]->Column_name) | ||||
|                             && ((string) $newLookup[$name][$i]['Seq_in_index'] === $oldLookup[$name][$i]->Seq_in_index) | ||||
|                             && ((string) $newLookup[$name][$i]['Collation'] === $oldLookup[$name][$i]->Collation) | ||||
|                             && ((string) $newLookup[$name][$i]['Sub_part'] === $oldLookup[$name][$i]->Sub_part) | ||||
|                             && ((string) $newLookup[$name][$i]['Index_type'] === $oldLookup[$name][$i]->Index_type)); | ||||
|  | ||||
|                         /* | ||||
|                         Debug. | ||||
|                         echo '<pre>'; | ||||
|                         echo '<br>Non_unique:   '. | ||||
|                             ((string) $newLookup[$name][$i]['Non_unique'] == $oldLookup[$name][$i]->Non_unique ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Non_unique'].' vs '.$oldLookup[$name][$i]->Non_unique; | ||||
|                         echo '<br>Column_name:  '. | ||||
|                             ((string) $newLookup[$name][$i]['Column_name'] == $oldLookup[$name][$i]->Column_name ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Column_name'].' vs '.$oldLookup[$name][$i]->Column_name; | ||||
|                         echo '<br>Seq_in_index: '. | ||||
|                             ((string) $newLookup[$name][$i]['Seq_in_index'] == $oldLookup[$name][$i]->Seq_in_index ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Seq_in_index'].' vs '.$oldLookup[$name][$i]->Seq_in_index; | ||||
|                         echo '<br>Collation:    '. | ||||
|                             ((string) $newLookup[$name][$i]['Collation'] == $oldLookup[$name][$i]->Collation ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Collation'].' vs '.$oldLookup[$name][$i]->Collation; | ||||
|                         echo '<br>Sub_part:    '. | ||||
|                             ((string) $newLookup[$name][$i]['Sub_part'] == $oldLookup[$name][$i]->Sub_part ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Sub_part'].' vs '.$oldLookup[$name][$i]->Sub_part; | ||||
|                         echo '<br>Index_type:   '. | ||||
|                             ((string) $newLookup[$name][$i]['Index_type'] == $oldLookup[$name][$i]->Index_type ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Index_type'].' vs '.$oldLookup[$name][$i]->Index_type; | ||||
|                         echo '<br>Same = '.($same ? 'true' : 'false'); | ||||
|                         echo '</pre>'; | ||||
|                          */ | ||||
|  | ||||
|                         if (!$same) { | ||||
|                             // Break out of the loop. No need to check further. | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     // Count is different, just drop and add. | ||||
|                     $same = false; | ||||
|                 } | ||||
|  | ||||
|                 if (!$same) { | ||||
|                     $alters[] = $this->getDropKeySql($table, $name); | ||||
|                     $alters[] = $this->getAddKeySql($table, $keys); | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldLookup[$name]); | ||||
|             } else { | ||||
|                 // This is a new key. | ||||
|                 $alters[] = $this->getAddKeySql($table, $keys); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any keys left are orphans. | ||||
|         foreach ($oldLookup as $name => $keys) { | ||||
|             if (strtoupper($name) === 'PRIMARY') { | ||||
|                 $alters[] = $this->getDropPrimaryKeySql($table); | ||||
|             } else { | ||||
|                 $alters[] = $this->getDropKeySql($table, $name); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $alters; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to alter a column. | ||||
|      * | ||||
|      * @param   string             $table  The name of the database table to alter. | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the field. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getChangeColumnSql($table, \SimpleXMLElement $field) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' CHANGE COLUMN ' . $this->db->quoteName((string) $field['Field']) . ' ' | ||||
|             . $this->getColumnSql($field); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a single column that would be included in a table create or alter statement. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML field definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getColumnSql(\SimpleXMLElement $field) | ||||
|     { | ||||
|         // Initialise variables. | ||||
|         // TODO Incorporate into parent class and use $this. | ||||
|         $blobs = ['text', 'smalltext', 'mediumtext', 'largetext']; | ||||
|  | ||||
|         $fName    = (string) $field['Field']; | ||||
|         $fType    = (string) $field['Type']; | ||||
|         $fNull    = (string) $field['Null']; | ||||
|         $fDefault = isset($field['Default']) ? (string) $field['Default'] : null; | ||||
|         $fExtra   = (string) $field['Extra']; | ||||
|  | ||||
|         $sql = $this->db->quoteName($fName) . ' ' . $fType; | ||||
|  | ||||
|         if ($fNull === 'NO') { | ||||
|             if ($fDefault === null || \in_array($fType, $blobs, true)) { | ||||
|                 $sql .= ' NOT NULL'; | ||||
|             } else { | ||||
|                 // TODO Don't quote numeric values. | ||||
|                 if (stristr($fDefault, 'CURRENT') !== false) { | ||||
|                     $sql .= ' NOT NULL DEFAULT CURRENT_TIMESTAMP()'; | ||||
|                 } else { | ||||
|                     $sql .= ' NOT NULL DEFAULT ' . $this->db->quote($fDefault); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             if ($fDefault === null) { | ||||
|                 $sql .= ' DEFAULT NULL'; | ||||
|             } else { | ||||
|                 // TODO Don't quote numeric values. | ||||
|                 $sql .= ' DEFAULT ' . $this->db->quote($fDefault); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($fExtra) { | ||||
|             // MySql 8.0 introduces DEFAULT_GENERATED in the extra column and should be replaced with the default value | ||||
|             if (stristr($fExtra, 'DEFAULT_GENERATED') !== false) { | ||||
|                 $sql .= ' ' . strtoupper(str_ireplace('DEFAULT_GENERATED', 'DEFAULT ' . $fDefault, $fExtra)); | ||||
|             } else { | ||||
|                 $sql .= ' ' . strtoupper($fExtra); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $sql; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   string  $name   The name of the key to drop. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropKeySql($table, $name) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP KEY ' . $this->db->quoteName($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropPrimaryKeySql($table) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP PRIMARY KEY'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   array  $keys  An array of objects that comprise the keys for the table. | ||||
|      * | ||||
|      * @return  array  The lookup array. array({key name} => array(object, ...)) | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception | ||||
|      */ | ||||
|     protected function getKeyLookup($keys) | ||||
|     { | ||||
|         // First pass, create a lookup of the keys. | ||||
|         $lookup = []; | ||||
|  | ||||
|         foreach ($keys as $key) { | ||||
|             if ($key instanceof \SimpleXMLElement) { | ||||
|                 $kName = (string) $key['Key_name']; | ||||
|             } else { | ||||
|                 $kName = $key->Key_name; | ||||
|             } | ||||
|  | ||||
|             if (empty($lookup[$kName])) { | ||||
|                 $lookup[$kName] = []; | ||||
|             } | ||||
|  | ||||
|             $lookup[$kName][] = $key; | ||||
|         } | ||||
|  | ||||
|         return $lookup; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a key. | ||||
|      * | ||||
|      * @param   array  $columns  An array of SimpleXMLElement objects comprising the key. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getKeySql($columns) | ||||
|     { | ||||
|         $kNonUnique = (string) $columns[0]['Non_unique']; | ||||
|         $kName      = (string) $columns[0]['Key_name']; | ||||
|         $prefix     = ''; | ||||
|  | ||||
|         if ($kName === 'PRIMARY') { | ||||
|             $prefix = 'PRIMARY '; | ||||
|         } elseif ($kNonUnique == 0) { | ||||
|             $prefix = 'UNIQUE '; | ||||
|         } | ||||
|  | ||||
|         $kColumns = []; | ||||
|  | ||||
|         foreach ($columns as $column) { | ||||
|             $kLength = ''; | ||||
|  | ||||
|             if (!empty($column['Sub_part'])) { | ||||
|                 $kLength = '(' . $column['Sub_part'] . ')'; | ||||
|             } | ||||
|  | ||||
|             $kColumns[] = $this->db->quoteName((string) $column['Column_name']) . $kLength; | ||||
|         } | ||||
|  | ||||
|         return $prefix . 'KEY ' . ($kName !== 'PRIMARY' ? $this->db->quoteName($kName) : '') . ' (' . implode(',', $kColumns) . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a table. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $table  The table information. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     protected function xmlToCreate(\SimpleXMLElement $table) | ||||
|     { | ||||
|         $existingTables = $this->db->getTableList(); | ||||
|         $tableName      = (string) $table['name']; | ||||
|  | ||||
|         if (\in_array($tableName, $existingTables)) { | ||||
|             throw new \RuntimeException('The table you are trying to create already exists'); | ||||
|         } | ||||
|  | ||||
|         $createTableStatement = 'CREATE TABLE ' . $this->db->quoteName($tableName) . ' ('; | ||||
|  | ||||
|         foreach ($table->xpath('field') as $field) { | ||||
|             $createTableStatement .= $this->getColumnSql($field) . ', '; | ||||
|         } | ||||
|  | ||||
|         $newLookup = $this->getKeyLookup($table->xpath('key')); | ||||
|  | ||||
|         foreach ($newLookup as $key) { | ||||
|             $createTableStatement .= $this->getKeySql($key) . ', '; | ||||
|         } | ||||
|  | ||||
|         $createTableStatement = rtrim($createTableStatement, ', '); | ||||
|  | ||||
|         $createTableStatement .= ')'; | ||||
|  | ||||
|         return $createTableStatement; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								libraries/vendor/joomla/database/src/Mysql/MysqlQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysql; | ||||
|  | ||||
| use Joomla\Database\Pdo\PdoQuery; | ||||
| use Joomla\Database\Query\MysqlQueryBuilder; | ||||
|  | ||||
| /** | ||||
|  * MySQL Query Building Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqlQuery extends PdoQuery | ||||
| { | ||||
|     use MysqlQueryBuilder; | ||||
|  | ||||
|     /** | ||||
|      * The list of zero or null representation of a datetime. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $nullDatetimeList = ['0000-00-00 00:00:00', '1000-01-01 00:00:00']; | ||||
| } | ||||
							
								
								
									
										1085
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1085
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										116
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysqli; | ||||
|  | ||||
| use Joomla\Database\DatabaseExporter; | ||||
|  | ||||
| /** | ||||
|  * MySQLi Database Exporter. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqliExporter extends DatabaseExporter | ||||
| { | ||||
|     /** | ||||
|      * Builds the XML data for the tables to export. | ||||
|      * | ||||
|      * @return  string  An XML string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXml() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         $buffer[] = '<?xml version="1.0"?>'; | ||||
|         $buffer[] = '<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'; | ||||
|         $buffer[] = ' <database name="">'; | ||||
|  | ||||
|         if ($this->options->withStructure) { | ||||
|             $buffer = array_merge($buffer, $this->buildXmlStructure()); | ||||
|         } | ||||
|  | ||||
|         if ($this->options->withData) { | ||||
|             $buffer = array_merge($buffer, $this->buildXmlData()); | ||||
|         } | ||||
|  | ||||
|         $buffer[] = ' </database>'; | ||||
|         $buffer[] = '</mysqldump>'; | ||||
|  | ||||
|         return implode("\n", $buffer); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML structure to export. | ||||
|      * | ||||
|      * @return  array  An array of XML lines (strings). | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXmlStructure() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         foreach ($this->from as $table) { | ||||
|             // Replace the magic prefix if found. | ||||
|             $table = $this->getGenericTableName($table); | ||||
|  | ||||
|             // Get the details columns information. | ||||
|             $fields = $this->db->getTableColumns($table, false); | ||||
|             $keys   = $this->db->getTableKeys($table); | ||||
|  | ||||
|             $buffer[] = '  <table_structure name="' . $table . '">'; | ||||
|  | ||||
|             foreach ($fields as $field) { | ||||
|                 $buffer[] = '   <field Field="' . $field->Field . '" Type="' . $field->Type . '" Null="' . $field->Null . '" Key="' . | ||||
|                     $field->Key . '"' . (isset($field->Default) ? ' Default="' . $field->Default . '"' : '') . ' Extra="' . $field->Extra . '"' . | ||||
|                     ' />'; | ||||
|             } | ||||
|  | ||||
|             foreach ($keys as $key) { | ||||
|                 $buffer[] = '   <key Table="' . $table . '" Non_unique="' . $key->Non_unique . '" Key_name="' . $key->Key_name . '"' . | ||||
|                     ' Seq_in_index="' . $key->Seq_in_index . '" Column_name="' . $key->Column_name . '" Collation="' . $key->Collation . '"' . | ||||
|                     ' Null="' . $key->Null . '" Index_type="' . $key->Index_type . '"' . | ||||
|                     ' Sub_part="' . $key->Sub_part . '"' . | ||||
|                     ' Comment="' . htmlspecialchars($key->Comment, \ENT_COMPAT, 'UTF-8') . '"' . | ||||
|                     ' />'; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  </table_structure>'; | ||||
|         } | ||||
|  | ||||
|         return $buffer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         // Check if the db connector has been set. | ||||
|         if (!($this->db instanceof MysqliDriver)) { | ||||
|             throw new \RuntimeException('Database connection wrong type.'); | ||||
|         } | ||||
|  | ||||
|         // Check if the tables have been specified. | ||||
|         if (empty($this->from)) { | ||||
|             throw new \RuntimeException('ERROR: No Tables Specified'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										395
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,395 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysqli; | ||||
|  | ||||
| use Joomla\Database\DatabaseImporter; | ||||
|  | ||||
| /** | ||||
|  * MySQLi Database Importer. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqliImporter extends DatabaseImporter | ||||
| { | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         // Check if the db connector has been set. | ||||
|         if (!($this->db instanceof MysqliDriver)) { | ||||
|             throw new \RuntimeException('Database connection wrong type.'); | ||||
|         } | ||||
|  | ||||
|         // Check if the tables have been specified. | ||||
|         if (empty($this->from)) { | ||||
|             throw new \RuntimeException('ERROR: No Tables Specified'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a table. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $table  The table information. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.4.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     protected function xmlToCreate(\SimpleXMLElement $table) | ||||
|     { | ||||
|         $existingTables = $this->db->getTableList(); | ||||
|         $tableName      = (string) $table['name']; | ||||
|  | ||||
|         if (\in_array($tableName, $existingTables, true)) { | ||||
|             throw new \RuntimeException('The table you are trying to create already exists'); | ||||
|         } | ||||
|  | ||||
|         $createTableStatement = 'CREATE TABLE ' . $this->db->quoteName($tableName) . ' ('; | ||||
|  | ||||
|         foreach ($table->xpath('field') as $field) { | ||||
|             $createTableStatement .= $this->getColumnSql($field) . ', '; | ||||
|         } | ||||
|  | ||||
|         $newLookup = $this->getKeyLookup($table->xpath('key')); | ||||
|  | ||||
|         foreach ($newLookup as $key) { | ||||
|             $createTableStatement .= $this->getKeySql($key) . ', '; | ||||
|         } | ||||
|  | ||||
|         $createTableStatement = rtrim($createTableStatement, ', '); | ||||
|  | ||||
|         $createTableStatement .= ')'; | ||||
|  | ||||
|         return $createTableStatement; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   array   $keys   An array of the fields pertaining to this key. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAddKeySql($table, $keys) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ADD ' . $this->getKeySql($keys); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get alters for table if there is a difference. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $structure  The XML structure of the table. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAlterTableSql(\SimpleXMLElement $structure) | ||||
|     { | ||||
|         $table     = $this->getRealTableName($structure['name']); | ||||
|         $oldFields = $this->db->getTableColumns($table, false); | ||||
|         $oldKeys   = $this->db->getTableKeys($table); | ||||
|         $alters    = []; | ||||
|  | ||||
|         // Get the fields and keys from the XML that we are aiming for. | ||||
|         $newFields = $structure->xpath('field'); | ||||
|         $newKeys   = $structure->xpath('key'); | ||||
|  | ||||
|         // Loop through each field in the new structure. | ||||
|         foreach ($newFields as $field) { | ||||
|             $fName = (string) $field['Field']; | ||||
|  | ||||
|             if (isset($oldFields[$fName])) { | ||||
|                 // The field exists, check it's the same. | ||||
|                 $column = $oldFields[$fName]; | ||||
|  | ||||
|                 // Test whether there is a change. | ||||
|                 $change = ((string) $field['Type'] !== $column->Type) || ((string) $field['Null'] !== $column->Null) | ||||
|                     || ((string) $field['Default'] !== $column->Default) || ((string) $field['Extra'] !== $column->Extra); | ||||
|  | ||||
|                 if ($change) { | ||||
|                     $alters[] = $this->getChangeColumnSql($table, $field); | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldFields[$fName]); | ||||
|             } else { | ||||
|                 // The field is new. | ||||
|                 $alters[] = $this->getAddColumnSql($table, $field); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any columns left are orphans | ||||
|         foreach ($oldFields as $name => $column) { | ||||
|             // Delete the column. | ||||
|             $alters[] = $this->getDropColumnSql($table, $name); | ||||
|         } | ||||
|  | ||||
|         // Get the lookups for the old and new keys. | ||||
|         $oldLookup = $this->getKeyLookup($oldKeys); | ||||
|         $newLookup = $this->getKeyLookup($newKeys); | ||||
|  | ||||
|         // Loop through each key in the new structure. | ||||
|         foreach ($newLookup as $name => $keys) { | ||||
|             // Check if there are keys on this field in the existing table. | ||||
|             if (isset($oldLookup[$name])) { | ||||
|                 $same     = true; | ||||
|                 $newCount = \count($newLookup[$name]); | ||||
|                 $oldCount = \count($oldLookup[$name]); | ||||
|  | ||||
|                 // There is a key on this field in the old and new tables. Are they the same? | ||||
|                 if ($newCount === $oldCount) { | ||||
|                     // Need to loop through each key and do a fine grained check. | ||||
|                     for ($i = 0; $i < $newCount; $i++) { | ||||
|                         $same = (((string) $newLookup[$name][$i]['Non_unique'] === $oldLookup[$name][$i]->Non_unique) | ||||
|                             && ((string) $newLookup[$name][$i]['Column_name'] === $oldLookup[$name][$i]->Column_name) | ||||
|                             && ((string) $newLookup[$name][$i]['Seq_in_index'] === $oldLookup[$name][$i]->Seq_in_index) | ||||
|                             && ((string) $newLookup[$name][$i]['Collation'] === $oldLookup[$name][$i]->Collation) | ||||
|                             && ((string) $newLookup[$name][$i]['Sub_part'] == $oldLookup[$name][$i]->Sub_part) | ||||
|                             && ((string) $newLookup[$name][$i]['Index_type'] === $oldLookup[$name][$i]->Index_type)); | ||||
|  | ||||
|                         /* | ||||
|                         Debug. | ||||
|                         echo '<pre>'; | ||||
|                         echo '<br>Non_unique:   '. | ||||
|                             ((string) $newLookup[$name][$i]['Non_unique'] == $oldLookup[$name][$i]->Non_unique ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Non_unique'].' vs '.$oldLookup[$name][$i]->Non_unique; | ||||
|                         echo '<br>Column_name:  '. | ||||
|                             ((string) $newLookup[$name][$i]['Column_name'] == $oldLookup[$name][$i]->Column_name ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Column_name'].' vs '.$oldLookup[$name][$i]->Column_name; | ||||
|                         echo '<br>Seq_in_index: '. | ||||
|                             ((string) $newLookup[$name][$i]['Seq_in_index'] == $oldLookup[$name][$i]->Seq_in_index ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Seq_in_index'].' vs '.$oldLookup[$name][$i]->Seq_in_index; | ||||
|                         echo '<br>Collation:    '. | ||||
|                             ((string) $newLookup[$name][$i]['Collation'] == $oldLookup[$name][$i]->Collation ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Collation'].' vs '.$oldLookup[$name][$i]->Collation; | ||||
|                         echo '<br>Sub_part:    '. | ||||
|                             ((string) $newLookup[$name][$i]['Sub_part'] == $oldLookup[$name][$i]->Sub_part ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Sub_part'].' vs '.$oldLookup[$name][$i]->Sub_part; | ||||
|                         echo '<br>Index_type:   '. | ||||
|                             ((string) $newLookup[$name][$i]['Index_type'] == $oldLookup[$name][$i]->Index_type ? 'Pass' : 'Fail').' '. | ||||
|                             (string) $newLookup[$name][$i]['Index_type'].' vs '.$oldLookup[$name][$i]->Index_type; | ||||
|                         echo '<br>Same = '.($same ? 'true' : 'false'); | ||||
|                         echo '</pre>'; | ||||
|                          */ | ||||
|  | ||||
|                         if (!$same) { | ||||
|                             // Break out of the loop. No need to check further. | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     // Count is different, just drop and add. | ||||
|                     $same = false; | ||||
|                 } | ||||
|  | ||||
|                 if (!$same) { | ||||
|                     $alters[] = $this->getDropKeySql($table, $name); | ||||
|                     $alters[] = $this->getAddKeySql($table, $keys); | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldLookup[$name]); | ||||
|             } else { | ||||
|                 // This is a new key. | ||||
|                 $alters[] = $this->getAddKeySql($table, $keys); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any keys left are orphans. | ||||
|         foreach ($oldLookup as $name => $keys) { | ||||
|             if (strtoupper($name) === 'PRIMARY') { | ||||
|                 $alters[] = $this->getDropPrimaryKeySql($table); | ||||
|             } else { | ||||
|                 $alters[] = $this->getDropKeySql($table, $name); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $alters; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to alter a column. | ||||
|      * | ||||
|      * @param   string             $table  The name of the database table to alter. | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the field. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getChangeColumnSql($table, \SimpleXMLElement $field) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' CHANGE COLUMN ' . $this->db->quoteName((string) $field['Field']) . ' ' | ||||
|             . $this->getColumnSql($field); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a single column that would be included in a table create or alter statement. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML field definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getColumnSql(\SimpleXMLElement $field) | ||||
|     { | ||||
|         // TODO Incorporate into parent class and use $this. | ||||
|         $blobs = ['text', 'smalltext', 'mediumtext', 'largetext']; | ||||
|  | ||||
|         $fName    = (string) $field['Field']; | ||||
|         $fType    = (string) $field['Type']; | ||||
|         $fNull    = (string) $field['Null']; | ||||
|         $fDefault = isset($field['Default']) ? (string) $field['Default'] : null; | ||||
|         $fExtra   = (string) $field['Extra']; | ||||
|  | ||||
|         $sql = $this->db->quoteName($fName) . ' ' . $fType; | ||||
|  | ||||
|         if ($fNull === 'NO') { | ||||
|             if ($fDefault === null || \in_array($fType, $blobs, true)) { | ||||
|                 $sql .= ' NOT NULL'; | ||||
|             } else { | ||||
|                 // TODO Don't quote numeric values. | ||||
|                 if (stristr($fDefault, 'CURRENT') !== false) { | ||||
|                     $sql .= ' NOT NULL DEFAULT CURRENT_TIMESTAMP()'; | ||||
|                 } else { | ||||
|                     $sql .= ' NOT NULL DEFAULT ' . $this->db->quote($fDefault); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             if ($fDefault === null) { | ||||
|                 $sql .= ' DEFAULT NULL'; | ||||
|             } else { | ||||
|                 // TODO Don't quote numeric values. | ||||
|                 $sql .= ' DEFAULT ' . $this->db->quote($fDefault); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($fExtra) { | ||||
|             // MySql 8.0 introduces DEFAULT_GENERATED in the extra column and should be replaced with the default value | ||||
|             if (stristr($fExtra, 'DEFAULT_GENERATED') !== false) { | ||||
|                 $sql .= ' ' . strtoupper(str_ireplace('DEFAULT_GENERATED', 'DEFAULT ' . $fDefault, $fExtra)); | ||||
|             } else { | ||||
|                 $sql .= ' ' . strtoupper($fExtra); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $sql; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   string  $name   The name of the key to drop. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropKeySql($table, $name) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP KEY ' . $this->db->quoteName($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropPrimaryKeySql($table) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' DROP PRIMARY KEY'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   array  $keys  An array of objects that comprise the keys for the table. | ||||
|      * | ||||
|      * @return  array  The lookup array. array({key name} => array(object, ...)) | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getKeyLookup($keys) | ||||
|     { | ||||
|         // First pass, create a lookup of the keys. | ||||
|         $lookup = []; | ||||
|  | ||||
|         foreach ($keys as $key) { | ||||
|             if ($key instanceof \SimpleXMLElement) { | ||||
|                 $kName = (string) $key['Key_name']; | ||||
|             } else { | ||||
|                 $kName = $key->Key_name; | ||||
|             } | ||||
|  | ||||
|             if (empty($lookup[$kName])) { | ||||
|                 $lookup[$kName] = []; | ||||
|             } | ||||
|  | ||||
|             $lookup[$kName][] = $key; | ||||
|         } | ||||
|  | ||||
|         return $lookup; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a key. | ||||
|      * | ||||
|      * @param   array  $columns  An array of SimpleXMLElement objects comprising the key. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getKeySql($columns) | ||||
|     { | ||||
|         $kNonUnique = (string) $columns[0]['Non_unique']; | ||||
|         $kName      = (string) $columns[0]['Key_name']; | ||||
|         $prefix     = ''; | ||||
|  | ||||
|         if ($kName === 'PRIMARY') { | ||||
|             $prefix = 'PRIMARY '; | ||||
|         } elseif ($kNonUnique == 0) { | ||||
|             $prefix = 'UNIQUE '; | ||||
|         } | ||||
|  | ||||
|         $kColumns = []; | ||||
|  | ||||
|         foreach ($columns as $column) { | ||||
|             $kLength = ''; | ||||
|  | ||||
|             if (!empty($column['Sub_part'])) { | ||||
|                 $kLength = '(' . $column['Sub_part'] . ')'; | ||||
|             } | ||||
|  | ||||
|             $kColumns[] = $this->db->quoteName((string) $column['Column_name']) . $kLength; | ||||
|         } | ||||
|  | ||||
|         return $prefix . 'KEY ' . ($kName !== 'PRIMARY' ? $this->db->quoteName($kName) : '') . ' (' . implode(',', $kColumns) . ')'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysqli; | ||||
|  | ||||
| use Joomla\Database\DatabaseQuery; | ||||
| use Joomla\Database\Query\MysqlQueryBuilder; | ||||
|  | ||||
| /** | ||||
|  * MySQLi Query Building Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class MysqliQuery extends DatabaseQuery | ||||
| { | ||||
|     use MysqlQueryBuilder; | ||||
|  | ||||
|     /** | ||||
|      * The list of zero or null representation of a datetime. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $nullDatetimeList = ['0000-00-00 00:00:00', '1000-01-01 00:00:00']; | ||||
| } | ||||
							
								
								
									
										588
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliStatement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										588
									
								
								libraries/vendor/joomla/database/src/Mysqli/MysqliStatement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,588 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Mysqli; | ||||
|  | ||||
| use Joomla\Database\Exception\ExecutionFailureException; | ||||
| use Joomla\Database\Exception\PrepareStatementFailureException; | ||||
| use Joomla\Database\FetchMode; | ||||
| use Joomla\Database\FetchOrientation; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Database\StatementInterface; | ||||
|  | ||||
| /** | ||||
|  * MySQLi Database Statement. | ||||
|  * | ||||
|  * This class is modeled on \Doctrine\DBAL\Driver\Mysqli\MysqliStatement | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class MysqliStatement implements StatementInterface | ||||
| { | ||||
|     /** | ||||
|      * Values which have been bound to the statement. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $bindedValues; | ||||
|  | ||||
|     /** | ||||
|      * Mapping between named parameters and position in query. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $parameterKeyMapping; | ||||
|  | ||||
|     /** | ||||
|      * Mapping array for parameter types. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $parameterTypeMapping = [ | ||||
|         ParameterType::BOOLEAN      => 'i', | ||||
|         ParameterType::INTEGER      => 'i', | ||||
|         ParameterType::LARGE_OBJECT => 's', | ||||
|         ParameterType::NULL         => 's', | ||||
|         ParameterType::STRING       => 's', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * Column names from the executed statement. | ||||
|      * | ||||
|      * @var    array|boolean|null | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $columnNames; | ||||
|  | ||||
|     /** | ||||
|      * The database connection resource. | ||||
|      * | ||||
|      * @var    \mysqli | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $connection; | ||||
|  | ||||
|     /** | ||||
|      * The default fetch mode for the statement. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $defaultFetchStyle = FetchMode::MIXED; | ||||
|  | ||||
|     /** | ||||
|      * The query string being prepared. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $query; | ||||
|  | ||||
|     /** | ||||
|      * Internal tracking flag to set whether there is a result set available for processing | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $result = false; | ||||
|  | ||||
|     /** | ||||
|      * Values which have been bound to the rows of each result set. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $rowBindedValues; | ||||
|  | ||||
|     /** | ||||
|      * The prepared statement. | ||||
|      * | ||||
|      * @var    \mysqli_stmt | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $statement; | ||||
|  | ||||
|     /** | ||||
|      * Bound parameter types. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $typesKeyMapping; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   \mysqli  $connection  The database connection resource | ||||
|      * @param   string   $query       The query this statement will process | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  PrepareStatementFailureException | ||||
|      */ | ||||
|     public function __construct(\mysqli $connection, string $query) | ||||
|     { | ||||
|         $this->connection   = $connection; | ||||
|         $this->query        = $query; | ||||
|  | ||||
|         $query = $this->prepareParameterKeyMapping($query); | ||||
|  | ||||
|         $this->statement  = $connection->prepare($query); | ||||
|  | ||||
|         if (!$this->statement) { | ||||
|             throw new PrepareStatementFailureException($this->connection->error, $this->connection->errno); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Replace named parameters with numbered parameters | ||||
|      * | ||||
|      * @param   string  $sql  The SQL statement to prepare. | ||||
|      * | ||||
|      * @return  string  The processed SQL statement. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function prepareParameterKeyMapping($sql) | ||||
|     { | ||||
|         $escaped    = false; | ||||
|         $startPos   = 0; | ||||
|         $quoteChar  = ''; | ||||
|         $literal    = ''; | ||||
|         $mapping    = []; | ||||
|         $position   = 0; | ||||
|         $matches    = []; | ||||
|         $pattern    = '/([:][a-zA-Z0-9_]+)/'; | ||||
|  | ||||
|         if (!preg_match($pattern, $sql, $matches)) { | ||||
|             return $sql; | ||||
|         } | ||||
|  | ||||
|         $sql = trim($sql); | ||||
|         $n   = \strlen($sql); | ||||
|  | ||||
|         while ($startPos < $n) { | ||||
|             if (!preg_match($pattern, $sql, $matches, 0, $startPos)) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $j = strpos($sql, "'", $startPos); | ||||
|             $k = strpos($sql, '"', $startPos); | ||||
|  | ||||
|             if (($k !== false) && (($k < $j) || ($j === false))) { | ||||
|                 $quoteChar = '"'; | ||||
|                 $j         = $k; | ||||
|             } else { | ||||
|                 $quoteChar = "'"; | ||||
|             } | ||||
|  | ||||
|             if ($j === false) { | ||||
|                 $j = $n; | ||||
|             } | ||||
|  | ||||
|             // Search for named prepared parameters and replace it with ? and save its position | ||||
|             $substring = substr($sql, $startPos, $j - $startPos); | ||||
|  | ||||
|             if (preg_match_all($pattern, $substring, $matches, PREG_PATTERN_ORDER + PREG_OFFSET_CAPTURE)) { | ||||
|                 foreach ($matches[0] as $i => $match) { | ||||
|                     if ($i === 0) { | ||||
|                         $literal .= substr($substring, 0, $match[1]); | ||||
|                     } | ||||
|  | ||||
|                     if (!isset($mapping[$match[0]])) { | ||||
|                         $mapping[$match[0]] = []; | ||||
|                     } | ||||
|  | ||||
|                     $mapping[$match[0]][]   = $position++; | ||||
|                     $endOfPlaceholder       = $match[1] + strlen($match[0]); | ||||
|                     $beginOfNextPlaceholder = $matches[0][$i + 1][1] ?? strlen($substring); | ||||
|                     $beginOfNextPlaceholder -= $endOfPlaceholder; | ||||
|                     $literal                .= '?' . substr($substring, $endOfPlaceholder, $beginOfNextPlaceholder); | ||||
|                 } | ||||
|             } else { | ||||
|                 $literal .= $substring; | ||||
|             } | ||||
|  | ||||
|             $startPos = $j; | ||||
|             $j++; | ||||
|  | ||||
|             if ($j >= $n) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             // Quote comes first, find end of quote | ||||
|             while (true) { | ||||
|                 $k       = strpos($sql, $quoteChar, $j); | ||||
|                 $escaped = false; | ||||
|  | ||||
|                 if ($k === false) { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 $l = $k - 1; | ||||
|  | ||||
|                 while ($l >= 0 && $sql[$l] === '\\') { | ||||
|                     $l--; | ||||
|                     $escaped = !$escaped; | ||||
|                 } | ||||
|  | ||||
|                 if ($escaped) { | ||||
|                     $j = $k + 1; | ||||
|  | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             if ($k === false) { | ||||
|                 // Error in the query - no end quote; ignore it | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $literal .= substr($sql, $startPos, $k - $startPos + 1); | ||||
|             $startPos = $k + 1; | ||||
|         } | ||||
|  | ||||
|         if ($startPos < $n) { | ||||
|             $literal .= substr($sql, $startPos, $n - $startPos); | ||||
|         } | ||||
|  | ||||
|         $this->parameterKeyMapping = $mapping; | ||||
|  | ||||
|         return $literal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Binds a parameter to the specified variable name. | ||||
|      * | ||||
|      * @param   string|integer  $parameter      Parameter identifier. For a prepared statement using named placeholders, this will be a parameter | ||||
|      *                                          name of the form `:name`. For a prepared statement using question mark placeholders, this will be | ||||
|      *                                          the 1-indexed position of the parameter. | ||||
|      * @param   mixed           $variable       Name of the PHP variable to bind to the SQL statement parameter. | ||||
|      * @param   integer         $dataType       Constant corresponding to a SQL datatype, this should be the processed type from the QueryInterface. | ||||
|      * @param   integer         $length         The length of the variable. Usually required for OUTPUT parameters. | ||||
|      * @param   array           $driverOptions  Optional driver options to be used. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function bindParam($parameter, &$variable, string $dataType = ParameterType::STRING, ?int $length = null, ?array $driverOptions = null) | ||||
|     { | ||||
|         $this->bindedValues[$parameter] =& $variable; | ||||
|  | ||||
|         // Validate parameter type | ||||
|         if (!isset($this->parameterTypeMapping[$dataType])) { | ||||
|             throw new \InvalidArgumentException(sprintf('Unsupported parameter type `%s`', $dataType)); | ||||
|         } | ||||
|  | ||||
|         $this->typesKeyMapping[$parameter] = $this->parameterTypeMapping[$dataType]; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Binds a array of values to bound parameters. | ||||
|      * | ||||
|      * @param   array  $values  The values to bind to the statement | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function bindValues(array $values) | ||||
|     { | ||||
|         $params = []; | ||||
|         $types  = str_repeat('s', \count($values)); | ||||
|  | ||||
|         if (!empty($this->parameterKeyMapping)) { | ||||
|             foreach ($values as $key => &$value) { | ||||
|                 $params[$this->parameterKeyMapping[$key]] =& $value; | ||||
|             } | ||||
|  | ||||
|             ksort($params); | ||||
|         } else { | ||||
|             foreach ($values as $key => &$value) { | ||||
|                 $params[] =& $value; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         array_unshift($params, $types); | ||||
|  | ||||
|         return \call_user_func_array([$this->statement, 'bind_param'], $params); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Closes the cursor, enabling the statement to be executed again. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function closeCursor(): void | ||||
|     { | ||||
|         $this->statement->free_result(); | ||||
|         $this->result = false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches the SQLSTATE associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  int | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorCode() | ||||
|     { | ||||
|         return $this->statement->errno; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches extended error information associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorInfo() | ||||
|     { | ||||
|         return $this->statement->error; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Executes a prepared statement | ||||
|      * | ||||
|      * @param   array|null  $parameters  An array of values with as many elements as there are bound parameters in the SQL statement being executed. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function execute(?array $parameters = null) | ||||
|     { | ||||
|         if ($this->bindedValues !== null) { | ||||
|             $params = []; | ||||
|             $types  = []; | ||||
|  | ||||
|             if (!empty($this->parameterKeyMapping)) { | ||||
|                 foreach ($this->bindedValues as $key => &$value) { | ||||
|                     $paramKey = $this->parameterKeyMapping[$key]; | ||||
|  | ||||
|                     foreach ($paramKey as $currentKey) { | ||||
|                         $params[$currentKey] =& $value; | ||||
|                         $types[$currentKey]  = $this->typesKeyMapping[$key]; | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 foreach ($this->bindedValues as $key => &$value) { | ||||
|                     $params[]    =& $value; | ||||
|                     $types[$key] = $this->typesKeyMapping[$key]; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             ksort($params); | ||||
|             ksort($types); | ||||
|  | ||||
|             array_unshift($params, implode('', $types)); | ||||
|  | ||||
|             if (!\call_user_func_array([$this->statement, 'bind_param'], $params)) { | ||||
|                 throw new PrepareStatementFailureException($this->statement->error, $this->statement->errno); | ||||
|             } | ||||
|         } elseif ($parameters !== null) { | ||||
|             if (!$this->bindValues($parameters)) { | ||||
|                 throw new PrepareStatementFailureException($this->statement->error, $this->statement->errno); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             if (!$this->statement->execute()) { | ||||
|                 throw new ExecutionFailureException($this->query, $this->statement->error, $this->statement->errno); | ||||
|             } | ||||
|         } catch (\Throwable $e) { | ||||
|             throw new ExecutionFailureException($this->query, $e->getMessage(), $e->getCode(), $e); | ||||
|         } | ||||
|  | ||||
|         if ($this->columnNames === null) { | ||||
|             $meta = $this->statement->result_metadata(); | ||||
|  | ||||
|             if ($meta !== false) { | ||||
|                 $columnNames = []; | ||||
|  | ||||
|                 foreach ($meta->fetch_fields() as $col) { | ||||
|                     $columnNames[] = $col->name; | ||||
|                 } | ||||
|  | ||||
|                 $meta->free(); | ||||
|  | ||||
|                 $this->columnNames = $columnNames; | ||||
|             } else { | ||||
|                 $this->columnNames = false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($this->columnNames !== false) { | ||||
|             $this->statement->store_result(); | ||||
|  | ||||
|             $this->rowBindedValues = array_fill(0, \count($this->columnNames), null); | ||||
|             $refs                  = []; | ||||
|  | ||||
|             foreach ($this->rowBindedValues as $key => &$value) { | ||||
|                 $refs[$key] =& $value; | ||||
|             } | ||||
|  | ||||
|             if (!\call_user_func_array([$this->statement, 'bind_result'], $refs)) { | ||||
|                 throw new \RuntimeException($this->statement->error, $this->statement->errno); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->result = true; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches the next row from a result set | ||||
|      * | ||||
|      * @param   integer|null  $fetchStyle         Controls how the next row will be returned to the caller. This value must be one of the | ||||
|      *                                            FetchMode constants, defaulting to value of FetchMode::MIXED. | ||||
|      * @param   integer       $cursorOrientation  For a StatementInterface object representing a scrollable cursor, this value determines which row | ||||
|      *                                            will be returned to the caller. This value must be one of the FetchOrientation constants, | ||||
|      *                                            defaulting to FetchOrientation::NEXT. | ||||
|      * @param   integer       $cursorOffset       For a StatementInterface object representing a scrollable cursor for which the cursorOrientation | ||||
|      *                                            parameter is set to FetchOrientation::ABS, this value specifies the absolute number of the row in | ||||
|      *                                            the result set that shall be fetched. For a StatementInterface object representing a scrollable | ||||
|      *                                            cursor for which the cursorOrientation parameter is set to FetchOrientation::REL, this value | ||||
|      *                                            specifies the row to fetch relative to the cursor position before `fetch()` was called. | ||||
|      * | ||||
|      * @return  mixed  The return value of this function on success depends on the fetch type. In all cases, boolean false is returned on failure. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function fetch(?int $fetchStyle = null, int $cursorOrientation = FetchOrientation::NEXT, int $cursorOffset = 0) | ||||
|     { | ||||
|         if (!$this->result) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $fetchStyle = $fetchStyle ?: $this->defaultFetchStyle; | ||||
|  | ||||
|         if ($fetchStyle === FetchMode::COLUMN) { | ||||
|             return $this->fetchColumn(); | ||||
|         } | ||||
|  | ||||
|         $values = $this->fetchData(); | ||||
|  | ||||
|         if ($values === null) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if ($values === false) { | ||||
|             throw new \RuntimeException($this->statement->error, $this->statement->errno); | ||||
|         } | ||||
|  | ||||
|         switch ($fetchStyle) { | ||||
|             case FetchMode::NUMERIC: | ||||
|                 return $values; | ||||
|  | ||||
|             case FetchMode::ASSOCIATIVE: | ||||
|                 return array_combine($this->columnNames, $values); | ||||
|  | ||||
|             case FetchMode::MIXED: | ||||
|                 $ret = array_combine($this->columnNames, $values); | ||||
|                 $ret += $values; | ||||
|  | ||||
|                 return $ret; | ||||
|  | ||||
|             case FetchMode::STANDARD_OBJECT: | ||||
|                 return (object) array_combine($this->columnNames, $values); | ||||
|  | ||||
|             default: | ||||
|                 throw new \InvalidArgumentException("Unknown fetch type '{$fetchStyle}'"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a single column from the next row of a result set | ||||
|      * | ||||
|      * @param   integer  $columnIndex  0-indexed number of the column you wish to retrieve from the row. | ||||
|      *                                 If no value is supplied, the first column is retrieved. | ||||
|      * | ||||
|      * @return  mixed  Returns a single column from the next row of a result set or boolean false if there are no more rows. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function fetchColumn($columnIndex = 0) | ||||
|     { | ||||
|         $row = $this->fetch(FetchMode::NUMERIC); | ||||
|  | ||||
|         if ($row === false) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $row[$columnIndex] ?? null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetch the data from the statement. | ||||
|      * | ||||
|      * @return  array|boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function fetchData() | ||||
|     { | ||||
|         $return = $this->statement->fetch(); | ||||
|  | ||||
|         if ($return === true) { | ||||
|             $values = []; | ||||
|  | ||||
|             foreach ($this->rowBindedValues as $v) { | ||||
|                 $values[] = $v; | ||||
|             } | ||||
|  | ||||
|             return $values; | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the number of rows affected by the last SQL statement. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rowCount(): int | ||||
|     { | ||||
|         if ($this->columnNames === false) { | ||||
|             return $this->statement->affected_rows; | ||||
|         } | ||||
|  | ||||
|         return $this->statement->num_rows; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the fetch mode to use while iterating this statement. | ||||
|      * | ||||
|      * @param   integer  $fetchMode  The fetch mode, must be one of the FetchMode constants. | ||||
|      * @param   mixed    ...$args    Optional mode-specific arguments. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function setFetchMode(int $fetchMode, ...$args): void | ||||
|     { | ||||
|         $this->defaultFetchStyle = $fetchMode; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										67
									
								
								libraries/vendor/joomla/database/src/ParameterType.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								libraries/vendor/joomla/database/src/ParameterType.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Class defining the parameter types for prepared statements | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| final class ParameterType | ||||
| { | ||||
|     /** | ||||
|      * Defines a boolean parameter | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const BOOLEAN = 'boolean'; | ||||
|  | ||||
|     /** | ||||
|      * Defines an integer parameter | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const INTEGER = 'int'; | ||||
|  | ||||
|     /** | ||||
|      * Defines a large object parameter | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const LARGE_OBJECT = 'lob'; | ||||
|  | ||||
|     /** | ||||
|      * Defines a null parameter | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const NULL = 'null'; | ||||
|  | ||||
|     /** | ||||
|      * Defines a string parameter | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     public const STRING = 'string'; | ||||
|  | ||||
|     /** | ||||
|      * Private constructor to prevent instantiation of this class | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function __construct() | ||||
|     { | ||||
|     } | ||||
| } | ||||
							
								
								
									
										748
									
								
								libraries/vendor/joomla/database/src/Pdo/PdoDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										748
									
								
								libraries/vendor/joomla/database/src/Pdo/PdoDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,748 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Pdo; | ||||
|  | ||||
| use Joomla\Database\DatabaseDriver; | ||||
| use Joomla\Database\DatabaseEvents; | ||||
| use Joomla\Database\Event\ConnectionEvent; | ||||
| use Joomla\Database\Exception\ConnectionFailureException; | ||||
| use Joomla\Database\Exception\ExecutionFailureException; | ||||
| use Joomla\Database\Exception\PrepareStatementFailureException; | ||||
| use Joomla\Database\Exception\UnsupportedAdapterException; | ||||
| use Joomla\Database\StatementInterface; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework PDO Database Driver Class | ||||
|  * | ||||
|  * @link   https://www.php.net/pdo | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| abstract class PdoDriver extends DatabaseDriver | ||||
| { | ||||
|     /** | ||||
|      * The database connection resource. | ||||
|      * | ||||
|      * @var    \PDO | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $connection; | ||||
|  | ||||
|     /** | ||||
|      * The name of the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $name = 'pdo'; | ||||
|  | ||||
|     /** | ||||
|      * The character(s) used to quote SQL statement names such as table names or field names, etc. | ||||
|      * | ||||
|      * If a single character string the same character is used for both sides of the quoted name, else the first character will be used for the | ||||
|      * opening quote and the second for the closing quote. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nameQuote = "'"; | ||||
|  | ||||
|     /** | ||||
|      * The null or zero representation of a timestamp for the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nullDate = '0000-00-00 00:00:00'; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array  $options  List of options used to configure the connection | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct(array $options) | ||||
|     { | ||||
|         // Get some basic values from the options. | ||||
|         $options['driver']        = $options['driver'] ?? 'odbc'; | ||||
|         $options['dsn']           = $options['dsn'] ?? ''; | ||||
|         $options['host']          = $options['host'] ?? 'localhost'; | ||||
|         $options['database']      = $options['database'] ?? ''; | ||||
|         $options['user']          = $options['user'] ?? ''; | ||||
|         $options['port']          = isset($options['port']) ? (int) $options['port'] : null; | ||||
|         $options['password']      = $options['password'] ?? ''; | ||||
|         $options['driverOptions'] = $options['driverOptions'] ?? []; | ||||
|         $options['ssl']           = isset($options['ssl']) ? $options['ssl'] : []; | ||||
|         $options['socket']        = \strpos($options['host'], 'unix:') !== false ? \str_replace('unix:', '', $options['host']) : null; | ||||
|  | ||||
|         if ($options['ssl'] !== []) { | ||||
|             $options['ssl']['enable']             = isset($options['ssl']['enable']) ? $options['ssl']['enable'] : false; | ||||
|             $options['ssl']['cipher']             = isset($options['ssl']['cipher']) ? $options['ssl']['cipher'] : null; | ||||
|             $options['ssl']['ca']                 = isset($options['ssl']['ca']) ? $options['ssl']['ca'] : null; | ||||
|             $options['ssl']['capath']             = isset($options['ssl']['capath']) ? $options['ssl']['capath'] : null; | ||||
|             $options['ssl']['key']                = isset($options['ssl']['key']) ? $options['ssl']['key'] : null; | ||||
|             $options['ssl']['cert']               = isset($options['ssl']['cert']) ? $options['ssl']['cert'] : null; | ||||
|             $options['ssl']['verify_server_cert'] = isset($options['ssl']['verify_server_cert']) ? $options['ssl']['verify_server_cert'] : null; | ||||
|         } | ||||
|  | ||||
|         // Finalize initialisation | ||||
|         parent::__construct($options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Destructor. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __destruct() | ||||
|     { | ||||
|         $this->disconnect(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Connects to the database if needed. | ||||
|      * | ||||
|      * @return  void  Returns void if the database connected successfully. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function connect() | ||||
|     { | ||||
|         if ($this->connection) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Make sure the PDO extension for PHP is installed and enabled. | ||||
|         if (!static::isSupported()) { | ||||
|             throw new UnsupportedAdapterException('PDO Extension is not available.', 1); | ||||
|         } | ||||
|  | ||||
|         // Find the correct PDO DSN Format to use: | ||||
|         switch ($this->options['driver']) { | ||||
|             case 'cubrid': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 33000; | ||||
|  | ||||
|                 $format = 'cubrid:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; | ||||
|  | ||||
|                 $replace = ['#HOST#', '#PORT#', '#DBNAME#']; | ||||
|                 $with    = [$this->options['host'], $this->options['port'], $this->options['database']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'dblib': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 1433; | ||||
|  | ||||
|                 $format = 'dblib:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; | ||||
|  | ||||
|                 $replace = ['#HOST#', '#PORT#', '#DBNAME#']; | ||||
|                 $with    = [$this->options['host'], $this->options['port'], $this->options['database']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'firebird': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 3050; | ||||
|  | ||||
|                 $format = 'firebird:dbname=#DBNAME#'; | ||||
|  | ||||
|                 $replace = ['#DBNAME#']; | ||||
|                 $with    = [$this->options['database']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'ibm': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 56789; | ||||
|  | ||||
|                 if (!empty($this->options['dsn'])) { | ||||
|                     $format = 'ibm:DSN=#DSN#'; | ||||
|  | ||||
|                     $replace = ['#DSN#']; | ||||
|                     $with    = [$this->options['dsn']]; | ||||
|                 } else { | ||||
|                     $format = 'ibm:hostname=#HOST#;port=#PORT#;database=#DBNAME#'; | ||||
|  | ||||
|                     $replace = ['#HOST#', '#PORT#', '#DBNAME#']; | ||||
|                     $with    = [$this->options['host'], $this->options['port'], $this->options['database']]; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'informix': | ||||
|                 $this->options['port']     = $this->options['port'] ?? 1526; | ||||
|                 $this->options['protocol'] = $this->options['protocol'] ?? 'onsoctcp'; | ||||
|  | ||||
|                 if (!empty($this->options['dsn'])) { | ||||
|                     $format = 'informix:DSN=#DSN#'; | ||||
|  | ||||
|                     $replace = ['#DSN#']; | ||||
|                     $with    = [$this->options['dsn']]; | ||||
|                 } else { | ||||
|                     $format = 'informix:host=#HOST#;service=#PORT#;database=#DBNAME#;server=#SERVER#;protocol=#PROTOCOL#'; | ||||
|  | ||||
|                     $replace = ['#HOST#', '#PORT#', '#DBNAME#', '#SERVER#', '#PROTOCOL#']; | ||||
|                     $with    = [ | ||||
|                         $this->options['host'], | ||||
|                         $this->options['port'], | ||||
|                         $this->options['database'], | ||||
|                         $this->options['server'], | ||||
|                         $this->options['protocol'], | ||||
|                     ]; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'mssql': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 1433; | ||||
|  | ||||
|                 $format = 'mssql:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; | ||||
|  | ||||
|                 $replace = ['#HOST#', '#PORT#', '#DBNAME#']; | ||||
|                 $with    = [$this->options['host'], $this->options['port'], $this->options['database']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'mysql': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 3306; | ||||
|  | ||||
|                 if ($this->options['socket'] !== null) { | ||||
|                     $format = 'mysql:unix_socket=#SOCKET#;dbname=#DBNAME#;charset=#CHARSET#'; | ||||
|                 } else { | ||||
|                     $format = 'mysql:host=#HOST#;port=#PORT#;dbname=#DBNAME#;charset=#CHARSET#'; | ||||
|                 } | ||||
|  | ||||
|                 $replace = ['#HOST#', '#PORT#', '#SOCKET#', '#DBNAME#', '#CHARSET#']; | ||||
|                 $with    = [ | ||||
|                     $this->options['host'], | ||||
|                     $this->options['port'], | ||||
|                     $this->options['socket'], | ||||
|                     $this->options['database'], | ||||
|                     $this->options['charset'], | ||||
|                 ]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'oci': | ||||
|                 $this->options['port']    = $this->options['port'] ?? 1521; | ||||
|                 $this->options['charset'] = $this->options['charset'] ?? 'AL32UTF8'; | ||||
|  | ||||
|                 if (!empty($this->options['dsn'])) { | ||||
|                     $format = 'oci:dbname=#DSN#'; | ||||
|  | ||||
|                     $replace = ['#DSN#']; | ||||
|                     $with    = [$this->options['dsn']]; | ||||
|                 } else { | ||||
|                     $format = 'oci:dbname=//#HOST#:#PORT#/#DBNAME#'; | ||||
|  | ||||
|                     $replace = ['#HOST#', '#PORT#', '#DBNAME#']; | ||||
|                     $with    = [$this->options['host'], $this->options['port'], $this->options['database']]; | ||||
|                 } | ||||
|  | ||||
|                 $format .= ';charset=' . $this->options['charset']; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'odbc': | ||||
|                 $format = 'odbc:DSN=#DSN#;UID:#USER#;PWD=#PASSWORD#'; | ||||
|  | ||||
|                 $replace = ['#DSN#', '#USER#', '#PASSWORD#']; | ||||
|                 $with    = [$this->options['dsn'], $this->options['user'], $this->options['password']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'pgsql': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 5432; | ||||
|  | ||||
|                 if ($this->options['socket'] !== null) { | ||||
|                     $format = 'pgsql:host=#SOCKET#;dbname=#DBNAME#'; | ||||
|                 } else { | ||||
|                     $format = 'pgsql:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; | ||||
|                 } | ||||
|  | ||||
|                 $replace = ['#HOST#', '#PORT#', '#SOCKET#', '#DBNAME#']; | ||||
|                 $with    = [$this->options['host'], $this->options['port'], $this->options['socket'], $this->options['database']]; | ||||
|  | ||||
|                 // For data in transit TLS encryption. | ||||
|                 if ($this->options['ssl'] !== [] && $this->options['ssl']['enable'] === true) { | ||||
|                     if (isset($this->options['ssl']['verify_server_cert']) && $this->options['ssl']['verify_server_cert'] === true) { | ||||
|                         $format .= ';sslmode=verify-full'; | ||||
|                     } else { | ||||
|                         $format .= ';sslmode=require'; | ||||
|                     } | ||||
|  | ||||
|                     $sslKeysMapping = [ | ||||
|                         'cipher' => null, | ||||
|                         'ca'     => 'sslrootcert', | ||||
|                         'capath' => null, | ||||
|                         'key'    => 'sslkey', | ||||
|                         'cert'   => 'sslcert', | ||||
|                     ]; | ||||
|  | ||||
|                     // If customised, add cipher suite, ca file path, ca path, private key file path and certificate file path to PDO driver options. | ||||
|                     foreach ($sslKeysMapping as $key => $value) { | ||||
|                         if ($value !== null && $this->options['ssl'][$key] !== null) { | ||||
|                             $format .= ';' . $value . '=' . $this->options['ssl'][$key]; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'sqlite': | ||||
|                 if (isset($this->options['version']) && $this->options['version'] == 2) { | ||||
|                     $format = 'sqlite2:#DBNAME#'; | ||||
|                 } else { | ||||
|                     $format = 'sqlite:#DBNAME#'; | ||||
|                 } | ||||
|  | ||||
|                 $replace = ['#DBNAME#']; | ||||
|                 $with    = [$this->options['database']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'sybase': | ||||
|                 $this->options['port'] = $this->options['port'] ?? 1433; | ||||
|  | ||||
|                 $format = 'mssql:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; | ||||
|  | ||||
|                 $replace = ['#HOST#', '#PORT#', '#DBNAME#']; | ||||
|                 $with    = [$this->options['host'], $this->options['port'], $this->options['database']]; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 throw new UnsupportedAdapterException('The ' . $this->options['driver'] . ' driver is not supported.'); | ||||
|         } | ||||
|  | ||||
|         // Create the connection string: | ||||
|         $connectionString = str_replace($replace, $with, $format); | ||||
|  | ||||
|         try { | ||||
|             $this->connection = new \PDO( | ||||
|                 $connectionString, | ||||
|                 $this->options['user'], | ||||
|                 $this->options['password'], | ||||
|                 $this->options['driverOptions'] | ||||
|             ); | ||||
|         } catch (\PDOException $e) { | ||||
|             throw new ConnectionFailureException('Could not connect to PDO: ' . $e->getMessage(), $e->getCode(), $e); | ||||
|         } | ||||
|  | ||||
|         $this->setOption(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); | ||||
|  | ||||
|         $this->dispatchEvent(new ConnectionEvent(DatabaseEvents::POST_CONNECT, $this)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to escape a string for usage in an SQL statement. | ||||
|      * | ||||
|      * Oracle escaping reference: | ||||
|      * http://www.orafaq.com/wiki/SQL_FAQ#How_does_one_escape_special_characters_when_writing_SQL_queries.3F | ||||
|      * | ||||
|      * SQLite escaping notes: | ||||
|      * http://www.sqlite.org/faq.html#q14 | ||||
|      * | ||||
|      * Method body is as implemented by the Zend Framework | ||||
|      * | ||||
|      * Note: Using query objects with bound variables is preferable to the below. | ||||
|      * | ||||
|      * @param   string   $text   The string to be escaped. | ||||
|      * @param   boolean  $extra  Unused optional parameter to provide extra escaping. | ||||
|      * | ||||
|      * @return  string  The escaped string. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function escape($text, $extra = false) | ||||
|     { | ||||
|         if (\is_int($text)) { | ||||
|             return $text; | ||||
|         } | ||||
|  | ||||
|         if (\is_float($text)) { | ||||
|             // Force the dot as a decimal point. | ||||
|             return str_replace(',', '.', (string) $text); | ||||
|         } | ||||
|  | ||||
|         $text = str_replace("'", "''", (string) $text); | ||||
|  | ||||
|         return addcslashes($text, "\000\n\r\\\032"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the SQL statement. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function execute() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Take a local copy so that we don't modify the original query and cause issues later | ||||
|         $sql = $this->replacePrefix((string) $this->sql); | ||||
|  | ||||
|         // Increment the query counter. | ||||
|         $this->count++; | ||||
|  | ||||
|         // Get list of bounded parameters | ||||
|         $bounded =& $this->sql->getBounded(); | ||||
|  | ||||
|         // If there is a monitor registered, let it know we are starting this query | ||||
|         if ($this->monitor) { | ||||
|             $this->monitor->startQuery($sql, $bounded); | ||||
|         } | ||||
|  | ||||
|         // Execute the query. | ||||
|         $this->executed = false; | ||||
|  | ||||
|         // Bind the variables | ||||
|         foreach ($bounded as $key => $obj) { | ||||
|             $this->statement->bindParam($key, $obj->value, $obj->dataType, $obj->length, $obj->driverOptions); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             $this->executed = $this->statement->execute(); | ||||
|  | ||||
|             // If there is a monitor registered, let it know we have finished this query | ||||
|             if ($this->monitor) { | ||||
|                 $this->monitor->stopQuery(); | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } catch (\PDOException $exception) { | ||||
|             // If there is a monitor registered, let it know we have finished this query | ||||
|             if ($this->monitor) { | ||||
|                 $this->monitor->stopQuery(); | ||||
|             } | ||||
|  | ||||
|             // Get the error number and message before we execute any more queries. | ||||
|             $errorNum = (int) $this->statement->errorCode(); | ||||
|             $errorMsg = (string) implode(', ', $this->statement->errorInfo()); | ||||
|  | ||||
|             // Check if the server was disconnected. | ||||
|             try { | ||||
|                 if (!$this->connected()) { | ||||
|                     try { | ||||
|                         // Attempt to reconnect. | ||||
|                         $this->connection = null; | ||||
|                         $this->connect(); | ||||
|                     } catch (ConnectionFailureException $e) { | ||||
|                         // If connect fails, ignore that exception and throw the normal exception. | ||||
|                         throw new ExecutionFailureException($sql, $errorMsg, $errorNum); | ||||
|                     } | ||||
|  | ||||
|                     // Since we were able to reconnect, run the query again. | ||||
|                     return $this->execute(); | ||||
|                 } | ||||
|             } catch (\LogicException $e) { | ||||
|                 throw new ExecutionFailureException($sql, $errorMsg, $errorNum, $e); | ||||
|             } | ||||
|  | ||||
|             // Throw the normal query exception. | ||||
|             throw new ExecutionFailureException($sql, $errorMsg, $errorNum); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retrieve a PDO database connection attribute | ||||
|      * https://www.php.net/manual/en/pdo.getattribute.php | ||||
|      * | ||||
|      * Usage: $db->getOption(PDO::ATTR_CASE); | ||||
|      * | ||||
|      * @param   mixed  $key  One of the PDO::ATTR_* Constants | ||||
|      * | ||||
|      * @return  mixed | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getOption($key) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->connection->getAttribute($key); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the version of the database connector. | ||||
|      * | ||||
|      * @return  string  The database connector version. | ||||
|      * | ||||
|      * @since   1.5.0 | ||||
|      */ | ||||
|     public function getVersion() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->getOption(\PDO::ATTR_SERVER_VERSION); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a query to run and verify the database is operational. | ||||
|      * | ||||
|      * @return  string  The query to check the health of the DB. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getConnectedQuery() | ||||
|     { | ||||
|         return 'SELECT 1'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets an attribute on the PDO database handle. | ||||
|      * https://www.php.net/manual/en/pdo.setattribute.php | ||||
|      * | ||||
|      * Usage: $db->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER); | ||||
|      * | ||||
|      * @param   integer  $key    One of the PDO::ATTR_* Constants | ||||
|      * @param   mixed    $value  One of the associated PDO Constants | ||||
|      *                           related to the particular attribute | ||||
|      *                           key. | ||||
|      * | ||||
|      * @return boolean | ||||
|      * | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public function setOption($key, $value) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->connection->setAttribute($key, $value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Test to see if the PDO extension is available. | ||||
|      * Override as needed to check for specific PDO Drivers. | ||||
|      * | ||||
|      * @return  boolean  True on success, false otherwise. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function isSupported() | ||||
|     { | ||||
|         return \defined('\\PDO::ATTR_DRIVER_NAME'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Determines if the connection to the server is active. | ||||
|      * | ||||
|      * @return  boolean  True if connected to the database engine. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \LogicException | ||||
|      */ | ||||
|     public function connected() | ||||
|     { | ||||
|         // Flag to prevent recursion into this function. | ||||
|         static $checkingConnected = false; | ||||
|  | ||||
|         if ($checkingConnected) { | ||||
|             // Reset this flag and throw an exception. | ||||
|             $checkingConnected = false; | ||||
|  | ||||
|             throw new \LogicException('Recursion trying to check if connected.'); | ||||
|         } | ||||
|  | ||||
|         // Backup the query state. | ||||
|         $sql       = $this->sql; | ||||
|         $limit     = $this->limit; | ||||
|         $offset    = $this->offset; | ||||
|         $statement = $this->statement; | ||||
|  | ||||
|         try { | ||||
|             // Set the checking connection flag. | ||||
|             $checkingConnected = true; | ||||
|  | ||||
|             // Run a simple query to check the connection. | ||||
|             $this->setQuery($this->getConnectedQuery()); | ||||
|             $status = (bool) $this->loadResult(); | ||||
|         } catch (\Exception $e) { | ||||
|             // If we catch an exception here, we must not be connected. | ||||
|             $status = false; | ||||
|         } | ||||
|  | ||||
|         // Restore the query state. | ||||
|         $this->sql         = $sql; | ||||
|         $this->limit       = $limit; | ||||
|         $this->offset      = $offset; | ||||
|         $this->statement   = $statement; | ||||
|         $checkingConnected = false; | ||||
|  | ||||
|         return $status; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the auto-incremented value from the last INSERT statement. | ||||
|      * | ||||
|      * @return  string  The value of the auto-increment field from the last inserted row. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function insertid() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Error suppress this to prevent PDO warning us that the driver doesn't support this operation. | ||||
|         return @$this->connection->lastInsertId(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Select a database for use. | ||||
|      * | ||||
|      * @param   string  $database  The name of the database to select for use. | ||||
|      * | ||||
|      * @return  boolean  True if the database was successfully selected. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function select($database) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the connection to use UTF-8 character encoding. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function setUtf() | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to commit a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, commit to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionCommit($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth === 1) { | ||||
|             $this->connection->commit(); | ||||
|         } | ||||
|  | ||||
|         $this->transactionDepth--; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to roll back a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, rollback to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionRollback($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth === 1) { | ||||
|             $this->connection->rollBack(); | ||||
|         } | ||||
|  | ||||
|         $this->transactionDepth--; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to initialize a transaction. | ||||
|      * | ||||
|      * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionStart($asSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$asSavepoint || !$this->transactionDepth) { | ||||
|             $this->connection->beginTransaction(); | ||||
|         } | ||||
|  | ||||
|         $this->transactionDepth++; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prepares a SQL statement for execution | ||||
|      * | ||||
|      * @param   string  $query  The SQL query to be prepared. | ||||
|      * | ||||
|      * @return  StatementInterface | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  PrepareStatementFailureException | ||||
|      */ | ||||
|     protected function prepareStatement(string $query): StatementInterface | ||||
|     { | ||||
|         try { | ||||
|             return new PdoStatement($this->connection->prepare($query, $this->options['driverOptions'])); | ||||
|         } catch (\PDOException $exception) { | ||||
|             throw new PrepareStatementFailureException($exception->getMessage(), $exception->getCode(), $exception); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * PDO does not support serialize | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __sleep() | ||||
|     { | ||||
|         $serializedProperties = []; | ||||
|  | ||||
|         $reflect = new \ReflectionClass($this); | ||||
|  | ||||
|         // Get properties of the current class | ||||
|         $properties = $reflect->getProperties(); | ||||
|  | ||||
|         foreach ($properties as $property) { | ||||
|             // Do not serialize properties that are PDO | ||||
|             if ($property->isStatic() === false && !($this->{$property->name} instanceof \PDO)) { | ||||
|                 $serializedProperties[] = $property->name; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $serializedProperties; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Wake up after serialization | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __wakeup() | ||||
|     { | ||||
|         // Get connection back | ||||
|         $this->__construct($this->options); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										53
									
								
								libraries/vendor/joomla/database/src/Pdo/PdoQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								libraries/vendor/joomla/database/src/Pdo/PdoQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Pdo; | ||||
|  | ||||
| use Joomla\Database\DatabaseQuery; | ||||
|  | ||||
| /** | ||||
|  * PDO Query Building Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| abstract class PdoQuery extends DatabaseQuery | ||||
| { | ||||
|     /** | ||||
|      * The list of zero or null representation of a datetime. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $nullDatetimeList = ['0000-00-00 00:00:00']; | ||||
|  | ||||
|     /** | ||||
|      * Casts a value to a char. | ||||
|      * | ||||
|      * Ensure that the value is properly quoted before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->castAsChar('a')); | ||||
|      * $query->select($query->castAsChar('a', 40)); | ||||
|      * | ||||
|      * @param   string  $value  The value to cast as a char. | ||||
|      * @param   string  $len    The length of the char. | ||||
|      * | ||||
|      * @return  string  Returns the cast value. | ||||
|      * | ||||
|      * @since   1.8.0 | ||||
|      */ | ||||
|     public function castAsChar($value, $len = null) | ||||
|     { | ||||
|         if (!$len) { | ||||
|             return $value; | ||||
|         } else { | ||||
|             return 'CAST(' . $value . ' AS CHAR(' . $len . '))'; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										243
									
								
								libraries/vendor/joomla/database/src/Pdo/PdoStatement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								libraries/vendor/joomla/database/src/Pdo/PdoStatement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,243 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Pdo; | ||||
|  | ||||
| use Joomla\Database\FetchMode; | ||||
| use Joomla\Database\FetchOrientation; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Database\StatementInterface; | ||||
|  | ||||
| /** | ||||
|  * PDO Database Statement. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class PdoStatement implements StatementInterface | ||||
| { | ||||
|     /** | ||||
|      * Mapping array for fetch modes. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private const FETCH_MODE_MAP = [ | ||||
|         FetchMode::ASSOCIATIVE     => \PDO::FETCH_ASSOC, | ||||
|         FetchMode::NUMERIC         => \PDO::FETCH_NUM, | ||||
|         FetchMode::MIXED           => \PDO::FETCH_BOTH, | ||||
|         FetchMode::STANDARD_OBJECT => \PDO::FETCH_OBJ, | ||||
|         FetchMode::COLUMN          => \PDO::FETCH_COLUMN, | ||||
|         FetchMode::CUSTOM_OBJECT   => \PDO::FETCH_CLASS, | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * Mapping array for parameter types. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private const PARAMETER_TYPE_MAP = [ | ||||
|         ParameterType::BOOLEAN      => \PDO::PARAM_BOOL, | ||||
|         ParameterType::INTEGER      => \PDO::PARAM_INT, | ||||
|         ParameterType::LARGE_OBJECT => \PDO::PARAM_LOB, | ||||
|         ParameterType::NULL         => \PDO::PARAM_NULL, | ||||
|         ParameterType::STRING       => \PDO::PARAM_STR, | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * The decorated PDOStatement object. | ||||
|      * | ||||
|      * @var    \PDOStatement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $pdoStatement; | ||||
|  | ||||
|     /** | ||||
|      * Statement constructor | ||||
|      * | ||||
|      * @param   \PDOStatement  $pdoStatement  The decorated PDOStatement object. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __construct(\PDOStatement $pdoStatement) | ||||
|     { | ||||
|         $this->pdoStatement = $pdoStatement; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Binds a parameter to the specified variable name. | ||||
|      * | ||||
|      * @param   string|integer  $parameter      Parameter identifier. For a prepared statement using named placeholders, this will be a parameter | ||||
|      *                                          name of the form `:name`. For a prepared statement using question mark placeholders, this will be | ||||
|      *                                          the 1-indexed position of the parameter. | ||||
|      * @param   mixed           $variable       Name of the PHP variable to bind to the SQL statement parameter. | ||||
|      * @param   string          $dataType       Constant corresponding to a SQL datatype, this should be the processed type from the QueryInterface. | ||||
|      * @param   integer         $length         The length of the variable. Usually required for OUTPUT parameters. | ||||
|      * @param   array           $driverOptions  Optional driver options to be used. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function bindParam($parameter, &$variable, string $dataType = ParameterType::STRING, ?int $length = null, ?array $driverOptions = null) | ||||
|     { | ||||
|         $type            = $this->convertParameterType($dataType); | ||||
|         $extraParameters = array_slice(func_get_args(), 3); | ||||
|  | ||||
|         if (count($extraParameters) !== 0) { | ||||
|             $extraParameters[0] = $extraParameters[0] ?? 0; | ||||
|         } | ||||
|  | ||||
|         $this->pdoStatement->bindParam($parameter, $variable, $type, ...$extraParameters); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Closes the cursor, enabling the statement to be executed again. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function closeCursor(): void | ||||
|     { | ||||
|         $this->pdoStatement->closeCursor(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches the SQLSTATE associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorCode() | ||||
|     { | ||||
|         return $this->pdoStatement->errorCode(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches extended error information associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorInfo() | ||||
|     { | ||||
|         return $this->pdoStatement->errorInfo(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Executes a prepared statement | ||||
|      * | ||||
|      * @param   array|null  $parameters  An array of values with as many elements as there are bound parameters in the SQL statement being executed. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function execute(?array $parameters = null) | ||||
|     { | ||||
|         return $this->pdoStatement->execute($parameters); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches the next row from a result set | ||||
|      * | ||||
|      * @param   integer|null  $fetchStyle         Controls how the next row will be returned to the caller. This value must be one of the | ||||
|      *                                            FetchMode constants, defaulting to value of FetchMode::MIXED. | ||||
|      * @param   integer       $cursorOrientation  For a StatementInterface object representing a scrollable cursor, this value determines which row | ||||
|      *                                            will be returned to the caller. This value must be one of the FetchOrientation constants, | ||||
|      *                                            defaulting to FetchOrientation::NEXT. | ||||
|      * @param   integer       $cursorOffset       For a StatementInterface object representing a scrollable cursor for which the cursorOrientation | ||||
|      *                                            parameter is set to FetchOrientation::ABS, this value specifies the absolute number of the row in | ||||
|      *                                            the result set that shall be fetched. For a StatementInterface object representing a scrollable | ||||
|      *                                            cursor for which the cursorOrientation parameter is set to FetchOrientation::REL, this value | ||||
|      *                                            specifies the row to fetch relative to the cursor position before `fetch()` was called. | ||||
|      * | ||||
|      * @return  mixed  The return value of this function on success depends on the fetch type. In all cases, boolean false is returned on failure. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function fetch(?int $fetchStyle = null, int $cursorOrientation = FetchOrientation::NEXT, int $cursorOffset = 0) | ||||
|     { | ||||
|         if ($fetchStyle === null) { | ||||
|             return $this->pdoStatement->fetch(); | ||||
|         } | ||||
|  | ||||
|         return $this->pdoStatement->fetch($this->convertFetchMode($fetchStyle), $cursorOrientation, $cursorOffset); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the number of rows affected by the last SQL statement. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rowCount(): int | ||||
|     { | ||||
|         return $this->pdoStatement->rowCount(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the fetch mode to use while iterating this statement. | ||||
|      * | ||||
|      * @param   integer  $fetchMode  The fetch mode, must be one of the FetchMode constants. | ||||
|      * @param   mixed    ...$args    Optional mode-specific arguments. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function setFetchMode(int $fetchMode, ...$args): void | ||||
|     { | ||||
|         $this->pdoStatement->setFetchMode($this->convertFetchMode($fetchMode), ...$args); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Converts the database API's fetch mode to a PDO fetch mode | ||||
|      * | ||||
|      * @param   integer  $mode  Fetch mode to convert | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \InvalidArgumentException if the fetch mode is unsupported | ||||
|      */ | ||||
|     private function convertFetchMode(int $mode): int | ||||
|     { | ||||
|         if (!isset(self::FETCH_MODE_MAP[$mode])) { | ||||
|             throw new \InvalidArgumentException(sprintf('Unsupported fetch mode `%s`', $mode)); | ||||
|         } | ||||
|  | ||||
|         return self::FETCH_MODE_MAP[$mode]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Converts the database API's parameter type to a PDO parameter type | ||||
|      * | ||||
|      * @param   string  $type  Parameter type to convert | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \InvalidArgumentException if the parameter type is unsupported | ||||
|      */ | ||||
|     private function convertParameterType(string $type): int | ||||
|     { | ||||
|         if (!isset(self::PARAMETER_TYPE_MAP[$type])) { | ||||
|             throw new \InvalidArgumentException(sprintf('Unsupported parameter type `%s`', $type)); | ||||
|         } | ||||
|  | ||||
|         return self::PARAMETER_TYPE_MAP[$type]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										1078
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1078
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										184
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlExporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,184 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Pgsql; | ||||
|  | ||||
| use Joomla\Database\DatabaseExporter; | ||||
|  | ||||
| /** | ||||
|  * PDO PostgreSQL Database Exporter. | ||||
|  * | ||||
|  * @since  1.5.0 | ||||
|  */ | ||||
| class PgsqlExporter extends DatabaseExporter | ||||
| { | ||||
|     /** | ||||
|      * Builds the XML data for the tables to export. | ||||
|      * | ||||
|      * @return  string  An XML string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXml() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         $buffer[] = '<?xml version="1.0"?>'; | ||||
|         $buffer[] = '<postgresqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'; | ||||
|         $buffer[] = ' <database name="">'; | ||||
|  | ||||
|         if ($this->options->withStructure) { | ||||
|             $buffer = array_merge($buffer, $this->buildXmlStructure()); | ||||
|         } | ||||
|  | ||||
|         if ($this->options->withData) { | ||||
|             $buffer = array_merge($buffer, $this->buildXmlData()); | ||||
|         } | ||||
|  | ||||
|         $buffer[] = ' </database>'; | ||||
|         $buffer[] = '</postgresqldump>'; | ||||
|  | ||||
|         return implode("\n", $buffer); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML structure to export. | ||||
|      * | ||||
|      * @return  array  An array of XML lines (strings). | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXmlStructure() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         foreach ($this->from as $table) { | ||||
|             // Replace the magic prefix if found. | ||||
|             $table = $this->getGenericTableName($table); | ||||
|  | ||||
|             // Get the details columns information. | ||||
|             $fields    = $this->db->getTableColumns($table, false); | ||||
|             $keys      = $this->db->getTableKeys($table); | ||||
|             $sequences = $this->db->getTableSequences($table); | ||||
|  | ||||
|             $buffer[] = '  <table_structure name="' . $table . '">'; | ||||
|  | ||||
|             foreach ($sequences as $sequence) { | ||||
|                 $buffer[] = '   <sequence Name="' . $this->getGenericTableName($sequence->sequence) . '" Schema="' . $sequence->schema . '"' . | ||||
|                     ' Table="' . $table . '" Column="' . $sequence->column . '" Type="' . $sequence->data_type . '"' . | ||||
|                     ' Start_Value="' . $sequence->start_value . '" Min_Value="' . $sequence->minimum_value . '"' . | ||||
|                     ' Max_Value="' . $sequence->maximum_value . '" Last_Value="' . $this->db->getSequenceLastValue($sequence->sequence) . '"' . | ||||
|                     ' Increment="' . $sequence->increment . '" Cycle_option="' . $sequence->cycle_option . '"' . | ||||
|                     ' Is_called="' . $this->db->getSequenceIsCalled($sequence->sequence) . '"' . | ||||
|                     ' />'; | ||||
|             } | ||||
|  | ||||
|             foreach ($fields as $field) { | ||||
|                 $buffer[] = '   <field Field="' . $field->column_name . '" Type="' . $field->type . '" Null="' . $field->null . '"' . | ||||
|                     ' Default="' . $field->Default . '" Comments="' . $field->comments . '" />'; | ||||
|             } | ||||
|  | ||||
|             foreach ($keys as $key) { | ||||
|                 $buffer[] = '   <key Index="' . $this->getGenericTableName($key->idxName) . '" is_primary="' . $key->isPrimary . '"' . | ||||
|                     ' is_unique="' . $key->isUnique . '" Key_name="' . $this->db->getNamesKey($table, $key->indKey) . '"' . | ||||
|                     ' Query=\'' . $key->Query . '\' />'; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  </table_structure>'; | ||||
|         } | ||||
|  | ||||
|         return $buffer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Builds the XML data to export. | ||||
|      * | ||||
|      * @return  array  An array of XML lines (strings). | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \Exception if an error occurs. | ||||
|      */ | ||||
|     protected function buildXmlData() | ||||
|     { | ||||
|         $buffer = []; | ||||
|  | ||||
|         foreach ($this->from as $table) { | ||||
|             // Replace the magic prefix if found. | ||||
|             $table = $this->getGenericTableName($table); | ||||
|  | ||||
|             // Get the details columns information. | ||||
|             $fields  = $this->db->getTableColumns($table, false); | ||||
|             $colblob = []; | ||||
|  | ||||
|             foreach ($fields as $field) { | ||||
|                 // Catch blob for xml conversion | ||||
|                 // PostgreSQL binary large object type | ||||
|                 if ($field->Type == 'bytea') { | ||||
|                     $colblob[] = $field->Field; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $query = $this->db->getQuery(true); | ||||
|             $query->select($query->quoteName(array_keys($fields))) | ||||
|                 ->from($query->quoteName($table)); | ||||
|             $this->db->setQuery($query); | ||||
|  | ||||
|             $rows = $this->db->loadObjectList(); | ||||
|  | ||||
|             if (!count($rows)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  <table_data name="' . $table . '">'; | ||||
|  | ||||
|             foreach ($rows as $row) { | ||||
|                 $buffer[] = '   <row>'; | ||||
|  | ||||
|                 foreach ($row as $key => $value) { | ||||
|                     if (!in_array($key, $colblob)) { | ||||
|                         $buffer[] = '    <field name="' . $key . '">' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '</field>'; | ||||
|                     } else { | ||||
|                         $buffer[] = '    <field name="' . $key . '">' . stream_get_contents($value) . '</field>'; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 $buffer[] = '   </row>'; | ||||
|             } | ||||
|  | ||||
|             $buffer[] = '  </table_data>'; | ||||
|         } | ||||
|  | ||||
|         return $buffer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.5.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         // Check if the db connector has been set. | ||||
|         if (!($this->db instanceof PgsqlDriver)) { | ||||
|             throw new \RuntimeException('Database connection wrong type.'); | ||||
|         } | ||||
|  | ||||
|         // Check if the tables have been specified. | ||||
|         if (empty($this->from)) { | ||||
|             throw new \RuntimeException('ERROR: No Tables Specified'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										555
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										555
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlImporter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,555 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Pgsql; | ||||
|  | ||||
| use Joomla\Database\DatabaseImporter; | ||||
|  | ||||
| /** | ||||
|  * PDO PostgreSQL Database Importer. | ||||
|  * | ||||
|  * @since  1.5.0 | ||||
|  */ | ||||
| class PgsqlImporter extends DatabaseImporter | ||||
| { | ||||
|     /** | ||||
|      * Checks if all data and options are in order prior to exporting. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.5.0 | ||||
|      * @throws  \RuntimeException if an error is encountered. | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         // Check if the db connector has been set. | ||||
|         if (!($this->db instanceof PgsqlDriver)) { | ||||
|             throw new \RuntimeException('Database connection wrong type.'); | ||||
|         } | ||||
|  | ||||
|         // Check if the tables have been specified. | ||||
|         if (empty($this->from)) { | ||||
|             throw new \RuntimeException('ERROR: No Tables Specified'); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add an index. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML index definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAddIndexSql(\SimpleXMLElement $field) | ||||
|     { | ||||
|         return (string) $field['Query']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get alters for table if there is a difference. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $structure  The XML structure of the table. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAlterTableSql(\SimpleXMLElement $structure) | ||||
|     { | ||||
|         $table       = $this->getRealTableName($structure['name']); | ||||
|         $oldFields   = $this->db->getTableColumns($table); | ||||
|         $oldKeys     = $this->db->getTableKeys($table); | ||||
|         $oldSequence = $this->db->getTableSequences($table); | ||||
|         $alters      = []; | ||||
|  | ||||
|         // Get the fields and keys from the XML that we are aiming for. | ||||
|         $newFields   = $structure->xpath('field'); | ||||
|         $newKeys     = $structure->xpath('key'); | ||||
|         $newSequence = $structure->xpath('sequence'); | ||||
|  | ||||
|         /* | ||||
|          * Sequence section | ||||
|          */ | ||||
|  | ||||
|         $oldSeq          = $this->getSeqLookup($oldSequence); | ||||
|         $newSequenceLook = $this->getSeqLookup($newSequence); | ||||
|  | ||||
|         foreach ($newSequenceLook as $kSeqName => $vSeq) { | ||||
|             if (isset($oldSeq[$kSeqName])) { | ||||
|                 // The field exists, check it's the same. | ||||
|                 $column = $oldSeq[$kSeqName][0]; | ||||
|  | ||||
|                 // Test whether there is a change. | ||||
|                 $change = ((string) $vSeq[0]['Type'] !== $column->Type) | ||||
|                     || ((string) $vSeq[0]['Start_Value'] !== $column->Start_Value) | ||||
|                     || ((string) $vSeq[0]['Min_Value'] !== $column->Min_Value) | ||||
|                     || ((string) $vSeq[0]['Max_Value'] !== $column->Max_Value) | ||||
|                     || ((string) $vSeq[0]['Increment'] !== $column->Increment) | ||||
|                     || ((string) $vSeq[0]['Cycle_option'] !== $column->Cycle_option) | ||||
|                     || ((string) $vSeq[0]['Table'] !== $column->Table) | ||||
|                     || ((string) $vSeq[0]['Column'] !== $column->Column) | ||||
|                     || ((string) $vSeq[0]['Schema'] !== $column->Schema) | ||||
|                     || ((string) $vSeq[0]['Name'] !== $column->Name); | ||||
|  | ||||
|                 if ($change) { | ||||
|                     $alters[] = $this->getChangeSequenceSql($kSeqName, $vSeq); | ||||
|                     $alters[] = $this->getSetvalSequenceSql($kSeqName, $vSeq); | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldSeq[$kSeqName]); | ||||
|             } else { | ||||
|                 // The sequence is new | ||||
|                 $alters[] = $this->getAddSequenceSql($newSequenceLook[$kSeqName][0]); | ||||
|                 $alters[] = $this->getSetvalSequenceSql($newSequenceLook[$kSeqName][0]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any sequences left are orphans | ||||
|         foreach ($oldSeq as $name => $column) { | ||||
|             // Delete the sequence. | ||||
|             $alters[] = $this->getDropSequenceSql($name); | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * Field section | ||||
|          */ | ||||
|  | ||||
|         // Loop through each field in the new structure. | ||||
|         foreach ($newFields as $field) { | ||||
|             $fName = (string) $field['Field']; | ||||
|  | ||||
|             if (isset($oldFields[$fName])) { | ||||
|                 // The field exists, check it's the same. | ||||
|                 $column = $oldFields[$fName]; | ||||
|  | ||||
|                 // Test whether there is a change. | ||||
|                 $change = ((string) $field['Type'] !== $column->Type) || ((string) $field['Null'] !== $column->Null) | ||||
|                     || ((string) $field['Default'] !== $column->Default); | ||||
|  | ||||
|                 if ($change) { | ||||
|                     $alters[] = $this->getChangeColumnSql($table, $field); | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldFields[$fName]); | ||||
|             } else { | ||||
|                 // The field is new. | ||||
|                 $alters[] = $this->getAddColumnSql($table, $field); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any columns left are orphans | ||||
|         foreach ($oldFields as $name => $column) { | ||||
|             // Delete the column. | ||||
|             $alters[] = $this->getDropColumnSql($table, $name); | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * Index section | ||||
|          */ | ||||
|  | ||||
|         // Get the lookups for the old and new keys | ||||
|         $oldLookup = $this->getKeyLookup($oldKeys); | ||||
|         $newLookup = $this->getKeyLookup($newKeys); | ||||
|  | ||||
|         // Loop through each key in the new structure. | ||||
|         foreach ($newLookup as $name => $keys) { | ||||
|             // Check if there are keys on this field in the existing table. | ||||
|             if (isset($oldLookup[$name])) { | ||||
|                 $same     = true; | ||||
|                 $newCount = \count($newLookup[$name]); | ||||
|                 $oldCount = \count($oldLookup[$name]); | ||||
|  | ||||
|                 // There is a key on this field in the old and new tables. Are they the same? | ||||
|                 if ($newCount === $oldCount) { | ||||
|                     for ($i = 0; $i < $newCount; $i++) { | ||||
|                         // Check only query field -> different query means different index | ||||
|                         $same = ((string) $newLookup[$name][$i]['Query'] === $oldLookup[$name][$i]->Query); | ||||
|  | ||||
|                         if (!$same) { | ||||
|                             // Break out of the loop. No need to check further. | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     // Count is different, just drop and add. | ||||
|                     $same = false; | ||||
|                 } | ||||
|  | ||||
|                 if (!$same) { | ||||
|                     $alters[] = $this->getDropIndexSql($name); | ||||
|                     $alters[] = (string) $newLookup[$name][0]['Query']; | ||||
|                 } | ||||
|  | ||||
|                 // Unset this field so that what we have left are fields that need to be removed. | ||||
|                 unset($oldLookup[$name]); | ||||
|             } else { | ||||
|                 // This is a new key. | ||||
|                 $alters[] = (string) $newLookup[$name][0]['Query']; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Any keys left are orphans. | ||||
|         foreach ($oldLookup as $name => $keys) { | ||||
|             if ($oldLookup[$name][0]->is_primary === 'TRUE') { | ||||
|                 $alters[] = $this->getDropPrimaryKeySql($table, $oldLookup[$name][0]->Index); | ||||
|             } else { | ||||
|                 $alters[] = $this->getDropIndexSql($name); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $alters; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a sequence. | ||||
|      * | ||||
|      * @param   string  $name  The name of the sequence to drop. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropSequenceSql($name) | ||||
|     { | ||||
|         return 'DROP SEQUENCE ' . $this->db->quoteName($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to add a sequence. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the sequence. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAddSequenceSql(\SimpleXMLElement $field) | ||||
|     { | ||||
|         $sql = 'CREATE SEQUENCE IF NOT EXISTS ' . (string) $field['Name'] | ||||
|             . ' INCREMENT BY ' . (string) $field['Increment'] . ' MINVALUE ' . $field['Min_Value'] | ||||
|             . ' MAXVALUE ' . (string) $field['Max_Value'] . ' START ' . (string) $field['Start_Value'] | ||||
|             . (((string) $field['Cycle_option'] === 'NO') ? ' NO' : '') . ' CYCLE' | ||||
|             . ' OWNED BY ' . $this->db->quoteName((string) $field['Schema'] . '.' . (string) $field['Table'] . '.' . (string) $field['Column']); | ||||
|  | ||||
|         return $sql; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to alter a sequence. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the sequence. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getChangeSequenceSql(\SimpleXMLElement $field) | ||||
|     { | ||||
|         $sql = 'ALTER SEQUENCE ' . (string) $field['Name'] | ||||
|             . ' INCREMENT BY ' . (string) $field['Increment'] . ' MINVALUE ' . (string) $field['Min_Value'] | ||||
|             . ' MAXVALUE ' . (string) $field['Max_Value'] . ' START ' . (string) $field['Start_Value'] | ||||
|             . ' OWNED BY ' . $this->db->quoteName((string) $field['Schema'] . '.' . (string) $field['Table'] . '.' . (string) $field['Column']); | ||||
|  | ||||
|         return $sql; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to setval a sequence. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the sequence. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function getSetvalSequenceSql($field) | ||||
|     { | ||||
|         $is_called = $field['Is_called'] == 't' || $field['Is_called'] == '1' ? 'TRUE' : 'FALSE'; | ||||
|  | ||||
|         return 'SELECT setval(\'' . (string) $field['Name'] . '\', ' . (string) $field['Last_Value'] . ', ' . $is_called . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the syntax to alter a column. | ||||
|      * | ||||
|      * @param   string             $table  The name of the database table to alter. | ||||
|      * @param   \SimpleXMLElement  $field  The XML definition for the field. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getChangeColumnSql($table, \SimpleXMLElement $field) | ||||
|     { | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ALTER COLUMN ' . $this->db->quoteName((string) $field['Field']) . ' ' | ||||
|             . $this->getAlterColumnSql($table, $field); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a single column that would be included in a table create statement. | ||||
|      * | ||||
|      * @param   string             $table  The name of the database table to alter. | ||||
|      * @param   \SimpleXMLElement  $field  The XML field definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getAlterColumnSql($table, \SimpleXMLElement $field) | ||||
|     { | ||||
|         // TODO Incorporate into parent class and use $this. | ||||
|         $blobs = ['text', 'smalltext', 'mediumtext', 'largetext']; | ||||
|  | ||||
|         $fName = (string) $field['Field']; | ||||
|         $fType = (string) $field['Type']; | ||||
|         $fNull = (string) $field['Null']; | ||||
|  | ||||
|         $fDefault = (isset($field['Default']) && $field['Default'] != 'NULL') ? | ||||
|             preg_match('/^[0-9]$/', $field['Default']) ? $field['Default'] : $this->db->quote((string) $field['Default']) | ||||
|             : null; | ||||
|  | ||||
|         $sql = ' TYPE ' . $fType; | ||||
|  | ||||
|         if ($fNull === 'NO') { | ||||
|             if ($fDefault === null || \in_array($fType, $blobs, true)) { | ||||
|                 $sql .= ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET NOT NULL' | ||||
|                     . ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' DROP DEFAULT'; | ||||
|             } else { | ||||
|                 $sql .= ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET NOT NULL' | ||||
|                     . ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET DEFAULT ' . $fDefault; | ||||
|             } | ||||
|         } else { | ||||
|             if ($fDefault !== null) { | ||||
|                 $sql .= ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' DROP NOT NULL' | ||||
|                     . ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET DEFAULT ' . $fDefault; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Sequence was created in other function, here is associated a default value but not yet owner | ||||
|         if (strpos($fDefault, 'nextval') !== false) { | ||||
|             $sequence = $table . '_' . $fName . '_seq'; | ||||
|             $owner    = $table . '.' . $fName; | ||||
|  | ||||
|             $sql .= ";\nALTER SEQUENCE " . $this->db->quoteName($sequence) . ' OWNED BY ' . $this->db->quoteName($owner); | ||||
|         } | ||||
|  | ||||
|         return $sql; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax for a single column that would be included in a table create statement. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $field  The XML field definition. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getColumnSql(\SimpleXMLElement $field) | ||||
|     { | ||||
|         $fName = (string) $field['Field']; | ||||
|         $fType = (string) $field['Type']; | ||||
|         $fNull = (string) $field['Null']; | ||||
|  | ||||
|         if (strpos($field['Default'], '::') != false) { | ||||
|             $fDefault = strstr($field['Default'], '::', true); | ||||
|         } else { | ||||
|             $fDefault = isset($field['Default']) && strlen($field['Default']) > 0 | ||||
|                 ? preg_match('/^[0-9]$/', $field['Default']) ? $field['Default'] : $this->db->quote((string) $field['Default']) | ||||
|                 : null; | ||||
|         } | ||||
|  | ||||
|         // Note, nextval() as default value means that type field is serial. | ||||
|         if (strpos($fDefault, 'nextval') !== false) { | ||||
|             $sql = $this->db->quoteName($fName) . ' SERIAL'; | ||||
|         } else { | ||||
|             $sql = $this->db->quoteName($fName) . ' ' . $fType; | ||||
|  | ||||
|             if ($fNull == 'NO') { | ||||
|                 if ($fDefault === null) { | ||||
|                     $sql .= ' NOT NULL'; | ||||
|                 } else { | ||||
|                     $sql .= ' NOT NULL DEFAULT ' . $fDefault; | ||||
|                 } | ||||
|             } else { | ||||
|                 if ($fDefault !== null) { | ||||
|                     $sql .= ' DEFAULT ' . $fDefault; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $sql; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop an index. | ||||
|      * | ||||
|      * @param   string  $name  The name of the key to drop. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropIndexSql($name) | ||||
|     { | ||||
|         return 'DROP INDEX ' . $this->db->quoteName($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to drop a key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   string  $name   The constraint name. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getDropPrimaryKeySql($table, $name) | ||||
|     { | ||||
|         return 'ALTER TABLE ONLY ' . $this->db->quoteName($table) . ' DROP CONSTRAINT ' . $this->db->quoteName($name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   array  $keys  An array of objects that comprise the keys for the table. | ||||
|      * | ||||
|      * @return  array  The lookup array. array({key name} => array(object, ...)) | ||||
|      * | ||||
|      * @since   1.2.0 | ||||
|      */ | ||||
|     protected function getKeyLookup($keys) | ||||
|     { | ||||
|         // First pass, create a lookup of the keys. | ||||
|         $lookup = []; | ||||
|  | ||||
|         foreach ($keys as $key) { | ||||
|             if ($key instanceof \SimpleXMLElement) { | ||||
|                 $kName = (string) $key['Index']; | ||||
|             } else { | ||||
|                 $kName = $key->Index; | ||||
|             } | ||||
|  | ||||
|             if (empty($lookup[$kName])) { | ||||
|                 $lookup[$kName] = []; | ||||
|             } | ||||
|  | ||||
|             $lookup[$kName][] = $key; | ||||
|         } | ||||
|  | ||||
|         return $lookup; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a unique constraint for a table key. | ||||
|      * | ||||
|      * @param   string  $table  The table name. | ||||
|      * @param   array   $key    The key. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     protected function getAddUniqueSql($table, $key) | ||||
|     { | ||||
|         if ($key instanceof \SimpleXMLElement) { | ||||
|             $kName  = (string) $key['Key_name']; | ||||
|             $kIndex = (string) $key['Index']; | ||||
|         } else { | ||||
|             $kName  = $key->Key_name; | ||||
|             $kIndex = $key->Index; | ||||
|         } | ||||
|  | ||||
|         $unique = $kIndex . ' UNIQUE (' . $kName . ')'; | ||||
|  | ||||
|         return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ADD CONSTRAINT ' . $unique; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of sequences for a table. | ||||
|      * | ||||
|      * @param   array  $sequences  An array of objects that comprise the sequences for the table. | ||||
|      * | ||||
|      * @return  array  The lookup array. array({key name} => array(object, ...)) | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getSeqLookup($sequences) | ||||
|     { | ||||
|         // First pass, create a lookup of the keys. | ||||
|         $lookup = []; | ||||
|  | ||||
|         foreach ($sequences as $seq) { | ||||
|             if ($seq instanceof \SimpleXMLElement) { | ||||
|                 $sName = (string) $seq['Name']; | ||||
|             } else { | ||||
|                 $sName = $seq->Name; | ||||
|             } | ||||
|  | ||||
|             if (empty($lookup[$sName])) { | ||||
|                 $lookup[$sName] = []; | ||||
|             } | ||||
|  | ||||
|             $lookup[$sName][] = $seq; | ||||
|         } | ||||
|  | ||||
|         return $lookup; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the SQL syntax to add a table. | ||||
|      * | ||||
|      * @param   \SimpleXMLElement  $table  The table information. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     protected function xmlToCreate(\SimpleXMLElement $table) | ||||
|     { | ||||
|         $existingTables = $this->db->getTableList(); | ||||
|         $tableName      = (string) $table['name']; | ||||
|  | ||||
|         if (in_array($tableName, $existingTables)) { | ||||
|             throw new \RuntimeException('The table you are trying to create already exists'); | ||||
|         } | ||||
|  | ||||
|         $createTableStatement = 'CREATE TABLE ' . $this->db->quoteName($tableName) . ' ('; | ||||
|  | ||||
|         foreach ($table->xpath('field') as $field) { | ||||
|             $createTableStatement .= $this->getColumnSql($field) . ', '; | ||||
|         } | ||||
|  | ||||
|         $createTableStatement = rtrim($createTableStatement, ', '); | ||||
|         $createTableStatement .= ');'; | ||||
|  | ||||
|         foreach ($table->xpath('sequence') as $seq) { | ||||
|             $createTableStatement .= $this->getAddSequenceSql($seq) . ';'; | ||||
|             $createTableStatement .= $this->getSetvalSequenceSql($seq) . ';'; | ||||
|         } | ||||
|  | ||||
|         foreach ($table->xpath('key') as $key) { | ||||
|             if ((($key['is_primary'] == 'f') || ($key['is_primary'] == '')) && (($key['is_unique'] == 't') || ($key['is_unique'] == '1'))) { | ||||
|                 $createTableStatement .= $this->getAddUniqueSql($tableName, $key) . ';'; | ||||
|             } else { | ||||
|                 $createTableStatement .= $this->getAddIndexSql($key) . ';'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $createTableStatement; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										62
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								libraries/vendor/joomla/database/src/Pgsql/PgsqlQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Pgsql; | ||||
|  | ||||
| use Joomla\Database\Pdo\PdoQuery; | ||||
| use Joomla\Database\Query\PostgresqlQueryBuilder; | ||||
| use Joomla\Database\Query\QueryElement; | ||||
|  | ||||
| /** | ||||
|  * PDO PostgreSQL Query Building Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  * | ||||
|  * @property-read  QueryElement  $forUpdate  The FOR UPDATE element used in "FOR UPDATE" lock | ||||
|  * @property-read  QueryElement  $forShare   The FOR SHARE element used in "FOR SHARE" lock | ||||
|  * @property-read  QueryElement  $noWait     The NOWAIT element used in "FOR SHARE" and "FOR UPDATE" lock | ||||
|  * @property-read  QueryElement  $returning  The RETURNING element of INSERT INTO | ||||
|  */ | ||||
| class PgsqlQuery extends PdoQuery | ||||
| { | ||||
|     use PostgresqlQueryBuilder; | ||||
|  | ||||
|     /** | ||||
|      * The list of zero or null representation of a datetime. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $nullDatetimeList = ['1970-01-01 00:00:00']; | ||||
|  | ||||
|     /** | ||||
|      * Casts a value to a char. | ||||
|      * | ||||
|      * Ensure that the value is properly quoted before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->castAsChar('a')); | ||||
|      * $query->select($query->castAsChar('a', 40)); | ||||
|      * | ||||
|      * @param   string  $value   The value to cast as a char. | ||||
|      * @param   string  $length  The length of the char. | ||||
|      * | ||||
|      * @return  string  Returns the cast value. | ||||
|      * | ||||
|      * @since   1.8.0 | ||||
|      */ | ||||
|     public function castAsChar($value, $length = null) | ||||
|     { | ||||
|         if ((int) $length < 1) { | ||||
|             return $value . '::text'; | ||||
|         } | ||||
|  | ||||
|         return 'CAST(' . $value . ' AS CHAR(' . $length . '))'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										61
									
								
								libraries/vendor/joomla/database/src/Query/LimitableInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								libraries/vendor/joomla/database/src/Query/LimitableInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Query; | ||||
|  | ||||
| use Joomla\Database\QueryInterface; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| trigger_deprecation( | ||||
|     'joomla/database', | ||||
|     '2.0.0', | ||||
|     '%s() is deprecated and will be removed in 3.0, all query objects should implement %s instead.', | ||||
|     LimitableInterface::class, | ||||
|     QueryInterface::class | ||||
| ); | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Joomla Database Query LimitableInterface. | ||||
|  * | ||||
|  * @since       1.0 | ||||
|  * @deprecated  3.0  Capabilities will be required in Joomla\Database\QueryInterface | ||||
|  */ | ||||
| interface LimitableInterface | ||||
| { | ||||
|     /** | ||||
|      * Method to modify a query already in string format with the needed additions to make the query limited to a particular number of | ||||
|      * results, or start at a particular offset. | ||||
|      * | ||||
|      * @param   string   $query   The query in string format | ||||
|      * @param   integer  $limit   The limit for the result set | ||||
|      * @param   integer  $offset  The offset for the result set | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function processLimit($query, $limit, $offset = 0); | ||||
|  | ||||
|     /** | ||||
|      * Sets the offset and limit for the result set, if the database driver supports it. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record) | ||||
|      * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) | ||||
|      * | ||||
|      * @param   integer  $limit   The limit for the result set | ||||
|      * @param   integer  $offset  The offset for the result set | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function setLimit($limit = 0, $offset = 0); | ||||
| } | ||||
							
								
								
									
										263
									
								
								libraries/vendor/joomla/database/src/Query/MysqlQueryBuilder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								libraries/vendor/joomla/database/src/Query/MysqlQueryBuilder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,263 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Query; | ||||
|  | ||||
| /** | ||||
|  * Trait for MySQL Query Building. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| trait MysqlQueryBuilder | ||||
| { | ||||
|     /** | ||||
|      * Magic function to convert the query to a string. | ||||
|      * | ||||
|      * @return  string  The completed query. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __toString() | ||||
|     { | ||||
|         switch ($this->type) { | ||||
|             case 'select': | ||||
|                 if ($this->selectRowNumber) { | ||||
|                     $orderBy      = $this->selectRowNumber['orderBy']; | ||||
|                     $tmpOffset    = $this->offset; | ||||
|                     $tmpLimit     = $this->limit; | ||||
|                     $this->offset = 0; | ||||
|                     $this->limit  = 0; | ||||
|                     $tmpOrder     = $this->order; | ||||
|                     $this->order  = null; | ||||
|                     $query        = parent::__toString(); | ||||
|                     $this->order  = $tmpOrder; | ||||
|                     $this->offset = $tmpOffset; | ||||
|                     $this->limit  = $tmpLimit; | ||||
|  | ||||
|                     // Add support for second order by, offset and limit | ||||
|                     $query = PHP_EOL . 'SELECT * FROM (' . $query . PHP_EOL . "ORDER BY $orderBy" . PHP_EOL . ') w'; | ||||
|  | ||||
|                     if ($this->order) { | ||||
|                         $query .= (string) $this->order; | ||||
|                     } | ||||
|  | ||||
|                     return $this->processLimit($query, $this->limit, $this->offset); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|         return parent::__toString(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to modify a query already in string format with the needed additions to make the query limited to a particular number of | ||||
|      * results, or start at a particular offset. | ||||
|      * | ||||
|      * @param   string   $query   The query in string format | ||||
|      * @param   integer  $limit   The limit for the result set | ||||
|      * @param   integer  $offset  The offset for the result set | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function processLimit($query, $limit, $offset = 0) | ||||
|     { | ||||
|         if ($limit > 0 && $offset > 0) { | ||||
|             $query .= ' LIMIT ' . $offset . ', ' . $limit; | ||||
|         } elseif ($limit > 0) { | ||||
|             $query .= ' LIMIT ' . $limit; | ||||
|         } | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Concatenates an array of column names or values. | ||||
|      * | ||||
|      * @param   string[]     $values     An array of values to concatenate. | ||||
|      * @param   string|null  $separator  As separator to place between each value. | ||||
|      * | ||||
|      * @return  string  The concatenated values. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function concatenate($values, $separator = null) | ||||
|     { | ||||
|         if ($separator !== null) { | ||||
|             $statement = 'CONCAT_WS(' . $this->quote($separator); | ||||
|  | ||||
|             foreach ($values as $value) { | ||||
|                 $statement .= ', ' . $value; | ||||
|             } | ||||
|  | ||||
|             return $statement . ')'; | ||||
|         } | ||||
|  | ||||
|         return 'CONCAT(' . implode(',', $values) . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Aggregate function to get input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->groupConcat('id', ','); | ||||
|      * | ||||
|      * @param   string  $expression  The expression to apply concatenation to, this may be a column name or complex SQL statement. | ||||
|      * @param   string  $separator   The delimiter of each concatenated value | ||||
|      * | ||||
|      * @return  string  Input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function groupConcat($expression, $separator = ',') | ||||
|     { | ||||
|         return 'GROUP_CONCAT(' . $expression . ' SEPARATOR ' . $this->quote($separator) . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to quote and optionally escape a string to database requirements for insertion into the database. | ||||
|      * | ||||
|      * This method is provided for use where the query object is passed to a function for modification. | ||||
|      * If you have direct access to the database object, it is recommended you use the quote method directly. | ||||
|      * | ||||
|      * Note that 'q' is an alias for this method as it is in DatabaseDriver. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->quote('fulltext'); | ||||
|      * $query->q('fulltext'); | ||||
|      * $query->q(array('option', 'fulltext')); | ||||
|      * | ||||
|      * @param   array|string  $text    A string or an array of strings to quote. | ||||
|      * @param   boolean       $escape  True (default) to escape the string, false to leave it unchanged. | ||||
|      * | ||||
|      * @return  string  The quoted input string. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException if the internal db property is not a valid object. | ||||
|      */ | ||||
|     abstract public function quote($text, $escape = true); | ||||
|  | ||||
|     /** | ||||
|      * Get the regular expression operator | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where('field ' . $query->regexp($search)); | ||||
|      * | ||||
|      * @param   string  $value  The regex pattern. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function regexp($value) | ||||
|     { | ||||
|         return ' REGEXP ' . $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the function to return a random floating-point value | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->rand(); | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rand() | ||||
|     { | ||||
|         return ' RAND() '; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Find a value in a varchar used like a set. | ||||
|      * | ||||
|      * Ensure that the value is an integer before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->findInSet((int) $parent->id, 'a.assigned_cat_ids') | ||||
|      * | ||||
|      * @param   string  $value  The value to search for. | ||||
|      * @param   string  $set    The set of values. | ||||
|      * | ||||
|      * @return  string  A representation of the MySQL find_in_set() function for the driver. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function findInSet($value, $set) | ||||
|     { | ||||
|         return ' find_in_set(' . $value . ', ' . $set . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Return the number of the current row. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('id'); | ||||
|      * $query->selectRowNumber('ordering,publish_up DESC', 'new_ordering'); | ||||
|      * $query->from('#__content'); | ||||
|      * | ||||
|      * @param   string  $orderBy           An expression of ordering for window function. | ||||
|      * @param   string  $orderColumnAlias  An alias for new ordering column. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      * | ||||
|      * @todo  Remove this method when the database version requirements have been raised | ||||
|      *        to >= 8.0.0 for MySQL and >= 10.2.0 for MariaDB so the ROW_NUMBER() window | ||||
|      *        function can be used in any case. | ||||
|      */ | ||||
|     public function selectRowNumber($orderBy, $orderColumnAlias) | ||||
|     { | ||||
|         // Use parent method with ROW_NUMBER() window function on MariaDB 11.0.0 and newer. | ||||
|         if ($this->db->isMariaDb() && version_compare($this->db->getVersion(), '11.0.0', '>=')) { | ||||
|             return parent::selectRowNumber($orderBy, $orderColumnAlias); | ||||
|         } | ||||
|  | ||||
|         $this->validateRowNumber($orderBy, $orderColumnAlias); | ||||
|  | ||||
|         return $this->select("(SELECT @rownum := @rownum + 1 FROM (SELECT @rownum := 0) AS r) AS $orderColumnAlias"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Casts a value to a char. | ||||
|      * | ||||
|      * Ensure that the value is properly quoted before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->castAs('CHAR', 'a')); | ||||
|      * | ||||
|      * @param   string  $type    The type of string to cast as. | ||||
|      * @param   string  $value   The value to cast as a char. | ||||
|      * @param   string  $length  The value to cast as a char. | ||||
|      * | ||||
|      * @return  string  SQL statement to cast the value as a char type. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function castAs(string $type, string $value, ?string $length = null) | ||||
|     { | ||||
|         switch (strtoupper($type)) { | ||||
|             case 'CHAR': | ||||
|                 if (!$length) { | ||||
|                     return $value; | ||||
|                 } else { | ||||
|                     return 'CAST(' . $value . ' AS CHAR(' . $length . '))'; | ||||
|                 } | ||||
|  | ||||
|                 // No break | ||||
|             case 'INT': | ||||
|                 return '(' . $value . ' + 0)'; | ||||
|         } | ||||
|  | ||||
|         return parent::castAs($type, $value, $length); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										696
									
								
								libraries/vendor/joomla/database/src/Query/PostgresqlQueryBuilder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										696
									
								
								libraries/vendor/joomla/database/src/Query/PostgresqlQueryBuilder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,696 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Query; | ||||
|  | ||||
| /** | ||||
|  * Trait for PostgreSQL Query Building. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| trait PostgresqlQueryBuilder | ||||
| { | ||||
|     /** | ||||
|      * The FOR UPDATE element used in "FOR UPDATE" lock | ||||
|      * | ||||
|      * @var    QueryElement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $forUpdate; | ||||
|  | ||||
|     /** | ||||
|      * The FOR SHARE element used in "FOR SHARE" lock | ||||
|      * | ||||
|      * @var    QueryElement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $forShare; | ||||
|  | ||||
|     /** | ||||
|      * The NOWAIT element used in "FOR SHARE" and "FOR UPDATE" lock | ||||
|      * | ||||
|      * @var    QueryElement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $noWait; | ||||
|  | ||||
|     /** | ||||
|      * The LIMIT element | ||||
|      * | ||||
|      * @var    QueryElement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $limit; | ||||
|  | ||||
|     /** | ||||
|      * The OFFSET element | ||||
|      * | ||||
|      * @var    QueryElement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $offset; | ||||
|  | ||||
|     /** | ||||
|      * The RETURNING element of INSERT INTO | ||||
|      * | ||||
|      * @var    QueryElement | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $returning; | ||||
|  | ||||
|     /** | ||||
|      * Magic function to convert the query to a string, only for PostgreSQL specific queries | ||||
|      * | ||||
|      * @return  string  The completed query. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __toString() | ||||
|     { | ||||
|         $query = ''; | ||||
|  | ||||
|         switch ($this->type) { | ||||
|             case 'select': | ||||
|                 $query .= (string) $this->select; | ||||
|                 $query .= (string) $this->from; | ||||
|  | ||||
|                 if ($this->join) { | ||||
|                     // Special case for joins | ||||
|                     foreach ($this->join as $join) { | ||||
|                         $query .= (string) $join; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($this->where) { | ||||
|                     $query .= (string) $this->where; | ||||
|                 } | ||||
|  | ||||
|                 if ($this->selectRowNumber) { | ||||
|                     if ($this->order) { | ||||
|                         $query .= (string) $this->order; | ||||
|                     } | ||||
|  | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 if ($this->group) { | ||||
|                     $query .= (string) $this->group; | ||||
|                 } | ||||
|  | ||||
|                 if ($this->having) { | ||||
|                     $query .= (string) $this->having; | ||||
|                 } | ||||
|  | ||||
|                 if ($this->merge) { | ||||
|                     // Special case for merge | ||||
|                     foreach ($this->merge as $element) { | ||||
|                         $query .= (string) $element; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($this->order) { | ||||
|                     $query .= (string) $this->order; | ||||
|                 } | ||||
|  | ||||
|                 if ($this->forUpdate) { | ||||
|                     $query .= (string) $this->forUpdate; | ||||
|                 } else { | ||||
|                     if ($this->forShare) { | ||||
|                         $query .= (string) $this->forShare; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($this->noWait) { | ||||
|                     $query .= (string) $this->noWait; | ||||
|                 } | ||||
|  | ||||
|                 $query = $this->processLimit($query, $this->limit, $this->offset); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'update': | ||||
|                 $query .= (string) $this->update; | ||||
|                 $query .= (string) $this->set; | ||||
|  | ||||
|                 if ($this->join) { | ||||
|                     $tmpFrom     = $this->from; | ||||
|                     $tmpWhere    = $this->where ? clone $this->where : null; | ||||
|                     $this->from  = null; | ||||
|  | ||||
|                     // Workaround for special case of JOIN with UPDATE | ||||
|                     foreach ($this->join as $join) { | ||||
|                         $joinElem = $join->getElements(); | ||||
|  | ||||
|                         $this->from($joinElem[0]); | ||||
|  | ||||
|                         if (isset($joinElem[1])) { | ||||
|                             $this->where($joinElem[1]); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     $query .= (string) $this->from; | ||||
|  | ||||
|                     if ($this->where) { | ||||
|                         $query .= (string) $this->where; | ||||
|                     } | ||||
|  | ||||
|                     $this->from  = $tmpFrom; | ||||
|                     $this->where = $tmpWhere; | ||||
|                 } elseif ($this->where) { | ||||
|                     $query .= (string) $this->where; | ||||
|                 } | ||||
|  | ||||
|                 $query = $this->processLimit($query, $this->limit, $this->offset); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'insert': | ||||
|                 $query .= (string) $this->insert; | ||||
|  | ||||
|                 if ($this->values) { | ||||
|                     if ($this->columns) { | ||||
|                         $query .= (string) $this->columns; | ||||
|                     } | ||||
|  | ||||
|                     $elements = $this->values->getElements(); | ||||
|  | ||||
|                     if (!($elements[0] instanceof $this)) { | ||||
|                         $query .= ' VALUES '; | ||||
|                     } | ||||
|  | ||||
|                     $query .= (string) $this->values; | ||||
|  | ||||
|                     if ($this->returning) { | ||||
|                         $query .= (string) $this->returning; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 $query = $this->processLimit($query, $this->limit, $this->offset); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 $query = parent::__toString(); | ||||
|  | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         if ($this->type === 'select' && $this->alias !== null) { | ||||
|             $query = '(' . $query . ') AS ' . $this->alias; | ||||
|         } | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Clear data from the query or a specific clause of the query. | ||||
|      * | ||||
|      * @param   string  $clause  Optionally, the name of the clause to clear, or nothing to clear the whole query. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function clear($clause = null) | ||||
|     { | ||||
|         switch ($clause) { | ||||
|             case 'limit': | ||||
|                 $this->limit = null; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'offset': | ||||
|                 $this->offset = null; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'forUpdate': | ||||
|                 $this->forUpdate = null; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'forShare': | ||||
|                 $this->forShare = null; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'noWait': | ||||
|                 $this->noWait = null; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'returning': | ||||
|                 $this->returning = null; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'select': | ||||
|             case 'update': | ||||
|             case 'delete': | ||||
|             case 'insert': | ||||
|             case 'querySet': | ||||
|             case 'from': | ||||
|             case 'join': | ||||
|             case 'set': | ||||
|             case 'where': | ||||
|             case 'group': | ||||
|             case 'having': | ||||
|             case 'merge': | ||||
|             case 'order': | ||||
|             case 'columns': | ||||
|             case 'values': | ||||
|                 parent::clear($clause); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 $this->forUpdate = null; | ||||
|                 $this->forShare  = null; | ||||
|                 $this->noWait    = null; | ||||
|                 $this->returning = null; | ||||
|  | ||||
|                 parent::clear($clause); | ||||
|  | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Casts a value to a char. | ||||
|      * | ||||
|      * Ensure that the value is properly quoted before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->castAs('CHAR', 'a')); | ||||
|      * | ||||
|      * @param   string   $type    The type of string to cast as. | ||||
|      * @param   string   $value   The value to cast as a char. | ||||
|      * @param   ?string  $length  The value to cast as a char. | ||||
|      * | ||||
|      * @return  string  SQL statement to cast the value as a char type. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function castAs(string $type, string $value, ?string $length = null) | ||||
|     { | ||||
|         switch (strtoupper($type)) { | ||||
|             case 'CHAR': | ||||
|                 if (!$length) { | ||||
|                     return $value . '::text'; | ||||
|                 } else { | ||||
|                     return 'CAST(' . $value . ' AS CHAR(' . $length . '))'; | ||||
|                 } | ||||
|  | ||||
|                 // No break | ||||
|             case 'INT': | ||||
|                 return 'CAST(' . $value . ' AS INTEGER)'; | ||||
|         } | ||||
|  | ||||
|         return parent::castAs($type, $value, $length); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Concatenates an array of column names or values. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->concatenate(array('a', 'b'))); | ||||
|      * | ||||
|      * @param   string[]     $values     An array of values to concatenate. | ||||
|      * @param   string|null  $separator  As separator to place between each value. | ||||
|      * | ||||
|      * @return  string  The concatenated values. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function concatenate($values, $separator = null) | ||||
|     { | ||||
|         if ($separator !== null) { | ||||
|             return implode(' || ' . $this->quote($separator) . ' || ', $values); | ||||
|         } | ||||
|  | ||||
|         return implode(' || ', $values); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the current date and time. | ||||
|      * | ||||
|      * @return  string  Return string used in query to obtain | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function currentTimestamp() | ||||
|     { | ||||
|         return 'NOW()'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the FOR UPDATE lock on select's output row | ||||
|      * | ||||
|      * @param   string  $tableName  The table to lock | ||||
|      * @param   string  $glue       The glue by which to join the conditions. Defaults to ',' . | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function forUpdate($tableName, $glue = ',') | ||||
|     { | ||||
|         $this->type = 'forUpdate'; | ||||
|  | ||||
|         if ($this->forUpdate === null) { | ||||
|             $glue            = strtoupper($glue); | ||||
|             $this->forUpdate = new QueryElement('FOR UPDATE', 'OF ' . $tableName, "$glue "); | ||||
|         } else { | ||||
|             $this->forUpdate->append($tableName); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the FOR SHARE lock on select's output row | ||||
|      * | ||||
|      * @param   string  $tableName  The table to lock | ||||
|      * @param   string  $glue       The glue by which to join the conditions. Defaults to ',' . | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function forShare($tableName, $glue = ',') | ||||
|     { | ||||
|         $this->type = 'forShare'; | ||||
|  | ||||
|         if ($this->forShare === null) { | ||||
|             $glue           = strtoupper($glue); | ||||
|             $this->forShare = new QueryElement('FOR SHARE', 'OF ' . $tableName, "$glue "); | ||||
|         } else { | ||||
|             $this->forShare->append($tableName); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Aggregate function to get input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->groupConcat('id', ','); | ||||
|      * | ||||
|      * @param   string  $expression  The expression to apply concatenation to, this may be a column name or complex SQL statement. | ||||
|      * @param   string  $separator   The delimiter of each concatenated value | ||||
|      * | ||||
|      * @return  string  Input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function groupConcat($expression, $separator = ',') | ||||
|     { | ||||
|         return 'string_agg(' . $expression . ', ' . $this->quote($separator) . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract year from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->year($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing year to be extracted. | ||||
|      * | ||||
|      * @return  string  Returns string to extract year from a date. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function year($date) | ||||
|     { | ||||
|         return 'EXTRACT (YEAR FROM ' . $date . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract month from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->month($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing month to be extracted. | ||||
|      * | ||||
|      * @return  string  Returns string to extract month from a date. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function month($date) | ||||
|     { | ||||
|         return 'EXTRACT (MONTH FROM ' . $date . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract day from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->day($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing day to be extracted. | ||||
|      * | ||||
|      * @return  string  Returns string to extract day from a date. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function day($date) | ||||
|     { | ||||
|         return 'EXTRACT (DAY FROM ' . $date . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract hour from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->hour($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing hour to be extracted. | ||||
|      * | ||||
|      * @return  string  Returns string to extract hour from a date. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function hour($date) | ||||
|     { | ||||
|         return 'EXTRACT (HOUR FROM ' . $date . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract minute from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->minute($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing minute to be extracted. | ||||
|      * | ||||
|      * @return  string  Returns string to extract minute from a date. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function minute($date) | ||||
|     { | ||||
|         return 'EXTRACT (MINUTE FROM ' . $date . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract seconds from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->second($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing second to be extracted. | ||||
|      * | ||||
|      * @return  string  Returns string to extract second from a date. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function second($date) | ||||
|     { | ||||
|         return 'EXTRACT (SECOND FROM ' . $date . ')'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the NOWAIT lock on select's output row | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function noWait() | ||||
|     { | ||||
|         $this->type = 'noWait'; | ||||
|  | ||||
|         if ($this->noWait === null) { | ||||
|             $this->noWait = new QueryElement('NOWAIT', null); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the LIMIT clause to the query | ||||
|      * | ||||
|      * @param   integer  $limit  Number of rows to return | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function limit($limit = 0) | ||||
|     { | ||||
|         if ($this->limit === null) { | ||||
|             $this->limit = new QueryElement('LIMIT', (int) $limit); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the OFFSET clause to the query | ||||
|      * | ||||
|      * @param   integer  $offset  An integer for skipping rows | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function offset($offset = 0) | ||||
|     { | ||||
|         if ($this->offset === null) { | ||||
|             $this->offset = new QueryElement('OFFSET', (int) $offset); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the RETURNING element to INSERT INTO statement. | ||||
|      * | ||||
|      * @param   mixed  $pkCol  The name of the primary key column. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function returning($pkCol) | ||||
|     { | ||||
|         if ($this->returning === null) { | ||||
|             $this->returning = new QueryElement('RETURNING', $pkCol); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to modify a query already in string format with the needed additions to make the query limited to a particular number of | ||||
|      * results, or start at a particular offset. | ||||
|      * | ||||
|      * @param   string   $query   The query in string format | ||||
|      * @param   integer  $limit   The limit for the result set | ||||
|      * @param   integer  $offset  The offset for the result set | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function processLimit($query, $limit, $offset = 0) | ||||
|     { | ||||
|         if ($limit > 0) { | ||||
|             $query .= ' LIMIT ' . $limit; | ||||
|         } | ||||
|  | ||||
|         if ($offset > 0) { | ||||
|             $query .= ' OFFSET ' . $offset; | ||||
|         } | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add to the current date and time. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->dateAdd()); | ||||
|      * | ||||
|      * Prefixing the interval with a - (negative sign) will cause subtraction to be used. | ||||
|      * | ||||
|      * @param   string  $date      The db quoted string representation of the date to add to | ||||
|      * @param   string  $interval  The string representation of the appropriate number of units | ||||
|      * @param   string  $datePart  The part of the date to perform the addition on | ||||
|      * | ||||
|      * @return  string  The string with the appropriate sql for addition of dates | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @link    http://www.postgresql.org/docs/9.0/static/functions-datetime.html. | ||||
|      */ | ||||
|     public function dateAdd($date, $interval, $datePart) | ||||
|     { | ||||
|         if (substr($interval, 0, 1) !== '-') { | ||||
|             return 'timestamp ' . $date . " + interval '" . $interval . ' ' . $datePart . "'"; | ||||
|         } | ||||
|  | ||||
|         return 'timestamp ' . $date . " - interval '" . ltrim($interval, '-') . ' ' . $datePart . "'"; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the regular expression operator | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where('field ' . $query->regexp($search)); | ||||
|      * | ||||
|      * @param   string  $value  The regex pattern. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function regexp($value) | ||||
|     { | ||||
|         return ' ~* ' . $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the function to return a random floating-point value | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->rand(); | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rand() | ||||
|     { | ||||
|         return ' RANDOM() '; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Find a value in a varchar used like a set. | ||||
|      * | ||||
|      * Ensure that the value is an integer before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->findInSet((int) $parent->id, 'a.assigned_cat_ids') | ||||
|      * | ||||
|      * @param   string  $value  The value to search for. | ||||
|      * @param   string  $set    The set of values. | ||||
|      * | ||||
|      * @return  string  A representation of the MySQL find_in_set() function for the driver. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function findInSet($value, $set) | ||||
|     { | ||||
|         return " $value = ANY (string_to_array($set, ',')::integer[]) "; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										75
									
								
								libraries/vendor/joomla/database/src/Query/PreparableInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								libraries/vendor/joomla/database/src/Query/PreparableInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Query; | ||||
|  | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Database\QueryInterface; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| trigger_deprecation( | ||||
|     'joomla/database', | ||||
|     '2.0.0', | ||||
|     '%s() is deprecated and will be removed in 3.0, all query objects should implement %s instead.', | ||||
|     PreparableInterface::class, | ||||
|     QueryInterface::class | ||||
| ); | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Joomla Database Query Preparable Interface. | ||||
|  * | ||||
|  * Adds bind/unbind methods as well as a getBounded() method to retrieve the stored bounded variables on demand prior to query execution. | ||||
|  * | ||||
|  * @since       1.0 | ||||
|  * @deprecated  3.0  Capabilities will be required in Joomla\Database\QueryInterface | ||||
|  */ | ||||
| interface PreparableInterface | ||||
| { | ||||
|     /** | ||||
|      * Method to add a variable to an internal array that will be bound to a prepared SQL statement before query execution. | ||||
|      * | ||||
|      * @param   array|string|integer  $key            The key that will be used in your SQL query to reference the value. Usually of | ||||
|      *                                                the form ':key', but can also be an integer. | ||||
|      * @param   mixed                 $value          The value that will be bound. It can be an array, in this case it has to be | ||||
|      *                                                same length of $key; The value is passed by reference to support output | ||||
|      *                                                parameters such as those possible with stored procedures. | ||||
|      * @param   array|string          $dataType       Constant corresponding to a SQL datatype. It can be an array, in this case it | ||||
|      *                                                has to be same length of $key | ||||
|      * @param   integer               $length         The length of the variable. Usually required for OUTPUT parameters. | ||||
|      * @param   array                 $driverOptions  Optional driver options to be used. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function bind($key, &$value, $dataType = ParameterType::STRING, $length = 0, $driverOptions = []); | ||||
|  | ||||
|     /** | ||||
|      * Method to unbind a bound variable. | ||||
|      * | ||||
|      * @param   array|string|integer  $key  The key or array of keys to unbind. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function unbind($key); | ||||
|  | ||||
|     /** | ||||
|      * Retrieves the bound parameters array when key is null and returns it by reference. If a key is provided then that item is returned. | ||||
|      * | ||||
|      * @param   mixed  $key  The bounded variable key to retrieve. | ||||
|      * | ||||
|      * @return  mixed | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function &getBounded($key = null); | ||||
| } | ||||
							
								
								
									
										170
									
								
								libraries/vendor/joomla/database/src/Query/QueryElement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								libraries/vendor/joomla/database/src/Query/QueryElement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,170 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Query; | ||||
|  | ||||
| /** | ||||
|  * Query Element Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class QueryElement | ||||
| { | ||||
|     /** | ||||
|      * The name of the element. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $name; | ||||
|  | ||||
|     /** | ||||
|      * An array of elements. | ||||
|      * | ||||
|      * @var    string[] | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $elements = []; | ||||
|  | ||||
|     /** | ||||
|      * Glue piece. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $glue; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   string           $name      The name of the element. | ||||
|      * @param   string[]|string  $elements  String or array. | ||||
|      * @param   string           $glue      The glue for elements. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct($name, $elements, $glue = ',') | ||||
|     { | ||||
|         $this->name = $name; | ||||
|         $this->glue = $glue; | ||||
|  | ||||
|         $this->append($elements); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Magic function to convert the query element to a string. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __toString() | ||||
|     { | ||||
|         if (substr($this->name, -2) === '()') { | ||||
|             return \PHP_EOL . substr($this->name, 0, -2) . '(' . implode($this->glue, $this->elements) . ')'; | ||||
|         } | ||||
|  | ||||
|         return \PHP_EOL . $this->name . ' ' . implode($this->glue, $this->elements); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Appends element parts to the internal list. | ||||
|      * | ||||
|      * @param   string[]|string  $elements  String or array. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function append($elements) | ||||
|     { | ||||
|         if (\is_array($elements)) { | ||||
|             $this->elements = array_merge($this->elements, $elements); | ||||
|         } else { | ||||
|             $this->elements = array_merge($this->elements, [$elements]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the elements of this element. | ||||
|      * | ||||
|      * @return  string[] | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getElements() | ||||
|     { | ||||
|         return $this->elements; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the glue of this element. | ||||
|      * | ||||
|      * @return  string  Glue of the element. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function getGlue() | ||||
|     { | ||||
|         return $this->glue; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the name of this element. | ||||
|      * | ||||
|      * @return  string  Name of the element. | ||||
|      * | ||||
|      * @since   1.7.0 | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return $this->name; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the name of this element. | ||||
|      * | ||||
|      * @param   string  $name  Name of the element. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.3.0 | ||||
|      */ | ||||
|     public function setName($name) | ||||
|     { | ||||
|         $this->name = $name; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to provide basic copy support. | ||||
|      * | ||||
|      * Any object pushed into the data of this class should have its own __clone() implementation. | ||||
|      * This method does not support copying objects in a multidimensional array. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __clone() | ||||
|     { | ||||
|         foreach ($this as $k => $v) { | ||||
|             if (\is_object($v)) { | ||||
|                 $this->{$k} = clone $v; | ||||
|             } elseif (\is_array($v)) { | ||||
|                 foreach ($v as $i => $element) { | ||||
|                     if (\is_object($element)) { | ||||
|                         $this->{$k}[$i] = clone $element; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										725
									
								
								libraries/vendor/joomla/database/src/QueryInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										725
									
								
								libraries/vendor/joomla/database/src/QueryInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,725 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| use Joomla\Database\Exception\QueryTypeAlreadyDefinedException; | ||||
| use Joomla\Database\Exception\UnknownTypeException; | ||||
| use Joomla\Database\Query\LimitableInterface; | ||||
| use Joomla\Database\Query\PreparableInterface; | ||||
|  | ||||
| /** | ||||
|  * Joomla Framework Query Building Interface. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| interface QueryInterface extends PreparableInterface, LimitableInterface | ||||
| { | ||||
|     /** | ||||
|      * Convert the query object to a string. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __toString(); | ||||
|  | ||||
|     /** | ||||
|      * Add a single column, or array of columns to the CALL clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->call('a.*')->call('b.id'); | ||||
|      * $query->call(array('a.*', 'b.id')); | ||||
|      * | ||||
|      * @param   array|string  $columns  A string or an array of field names. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  QueryTypeAlreadyDefinedException if the query type has already been defined | ||||
|      */ | ||||
|     public function call($columns); | ||||
|  | ||||
|     /** | ||||
|      * Casts a value to a specified type. | ||||
|      * | ||||
|      * Ensure that the value is properly quoted before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->castAs('CHAR', 'a')); | ||||
|      * | ||||
|      * @param   string  $type    The type of string to cast as. | ||||
|      * @param   string  $value   The value to cast as a char. | ||||
|      * @param   string  $length  Optionally specify the length of the field (if the type supports it otherwise | ||||
|      *                           ignored). | ||||
|      * | ||||
|      * @return  string  SQL statement to cast the value as a char type. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  UnknownTypeException  When unsupported cast for a database driver | ||||
|      */ | ||||
|     public function castAs(string $type, string $value, ?string $length = null); | ||||
|  | ||||
|     /** | ||||
|      * Gets the number of characters in a string. | ||||
|      * | ||||
|      * Note, use 'length' to find the number of bytes in a string. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->charLength('a')); | ||||
|      * | ||||
|      * @param   string       $field      A value. | ||||
|      * @param   string|null  $operator   Comparison operator between charLength integer value and $condition | ||||
|      * @param   string|null  $condition  Integer value to compare charLength with. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the length of a character. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function charLength($field, $operator = null, $condition = null); | ||||
|  | ||||
|     /** | ||||
|      * Clear data from the query or a specific clause of the query. | ||||
|      * | ||||
|      * @param   string  $clause  Optionally, the name of the clause to clear, or nothing to clear the whole query. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function clear($clause = null); | ||||
|  | ||||
|     /** | ||||
|      * Adds a column, or array of column names that would be used for an INSERT INTO statement. | ||||
|      * | ||||
|      * @param   array|string  $columns  A column name, or array of column names. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function columns($columns); | ||||
|  | ||||
|     /** | ||||
|      * Concatenates an array of column names or values. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->concatenate(array('a', 'b'))); | ||||
|      * | ||||
|      * @param   string[]     $values     An array of values to concatenate. | ||||
|      * @param   string|null  $separator  As separator to place between each value. | ||||
|      * | ||||
|      * @return  string  SQL statement representing the concatenated values. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function concatenate($values, $separator = null); | ||||
|  | ||||
|     /** | ||||
|      * Gets the current date and time. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where('published_up < '.$query->currentTimestamp()); | ||||
|      * | ||||
|      * @return  string  SQL statement to get the current timestamp. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function currentTimestamp(); | ||||
|  | ||||
|     /** | ||||
|      * Add a table name to the DELETE clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->delete('#__a')->where('id = 1'); | ||||
|      * | ||||
|      * @param   string  $table  The name of the table to delete from. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  QueryTypeAlreadyDefinedException if the query type has already been defined | ||||
|      */ | ||||
|     public function delete($table = null); | ||||
|  | ||||
|     /** | ||||
|      * Add a single column, or array of columns to the EXEC clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->exec('a.*')->exec('b.id'); | ||||
|      * $query->exec(array('a.*', 'b.id')); | ||||
|      * | ||||
|      * @param   array|string  $columns  A string or an array of field names. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  QueryTypeAlreadyDefinedException if the query type has already been defined | ||||
|      */ | ||||
|     public function exec($columns); | ||||
|  | ||||
|     /** | ||||
|      * Find a value in a varchar used like a set. | ||||
|      * | ||||
|      * Ensure that the value is an integer before passing to the method. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->findInSet((int) $parent->id, 'a.assigned_cat_ids') | ||||
|      * | ||||
|      * @param   string  $value  The value to search for. | ||||
|      * @param   string  $set    The set of values. | ||||
|      * | ||||
|      * @return  string  A representation of the MySQL find_in_set() function for the driver. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function findInSet($value, $set); | ||||
|  | ||||
|     /** | ||||
|      * Add a table to the FROM clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('*')->from('#__a'); | ||||
|      * $query->select('*')->from($subquery->alias('a')); | ||||
|      * | ||||
|      * @param   string|QueryInterface  $table  The name of the table or a QueryInterface object (or a child of it) with alias set. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function from($table); | ||||
|  | ||||
|     /** | ||||
|      * Add alias for current query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('*')->from('#__a')->alias('subquery'); | ||||
|      * | ||||
|      * @param   string  $alias  Alias used for a JDatabaseQuery. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function alias($alias); | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract year from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->year($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing year to be extracted. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the year from a date value. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function year($date); | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract month from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->month($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing month to be extracted. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the month from a date value. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function month($date); | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract day from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->day($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing day to be extracted. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the day from a date value. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function day($date); | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract hour from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->hour($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing hour to be extracted. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the hour from a date/time value. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function hour($date); | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract minute from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->minute($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing minute to be extracted. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the minute from a date/time value. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function minute($date); | ||||
|  | ||||
|     /** | ||||
|      * Used to get a string to extract seconds from date column. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->second($query->quoteName('dateColumn'))); | ||||
|      * | ||||
|      * @param   string  $date  Date column containing second to be extracted. | ||||
|      * | ||||
|      * @return  string  SQL statement to get the second from a date/time value. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function second($date); | ||||
|  | ||||
|     /** | ||||
|      * Add a grouping column to the GROUP clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->group('id'); | ||||
|      * | ||||
|      * @param   array|string  $columns  A string or array of ordering columns. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function group($columns); | ||||
|  | ||||
|     /** | ||||
|      * Aggregate function to get input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->groupConcat('id', ','); | ||||
|      * | ||||
|      * @param   string  $expression  The expression to apply concatenation to, this may be a column name or complex SQL statement. | ||||
|      * @param   string  $separator   The delimiter of each concatenated value | ||||
|      * | ||||
|      * @return  string  Input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function groupConcat($expression, $separator = ','); | ||||
|  | ||||
|     /** | ||||
|      * A conditions to the HAVING clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->group('id')->having('COUNT(id) > 5'); | ||||
|      * | ||||
|      * @param   array|string  $conditions  A string or array of columns. | ||||
|      * @param   string        $glue        The glue by which to join the conditions. Defaults to AND. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function having($conditions, $glue = 'AND'); | ||||
|  | ||||
|     /** | ||||
|      * Add a table name to the INSERT clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->insert('#__a')->set('id = 1'); | ||||
|      * $query->insert('#__a')->columns('id, title')->values('1,2')->values('3,4'); | ||||
|      * $query->insert('#__a')->columns('id, title')->values(array('1,2', '3,4')); | ||||
|      * | ||||
|      * @param   string   $table           The name of the table to insert data into. | ||||
|      * @param   boolean  $incrementField  The name of the field to auto increment. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  QueryTypeAlreadyDefinedException if the query type has already been defined | ||||
|      */ | ||||
|     public function insert($table, $incrementField = false); | ||||
|  | ||||
|     /** | ||||
|      * Add a JOIN clause to the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->join('INNER', 'b', 'b.id = a.id); | ||||
|      * | ||||
|      * @param   string  $type       The type of join. This string is prepended to the JOIN keyword. | ||||
|      * @param   string  $table      The name of table. | ||||
|      * @param   string  $condition  The join condition. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function join($type, $table, $condition = null); | ||||
|  | ||||
|     /** | ||||
|      * Get the length of a string in bytes. | ||||
|      * | ||||
|      * Note, use 'charLength' to find the number of characters in a string. | ||||
|      * | ||||
|      * Usage: | ||||
|      * query->where($query->length('a').' > 3'); | ||||
|      * | ||||
|      * @param   string  $value  The string to measure. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function length($value); | ||||
|  | ||||
|     /** | ||||
|      * Get the null or zero representation of a timestamp for the database driver. | ||||
|      * | ||||
|      * This method is provided for use where the query object is passed to a function for modification. | ||||
|      * If you have direct access to the database object, it is recommended you use the nullDate method directly. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where('modified_date <> '.$query->nullDate()); | ||||
|      * | ||||
|      * @param   boolean  $quoted  Optionally wraps the null date in database quotes (true by default). | ||||
|      * | ||||
|      * @return  string  Null or zero representation of a timestamp. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function nullDate($quoted = true); | ||||
|  | ||||
|     /** | ||||
|      * Generate a SQL statement to check if column represents a zero or null datetime. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where($query->isNullDatetime('modified_date')); | ||||
|      * | ||||
|      * @param   string  $column  A column name. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isNullDatetime($column); | ||||
|  | ||||
|     /** | ||||
|      * Add an ordering column to the ORDER clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->order('foo')->order('bar'); | ||||
|      * $query->order(array('foo','bar')); | ||||
|      * | ||||
|      * @param   array|string  $columns  A string or array of ordering columns. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function order($columns); | ||||
|  | ||||
|     /** | ||||
|      * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection | ||||
|      * risks and reserved word conflicts. | ||||
|      * | ||||
|      * This method is provided for use where the query object is passed to a function for modification. | ||||
|      * If you have direct access to the database object, it is recommended you use the quoteName method directly. | ||||
|      * | ||||
|      * Note that 'qn' is an alias for this method as it is in DatabaseDriver. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->quoteName('#__a'); | ||||
|      * $query->qn('#__a'); | ||||
|      * | ||||
|      * @param   array|string  $name  The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. | ||||
|      *                               Each type supports dot-notation name. | ||||
|      * @param   array|string  $as    The AS query part associated to $name. It can be string or array, in latter case it has to be | ||||
|      *                               same length of $name; if is null there will not be any AS part for string or array element. | ||||
|      * | ||||
|      * @return  array|string  The quote wrapped name, same type of $name. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException if the internal db property is not a valid object. | ||||
|      */ | ||||
|     public function quoteName($name, $as = null); | ||||
|  | ||||
|     /** | ||||
|      * Get the function to return a random floating-point value | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->rand(); | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rand(); | ||||
|  | ||||
|     /** | ||||
|      * Get the regular expression operator | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where('field ' . $query->regexp($search)); | ||||
|      * | ||||
|      * @param   string  $value  The regex pattern. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function regexp($value); | ||||
|  | ||||
|     /** | ||||
|      * Add a single column, or array of columns to the SELECT clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('a.*')->select('b.id'); | ||||
|      * $query->select(array('a.*', 'b.id')); | ||||
|      * | ||||
|      * @param   array|string  $columns  A string or an array of field names. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  QueryTypeAlreadyDefinedException if the query type has already been defined | ||||
|      */ | ||||
|     public function select($columns); | ||||
|  | ||||
|     /** | ||||
|      * Return the number of the current row. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('id'); | ||||
|      * $query->selectRowNumber('ordering,publish_up DESC', 'new_ordering'); | ||||
|      * $query->from('#__content'); | ||||
|      * | ||||
|      * @param   string  $orderBy           An expression of ordering for window function. | ||||
|      * @param   string  $orderColumnAlias  An alias for new ordering column. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function selectRowNumber($orderBy, $orderColumnAlias); | ||||
|  | ||||
|     /** | ||||
|      * Add a single condition string, or an array of strings to the SET clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->set('a = 1')->set('b = 2'); | ||||
|      * $query->set(array('a = 1', 'b = 2'); | ||||
|      * | ||||
|      * @param   array|string  $conditions  A string or array of string conditions. | ||||
|      * @param   string        $glue        The glue by which to join the condition strings. Defaults to `,`. | ||||
|      *                                     Note that the glue is set on first use and cannot be changed. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function set($conditions, $glue = ','); | ||||
|  | ||||
|     /** | ||||
|      * Add a table name to the UPDATE clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->update('#__foo')->set(...); | ||||
|      * | ||||
|      * @param   string  $table  A table to update. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  QueryTypeAlreadyDefinedException if the query type has already been defined | ||||
|      */ | ||||
|     public function update($table); | ||||
|  | ||||
|     /** | ||||
|      * Adds a tuple, or array of tuples that would be used as values for an INSERT INTO statement. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->values('1,2,3')->values('4,5,6'); | ||||
|      * $query->values(array('1,2,3', '4,5,6')); | ||||
|      * | ||||
|      * @param   array|string  $values  A single tuple, or array of tuples. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function values($values); | ||||
|  | ||||
|     /** | ||||
|      * Add a single condition, or an array of conditions to the WHERE clause of the query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where('a = 1')->where('b = 2'); | ||||
|      * $query->where(array('a = 1', 'b = 2')); | ||||
|      * | ||||
|      * @param   array|string  $conditions  A string or array of where conditions. | ||||
|      * @param   string        $glue        The glue by which to join the conditions. Defaults to AND. | ||||
|      *                                     Note that the glue is set on first use and cannot be changed. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function where($conditions, $glue = 'AND'); | ||||
|  | ||||
|     /** | ||||
|      * Add a WHERE IN statement to the query. | ||||
|      * | ||||
|      * Note that all values must be the same data type. | ||||
|      * | ||||
|      * Usage | ||||
|      * $query->whereIn('id', [1, 2, 3]); | ||||
|      * | ||||
|      * @param   string        $keyName    Key name for the where clause | ||||
|      * @param   array         $keyValues  Array of values to be matched | ||||
|      * @param   array|string  $dataType   Constant corresponding to a SQL datatype. It can be an array, in this case it | ||||
|      *                                    has to be same length of $keyValues | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since 2.0.0 | ||||
|      */ | ||||
|     public function whereIn(string $keyName, array $keyValues, $dataType = ParameterType::INTEGER); | ||||
|  | ||||
|     /** | ||||
|      * Add a WHERE NOT IN statement to the query. | ||||
|      * | ||||
|      * Note that all values must be the same data type. | ||||
|      * | ||||
|      * Usage | ||||
|      * $query->whereNotIn('id', [1, 2, 3]); | ||||
|      * | ||||
|      * @param   string        $keyName    Key name for the where clause | ||||
|      * @param   array         $keyValues  Array of values to be matched | ||||
|      * @param   array|string  $dataType   Constant corresponding to a SQL datatype. It can be an array, in this case it | ||||
|      *                                    has to be same length of $keyValues | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since 2.0.0 | ||||
|      */ | ||||
|     public function whereNotIn(string $keyName, array $keyValues, $dataType = ParameterType::INTEGER); | ||||
|  | ||||
|     /** | ||||
|      * Extend the WHERE clause with a single condition or an array of conditions, with a potentially different logical operator from the one in the | ||||
|      * current WHERE clause. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->where(array('a = 1', 'b = 2'))->extendWhere('XOR', array('c = 3', 'd = 4')); | ||||
|      * will produce: WHERE ((a = 1 AND b = 2) XOR (c = 3 AND d = 4) | ||||
|      * | ||||
|      * @param   string  $outerGlue   The glue by which to join the conditions to the current WHERE conditions. | ||||
|      * @param   mixed   $conditions  A string or array of WHERE conditions. | ||||
|      * @param   string  $innerGlue   The glue by which to join the conditions. Defaults to AND. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function extendWhere($outerGlue, $conditions, $innerGlue = 'AND'); | ||||
|  | ||||
|     /** | ||||
|      * Binds an array of values and returns an array of prepared parameter names. | ||||
|      * | ||||
|      * Note that all values must be the same data type. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->whereIn('column in (' . implode(',', $query->bindArray($keyValues, $dataType)) . ')'); | ||||
|      * | ||||
|      * @param   array         $values    Values to bind | ||||
|      * @param   array|string  $dataType  Constant corresponding to a SQL datatype. It can be an array, in this case it | ||||
|      *                                   has to be same length of $key | ||||
|      * | ||||
|      * @return  array   An array with parameter names | ||||
|      * | ||||
|      * @since 2.0.0 | ||||
|      */ | ||||
|     public function bindArray(array $values, $dataType = ParameterType::INTEGER); | ||||
|  | ||||
|     /** | ||||
|      * Add a query to UNION with the current query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->union('SELECT name FROM  #__foo') | ||||
|      * $query->union('SELECT name FROM  #__foo', true) | ||||
|      * | ||||
|      * @param   DatabaseQuery|string  $query     The DatabaseQuery object or string to union. | ||||
|      * @param   boolean               $distinct  True to only return distinct rows from the union. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function union($query, $distinct = true); | ||||
|  | ||||
|     /** | ||||
|      * Add a query to UNION ALL with the current query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->unionAll('SELECT name FROM  #__foo') | ||||
|      * | ||||
|      * @param   DatabaseQuery|string  $query  The DatabaseQuery object or string to union. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @see     union | ||||
|      * @since   1.5.0 | ||||
|      */ | ||||
|     public function unionAll($query); | ||||
|  | ||||
|     /** | ||||
|      * Set a single query to the query set. | ||||
|      * On this type of DatabaseQuery you can use union(), unionAll(), order() and setLimit() | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->querySet($query2->select('name')->from('#__foo')->order('id DESC')->setLimit(1)) | ||||
|      *       ->unionAll($query3->select('name')->from('#__foo')->order('id')->setLimit(1)) | ||||
|      *       ->order('name') | ||||
|      *       ->setLimit(1) | ||||
|      * | ||||
|      * @param   DatabaseQuery|string  $query  The DatabaseQuery object or string. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function querySet($query); | ||||
|  | ||||
|     /** | ||||
|      * Create a DatabaseQuery object of type querySet from current query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('name')->from('#__foo')->order('id DESC')->setLimit(1) | ||||
|      *       ->toQuerySet() | ||||
|      *       ->unionAll($query2->select('name')->from('#__foo')->order('id')->setLimit(1)) | ||||
|      *       ->order('name') | ||||
|      *       ->setLimit(1) | ||||
|      * | ||||
|      * @return  DatabaseQuery  A new object of the DatabaseQuery. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function toQuerySet(); | ||||
| } | ||||
							
								
								
									
										40
									
								
								libraries/vendor/joomla/database/src/QueryMonitorInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								libraries/vendor/joomla/database/src/QueryMonitorInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Interface defining a query monitor. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| interface QueryMonitorInterface | ||||
| { | ||||
|     /** | ||||
|      * Act on a query being started. | ||||
|      * | ||||
|      * @param   string         $sql          The SQL to be executed. | ||||
|      * @param   object[]|null  $boundParams  List of bound params, used with the query. | ||||
|      *                                       Each item is an object that holds: value, dataType | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function startQuery(string $sql, ?array $boundParams = null): void; | ||||
|  | ||||
|     /** | ||||
|      * Act on a query being stopped. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function stopQuery(): void; | ||||
| } | ||||
							
								
								
									
										55
									
								
								libraries/vendor/joomla/database/src/Service/DatabaseProvider.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								libraries/vendor/joomla/database/src/Service/DatabaseProvider.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Service; | ||||
|  | ||||
| use Joomla\Database\DatabaseDriver; | ||||
| use Joomla\Database\DatabaseFactory; | ||||
| use Joomla\Database\DatabaseInterface; | ||||
| use Joomla\DI\Container; | ||||
| use Joomla\DI\ServiceProviderInterface; | ||||
|  | ||||
| /** | ||||
|  * Database service provider | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class DatabaseProvider implements ServiceProviderInterface | ||||
| { | ||||
|     /** | ||||
|      * Registers the service provider with a DI container. | ||||
|      * | ||||
|      * @param   Container  $container  The DI container. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function register(Container $container) | ||||
|     { | ||||
|         $container->alias(DatabaseInterface::class, DatabaseDriver::class) | ||||
|             ->share( | ||||
|                 DatabaseDriver::class, | ||||
|                 function (Container $container) { | ||||
|                     /** @var \Joomla\Registry\Registry $config */ | ||||
|                     $config  = $container->get('config'); | ||||
|                     $options = (array) $config->get('database'); | ||||
|  | ||||
|                     return $container->get(DatabaseFactory::class)->getDriver($options['driver'], $options); | ||||
|                 } | ||||
|             ); | ||||
|  | ||||
|         $container->share( | ||||
|             DatabaseFactory::class, | ||||
|             function (Container $container) { | ||||
|                 return new DatabaseFactory(); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										29
									
								
								libraries/vendor/joomla/database/src/Sqlazure/SqlazureDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								libraries/vendor/joomla/database/src/Sqlazure/SqlazureDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Sqlazure; | ||||
|  | ||||
| use Joomla\Database\Sqlsrv\SqlsrvDriver; | ||||
|  | ||||
| /** | ||||
|  * SQL Azure Database Driver | ||||
|  * | ||||
|  * @link   https://msdn.microsoft.com/en-us/library/ee336279.aspx | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class SqlazureDriver extends SqlsrvDriver | ||||
| { | ||||
|     /** | ||||
|      * The name of the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $name = 'sqlazure'; | ||||
| } | ||||
							
								
								
									
										21
									
								
								libraries/vendor/joomla/database/src/Sqlazure/SqlazureQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								libraries/vendor/joomla/database/src/Sqlazure/SqlazureQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Sqlazure; | ||||
|  | ||||
| use Joomla\Database\Sqlsrv\SqlsrvQuery; | ||||
|  | ||||
| /** | ||||
|  * SQL Azure Query Building Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class SqlazureQuery extends SqlsrvQuery | ||||
| { | ||||
| } | ||||
							
								
								
									
										528
									
								
								libraries/vendor/joomla/database/src/Sqlite/SqliteDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										528
									
								
								libraries/vendor/joomla/database/src/Sqlite/SqliteDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,528 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Sqlite; | ||||
|  | ||||
| use Joomla\Database\Pdo\PdoDriver; | ||||
|  | ||||
| /** | ||||
|  * SQLite database driver supporting PDO based connections | ||||
|  * | ||||
|  * @link   https://www.php.net/manual/en/ref.pdo-sqlite.php | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class SqliteDriver extends PdoDriver | ||||
| { | ||||
|     /** | ||||
|      * The name of the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $name = 'sqlite'; | ||||
|  | ||||
|     /** | ||||
|      * The character(s) used to quote SQL statement names such as table names or field names, etc. | ||||
|      * | ||||
|      * If a single character string the same character is used for both sides of the quoted name, else the first character will be used for the | ||||
|      * opening quote and the second for the closing quote. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nameQuote = '`'; | ||||
|  | ||||
|     /** | ||||
|      * Destructor. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __destruct() | ||||
|     { | ||||
|         $this->disconnect(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Alter database's character set. | ||||
|      * | ||||
|      * @param   string  $dbName  The database name that will be altered | ||||
|      * | ||||
|      * @return  boolean|resource | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function alterDbCharacterSet($dbName) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Connects to the database if needed. | ||||
|      * | ||||
|      * @return  void  Returns void if the database connected successfully. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function connect() | ||||
|     { | ||||
|         if ($this->connection) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         parent::connect(); | ||||
|  | ||||
|         $this->connection->sqliteCreateFunction( | ||||
|             'ROW_NUMBER', | ||||
|             function ($init = null) { | ||||
|                 static $rownum, $partition; | ||||
|  | ||||
|                 if ($init !== null) { | ||||
|                     $rownum    = $init; | ||||
|                     $partition = null; | ||||
|  | ||||
|                     return $rownum; | ||||
|                 } | ||||
|  | ||||
|                 $args = \func_get_args(); | ||||
|                 array_shift($args); | ||||
|  | ||||
|                 $partitionBy = $args ? implode(',', $args) : null; | ||||
|  | ||||
|                 if ($partitionBy === null || $partitionBy === $partition) { | ||||
|                     $rownum++; | ||||
|                 } else { | ||||
|                     $rownum    = 1; | ||||
|                     $partition = $partitionBy; | ||||
|                 } | ||||
|  | ||||
|                 return $rownum; | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a new database using information from $options object. | ||||
|      * | ||||
|      * @param   \stdClass  $options  Object used to pass user and database name to database driver. This object must have "db_name" and "db_user" set. | ||||
|      * @param   boolean    $utf      True if the database supports the UTF-8 character set. | ||||
|      * | ||||
|      * @return  boolean|resource | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function createDatabase($options, $utf = true) | ||||
|     { | ||||
|         // SQLite doesn't have a query for this | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to escape a string for usage in an SQLite statement. | ||||
|      * | ||||
|      * Note: Using query objects with bound variables is preferable to the below. | ||||
|      * | ||||
|      * @param   string   $text   The string to be escaped. | ||||
|      * @param   boolean  $extra  Unused optional parameter to provide extra escaping. | ||||
|      * | ||||
|      * @return  string  The escaped string. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function escape($text, $extra = false) | ||||
|     { | ||||
|         if (\is_int($text)) { | ||||
|             return $text; | ||||
|         } | ||||
|  | ||||
|         if (\is_float($text)) { | ||||
|             // Force the dot as a decimal point. | ||||
|             return str_replace(',', '.', $text); | ||||
|         } | ||||
|  | ||||
|         return \SQLite3::escapeString($text); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database or boolean false if not supported. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getCollation() | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database connection collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database connection (string) or boolean false if not supported. | ||||
|      * | ||||
|      * @since   1.6.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getConnectionCollation() | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database encryption details (cipher and protocol) in use. | ||||
|      * | ||||
|      * @return  string  The database encryption details. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getConnectionEncryption(): string | ||||
|     { | ||||
|         // TODO: Not fake this | ||||
|         return ''; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to test if the database TLS connections encryption are supported. | ||||
|      * | ||||
|      * @return  boolean  Whether the database supports TLS connections encryption. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isConnectionEncryptionSupported(): bool | ||||
|     { | ||||
|         // TODO: Not fake this | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the table CREATE statement that creates the given tables. | ||||
|      * | ||||
|      * Note: Doesn't appear to have support in SQLite | ||||
|      * | ||||
|      * @param   mixed  $tables  A table name or a list of table names. | ||||
|      * | ||||
|      * @return  array  A list of the create SQL for the tables. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableCreate($tables) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Sanitize input to an array and iterate over the list. | ||||
|         $tables = (array) $tables; | ||||
|  | ||||
|         return $tables; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retrieves field information about a given table. | ||||
|      * | ||||
|      * @param   string   $table     The name of the database table. | ||||
|      * @param   boolean  $typeOnly  True to only return field types. | ||||
|      * | ||||
|      * @return  array  An array of fields for the database table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableColumns($table, $typeOnly = true) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $columns = []; | ||||
|  | ||||
|         $fieldCasing = $this->getOption(\PDO::ATTR_CASE); | ||||
|  | ||||
|         $this->setOption(\PDO::ATTR_CASE, \PDO::CASE_UPPER); | ||||
|  | ||||
|         $table = strtoupper($table); | ||||
|  | ||||
|         $fields = $this->setQuery('pragma table_info(' . $table . ')')->loadObjectList(); | ||||
|  | ||||
|         if ($typeOnly) { | ||||
|             foreach ($fields as $field) { | ||||
|                 $columns[$field->NAME] = $field->TYPE; | ||||
|             } | ||||
|         } else { | ||||
|             foreach ($fields as $field) { | ||||
|                 // Do some dirty translation to MySQL output. | ||||
|                 // TODO: Come up with and implement a standard across databases. | ||||
|                 $columns[$field->NAME] = (object) [ | ||||
|                     'Field'   => $field->NAME, | ||||
|                     'Type'    => $field->TYPE, | ||||
|                     'Null'    => $field->NOTNULL == '1' ? 'NO' : 'YES', | ||||
|                     'Default' => $field->DFLT_VALUE, | ||||
|                     'Key'     => $field->PK != '0' ? 'PRI' : '', | ||||
|                 ]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->setOption(\PDO::ATTR_CASE, $fieldCasing); | ||||
|  | ||||
|         return $columns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table. | ||||
|      * | ||||
|      * @return  array  An array of the column specification for the table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableKeys($table) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $keys = []; | ||||
|  | ||||
|         $fieldCasing = $this->getOption(\PDO::ATTR_CASE); | ||||
|  | ||||
|         $this->setOption(\PDO::ATTR_CASE, \PDO::CASE_UPPER); | ||||
|  | ||||
|         $table = strtoupper($table); | ||||
|  | ||||
|         $rows = $this->setQuery('pragma table_info( ' . $table . ')')->loadObjectList(); | ||||
|  | ||||
|         foreach ($rows as $column) { | ||||
|             if ($column->PK == 1) { | ||||
|                 $keys[$column->NAME] = $column; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->setOption(\PDO::ATTR_CASE, $fieldCasing); | ||||
|  | ||||
|         return $keys; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of all tables in the database (schema). | ||||
|      * | ||||
|      * @return  array   An array of all the tables in the database. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableList() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $type = 'table'; | ||||
|  | ||||
|         $query = $this->createQuery() | ||||
|             ->select('name') | ||||
|             ->from('sqlite_master') | ||||
|             ->where('type = :type') | ||||
|             ->bind(':type', $type) | ||||
|             ->order('name'); | ||||
|  | ||||
|         return $this->setQuery($query)->loadColumn(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the version of the database connector. | ||||
|      * | ||||
|      * @return  string  The database connector version. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getVersion() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->setQuery('SELECT sqlite_version()')->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Select a database for use. | ||||
|      * | ||||
|      * @param   string  $database  The name of the database to select for use. | ||||
|      * | ||||
|      * @return  boolean  True if the database was successfully selected. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function select($database) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the connection to use UTF-8 character encoding. | ||||
|      * | ||||
|      * Returns false automatically for the Oracle driver since | ||||
|      * you can only set the character set when the connection | ||||
|      * is created. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function setUtf() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Locks a table in the database. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table to unlock. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function lockTable($table) | ||||
|     { | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renames a table in the database. | ||||
|      * | ||||
|      * @param   string  $oldTable  The name of the table to be renamed | ||||
|      * @param   string  $newTable  The new name for the table. | ||||
|      * @param   string  $backup    Not used by Sqlite. | ||||
|      * @param   string  $prefix    Not used by Sqlite. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) | ||||
|     { | ||||
|         $this->setQuery('ALTER TABLE ' . $oldTable . ' RENAME TO ' . $newTable)->execute(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to truncate a table. | ||||
|      * | ||||
|      * @param   string  $table  The table to truncate | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.2.1 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function truncateTable($table) | ||||
|     { | ||||
|         $this->setQuery('DELETE FROM ' . $this->quoteName($table)) | ||||
|             ->execute(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Unlocks tables in the database. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function unlockTables() | ||||
|     { | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Test to see if the PDO ODBC connector is available. | ||||
|      * | ||||
|      * @return  boolean  True on success, false otherwise. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function isSupported() | ||||
|     { | ||||
|         return class_exists('\\PDO') && class_exists('\\SQLite3') && \in_array('sqlite', \PDO::getAvailableDrivers(), true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to commit a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, commit to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionCommit($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth <= 1) { | ||||
|             parent::transactionCommit($toSavepoint); | ||||
|         } else { | ||||
|             $this->transactionDepth--; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to roll back a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, rollback to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionRollback($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth <= 1) { | ||||
|             parent::transactionRollback($toSavepoint); | ||||
|         } else { | ||||
|             $savepoint = 'SP_' . ($this->transactionDepth - 1); | ||||
|             $this->setQuery('ROLLBACK TO ' . $this->quoteName($savepoint))->execute(); | ||||
|  | ||||
|             $this->transactionDepth--; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to initialize a transaction. | ||||
|      * | ||||
|      * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionStart($asSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$asSavepoint || !$this->transactionDepth) { | ||||
|             parent::transactionStart($asSavepoint); | ||||
|         } else { | ||||
|             $savepoint = 'SP_' . $this->transactionDepth; | ||||
|             $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint))->execute(); | ||||
|  | ||||
|             $this->transactionDepth++; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										269
									
								
								libraries/vendor/joomla/database/src/Sqlite/SqliteQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								libraries/vendor/joomla/database/src/Sqlite/SqliteQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,269 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Sqlite; | ||||
|  | ||||
| use Joomla\Database\DatabaseQuery; | ||||
| use Joomla\Database\Pdo\PdoQuery; | ||||
| use Joomla\Database\Query\QueryElement; | ||||
|  | ||||
| /** | ||||
|  * SQLite Query Building Class. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class SqliteQuery extends PdoQuery | ||||
| { | ||||
|     /** | ||||
|      * Magic function to convert the query to a string. | ||||
|      * | ||||
|      * @return  string  The completed query. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function __toString() | ||||
|     { | ||||
|         switch ($this->type) { | ||||
|             case 'select': | ||||
|                 if ($this->selectRowNumber) { | ||||
|                     $orderBy          = $this->selectRowNumber['orderBy']; | ||||
|                     $orderColumnAlias = $this->selectRowNumber['orderColumnAlias']; | ||||
|  | ||||
|                     $column = "ROW_NUMBER() AS $orderColumnAlias"; | ||||
|  | ||||
|                     if ($this->select === null) { | ||||
|                         $query = PHP_EOL . 'SELECT 1' | ||||
|                             . (string) $this->from | ||||
|                             . (string) $this->where; | ||||
|                     } else { | ||||
|                         $tmpOffset    = $this->offset; | ||||
|                         $tmpLimit     = $this->limit; | ||||
|                         $this->offset = 0; | ||||
|                         $this->limit  = 0; | ||||
|                         $tmpOrder     = $this->order; | ||||
|                         $this->order  = null; | ||||
|                         $query        = parent::__toString(); | ||||
|                         $column       = "w.*, $column"; | ||||
|                         $this->order  = $tmpOrder; | ||||
|                         $this->offset = $tmpOffset; | ||||
|                         $this->limit  = $tmpLimit; | ||||
|                     } | ||||
|  | ||||
|                     // Special sqlite query to count ROW_NUMBER | ||||
|                     $query = PHP_EOL . "SELECT $column" | ||||
|                         . PHP_EOL . "FROM ($query" . PHP_EOL . "ORDER BY $orderBy" | ||||
|                         . PHP_EOL . ') AS w,(SELECT ROW_NUMBER(0)) AS r' | ||||
|                         // Forbid to flatten subqueries. | ||||
|                         . ((string) $this->order ?: PHP_EOL . 'ORDER BY NULL'); | ||||
|  | ||||
|                     return $this->processLimit($query, $this->limit, $this->offset); | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case 'querySet': | ||||
|                 $query = $this->querySet; | ||||
|  | ||||
|                 if ($query->order || $query->limit || $query->offset) { | ||||
|                     // If ORDER BY or LIMIT statement exist then parentheses is required for the first query | ||||
|                     $query = PHP_EOL . "SELECT * FROM ($query)"; | ||||
|                 } | ||||
|  | ||||
|                 if ($this->merge) { | ||||
|                     // Special case for merge | ||||
|                     foreach ($this->merge as $element) { | ||||
|                         $query .= (string) $element; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($this->order) { | ||||
|                     $query .= (string) $this->order; | ||||
|                 } | ||||
|  | ||||
|                 return $query; | ||||
|  | ||||
|             case 'update': | ||||
|                 if ($this->join) { | ||||
|                     $table = $this->update->getElements(); | ||||
|                     $table = $table[0]; | ||||
|  | ||||
|                     $tableName = explode(' ', $table); | ||||
|                     $tableName = $tableName[0]; | ||||
|  | ||||
|                     if ($this->columns === null) { | ||||
|                         $fields = $this->db->getTableColumns($tableName); | ||||
|  | ||||
|                         foreach ($fields as $key => $value) { | ||||
|                             $fields[$key] = $key; | ||||
|                         } | ||||
|  | ||||
|                         $this->columns = new QueryElement('()', $fields); | ||||
|                     } | ||||
|  | ||||
|                     $fields   = $this->columns->getElements(); | ||||
|                     $elements = $this->set->getElements(); | ||||
|  | ||||
|                     foreach ($elements as $nameValue) { | ||||
|                         $setArray = explode(' = ', $nameValue, 2); | ||||
|  | ||||
|                         if ($setArray[0][0] === '`') { | ||||
|                             // Unquote column name | ||||
|                             $setArray[0] = substr($setArray[0], 1, -1); | ||||
|                         } | ||||
|  | ||||
|                         $fields[$setArray[0]] = $setArray[1]; | ||||
|                     } | ||||
|  | ||||
|                     $select = new static($this->db); | ||||
|                     $select->select(array_values($fields)) | ||||
|                         ->from($table); | ||||
|  | ||||
|                     $select->join  = $this->join; | ||||
|                     $select->where = $this->where; | ||||
|  | ||||
|                     return 'INSERT OR REPLACE INTO ' . $tableName | ||||
|                         . ' (' . implode(',', array_keys($fields)) . ')' | ||||
|                         . (string) $select; | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|         return parent::__toString(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the number of characters in a string. | ||||
|      * | ||||
|      * Note, use 'length' to find the number of bytes in a string. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->charLength('a')); | ||||
|      * | ||||
|      * @param   string       $field      A value. | ||||
|      * @param   string|null  $operator   Comparison operator between charLength integer value and $condition | ||||
|      * @param   string|null  $condition  Integer value to compare charLength with. | ||||
|      * | ||||
|      * @return  string  The required char length call. | ||||
|      * | ||||
|      * @since   1.1.0 | ||||
|      */ | ||||
|     public function charLength($field, $operator = null, $condition = null) | ||||
|     { | ||||
|         $statement = 'length(' . $field . ')'; | ||||
|  | ||||
|         if ($operator !== null && $condition !== null) { | ||||
|             $statement .= ' ' . $operator . ' ' . $condition; | ||||
|         } | ||||
|  | ||||
|         return $statement; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Concatenates an array of column names or values. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select($query->concatenate(array('a', 'b'))); | ||||
|      * | ||||
|      * @param   string[]     $values     An array of values to concatenate. | ||||
|      * @param   string|null  $separator  As separator to place between each value. | ||||
|      * | ||||
|      * @return  string  The concatenated values. | ||||
|      * | ||||
|      * @since   1.1.0 | ||||
|      */ | ||||
|     public function concatenate($values, $separator = null) | ||||
|     { | ||||
|         if ($separator !== null) { | ||||
|             return implode(' || ' . $this->quote($separator) . ' || ', $values); | ||||
|         } | ||||
|  | ||||
|         return implode(' || ', $values); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to modify a query already in string format with the needed additions to make the query limited to a particular number of | ||||
|      * results, or start at a particular offset. | ||||
|      * | ||||
|      * @param   string   $query   The query in string format | ||||
|      * @param   integer  $limit   The limit for the result set | ||||
|      * @param   integer  $offset  The offset for the result set | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function processLimit($query, $limit, $offset = 0) | ||||
|     { | ||||
|         if ($limit > 0 || $offset > 0) { | ||||
|             $query .= ' LIMIT ' . $offset . ', ' . $limit; | ||||
|         } | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Return the number of the current row. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->select('id'); | ||||
|      * $query->selectRowNumber('ordering,publish_up DESC', 'new_ordering'); | ||||
|      * $query->from('#__content'); | ||||
|      * | ||||
|      * @param   string  $orderBy           An expression of ordering for window function. | ||||
|      * @param   string  $orderColumnAlias  An alias for new ordering column. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function selectRowNumber($orderBy, $orderColumnAlias) | ||||
|     { | ||||
|         $this->validateRowNumber($orderBy, $orderColumnAlias); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add a query to UNION with the current query. | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->union('SELECT name FROM  #__foo') | ||||
|      * $query->union('SELECT name FROM  #__foo', true) | ||||
|      * | ||||
|      * @param   DatabaseQuery|string  $query     The DatabaseQuery object or string to union. | ||||
|      * @param   boolean               $distinct  True to only return distinct rows from the union. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function union($query, $distinct = true) | ||||
|     { | ||||
|         // Set up the name with parentheses, the DISTINCT flag is redundant | ||||
|         return $this->merge($distinct ? 'UNION SELECT * FROM ()' : 'UNION ALL SELECT * FROM ()', $query); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Aggregate function to get input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * Usage: | ||||
|      * $query->groupConcat('id', ','); | ||||
|      * | ||||
|      * @param   string  $expression  The expression to apply concatenation to, this may be a column name or complex SQL statement. | ||||
|      * @param   string  $separator   The delimiter of each concatenated value | ||||
|      * | ||||
|      * @return  string  Input values concatenated into a string, separated by delimiter | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function groupConcat($expression, $separator = ',') | ||||
|     { | ||||
|         return 'group_concat(' . $expression . ', ' . $this->quote($separator) . ')'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										933
									
								
								libraries/vendor/joomla/database/src/Sqlsrv/SqlsrvDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										933
									
								
								libraries/vendor/joomla/database/src/Sqlsrv/SqlsrvDriver.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,933 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Sqlsrv; | ||||
|  | ||||
| use Joomla\Database\DatabaseDriver; | ||||
| use Joomla\Database\DatabaseEvents; | ||||
| use Joomla\Database\Event\ConnectionEvent; | ||||
| use Joomla\Database\Exception\ConnectionFailureException; | ||||
| use Joomla\Database\Exception\ExecutionFailureException; | ||||
| use Joomla\Database\Exception\PrepareStatementFailureException; | ||||
| use Joomla\Database\Exception\UnsupportedAdapterException; | ||||
| use Joomla\Database\StatementInterface; | ||||
|  | ||||
| /** | ||||
|  * SQL Server Database Driver | ||||
|  * | ||||
|  * @link   https://www.php.net/manual/en/book.sqlsrv.php | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class SqlsrvDriver extends DatabaseDriver | ||||
| { | ||||
|     /** | ||||
|      * The name of the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $name = 'sqlsrv'; | ||||
|  | ||||
|     /** | ||||
|      * The character(s) used to quote SQL statement names such as table names or field names, etc. | ||||
|      * | ||||
|      * If a single character string the same character is used for both sides of the quoted name, else the first character will be used for the | ||||
|      * opening quote and the second for the closing quote. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nameQuote = '[]'; | ||||
|  | ||||
|     /** | ||||
|      * The null or zero representation of a timestamp for the database driver. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $nullDate = '1900-01-01 00:00:00'; | ||||
|  | ||||
|     /** | ||||
|      * The minimum supported database version. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected static $dbMinimum = '11.0.2100.60'; | ||||
|  | ||||
|     /** | ||||
|      * Test to see if the SQLSRV connector is available. | ||||
|      * | ||||
|      * @return  boolean  True on success, false otherwise. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function isSupported() | ||||
|     { | ||||
|         return \function_exists('sqlsrv_connect'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array  $options  List of options used to configure the connection | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function __construct(array $options) | ||||
|     { | ||||
|         // Get some basic values from the options. | ||||
|         $options['host']     = $options['host'] ?? 'localhost'; | ||||
|         $options['user']     = $options['user'] ?? ''; | ||||
|         $options['password'] = $options['password'] ?? ''; | ||||
|         $options['database'] = $options['database'] ?? ''; | ||||
|         $options['select']   = isset($options['select']) ? (bool) $options['select'] : true; | ||||
|         $options['encrypt']  = isset($options['encrypt']) ? (bool) $options['encrypt'] : true; | ||||
|  | ||||
|         // Finalize initialisation | ||||
|         parent::__construct($options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Connects to the database if needed. | ||||
|      * | ||||
|      * @return  void  Returns void if the database connected successfully. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function connect() | ||||
|     { | ||||
|         if ($this->connection) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Make sure the SQLSRV extension for PHP is installed and enabled. | ||||
|         if (!static::isSupported()) { | ||||
|             throw new UnsupportedAdapterException('PHP extension sqlsrv_connect is not available.'); | ||||
|         } | ||||
|  | ||||
|         // Build the connection configuration array. | ||||
|         $config = [ | ||||
|             'Database'             => $this->options['database'], | ||||
|             'uid'                  => $this->options['user'], | ||||
|             'pwd'                  => $this->options['password'], | ||||
|             'CharacterSet'         => 'UTF-8', | ||||
|             'ReturnDatesAsStrings' => true, | ||||
|             'Encrypt'              => $this->options['encrypt'], | ||||
|         ]; | ||||
|  | ||||
|         // Attempt to connect to the server. | ||||
|         if (!($this->connection = @ sqlsrv_connect($this->options['host'], $config))) { | ||||
|             throw new ConnectionFailureException('Could not connect to SQL Server'); | ||||
|         } | ||||
|  | ||||
|         // Make sure that DB warnings are not returned as errors. | ||||
|         sqlsrv_configure('WarningsReturnAsErrors', 0); | ||||
|  | ||||
|         // If auto-select is enabled select the given database. | ||||
|         if ($this->options['select'] && !empty($this->options['database'])) { | ||||
|             $this->select($this->options['database']); | ||||
|         } | ||||
|  | ||||
|         $this->dispatchEvent(new ConnectionEvent(DatabaseEvents::POST_CONNECT, $this)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Disconnects the database. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function disconnect() | ||||
|     { | ||||
|         // Close the connection. | ||||
|         if (\is_resource($this->connection)) { | ||||
|             sqlsrv_close($this->connection); | ||||
|         } | ||||
|  | ||||
|         parent::disconnect(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get table constraints | ||||
|      * | ||||
|      * @param   string  $tableName  The name of the database table. | ||||
|      * | ||||
|      * @return  array  Any constraints available for the table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function getTableConstraints($tableName) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return $this->setQuery('SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = ' . $this->quote($tableName)) | ||||
|             ->loadColumn(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Rename constraints. | ||||
|      * | ||||
|      * @param   array   $constraints  Array(strings) of table constraints | ||||
|      * @param   string  $prefix       A string | ||||
|      * @param   string  $backup       A string | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function renameConstraints($constraints = [], $prefix = null, $backup = null) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         foreach ($constraints as $constraint) { | ||||
|             $this->setQuery('sp_rename ' . $constraint . ',' . str_replace($prefix, $backup, $constraint)) | ||||
|                 ->execute(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to escape a string for usage in an SQL statement. | ||||
|      * | ||||
|      * The escaping for MSSQL isn't handled in the driver though that would be nice.  Because of this we need to handle the escaping ourselves. | ||||
|      * | ||||
|      * @param   string   $text   The string to be escaped. | ||||
|      * @param   boolean  $extra  Optional parameter to provide extra escaping. | ||||
|      * | ||||
|      * @return  string  The escaped string. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function escape($text, $extra = false) | ||||
|     { | ||||
|         if (\is_int($text)) { | ||||
|             return $text; | ||||
|         } | ||||
|  | ||||
|         if (\is_float($text)) { | ||||
|             // Force the dot as a decimal point. | ||||
|             return str_replace(',', '.', $text); | ||||
|         } | ||||
|  | ||||
|         $result = str_replace("'", "''", $text); | ||||
|  | ||||
|         // SQL Server does not accept NULL byte in query string | ||||
|         $result = str_replace("\0", "' + CHAR(0) + N'", $result); | ||||
|  | ||||
|         // Fix for SQL Sever escape sequence, see https://support.microsoft.com/en-us/kb/164291 | ||||
|         $result = str_replace( | ||||
|             ["\\\n",     "\\\r",     "\\\\\r\r\n"], | ||||
|             ["\\\\\n\n", "\\\\\r\r", "\\\\\r\n\r\n"], | ||||
|             $result | ||||
|         ); | ||||
|  | ||||
|         if ($extra) { | ||||
|             // Escape special chars | ||||
|             $result = str_replace( | ||||
|                 ['[',   '_',   '%'], | ||||
|                 ['[[]', '[_]', '[%]'], | ||||
|                 $result | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Quotes and optionally escapes a string to database requirements for use in database queries. | ||||
|      * | ||||
|      * @param   mixed    $text    A string or an array of strings to quote. | ||||
|      * @param   boolean  $escape  True (default) to escape the string, false to leave it unchanged. | ||||
|      * | ||||
|      * @return  string  The quoted input string. | ||||
|      * | ||||
|      * @since   1.6.0 | ||||
|      */ | ||||
|     public function quote($text, $escape = true) | ||||
|     { | ||||
|         if (\is_array($text)) { | ||||
|             return parent::quote($text, $escape); | ||||
|         } | ||||
|  | ||||
|         // To support unicode on MSSQL we have to add prefix N | ||||
|         return 'N\'' . ($escape ? $this->escape($text) : $text) . '\''; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Quotes a binary string to database requirements for use in database queries. | ||||
|      * | ||||
|      * @param   string  $data  A binary string to quote. | ||||
|      * | ||||
|      * @return  string  The binary quoted input string. | ||||
|      * | ||||
|      * @since   1.7.0 | ||||
|      */ | ||||
|     public function quoteBinary($data) | ||||
|     { | ||||
|         // ODBC syntax for hexadecimal literals | ||||
|         return '0x' . bin2hex($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Determines if the connection to the server is active. | ||||
|      * | ||||
|      * @return  boolean  True if connected to the database engine. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function connected() | ||||
|     { | ||||
|         // TODO: Run a blank query here | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Drops a table from the database. | ||||
|      * | ||||
|      * @param   string   $table     The name of the database table to drop. | ||||
|      * @param   boolean  $ifExists  Optionally specify that the table must exist before it is dropped. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function dropTable($table, $ifExists = true) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if ($ifExists) { | ||||
|             $this->setQuery( | ||||
|                 'IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ' | ||||
|                     . $this->quote($table) . ') DROP TABLE ' . $table | ||||
|             ); | ||||
|         } else { | ||||
|             $this->setQuery('DROP TABLE ' . $table); | ||||
|         } | ||||
|  | ||||
|         $this->execute(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database or boolean false if not supported. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getCollation() | ||||
|     { | ||||
|         // TODO: Not fake this | ||||
|         return 'MSSQL UTF-8 (UCS2)'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database connection collation in use by sampling a text field of a table in the database. | ||||
|      * | ||||
|      * @return  string|boolean  The collation in use by the database connection (string) or boolean false if not supported. | ||||
|      * | ||||
|      * @since   1.6.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getConnectionCollation() | ||||
|     { | ||||
|         // TODO: Not fake this | ||||
|         return 'MSSQL UTF-8 (UCS2)'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the database encryption details (cipher and protocol) in use. | ||||
|      * | ||||
|      * @return  string  The database encryption details. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getConnectionEncryption(): string | ||||
|     { | ||||
|         // TODO: Not fake this | ||||
|         return ''; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to test if the database TLS connections encryption are supported. | ||||
|      * | ||||
|      * @return  boolean  Whether the database supports TLS connections encryption. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function isConnectionEncryptionSupported(): bool | ||||
|     { | ||||
|         // TODO: Not fake this | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retrieves field information about the given tables. | ||||
|      * | ||||
|      * @param   mixed    $table     A table name | ||||
|      * @param   boolean  $typeOnly  True to only return field types. | ||||
|      * | ||||
|      * @return  array  An array of fields. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableColumns($table, $typeOnly = true) | ||||
|     { | ||||
|         $result = []; | ||||
|  | ||||
|         $table_temp = $this->replacePrefix((string) $table); | ||||
|  | ||||
|         // Set the query to get the table fields statement. | ||||
|         $this->setQuery( | ||||
|             'SELECT column_name as Field, data_type as Type, is_nullable as \'Null\', column_default as \'Default\'' . | ||||
|             ' FROM information_schema.columns WHERE table_name = ' . $this->quote($table_temp) | ||||
|         ); | ||||
|         $fields = $this->loadObjectList(); | ||||
|  | ||||
|         // If we only want the type as the value add just that to the list. | ||||
|         if ($typeOnly) { | ||||
|             foreach ($fields as $field) { | ||||
|                 $result[$field->Field] = preg_replace('/[(0-9)]/', '', $field->Type); | ||||
|             } | ||||
|         } else { | ||||
|             // If we want the whole field data object add that to the list. | ||||
|             foreach ($fields as $field) { | ||||
|                 $field->Default        = preg_replace("/(^(\(\(|\('|\(N'|\()|(('\)|(?<!\()\)\)|\))$))/i", '', $field->Default); | ||||
|                 $result[$field->Field] = $field; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the table CREATE statement that creates the given tables. | ||||
|      * | ||||
|      * This is unsupported by MSSQL. | ||||
|      * | ||||
|      * @param   mixed  $tables  A table name or a list of table names. | ||||
|      * | ||||
|      * @return  array  A list of the create SQL for the tables. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableCreate($tables) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         return []; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the details list of keys for a table. | ||||
|      * | ||||
|      * @param   string  $table  The name of the table. | ||||
|      * | ||||
|      * @return  array  An array of the column specification for the table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableKeys($table) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // TODO To implement. | ||||
|         return []; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get an array of all tables in the database. | ||||
|      * | ||||
|      * @return  array  An array of all the tables in the database. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function getTableList() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Set the query to get the tables statement. | ||||
|         return $this->setQuery('SELECT name FROM ' . $this->getDatabase() . '.sys.Tables WHERE type = \'U\';')->loadColumn(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the version of the database connector. | ||||
|      * | ||||
|      * @return  string  The database connector version. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getVersion() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $version = sqlsrv_server_info($this->connection); | ||||
|  | ||||
|         return $version['SQLServerVersion']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Inserts a row into a table based on an object's properties. | ||||
|      * | ||||
|      * @param   string  $table   The name of the database table to insert into. | ||||
|      * @param   object  $object  A reference to an object whose public properties match the table fields. | ||||
|      * @param   string  $key     The name of the primary key. If provided the object property is updated. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function insertObject($table, &$object, $key = null) | ||||
|     { | ||||
|         $fields       = []; | ||||
|         $values       = []; | ||||
|         $tableColumns = $this->getTableColumns($table); | ||||
|         $statement    = 'INSERT INTO ' . $this->quoteName($table) . ' (%s) VALUES (%s)'; | ||||
|  | ||||
|         foreach (get_object_vars($object) as $k => $v) { | ||||
|             // Skip columns that don't exist in the table. | ||||
|             if (!\array_key_exists($k, $tableColumns)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Only process non-null scalars. | ||||
|             if (\is_array($v) || \is_object($v) || $v === null) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (!$this->checkFieldExists($table, $k)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if ($k[0] === '_') { | ||||
|                 // Internal field | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if ($k === $key && $key == 0) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $fields[] = $this->quoteName($k); | ||||
|             $values[] = $this->quote($v); | ||||
|         } | ||||
|  | ||||
|         // Set the query and execute the insert. | ||||
|         $this->setQuery(sprintf($statement, implode(',', $fields), implode(',', $values)))->execute(); | ||||
|  | ||||
|         $id = $this->insertid(); | ||||
|  | ||||
|         if ($key && $id) { | ||||
|             $object->$key = $id; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the auto-incremented value from the last INSERT statement. | ||||
|      * | ||||
|      * @return  integer  The value of the auto-increment field from the last inserted row. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function insertid() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // TODO: SELECT IDENTITY | ||||
|         $this->setQuery('SELECT @@IDENTITY'); | ||||
|  | ||||
|         return (int) $this->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the SQL statement. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function execute() | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         // Take a local copy so that we don't modify the original query and cause issues later | ||||
|         $sql = $this->replacePrefix((string) $this->sql); | ||||
|  | ||||
|         // Increment the query counter. | ||||
|         $this->count++; | ||||
|  | ||||
|         // Get list of bounded parameters | ||||
|         $bounded =& $this->sql->getBounded(); | ||||
|  | ||||
|         // If there is a monitor registered, let it know we are starting this query | ||||
|         if ($this->monitor) { | ||||
|             $this->monitor->startQuery($sql, $bounded); | ||||
|         } | ||||
|  | ||||
|         // Execute the query. | ||||
|         $this->executed = false; | ||||
|  | ||||
|         // Bind the variables | ||||
|         foreach ($bounded as $key => $obj) { | ||||
|             $this->statement->bindParam($key, $obj->value, $obj->dataType); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             $this->executed = $this->statement->execute(); | ||||
|  | ||||
|             // If there is a monitor registered, let it know we have finished this query | ||||
|             if ($this->monitor) { | ||||
|                 $this->monitor->stopQuery(); | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } catch (ExecutionFailureException $exception) { | ||||
|             // If there is a monitor registered, let it know we have finished this query | ||||
|             if ($this->monitor) { | ||||
|                 $this->monitor->stopQuery(); | ||||
|             } | ||||
|  | ||||
|             // Check if the server was disconnected. | ||||
|             if (!$this->connected()) { | ||||
|                 try { | ||||
|                     // Attempt to reconnect. | ||||
|                     $this->connection = null; | ||||
|                     $this->connect(); | ||||
|                 } catch (ConnectionFailureException $e) { | ||||
|                     // If connect fails, ignore that exception and throw the normal exception. | ||||
|                     throw $exception; | ||||
|                 } | ||||
|  | ||||
|                 // Since we were able to reconnect, run the query again. | ||||
|                 return $this->execute(); | ||||
|             } | ||||
|  | ||||
|             // Throw the normal query exception. | ||||
|             throw $exception; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This function replaces a string identifier with the configured table prefix. | ||||
|      * | ||||
|      * @param   string  $sql     The SQL statement to prepare. | ||||
|      * @param   string  $prefix  The table prefix. | ||||
|      * | ||||
|      * @return  string  The processed SQL statement. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function replacePrefix($sql, $prefix = '#__') | ||||
|     { | ||||
|         $escaped   = false; | ||||
|         $startPos  = 0; | ||||
|         $quoteChar = ''; | ||||
|         $literal   = ''; | ||||
|  | ||||
|         $sql = trim($sql); | ||||
|         $n   = \strlen($sql); | ||||
|  | ||||
|         while ($startPos < $n) { | ||||
|             $ip = strpos($sql, $prefix, $startPos); | ||||
|  | ||||
|             if ($ip === false) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $j = strpos($sql, "N'", $startPos); | ||||
|             $k = strpos($sql, '"', $startPos); | ||||
|  | ||||
|             if (($k !== false) && (($k < $j) || ($j === false))) { | ||||
|                 $quoteChar = '"'; | ||||
|                 $j         = $k; | ||||
|             } else { | ||||
|                 $quoteChar = "'"; | ||||
|             } | ||||
|  | ||||
|             if ($j === false) { | ||||
|                 $j = $n; | ||||
|             } | ||||
|  | ||||
|             $literal .= str_replace($prefix, $this->tablePrefix, substr($sql, $startPos, $j - $startPos)); | ||||
|             $startPos = $j; | ||||
|  | ||||
|             $j = $startPos + 1; | ||||
|  | ||||
|             if ($j >= $n) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             // Quote comes first, find end of quote | ||||
|             while (true) { | ||||
|                 $k       = strpos($sql, $quoteChar, $j); | ||||
|                 $escaped = false; | ||||
|  | ||||
|                 if ($k === false) { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 $l = $k - 1; | ||||
|  | ||||
|                 while ($l >= 0 && $sql[$l] === '\\') { | ||||
|                     $l--; | ||||
|                     $escaped = !$escaped; | ||||
|                 } | ||||
|  | ||||
|                 if ($escaped) { | ||||
|                     $j = $k + 1; | ||||
|  | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             if ($k === false) { | ||||
|                 // Error in the query - no end quote; ignore it | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $literal .= substr($sql, $startPos, $k - $startPos + 1); | ||||
|             $startPos = $k + 1; | ||||
|         } | ||||
|  | ||||
|         if ($startPos < $n) { | ||||
|             $literal .= substr($sql, $startPos, $n - $startPos); | ||||
|         } | ||||
|  | ||||
|         return $literal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Select a database for use. | ||||
|      * | ||||
|      * @param   string  $database  The name of the database to select for use. | ||||
|      * | ||||
|      * @return  boolean  True if the database was successfully selected. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  ConnectionFailureException | ||||
|      */ | ||||
|     public function select($database) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$database) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!sqlsrv_query($this->connection, 'USE [' . $database . ']', null, ['scrollable' => \SQLSRV_CURSOR_STATIC])) { | ||||
|             throw new ConnectionFailureException('Could not connect to database'); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the connection to use UTF-8 character encoding. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function setUtf() | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to commit a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, commit to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionCommit($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth <= 1) { | ||||
|             $this->setQuery('COMMIT TRANSACTION')->execute(); | ||||
|  | ||||
|             $this->transactionDepth = 0; | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->transactionDepth--; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to roll back a transaction. | ||||
|      * | ||||
|      * @param   boolean  $toSavepoint  If true, rollback to the last savepoint. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionRollback($toSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$toSavepoint || $this->transactionDepth <= 1) { | ||||
|             $this->setQuery('ROLLBACK TRANSACTION')->execute(); | ||||
|  | ||||
|             $this->transactionDepth = 0; | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $savepoint = 'SP_' . ($this->transactionDepth - 1); | ||||
|         $this->setQuery('ROLLBACK TRANSACTION ' . $this->quoteName($savepoint))->execute(); | ||||
|  | ||||
|         $this->transactionDepth--; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to initialize a transaction. | ||||
|      * | ||||
|      * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function transactionStart($asSavepoint = false) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         if (!$asSavepoint || !$this->transactionDepth) { | ||||
|             $this->setQuery('BEGIN TRANSACTION')->execute(); | ||||
|  | ||||
|             $this->transactionDepth = 1; | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $savepoint = 'SP_' . $this->transactionDepth; | ||||
|         $this->setQuery('BEGIN TRANSACTION ' . $this->quoteName($savepoint))->execute(); | ||||
|  | ||||
|         $this->transactionDepth++; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to check and see if a field exists in a table. | ||||
|      * | ||||
|      * @param   string  $table  The table in which to verify the field. | ||||
|      * @param   string  $field  The field to verify. | ||||
|      * | ||||
|      * @return  boolean  True if the field exists in the table. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function checkFieldExists($table, $field) | ||||
|     { | ||||
|         $this->connect(); | ||||
|  | ||||
|         $table = $this->replacePrefix((string) $table); | ||||
|         $this->setQuery( | ||||
|             "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field' ORDER BY ORDINAL_POSITION" | ||||
|         ); | ||||
|  | ||||
|         return (bool) $this->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prepares a SQL statement for execution | ||||
|      * | ||||
|      * @param   string  $query  The SQL query to be prepared. | ||||
|      * | ||||
|      * @return  StatementInterface | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  PrepareStatementFailureException | ||||
|      */ | ||||
|     protected function prepareStatement(string $query): StatementInterface | ||||
|     { | ||||
|         return new SqlsrvStatement($this->connection, $query); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renames a table in the database. | ||||
|      * | ||||
|      * @param   string  $oldTable  The name of the table to be renamed | ||||
|      * @param   string  $newTable  The new name for the table. | ||||
|      * @param   string  $backup    Table prefix | ||||
|      * @param   string  $prefix    For the table - used to rename constraints in non-mysql databases | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) | ||||
|     { | ||||
|         $constraints = []; | ||||
|  | ||||
|         if ($prefix !== null && $backup !== null) { | ||||
|             $constraints = $this->getTableConstraints($oldTable); | ||||
|         } | ||||
|  | ||||
|         if (!empty($constraints)) { | ||||
|             $this->renameConstraints($constraints, $prefix, $backup); | ||||
|         } | ||||
|  | ||||
|         $this->setQuery("sp_rename '" . $oldTable . "', '" . $newTable . "'"); | ||||
|  | ||||
|         $this->execute(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Locks a table in the database. | ||||
|      * | ||||
|      * @param   string  $tableName  The name of the table to lock. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function lockTable($tableName) | ||||
|     { | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Unlocks tables in the database. | ||||
|      * | ||||
|      * @return  $this | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     public function unlockTables() | ||||
|     { | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										1078
									
								
								libraries/vendor/joomla/database/src/Sqlsrv/SqlsrvQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1078
									
								
								libraries/vendor/joomla/database/src/Sqlsrv/SqlsrvQuery.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										554
									
								
								libraries/vendor/joomla/database/src/Sqlsrv/SqlsrvStatement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										554
									
								
								libraries/vendor/joomla/database/src/Sqlsrv/SqlsrvStatement.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,554 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database\Sqlsrv; | ||||
|  | ||||
| use Joomla\Database\Exception\ExecutionFailureException; | ||||
| use Joomla\Database\Exception\PrepareStatementFailureException; | ||||
| use Joomla\Database\FetchMode; | ||||
| use Joomla\Database\FetchOrientation; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Database\StatementInterface; | ||||
|  | ||||
| /** | ||||
|  * SQL Server Database Statement. | ||||
|  * | ||||
|  * This class is modeled on \Doctrine\DBAL\Driver\SQLSrv\SQLSrvStatement | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| class SqlsrvStatement implements StatementInterface | ||||
| { | ||||
|     /** | ||||
|      * The database connection resource. | ||||
|      * | ||||
|      * @var    resource | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $connection; | ||||
|  | ||||
|     /** | ||||
|      * The default fetch mode for the statement. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $defaultFetchStyle = FetchMode::MIXED; | ||||
|  | ||||
|     /** | ||||
|      * The default class to use for building object result sets. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $defaultObjectClass = \stdClass::class; | ||||
|  | ||||
|     /** | ||||
|      * Mapping array converting fetch modes to the native engine type. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $fetchMap = [ | ||||
|         FetchMode::MIXED       => SQLSRV_FETCH_BOTH, | ||||
|         FetchMode::ASSOCIATIVE => SQLSRV_FETCH_ASSOC, | ||||
|         FetchMode::NUMERIC     => SQLSRV_FETCH_NUMERIC, | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * The query string being prepared. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $query; | ||||
|  | ||||
|     /** | ||||
|      * Internal tracking flag to set whether there is a result set available for processing | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $result = false; | ||||
|  | ||||
|     /** | ||||
|      * The prepared statement. | ||||
|      * | ||||
|      * @var    resource | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $statement; | ||||
|  | ||||
|     /** | ||||
|      * Bound parameter types. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $typesKeyMapping; | ||||
|  | ||||
|     /** | ||||
|      * References to the variables bound as statement parameters. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     private $bindedValues = []; | ||||
|  | ||||
|     /** | ||||
|      * Mapping between named parameters and position in query. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $parameterKeyMapping; | ||||
|  | ||||
|     /** | ||||
|      * Mapping array for parameter types. | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  2.0.0 | ||||
|      */ | ||||
|     protected $parameterTypeMapping = [ | ||||
|         ParameterType::BOOLEAN      => ParameterType::BOOLEAN, | ||||
|         ParameterType::INTEGER      => ParameterType::INTEGER, | ||||
|         ParameterType::LARGE_OBJECT => ParameterType::LARGE_OBJECT, | ||||
|         ParameterType::NULL         => ParameterType::NULL, | ||||
|         ParameterType::STRING       => ParameterType::STRING, | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   resource  $connection  The database connection resource | ||||
|      * @param   string    $query       The query this statement will process | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      * @throws  PrepareStatementFailureException | ||||
|      */ | ||||
|     public function __construct($connection, string $query) | ||||
|     { | ||||
|         // Initial parameter types for prepared statements | ||||
|         $this->parameterTypeMapping = [ | ||||
|             ParameterType::BOOLEAN      => SQLSRV_PHPTYPE_INT, | ||||
|             ParameterType::INTEGER      => SQLSRV_PHPTYPE_INT, | ||||
|             ParameterType::LARGE_OBJECT => SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), | ||||
|             ParameterType::NULL         => SQLSRV_PHPTYPE_NULL, | ||||
|             ParameterType::STRING       => SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), | ||||
|         ]; | ||||
|  | ||||
|         $this->connection = $connection; | ||||
|         $this->query      = $this->prepareParameterKeyMapping($query); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Replace named parameters with numbered parameters | ||||
|      * | ||||
|      * @param   string  $sql  The SQL statement to prepare. | ||||
|      * | ||||
|      * @return  string  The processed SQL statement. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function prepareParameterKeyMapping($sql) | ||||
|     { | ||||
|         $escaped    = false; | ||||
|         $startPos   = 0; | ||||
|         $quoteChar  = ''; | ||||
|         $literal    = ''; | ||||
|         $mapping    = []; | ||||
|         $position   = 0; | ||||
|         $matches    = []; | ||||
|         $pattern    = '/([:][a-zA-Z0-9_]+)/'; | ||||
|  | ||||
|         if (!preg_match($pattern, $sql, $matches)) { | ||||
|             return $sql; | ||||
|         } | ||||
|  | ||||
|         $sql = trim($sql); | ||||
|         $n   = \strlen($sql); | ||||
|  | ||||
|         while ($startPos < $n) { | ||||
|             if (!preg_match($pattern, $sql, $matches, 0, $startPos)) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $j = strpos($sql, "'", $startPos); | ||||
|             $k = strpos($sql, '"', $startPos); | ||||
|  | ||||
|             if (($k !== false) && (($k < $j) || ($j === false))) { | ||||
|                 $quoteChar = '"'; | ||||
|                 $j         = $k; | ||||
|             } else { | ||||
|                 $quoteChar = "'"; | ||||
|             } | ||||
|  | ||||
|             if ($j === false) { | ||||
|                 $j = $n; | ||||
|             } | ||||
|  | ||||
|             // Search for named prepared parameters and replace it with ? and save its position | ||||
|             $substring = substr($sql, $startPos, $j - $startPos); | ||||
|  | ||||
|             if (preg_match_all($pattern, $substring, $matches, PREG_PATTERN_ORDER + PREG_OFFSET_CAPTURE)) { | ||||
|                 foreach ($matches[0] as $i => $match) { | ||||
|                     if ($i === 0) { | ||||
|                         $literal .= substr($substring, 0, $match[1]); | ||||
|                     } | ||||
|  | ||||
|                     if (!isset($mapping[$match[0]])) { | ||||
|                         $mapping[$match[0]] = []; | ||||
|                     } | ||||
|  | ||||
|                     $mapping[$match[0]][]   = $position++; | ||||
|                     $endOfPlaceholder       = $match[1] + strlen($match[0]); | ||||
|                     $beginOfNextPlaceholder = $matches[0][$i + 1][1] ?? strlen($substring); | ||||
|                     $beginOfNextPlaceholder -= $endOfPlaceholder; | ||||
|                     $literal                .= '?' . substr($substring, $endOfPlaceholder, $beginOfNextPlaceholder); | ||||
|                 } | ||||
|             } else { | ||||
|                 $literal .= $substring; | ||||
|             } | ||||
|  | ||||
|             $startPos = $j; | ||||
|             $j++; | ||||
|  | ||||
|             if ($j >= $n) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             // Quote comes first, find end of quote | ||||
|             while (true) { | ||||
|                 $k       = strpos($sql, $quoteChar, $j); | ||||
|                 $escaped = false; | ||||
|  | ||||
|                 if ($k === false) { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 $l = $k - 1; | ||||
|  | ||||
|                 while ($l >= 0 && $sql[$l] === '\\') { | ||||
|                     $l--; | ||||
|                     $escaped = !$escaped; | ||||
|                 } | ||||
|  | ||||
|                 if ($escaped) { | ||||
|                     $j = $k + 1; | ||||
|  | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             if ($k === false) { | ||||
|                 // Error in the query - no end quote; ignore it | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $literal .= substr($sql, $startPos, $k - $startPos + 1); | ||||
|             $startPos = $k + 1; | ||||
|         } | ||||
|  | ||||
|         if ($startPos < $n) { | ||||
|             $literal .= substr($sql, $startPos, $n - $startPos); | ||||
|         } | ||||
|  | ||||
|         $this->parameterKeyMapping = $mapping; | ||||
|  | ||||
|         return $literal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Binds a parameter to the specified variable name. | ||||
|      * | ||||
|      * @param   string|integer  $parameter       Parameter identifier. For a prepared statement using named placeholders, this will be a parameter | ||||
|      *                                           name of the form `:name`. For a prepared statement using question mark placeholders, this will be | ||||
|      *                                           the 1-indexed position of the parameter. | ||||
|      * @param   mixed           $variable        Name of the PHP variable to bind to the SQL statement parameter. | ||||
|      * @param   string          $dataType        Constant corresponding to a SQL datatype, this should be the processed type from the QueryInterface. | ||||
|      * @param   ?integer        $length          The length of the variable. Usually required for OUTPUT parameters. | ||||
|      * @param   ?array          $driverOptions   Optional driver options to be used. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function bindParam($parameter, &$variable, string $dataType = ParameterType::STRING, ?int $length = null, ?array $driverOptions = null) | ||||
|     { | ||||
|         $this->bindedValues[$parameter] =& $variable; | ||||
|  | ||||
|         // Validate parameter type | ||||
|         if (!isset($this->parameterTypeMapping[$dataType])) { | ||||
|             throw new \InvalidArgumentException(sprintf('Unsupported parameter type `%s`', $dataType)); | ||||
|         } | ||||
|  | ||||
|         $this->typesKeyMapping[$parameter] = $this->parameterTypeMapping[$dataType]; | ||||
|  | ||||
|         $this->statement = null; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Binds a value to the specified variable. | ||||
|      * | ||||
|      * @param   string|integer  $parameter       Parameter identifier. For a prepared statement using named placeholders, this will be a parameter | ||||
|      *                                           name of the form `:name`. For a prepared statement using question mark placeholders, this will be | ||||
|      *                                           the 1-indexed position of the parameter. | ||||
|      * @param   mixed           $variable        Name of the PHP variable to bind to the SQL statement parameter. | ||||
|      * @param   string          $dataType        Constant corresponding to a SQL datatype, this should be the processed type from the QueryInterface. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function bindValue($parameter, $variable, $dataType = ParameterType::STRING) | ||||
|     { | ||||
|         $this->bindedValues[$parameter]    = $variable; | ||||
|         $this->typesKeyMapping[$parameter] = $dataType; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Closes the cursor, enabling the statement to be executed again. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function closeCursor(): void | ||||
|     { | ||||
|         if (!$this->result || !\is_resource($this->statement)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Emulate freeing the result fetching and discarding rows, similarly to what PDO does in this case | ||||
|         while (sqlsrv_fetch($this->statement)) { | ||||
|             // Do nothing (see above) | ||||
|         } | ||||
|  | ||||
|         $this->result = false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches the SQLSTATE associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorCode() | ||||
|     { | ||||
|         $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); | ||||
|  | ||||
|         if ($errors) { | ||||
|             return $errors[0]['code']; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches extended error information associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorInfo() | ||||
|     { | ||||
|         return sqlsrv_errors(SQLSRV_ERR_ERRORS); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Executes a prepared statement | ||||
|      * | ||||
|      * @param   array|null  $parameters  An array of values with as many elements as there are bound parameters in the SQL statement being executed. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function execute(?array $parameters = null) | ||||
|     { | ||||
|         if (empty($this->bindedValues) && $parameters !== null) { | ||||
|             $hasZeroIndex = array_key_exists(0, $parameters); | ||||
|  | ||||
|             foreach ($parameters as $key => $val) { | ||||
|                 $key = ($hasZeroIndex && is_numeric($key)) ? $key + 1 : $key; | ||||
|                 $this->bindValue($key, $val); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!$this->statement) { | ||||
|             $this->statement = $this->prepare(); | ||||
|         } | ||||
|  | ||||
|         if (!sqlsrv_execute($this->statement)) { | ||||
|             $errors = $this->errorInfo(); | ||||
|  | ||||
|             throw new ExecutionFailureException($this->query, $errors[0]['message'], $errors[0]['code']); | ||||
|         } | ||||
|  | ||||
|         $this->result = true; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fetches the next row from a result set | ||||
|      * | ||||
|      * @param   integer|null  $fetchStyle         Controls how the next row will be returned to the caller. This value must be one of the | ||||
|      *                                            FetchMode constants, defaulting to value of FetchMode::MIXED. | ||||
|      * @param   integer       $cursorOrientation  For a StatementInterface object representing a scrollable cursor, this value determines which row | ||||
|      *                                            will be returned to the caller. This value must be one of the FetchOrientation constants, | ||||
|      *                                            defaulting to FetchOrientation::NEXT. | ||||
|      * @param   integer       $cursorOffset       For a StatementInterface object representing a scrollable cursor for which the cursorOrientation | ||||
|      *                                            parameter is set to FetchOrientation::ABS, this value specifies the absolute number of the row in | ||||
|      *                                            the result set that shall be fetched. For a StatementInterface object representing a scrollable | ||||
|      *                                            cursor for which the cursorOrientation parameter is set to FetchOrientation::REL, this value | ||||
|      *                                            specifies the row to fetch relative to the cursor position before `fetch()` was called. | ||||
|      * | ||||
|      * @return  mixed  The return value of this function on success depends on the fetch type. In all cases, boolean false is returned on failure. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function fetch(?int $fetchStyle = null, int $cursorOrientation = FetchOrientation::NEXT, int $cursorOffset = 0) | ||||
|     { | ||||
|         if (!$this->result) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $fetchStyle = $fetchStyle ?: $this->defaultFetchStyle; | ||||
|  | ||||
|         if ($fetchStyle === FetchMode::COLUMN) { | ||||
|             return $this->fetchColumn(); | ||||
|         } | ||||
|  | ||||
|         if (isset($this->fetchMap[$fetchStyle])) { | ||||
|             return sqlsrv_fetch_array($this->statement, $this->fetchMap[$fetchStyle]) ?: false; | ||||
|         } | ||||
|  | ||||
|         if (\in_array($fetchStyle, [FetchMode::STANDARD_OBJECT, FetchMode::CUSTOM_OBJECT], true)) { | ||||
|             return sqlsrv_fetch_object($this->statement, $this->defaultObjectClass) ?: false; | ||||
|         } | ||||
|  | ||||
|         throw new \InvalidArgumentException("Unknown fetch type '{$fetchStyle}'"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a single column from the next row of a result set | ||||
|      * | ||||
|      * @param   integer  $columnIndex  0-indexed number of the column you wish to retrieve from the row. | ||||
|      *                                 If no value is supplied, the first column is retrieved. | ||||
|      * | ||||
|      * @return  mixed  Returns a single column from the next row of a result set or boolean false if there are no more rows. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function fetchColumn($columnIndex = 0) | ||||
|     { | ||||
|         $row = $this->fetch(FetchMode::NUMERIC); | ||||
|  | ||||
|         if ($row === false) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $row[$columnIndex] ?? null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prepares the SQL Server statement resource for execution | ||||
|      * | ||||
|      * @return  resource | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     private function prepare() | ||||
|     { | ||||
|         $params  = []; | ||||
|         $options = []; | ||||
|  | ||||
|         foreach ($this->bindedValues as $key => &$value) { | ||||
|             $variable = [ | ||||
|                 &$value, | ||||
|                 SQLSRV_PARAM_IN, | ||||
|             ]; | ||||
|  | ||||
|             if ($this->typesKeyMapping[$key] === $this->parameterTypeMapping[ParameterType::LARGE_OBJECT]) { | ||||
|                 $variable[] = $this->typesKeyMapping[$key]; | ||||
|                 $variable[] = SQLSRV_SQLTYPE_VARBINARY('max'); | ||||
|             } | ||||
|  | ||||
|             if (isset($this->parameterKeyMapping[$key])) { | ||||
|                 $paramKey = $this->parameterKeyMapping[$key]; | ||||
|  | ||||
|                 foreach ($paramKey as $currentKey) { | ||||
|                     $params[$currentKey] = $variable; | ||||
|                 } | ||||
|             } else { | ||||
|                 $params[] = $variable; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Cleanup referenced variable | ||||
|         unset($value); | ||||
|  | ||||
|         // SQLSRV Function sqlsrv_num_rows requires a static or keyset cursor. | ||||
|         if (strncmp(strtoupper(ltrim($this->query)), 'SELECT', \strlen('SELECT')) === 0) { | ||||
|             $options = ['Scrollable' => SQLSRV_CURSOR_KEYSET]; | ||||
|         } | ||||
|  | ||||
|         $statement = sqlsrv_prepare($this->connection, $this->query, $params, $options); | ||||
|  | ||||
|         if (!$statement) { | ||||
|             $errors = $this->errorInfo(); | ||||
|  | ||||
|             throw new PrepareStatementFailureException($errors[0]['message'], $errors[0]['code']); | ||||
|         } | ||||
|  | ||||
|         return $statement; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the number of rows affected by the last SQL statement. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rowCount(): int | ||||
|     { | ||||
|         if (strncmp(strtoupper(ltrim($this->query)), 'SELECT', \strlen('SELECT')) === 0) { | ||||
|             return sqlsrv_num_rows($this->statement); | ||||
|         } | ||||
|  | ||||
|         return sqlsrv_rows_affected($this->statement); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the fetch mode to use while iterating this statement. | ||||
|      * | ||||
|      * @param   integer  $fetchMode  The fetch mode, must be one of the FetchMode constants. | ||||
|      * @param   mixed    ...$args    Optional mode-specific arguments. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function setFetchMode(int $fetchMode, ...$args): void | ||||
|     { | ||||
|         $this->defaultFetchStyle = $fetchMode; | ||||
|  | ||||
|         if (isset($args[0])) { | ||||
|             $this->defaultObjectClass = $args[0]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										116
									
								
								libraries/vendor/joomla/database/src/StatementInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								libraries/vendor/joomla/database/src/StatementInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Interface defining a query statement. | ||||
|  * | ||||
|  * This interface is a partial standalone implementation of PDOStatement. | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| interface StatementInterface | ||||
| { | ||||
|     /** | ||||
|      * Binds a parameter to the specified variable name. | ||||
|      * | ||||
|      * @param   string|integer  $parameter      Parameter identifier. For a prepared statement using named placeholders, this will be a parameter | ||||
|      *                                          name of the form `:name`. For a prepared statement using question mark placeholders, this will be | ||||
|      *                                          the 1-indexed position of the parameter. | ||||
|      * @param   mixed           $variable       Name of the PHP variable to bind to the SQL statement parameter. | ||||
|      * @param   string          $dataType       Constant corresponding to a SQL datatype, this should be the processed type from the QueryInterface. | ||||
|      * @param   ?integer        $length         The length of the variable. Usually required for OUTPUT parameters. | ||||
|      * @param   ?array          $driverOptions  Optional driver options to be used. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function bindParam($parameter, &$variable, string $dataType = ParameterType::STRING, ?int $length = null, ?array $driverOptions = null); | ||||
|  | ||||
|     /** | ||||
|      * Closes the cursor, enabling the statement to be executed again. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function closeCursor(): void; | ||||
|  | ||||
|     /** | ||||
|      * Fetches the SQLSTATE associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorCode(); | ||||
|  | ||||
|     /** | ||||
|      * Fetches extended error information associated with the last operation on the statement handle. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function errorInfo(); | ||||
|  | ||||
|     /** | ||||
|      * Executes a prepared statement | ||||
|      * | ||||
|      * @param   array|null  $parameters  An array of values with as many elements as there are bound parameters in the SQL statement being executed. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function execute(?array $parameters = null); | ||||
|  | ||||
|     /** | ||||
|      * Fetches the next row from a result set | ||||
|      * | ||||
|      * @param   integer|null  $fetchStyle         Controls how the next row will be returned to the caller. This value must be one of the | ||||
|      *                                            FetchMode constants, defaulting to value of FetchMode::MIXED. | ||||
|      * @param   integer       $cursorOrientation  For a StatementInterface object representing a scrollable cursor, this value determines which row | ||||
|      *                                            will be returned to the caller. This value must be one of the FetchOrientation constants, | ||||
|      *                                            defaulting to FetchOrientation::NEXT. | ||||
|      * @param   integer       $cursorOffset       For a StatementInterface object representing a scrollable cursor for which the cursorOrientation | ||||
|      *                                            parameter is set to FetchOrientation::ABS, this value specifies the absolute number of the row in | ||||
|      *                                            the result set that shall be fetched. For a StatementInterface object representing a scrollable | ||||
|      *                                            cursor for which the cursorOrientation parameter is set to FetchOrientation::REL, this value | ||||
|      *                                            specifies the row to fetch relative to the cursor position before `fetch()` was called. | ||||
|      * | ||||
|      * @return  mixed  The return value of this function on success depends on the fetch type. In all cases, boolean false is returned on failure. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function fetch(?int $fetchStyle = null, int $cursorOrientation = FetchOrientation::NEXT, int $cursorOffset = 0); | ||||
|  | ||||
|     /** | ||||
|      * Returns the number of rows affected by the last SQL statement. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function rowCount(): int; | ||||
|  | ||||
|     /** | ||||
|      * Sets the fetch mode to use while iterating this statement. | ||||
|      * | ||||
|      * @param   integer  $fetchMode  The fetch mode, must be one of the FetchMode constants. | ||||
|      * @param   mixed    ...$args    Optional mode-specific arguments. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function setFetchMode(int $fetchMode, ...$args): void; | ||||
| } | ||||
							
								
								
									
										40
									
								
								libraries/vendor/joomla/database/src/UTF8MB4SupportInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								libraries/vendor/joomla/database/src/UTF8MB4SupportInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Database Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Database; | ||||
|  | ||||
| /** | ||||
|  * Interface defining a driver which has support for the MySQL `utf8mb4` character set | ||||
|  * | ||||
|  * @since  2.0.0 | ||||
|  */ | ||||
| interface UTF8MB4SupportInterface | ||||
| { | ||||
|     /** | ||||
|      * Automatically downgrade a CREATE TABLE or ALTER TABLE query from utf8mb4 (UTF-8 Multibyte) to plain utf8. | ||||
|      * | ||||
|      * Used when the server doesn't support UTF-8 Multibyte. | ||||
|      * | ||||
|      * @param   string  $query  The query to convert | ||||
|      * | ||||
|      * @return  string  The converted query | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function convertUtf8mb4QueryToUtf8($query); | ||||
|  | ||||
|     /** | ||||
|      * Check whether the database engine supports the UTF-8 Multibyte (utf8mb4) character encoding. | ||||
|      * | ||||
|      * @return  boolean  True if the database engine supports UTF-8 Multibyte. | ||||
|      * | ||||
|      * @since   2.0.0 | ||||
|      */ | ||||
|     public function hasUtf8mb4Support(); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user