Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.05% covered (warning)
86.05%
37 / 43
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
BasicImporter
86.05% covered (warning)
86.05%
37 / 43
0.00% covered (danger)
0.00%
0 / 2
10.27
0.00% covered (danger)
0.00%
0 / 1
 importFromCsvFileToDb
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
2.01
 doImport
85.29% covered (warning)
85.29%
29 / 34
0.00% covered (danger)
0.00%
0 / 1
8.20
1<?php
2
3namespace PropertySuggester\UpdateTable\Importer;
4
5use PropertySuggester\UpdateTable\ImportContext;
6use UnexpectedValueException;
7use Wikimedia\Rdbms\IDatabase;
8use Wikimedia\Rdbms\ILBFactory;
9
10/**
11 * A strategy which imports entries from a CSV file into a DB table. Used as fallback, when no
12 * special import commands are supported by the DBMS.
13 *
14 * @author BP2013N2
15 * @license GPL-2.0-or-later
16 */
17class BasicImporter implements Importer {
18
19    /**
20     * Import using SQL Insert
21     * @param ImportContext $importContext
22     * @return bool
23     */
24    public function importFromCsvFileToDb( ImportContext $importContext ) {
25        $fileHandle = fopen( $importContext->getCsvFilePath(), "r" );
26        if ( $fileHandle == false ) {
27            return false;
28        }
29
30        $lbFactory = $importContext->getLbFactory();
31        $lb = $lbFactory->getMainLB();
32        $db = $lb->getConnection( DB_PRIMARY );
33        $this->doImport( $fileHandle, $lbFactory, $db, $importContext );
34        fclose( $fileHandle );
35
36        return true;
37    }
38
39    /**
40     * @param resource $fileHandle
41     * @param ILBFactory $lbFactory
42     * @param IDatabase $db
43     * @param ImportContext $importContext
44     * @throws UnexpectedValueException
45     * @suppress SecurityCheck-SQLInjection ImportContext::getTargetTableName is marked as unsafe
46     */
47    private function doImport(
48        $fileHandle,
49        ILBFactory $lbFactory,
50        IDatabase $db,
51        ImportContext $importContext
52    ) {
53        $accumulator = [];
54        $batchSize = $importContext->getBatchSize();
55        $i = 0;
56        $header = fgetcsv( $fileHandle, 0, $importContext->getCsvDelimiter() );
57        $expectedHeader = [ 'pid1', 'qid1', 'pid2', 'count', 'probability', 'context' ];
58        if ( $header != $expectedHeader ) {
59            throw new UnexpectedValueException(
60                "provided csv-file does not match the expected format:\n" .
61                    implode( ',', $expectedHeader )
62            );
63        }
64
65        while ( true ) {
66            $data = fgetcsv( $fileHandle, 0, $importContext->getCsvDelimiter() );
67
68            if ( $data == false || ++$i % $batchSize == 0 ) {
69                $db->commit( __METHOD__, 'flush' );
70                $lbFactory->waitForReplication();
71                $db->newInsertQueryBuilder()
72                    ->insertInto( $importContext->getTargetTableName() )
73                    ->rows( $accumulator )
74                    ->caller( __METHOD__ )
75                    ->execute();
76                if ( !$importContext->isQuiet() ) {
77                    print "$i rows inserted\n";
78                }
79                $accumulator = [];
80                if ( $data == false ) {
81                    break;
82                }
83            }
84
85            $qid1 = is_numeric( $data[1] ) ? $data[1] : 0;
86
87            $accumulator[] = [
88                'pid1' => $data[0],
89                'qid1' => $qid1,
90                'pid2' => $data[2],
91                'count' => $data[3],
92                'probability' => $data[4],
93                'context' => $data[5],
94            ];
95        }
96    }
97
98}