From 3377d521867aece6dedc7fd71b922760356fdd0f Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 22 Apr 2022 03:31:40 +1200 Subject: [PATCH] Make tablename a property of the datasource The datasource stores the table name on the job - we don't need to pass it around. Also - stop cleaning up the temp table at the end - we want it to output results but will add a cleanup routine later --- CRM/Contact/Import/Form/MapField.php | 3 +- CRM/Contact/Import/Form/Preview.php | 3 +- CRM/Contact/Import/ImportJob.php | 47 ++----------------- CRM/Contact/Import/Parser/Contact.php | 23 +++++---- CRM/Import/DataSource/CSV.php | 5 +- CRM/Import/DataSource/SQL.php | 13 ++--- .../phpunit/CRM/Import/DataSource/CsvTest.php | 17 ++++--- 7 files changed, 36 insertions(+), 75 deletions(-) diff --git a/CRM/Contact/Import/Form/MapField.php b/CRM/Contact/Import/Form/MapField.php index ab5beededf..1685116c53 100644 --- a/CRM/Contact/Import/Form/MapField.php +++ b/CRM/Contact/Import/Form/MapField.php @@ -75,7 +75,6 @@ class CRM_Contact_Import_Form_MapField extends CRM_Import_Form_MapField { */ public function preProcess() { $this->_mapperFields = $this->getAvailableFields(); - $this->_importTableName = $this->get('importTableName'); $this->_contactSubType = $this->getSubmittedValue('contactSubType'); //format custom field names, CRM-2676 $contactType = $this->getContactType(); @@ -557,7 +556,7 @@ class CRM_Contact_Import_Form_MapField extends CRM_Import_Form_MapField { ); $parser->setUserJobID($this->getUserJobID()); - $parser->run($this->_importTableName, + $parser->run(NULL, $mapper, CRM_Import_Parser::MODE_PREVIEW, NULL, diff --git a/CRM/Contact/Import/Form/Preview.php b/CRM/Contact/Import/Form/Preview.php index e3c5990744..5699d7db05 100644 --- a/CRM/Contact/Import/Form/Preview.php +++ b/CRM/Contact/Import/Form/Preview.php @@ -220,8 +220,7 @@ class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview { 'userJobID' => $this->getUserJobID(), ); - $tableName = $this->get('importTableName'); - $importJob = new CRM_Contact_Import_ImportJob($tableName); + $importJob = new CRM_Contact_Import_ImportJob(); $importJob->setJobParams($importJobParams); // If ACL applies to the current user, update cache before running the import. diff --git a/CRM/Contact/Import/ImportJob.php b/CRM/Contact/Import/ImportJob.php index 05a2a13b7e..36fe0f835a 100644 --- a/CRM/Contact/Import/ImportJob.php +++ b/CRM/Contact/Import/ImportJob.php @@ -50,37 +50,6 @@ class CRM_Contact_Import_ImportJob { protected $_userJobID; - /** - * @param string|null $tableName - * @param string|null $createSql - * @param bool $createTable - * - * @throws \CRM_Core_Exception - */ - public function __construct($tableName = NULL, $createSql = NULL, $createTable = FALSE) { - $dao = new CRM_Core_DAO(); - $db = $dao->getDatabaseConnection(); - - if ($createTable) { - if (!$createSql) { - throw new CRM_Core_Exception(ts('Either an existing table name or an SQL query to build one are required')); - } - if ($tableName) { - // Drop previous table if passed in and create new one. - $db->query("DROP TABLE IF EXISTS $tableName"); - } - $table = CRM_Utils_SQL_TempTable::build()->setDurable(); - $tableName = $table->getName(); - $table->createWithQuery($createSql); - } - - if (!$tableName) { - throw new CRM_Core_Exception(ts('Import Table is required.')); - } - - $this->_tableName = $tableName; - } - /** * @return null|string */ @@ -92,19 +61,9 @@ class CRM_Contact_Import_ImportJob { * Has the job completed. * * @return bool - * @throws Exception */ - public function isComplete() { - if (!$this->_statusFieldName) { - throw new CRM_Core_Exception("Could not get name of the import status field"); - } - $query = "SELECT * FROM $this->_tableName - WHERE $this->_statusFieldName = 'NEW' LIMIT 1"; - $result = CRM_Core_DAO::executeQuery($query); - if ($result->fetch()) { - return FALSE; - } - return TRUE; + public function isComplete(): bool { + return $this->_parser->isComplete(); } /** @@ -220,7 +179,7 @@ class CRM_Contact_Import_ImportJob { $parserParameters['relatedContactWebsiteType'] ); $this->_parser->setUserJobID($this->_userJobID); - $this->_parser->run($this->_tableName, $mapperFields, + $this->_parser->run(NULL, $mapperFields, CRM_Import_Parser::MODE_IMPORT, $this->_contactType, $this->_primaryKeyName, diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index 6879a3b427..53afad761a 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -2583,15 +2583,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { $this->_conflicts = []; $this->_unparsedAddresses = []; - // Transitional support for deprecating table_name (and other fields) - // form input - the goal is to load them from userJob - but eventually - // we will just load the datasource object and this code will not know the - // table name. - if (!$tableName && $this->userJobID) { - $tableName = $this->getUserJob()['metadata']['DataSource']['table_name']; - } - - $this->_tableName = $tableName; + $this->_tableName = $tableName = $this->getUserJob()['metadata']['DataSource']['table_name']; $this->_primaryKeyName = '_id'; $this->_statusFieldName = '_status'; @@ -3651,4 +3643,17 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { return $params; } + /** + * Is the job complete. + * + * This function transitionally accesses the table from the userJob + * directly - but the function should be moved to the dataSource class. + * + * @throws \API_Exception + */ + public function isComplete() { + $tableName = $this->getUserJob()['metadata']['DataSource']['table_name']; + return (bool) CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM $tableName WHERE _status = 'NEW' LIMIT 1"); + } + } diff --git a/CRM/Import/DataSource/CSV.php b/CRM/Import/DataSource/CSV.php index 0c921e68ad..8ea4f0cda9 100644 --- a/CRM/Import/DataSource/CSV.php +++ b/CRM/Import/DataSource/CSV.php @@ -79,7 +79,6 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource { * @throws \API_Exception */ public function postProcess(&$params, &$db, &$form) { - $firstRowIsColumnHeader = $params['skipColumnHeader'] ?? FALSE; $result = self::_CsvToTable( $this->getSubmittedValue('uploadFile')['name'], $this->getSubmittedValue('skipColumnHeader'), @@ -87,11 +86,9 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource { ); $this->addTrackingFieldsToTable($result['import_table_name']); - $form->set('originalColHeader', CRM_Utils_Array::value('column_headers', $result)); - $form->set('importTableName', $result['import_table_name']); $this->updateUserJobMetadata('DataSource', [ 'table_name' => $result['import_table_name'], - 'column_headers' => $firstRowIsColumnHeader ? $result['column_headers'] : [], + 'column_headers' => $this->getSubmittedValue('skipColumnHeader') ? $result['column_headers'] : [], 'number_of_columns' => $result['number_of_columns'], ]); } diff --git a/CRM/Import/DataSource/SQL.php b/CRM/Import/DataSource/SQL.php index 6ac730faf3..7cee46dfba 100644 --- a/CRM/Import/DataSource/SQL.php +++ b/CRM/Import/DataSource/SQL.php @@ -85,17 +85,14 @@ class CRM_Import_DataSource_SQL extends CRM_Import_DataSource { * @throws \Civi\API\Exception\UnauthorizedException */ public function postProcess(&$params, &$db, &$form) { - $importJob = new CRM_Contact_Import_ImportJob( - NULL, - $params['sqlQuery'], TRUE - ); - $tableName = $importJob->getTableName(); + $table = CRM_Utils_SQL_TempTable::build()->setDurable(); + $tableName = $table->getName(); + $table->createWithQuery($this->getSubmittedValue('sqlQuery')); - $form->set('importTableName', $tableName); // Get the names of the fields to be imported. Any fields starting with an // underscore are considered to be internal to the import process) $columnsResult = CRM_Core_DAO::executeQuery( - 'SHOW FIELDS FROM ' . $importJob->getTableName() . " + 'SHOW FIELDS FROM ' . $tableName . " WHERE Field NOT LIKE '\_%'"); $columnNames = []; @@ -105,7 +102,7 @@ class CRM_Import_DataSource_SQL extends CRM_Import_DataSource { $this->addTrackingFieldsToTable($tableName); $this->updateUserJobMetadata('DataSource', [ - 'table_name' => $importJob->getTableName(), + 'table_name' => $tableName, 'column_headers' => $columnNames, 'number_of_columns' => count($columnNames), ]); diff --git a/tests/phpunit/CRM/Import/DataSource/CsvTest.php b/tests/phpunit/CRM/Import/DataSource/CsvTest.php index beb103bd44..594060c0ed 100644 --- a/tests/phpunit/CRM/Import/DataSource/CsvTest.php +++ b/tests/phpunit/CRM/Import/DataSource/CsvTest.php @@ -28,15 +28,19 @@ class CRM_Import_DataSource_CsvTest extends CiviUnitTestCase { * @param array $fileData * * @dataProvider getCsvFiles + * + * @throws \API_Exception + * @throws \CRM_Core_Exception */ public function testToCsv(array $fileData): void { $form = $this->submitDatasourceForm($fileData['filename']); - $tableName = $form->get('importTableName'); + $csvObject = new CRM_Import_DataSource_Csv($form->getUserJobID()); + $rows = $csvObject->getRows(0, 0, [], FALSE); foreach (['first_name', 'last_name', 'email'] as $field) { - $json = json_encode(CRM_Core_DAO::singleValueQuery("SELECT $field FROM $tableName")); + $json = json_encode($rows[0][$field]); $this->assertEquals($fileData["{$field}_json"], $json, "{$fileData['filename']} failed on $field"); } - CRM_Core_DAO::executeQuery("DROP TABLE $tableName"); + $csvObject->purge(); } /** @@ -129,10 +133,11 @@ class CRM_Import_DataSource_CsvTest extends CiviUnitTestCase { */ public function testBlankLineAtEnd(): void { $form = $this->submitDatasourceForm('blankLineAtEnd.csv'); - $tableName = $form->get('importTableName'); - $json = json_encode(CRM_Core_DAO::singleValueQuery("SELECT email FROM $tableName")); + $csvObject = new CRM_Import_DataSource_Csv($form->getUserJobID()); + + $json = json_encode($csvObject->getRow()['email']); $this->assertEquals('"yogi@yellowstone.park"', $json); - CRM_Core_DAO::executeQuery("DROP TABLE $tableName"); + $csvObject->purge(); } /** -- 2.25.1