Don't write History for link import
With large imports it has a large impact on performances and isn't really useful. Instead, write an IMPORT event, which let client using the history service resync its DB. -> 15k link import done in 6 seconds. Fixes #985
This commit is contained in:
parent
78865393a6
commit
66e74d50d3
3 changed files with 65 additions and 48 deletions
|
@ -16,6 +16,7 @@
|
||||||
* - UPDATED: link updated
|
* - UPDATED: link updated
|
||||||
* - DELETED: link deleted
|
* - DELETED: link deleted
|
||||||
* - SETTINGS: the settings have been updated through the UI.
|
* - SETTINGS: the settings have been updated through the UI.
|
||||||
|
* - IMPORT: bulk links import
|
||||||
*
|
*
|
||||||
* Note: new events are put at the beginning of the file and history array.
|
* Note: new events are put at the beginning of the file and history array.
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +42,11 @@ class History
|
||||||
*/
|
*/
|
||||||
const SETTINGS = 'SETTINGS';
|
const SETTINGS = 'SETTINGS';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Action key: a bulk import has been processed.
|
||||||
|
*/
|
||||||
|
const IMPORT = 'IMPORT';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string History file path.
|
* @var string History file path.
|
||||||
*/
|
*/
|
||||||
|
@ -121,6 +127,16 @@ public function updateSettings()
|
||||||
$this->addEvent(self::SETTINGS);
|
$this->addEvent(self::SETTINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Event: bulk import.
|
||||||
|
*
|
||||||
|
* Note: we don't store links add/update one by one since it can have a huge impact on performances.
|
||||||
|
*/
|
||||||
|
public function importLinks()
|
||||||
|
{
|
||||||
|
$this->addEvent(self::IMPORT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a new event and write it in the history file.
|
* Save a new event and write it in the history file.
|
||||||
*
|
*
|
||||||
|
|
|
@ -66,6 +66,7 @@ public static function filterAndFormat($linkDb, $selection, $prependNoteUrl, $in
|
||||||
* @param int $importCount how many links were imported
|
* @param int $importCount how many links were imported
|
||||||
* @param int $overwriteCount how many links were overwritten
|
* @param int $overwriteCount how many links were overwritten
|
||||||
* @param int $skipCount how many links were skipped
|
* @param int $skipCount how many links were skipped
|
||||||
|
* @param int $duration how many seconds did the import take
|
||||||
*
|
*
|
||||||
* @return string Summary of the bookmark import status
|
* @return string Summary of the bookmark import status
|
||||||
*/
|
*/
|
||||||
|
@ -74,14 +75,16 @@ private static function importStatus(
|
||||||
$filesize,
|
$filesize,
|
||||||
$importCount=0,
|
$importCount=0,
|
||||||
$overwriteCount=0,
|
$overwriteCount=0,
|
||||||
$skipCount=0
|
$skipCount=0,
|
||||||
|
$duration=0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$status = 'File '.$filename.' ('.$filesize.' bytes) ';
|
$status = 'File '.$filename.' ('.$filesize.' bytes) ';
|
||||||
if ($importCount == 0 && $overwriteCount == 0 && $skipCount == 0) {
|
if ($importCount == 0 && $overwriteCount == 0 && $skipCount == 0) {
|
||||||
$status .= 'has an unknown file format. Nothing was imported.';
|
$status .= 'has an unknown file format. Nothing was imported.';
|
||||||
} else {
|
} else {
|
||||||
$status .= 'was successfully processed: '.$importCount.' links imported, ';
|
$status .= 'was successfully processed in '. $duration .' seconds: ';
|
||||||
|
$status .= $importCount.' links imported, ';
|
||||||
$status .= $overwriteCount.' links overwritten, ';
|
$status .= $overwriteCount.' links overwritten, ';
|
||||||
$status .= $skipCount.' links skipped.';
|
$status .= $skipCount.' links skipped.';
|
||||||
}
|
}
|
||||||
|
@ -101,6 +104,7 @@ private static function importStatus(
|
||||||
*/
|
*/
|
||||||
public static function import($post, $files, $linkDb, $conf, $history)
|
public static function import($post, $files, $linkDb, $conf, $history)
|
||||||
{
|
{
|
||||||
|
$start = time();
|
||||||
$filename = $files['filetoupload']['name'];
|
$filename = $files['filetoupload']['name'];
|
||||||
$filesize = $files['filetoupload']['size'];
|
$filesize = $files['filetoupload']['size'];
|
||||||
$data = file_get_contents($files['filetoupload']['tmp_name']);
|
$data = file_get_contents($files['filetoupload']['tmp_name']);
|
||||||
|
@ -184,7 +188,6 @@ public static function import($post, $files, $linkDb, $conf, $history)
|
||||||
$linkDb[$existingLink['id']] = $newLink;
|
$linkDb[$existingLink['id']] = $newLink;
|
||||||
$importCount++;
|
$importCount++;
|
||||||
$overwriteCount++;
|
$overwriteCount++;
|
||||||
$history->updateLink($newLink);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,16 +199,19 @@ public static function import($post, $files, $linkDb, $conf, $history)
|
||||||
$newLink['shorturl'] = link_small_hash($newLink['created'], $newLink['id']);
|
$newLink['shorturl'] = link_small_hash($newLink['created'], $newLink['id']);
|
||||||
$linkDb[$newLink['id']] = $newLink;
|
$linkDb[$newLink['id']] = $newLink;
|
||||||
$importCount++;
|
$importCount++;
|
||||||
$history->addLink($newLink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$linkDb->save($conf->get('resource.page_cache'));
|
$linkDb->save($conf->get('resource.page_cache'));
|
||||||
|
$history->importLinks();
|
||||||
|
|
||||||
|
$duration = time() - $start;
|
||||||
return self::importStatus(
|
return self::importStatus(
|
||||||
$filename,
|
$filename,
|
||||||
$filesize,
|
$filesize,
|
||||||
$importCount,
|
$importCount,
|
||||||
$overwriteCount,
|
$overwriteCount,
|
||||||
$skipCount
|
$skipCount,
|
||||||
|
$duration
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,8 +132,8 @@ public function testImportNoDoctype()
|
||||||
public function testImportInternetExplorerEncoding()
|
public function testImportInternetExplorerEncoding()
|
||||||
{
|
{
|
||||||
$files = file2array('internet_explorer_encoding.htm');
|
$files = file2array('internet_explorer_encoding.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File internet_explorer_encoding.htm (356 bytes) was successfully processed:'
|
'File internet_explorer_encoding.htm (356 bytes) was successfully processed in %d seconds:'
|
||||||
.' 1 links imported, 0 links overwritten, 0 links skipped.',
|
.' 1 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -161,8 +161,8 @@ public function testImportInternetExplorerEncoding()
|
||||||
public function testImportNested()
|
public function testImportNested()
|
||||||
{
|
{
|
||||||
$files = file2array('netscape_nested.htm');
|
$files = file2array('netscape_nested.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_nested.htm (1337 bytes) was successfully processed:'
|
'File netscape_nested.htm (1337 bytes) was successfully processed in %d seconds:'
|
||||||
.' 8 links imported, 0 links overwritten, 0 links skipped.',
|
.' 8 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -283,8 +283,8 @@ public function testImportNested()
|
||||||
public function testImportDefaultPrivacyNoPost()
|
public function testImportDefaultPrivacyNoPost()
|
||||||
{
|
{
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -328,8 +328,8 @@ public function testImportKeepPrivacy()
|
||||||
{
|
{
|
||||||
$post = array('privacy' => 'default');
|
$post = array('privacy' => 'default');
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -372,8 +372,8 @@ public function testImportAsPublic()
|
||||||
{
|
{
|
||||||
$post = array('privacy' => 'public');
|
$post = array('privacy' => 'public');
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -396,8 +396,8 @@ public function testImportAsPrivate()
|
||||||
{
|
{
|
||||||
$post = array('privacy' => 'private');
|
$post = array('privacy' => 'private');
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -422,8 +422,8 @@ public function testOverwriteAsPublic()
|
||||||
|
|
||||||
// import links as private
|
// import links as private
|
||||||
$post = array('privacy' => 'private');
|
$post = array('privacy' => 'private');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -442,8 +442,8 @@ public function testOverwriteAsPublic()
|
||||||
'privacy' => 'public',
|
'privacy' => 'public',
|
||||||
'overwrite' => 'true'
|
'overwrite' => 'true'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 2 links overwritten, 0 links skipped.',
|
.' 2 links imported, 2 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -468,8 +468,8 @@ public function testOverwriteAsPrivate()
|
||||||
|
|
||||||
// import links as public
|
// import links as public
|
||||||
$post = array('privacy' => 'public');
|
$post = array('privacy' => 'public');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -489,8 +489,8 @@ public function testOverwriteAsPrivate()
|
||||||
'privacy' => 'private',
|
'privacy' => 'private',
|
||||||
'overwrite' => 'true'
|
'overwrite' => 'true'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 2 links overwritten, 0 links skipped.',
|
.' 2 links imported, 2 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -513,8 +513,8 @@ public function testSkipOverwrite()
|
||||||
{
|
{
|
||||||
$post = array('privacy' => 'public');
|
$post = array('privacy' => 'public');
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -523,8 +523,8 @@ public function testSkipOverwrite()
|
||||||
|
|
||||||
// re-import as private, DO NOT enable overwriting
|
// re-import as private, DO NOT enable overwriting
|
||||||
$post = array('privacy' => 'private');
|
$post = array('privacy' => 'private');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 0 links imported, 0 links overwritten, 2 links skipped.',
|
.' 0 links imported, 0 links overwritten, 2 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -542,8 +542,8 @@ public function testSetDefaultTags()
|
||||||
'default_tags' => 'tag1,tag2 tag3'
|
'default_tags' => 'tag1,tag2 tag3'
|
||||||
);
|
);
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -569,8 +569,8 @@ public function testSanitizeDefaultTags()
|
||||||
'default_tags' => 'tag1&,tag2 "tag3"'
|
'default_tags' => 'tag1&,tag2 "tag3"'
|
||||||
);
|
);
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File netscape_basic.htm (482 bytes) was successfully processed:'
|
'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
|
||||||
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
.' 2 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -594,8 +594,8 @@ public function testSanitizeDefaultTags()
|
||||||
public function testImportSameDate()
|
public function testImportSameDate()
|
||||||
{
|
{
|
||||||
$files = file2array('same_date.htm');
|
$files = file2array('same_date.htm');
|
||||||
$this->assertEquals(
|
$this->assertStringMatchesFormat(
|
||||||
'File same_date.htm (453 bytes) was successfully processed:'
|
'File same_date.htm (453 bytes) was successfully processed in %d seconds:'
|
||||||
.' 3 links imported, 0 links overwritten, 0 links skipped.',
|
.' 3 links imported, 0 links overwritten, 0 links skipped.',
|
||||||
NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf, $this->history)
|
NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf, $this->history)
|
||||||
);
|
);
|
||||||
|
@ -622,24 +622,19 @@ public function testImportCreateUpdateHistory()
|
||||||
'overwrite' => 'true',
|
'overwrite' => 'true',
|
||||||
];
|
];
|
||||||
$files = file2array('netscape_basic.htm');
|
$files = file2array('netscape_basic.htm');
|
||||||
$nbLinks = 2;
|
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history);
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history);
|
||||||
$history = $this->history->getHistory();
|
$history = $this->history->getHistory();
|
||||||
$this->assertEquals($nbLinks, count($history));
|
$this->assertEquals(1, count($history));
|
||||||
foreach ($history as $value) {
|
$this->assertEquals(History::IMPORT, $history[0]['event']);
|
||||||
$this->assertEquals(History::CREATED, $value['event']);
|
$this->assertTrue(new DateTime('-5 seconds') < $history[0]['datetime']);
|
||||||
$this->assertTrue(new DateTime('-5 seconds') < $value['datetime']);
|
|
||||||
$this->assertTrue(is_int($value['id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
// re-import as private, enable overwriting
|
// re-import as private, enable overwriting
|
||||||
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history);
|
NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history);
|
||||||
$history = $this->history->getHistory();
|
$history = $this->history->getHistory();
|
||||||
$this->assertEquals($nbLinks * 2, count($history));
|
$this->assertEquals(2, count($history));
|
||||||
for ($i = 0 ; $i < $nbLinks ; $i++) {
|
$this->assertEquals(History::IMPORT, $history[0]['event']);
|
||||||
$this->assertEquals(History::UPDATED, $history[$i]['event']);
|
$this->assertTrue(new DateTime('-5 seconds') < $history[0]['datetime']);
|
||||||
$this->assertTrue(new DateTime('-5 seconds') < $history[$i]['datetime']);
|
$this->assertEquals(History::IMPORT, $history[1]['event']);
|
||||||
$this->assertTrue(is_int($history[$i]['id']));
|
$this->assertTrue(new DateTime('-5 seconds') < $history[1]['datetime']);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue