Skip to content

Commit

Permalink
CSV Import note performance, refs #12676
Browse files Browse the repository at this point in the history
The code in the csv:import logic prevents duplicate notes from being
created if:
- it already exist in the database for this object, culture and note
type.
- the same note content, and type is duplicated in the import file.

Change the logic so that it retrieves all existing notes once only when
checking if notes exist.
  • Loading branch information
sbreker committed Jan 7, 2019
1 parent ad70aa7 commit 6b5c215
Showing 1 changed file with 48 additions and 10 deletions.
58 changes: 48 additions & 10 deletions lib/QubitFlatfileImport.class.php
Expand Up @@ -1444,6 +1444,11 @@ public function createOrUpdateNotes($typeId, $textArray, $transformationLogic =
}
}

// Get existing notes content as array - do this once per CSV row to reduce DB requests.
// Update array with note->content being added so values within CSV are also
// checked as they are added.
$existingNotes = $this->getExistingNotes($this->object->id, $typeId, $this->columnValue('culture'));

foreach ($textArray as $i => $text)
{
$options = array();
Expand All @@ -1459,7 +1464,7 @@ public function createOrUpdateNotes($typeId, $textArray, $transformationLogic =
}

// checkNoteExists will prevent note duplication.
if (!$this->checkNoteExists($this->object->id, $typeId, $this->content($text), $this->columnValue('culture')))
if (!$this->checkNoteExists($existingNotes, $this->content($text)))
{
$this->createOrUpdateNote($typeId, $text, $options);
}
Expand Down Expand Up @@ -1510,27 +1515,60 @@ public function createOrUpdateNote($typeId, $text, $options = array())
}

/**
* Return whether a note already exists given specified parameters.
* Return an array containing all note content for the object, type and culture.
*
* This function is to prevent creating duplicate notes when updating descriptions.
* This function is used to build a list to match against existing to prevent
* creating duplicate notes when updating descriptions.
*
* @param int $objectId Object id for object that the note belongs to.
* @param int $typeId Note type id indicating note type.
* @param string $content Note content to check against.
* @param string $culture Note culture to check against.
*
* @return bool True if the same note exists, false otherwise.
* @return bool Array of all note content.
*/
private function checkNoteExists($objectId, $typeId, $content, $culture)
private function getExistingNotes($objectId, $typeId, $culture)
{
$query = "SELECT n.id FROM note n
$existingNotes = array();

$query = "SELECT n.id, i.content FROM note n
INNER JOIN note_i18n i ON n.id=i.id
WHERE n.object_id=?
AND n.type_id=?
AND i.content=?
AND i.culture=?";
$statement = self::sqlQuery($query, array($objectId, $typeId, $content, $culture));
return false !== $statement->fetch(PDO::FETCH_OBJ);

$statement = self::sqlQuery($query, array($objectId, $typeId, $culture));

foreach ($statement->fetchAll(PDO::FETCH_OBJ) as $row)
{
$existingNotes[] = $row->content;
}
return $existingNotes;
}

/**
* Return whether a note already exists given specified parameters.
*
* This function is to prevent creating duplicate notes when updating descriptions.
*
* @param array $existingNotes Notes already found in the database for this
* @param string $content Note content to check against.
*
* @return bool True if the same note exists, false otherwise.
*/
private function checkNoteExists(&$existingNotes, $content)
{
// Try to match this note against list of notes from the database for this object.
foreach ($existingNotes as $note)
{
if ($content == $note)
{
return true;
}
}
// If we do not match the note, add it to the list to match against the next note.
// This is to prevent performing another DB lookup to re-grab all the notes.
$existingNotes[] = $content;
return false;
}

/**
Expand Down

0 comments on commit 6b5c215

Please sign in to comment.