dev/core#183 Fix import csv to use temp table builder
authoreileen <emcnaughton@wikimedia.org>
Tue, 14 Jul 2020 05:57:39 +0000 (17:57 +1200)
committereileen <emcnaughton@wikimedia.org>
Mon, 20 Jul 2020 19:37:27 +0000 (07:37 +1200)
CRM/Contact/Import/ImportJob.php
CRM/Import/DataSource/CSV.php
CRM/Import/DataSource/SQL.php
tests/phpunit/CRM/Contact/Import/Form/DataSourceTest.php
tests/phpunit/CRM/Import/DataSource/CsvTest.php

index e72d45a76d31f7c3bf75e5ce10d05e9cc38b9914..75d570e637cef27d298e89e57818361576d37b82 100644 (file)
@@ -141,7 +141,7 @@ class CRM_Contact_Import_ImportJob {
       //need to differentiate non location elements.
       // @todo merge this with duplicate code on MapField class.
       if ($selOne && (is_numeric($selOne) || $selOne === 'Primary')) {
-        if ($fldName == 'url') {
+        if ($fldName === 'url') {
           $header[] = $websiteTypes[$selOne];
           $parserParameters['mapperWebsiteType'][$key] = $selOne;
         }
@@ -149,11 +149,11 @@ class CRM_Contact_Import_ImportJob {
           $header[] = $locationTypes[$selOne];
           $parserParameters['mapperLocType'][$key] = $selOne;
           if ($selTwo && is_numeric($selTwo)) {
-            if ($fldName == 'phone') {
+            if ($fldName === 'phone') {
               $header[] = $phoneTypes[$selTwo];
               $parserParameters['mapperPhoneType'][$key] = $selTwo;
             }
-            elseif ($fldName == 'im') {
+            elseif ($fldName === 'im') {
               $header[] = $imProviders[$selTwo];
               $parserParameters['mapperImProvider'][$key] = $selTwo;
             }
@@ -337,6 +337,7 @@ class CRM_Contact_Import_ImportJob {
    * @param $newTagDesc
    *
    * @return array|bool
+   * @throws \CRM_Core_Exception
    */
   private function _tagImportedContactsWithNewTag(
     $contactIds,
index 33dce5584bd4be74a066b6f205887d8da9ab5167..9651e47888aecb9b023947367cc1e354d0a22153 100644 (file)
@@ -76,6 +76,8 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource {
    * @param array $params
    * @param string $db
    * @param \CRM_Core_Form $form
+   *
+   * @throws \CRM_Core_Exception
    */
   public function postProcess(&$params, &$db, &$form) {
     $file = $params['uploadFile']['name'];
@@ -102,19 +104,20 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource {
    *   File name to load.
    * @param bool $headers
    *   Whether the first row contains headers.
-   * @param string $table
+   * @param string $tableName
    *   Name of table from which data imported.
    * @param string $fieldSeparator
    *   Character that separates the various columns in the file.
    *
-   * @return string
+   * @return array
    *   name of the created table
+   * @throws \CRM_Core_Exception
    */
   private static function _CsvToTable(
     &$db,
     $file,
     $headers = FALSE,
-    $table = NULL,
+    $tableName = NULL,
     $fieldSeparator = ','
   ) {
     $result = [];
@@ -184,16 +187,17 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource {
       }
     }
 
-    // FIXME: we should regen this table's name if it exists rather than drop it
-    if (!$table) {
-      $table = 'civicrm_import_job_' . md5(uniqid(rand(), TRUE));
+    if ($tableName) {
+      // Drop previous table if passed in and create new one.
+      $db->query("DROP TABLE IF EXISTS $tableName");
     }
-
-    $db->query("DROP TABLE IF EXISTS $table");
+    $table = CRM_Utils_SQL_TempTable::build()->setDurable();
+    $tableName = $table->getName();
+    // Do we still need this?
+    $db->query("DROP TABLE IF EXISTS $tableName");
+    $table->createWithColumns(implode(' text, ', $columns) . ' text');
 
     $numColumns = count($columns);
-    $create = "CREATE TABLE $table (" . implode(' text, ', $columns) . " text) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci";
-    $db->query($create);
 
     // the proper approach, but some MySQL installs do not have this enabled
     // $load = "LOAD DATA LOCAL INFILE '$file' INTO TABLE $table FIELDS TERMINATED BY '$fieldSeparator' OPTIONALLY ENCLOSED BY '\"'";
@@ -230,7 +234,7 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource {
       $count++;
 
       if ($count >= self::NUM_ROWS_TO_INSERT && !empty($sql)) {
-        $sql = "INSERT IGNORE INTO $table VALUES $sql";
+        $sql = "INSERT IGNORE INTO $tableName VALUES $sql";
         $db->query($sql);
 
         $sql = NULL;
@@ -240,14 +244,14 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource {
     }
 
     if (!empty($sql)) {
-      $sql = "INSERT IGNORE INTO $table VALUES $sql";
+      $sql = "INSERT IGNORE INTO $tableName VALUES $sql";
       $db->query($sql);
     }
 
     fclose($fd);
 
     //get the import tmp table name.
-    $result['import_table_name'] = $table;
+    $result['import_table_name'] = $tableName;
 
     return $result;
   }
index e74e92242f8a2be5d47f5d28288533d7f38300e4..26d3e09faa1a9d779cc8b394e7585718d03a5714 100644 (file)
@@ -80,6 +80,8 @@ class CRM_Import_DataSource_SQL extends CRM_Import_DataSource {
    * @param array $params
    * @param string $db
    * @param \CRM_Core_Form $form
+   *
+   * @throws \CRM_Core_Exception
    */
   public function postProcess(&$params, &$db, &$form) {
     $importJob = new CRM_Contact_Import_ImportJob(
index 3bc911ea1653058d92468efdb0c32a9805b0255d..4fe0097e160c3c8eea9d002225bfb22edcd1c169 100644 (file)
@@ -34,4 +34,17 @@ class CRM_Contact_Import_Form_DataSourceTest extends CiviUnitTestCase {
     $this->assertEquals([1 => 'Well dressed ducks'], CRM_Core_Smarty::singleton()->get_template_vars('savedMapping'));
   }
 
+  /**
+   * Check for (lack of) sql errors on sql import post process.
+   */
+  public function testSQLSource() {
+    $this->callAPISuccess('Mapping', 'create', ['name' => 'Well dressed ducks', 'mapping_type_id' => 'Import Contact']);
+    /** @var CRM_Import_DataSource_SQL $form */
+    $form = $this->getFormObject('CRM_Import_DataSource_SQL');
+    $coreForm = $this->getFormObject('CRM_Core_Form');
+    $db = NULL;
+    $params = ['sqlQuery' => 'SELECT 1 as id'];
+    $form->postProcess($params, $db, $coreForm);
+  }
+
 }
index 877ac89faa178ae3175ec621256a9d52e1183930..a93f31aeb42f963db9d95063619e60344beea2ce 100644 (file)
@@ -20,6 +20,7 @@ class CRM_Import_DataSource_CsvTest extends CiviUnitTestCase {
    * @param string $fileName
    *
    * @dataProvider getCsvFiles
+   * @throws \CRM_Core_Exception
    */
   public function testToCsv($fileName) {
     $dataSource = new CRM_Import_DataSource_CSV();