Make tablename a property of the datasource
authorEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 21 Apr 2022 15:31:40 +0000 (03:31 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 5 May 2022 10:59:54 +0000 (22:59 +1200)
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
CRM/Contact/Import/Form/Preview.php
CRM/Contact/Import/ImportJob.php
CRM/Contact/Import/Parser/Contact.php
CRM/Import/DataSource/CSV.php
CRM/Import/DataSource/SQL.php
tests/phpunit/CRM/Import/DataSource/CsvTest.php

index ab5beededfe5579fcd358cc0d27f7e8b2cf7e925..1685116c5300550851cc17300dfa6d5e72fcac0b 100644 (file)
@@ -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,
index e3c599074491361af4eea3451f988e48b7177caf..5699d7db05b431ac63a859350b8a9a39d13bcf91 100644 (file)
@@ -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.
index 05a2a13b7ecead7747f49688cead4c8626906915..36fe0f835a7febe54bff9e2e4b6901d074bcc0d4 100644 (file)
@@ -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,
index 6879a3b427bc62416dec60d3f7caef8b9929db12..53afad761a98dc06783ec605ff97c7947184e609 100644 (file)
@@ -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");
+  }
+
 }
index 0c921e68ad2bb2e92bc43f0ad0f33caa4e065ad3..8ea4f0cda93243cc8369df02aaf10e35ab868245 100644 (file)
@@ -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'],
     ]);
   }
index 6ac730faf39f3ce983369ba5018d29d5df77d287..7cee46dfba19e7ec002bf05d66a6df251f0150ad 100644 (file)
@@ -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),
     ]);
index beb103bd44172affbf236ab99204e3724ae01ed2..594060c0ed440b73d986ed5a239af75658ec0596 100644 (file)
@@ -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();
   }
 
   /**