Completed
Push — master ( fba866...b10a48 )
by Ori
03:03
created

CsvDataSource   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 2
dl 0
loc 104
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
C open() 0 29 7
A getSkippedRows() 0 4 1
A getNextLine() 0 10 2
A isEof() 0 9 2
A close() 0 9 2
A getRow() 0 9 2
1
<?php
2
namespace frictionlessdata\tableschema\DataSources;
3
4
use frictionlessdata\tableschema\Exceptions\DataSourceException;
5
6
/**
7
 * handles reading data from a csv source
8
 * responsible for finding the header row based on options
9
 * support skipping rows from the csv
10
 */
11
class CsvDataSource extends BaseDataSource
12
{
13
    /**
14
     * @throws DataSourceException
15
     */
16
    public function open()
17
    {
18
        $this->curRowNum = 0;
19
        try {
20
            $this->resource = fopen($this->dataSource, "r");
21
        } catch (\Exception $e) {
22
            throw new DataSourceException($e->getMessage());
23
        }
24
        $this->headerRow = $this->getOption("headerRow");
25
        if ($this->headerRow) {
26
            $headerRowNum = 0;
27
            $defaultSkipRows = 0;
28
        } else {
29
            $defaultSkipRows = $headerRowNum = $this->getOption("headerRowNum", 1);
30
        }
31
        $skipRows = $this->getOption("skipRows", $defaultSkipRows);
32
        if ($skipRows > 0) {
33
            foreach (range(1, $skipRows) as $i) {
34
                $row = $this->getRow();
35
                $this->skippedRows[] = $row;
36
                if ($i == $headerRowNum) {
37
                    $this->headerRow = $row;
38
                }
39
            }
40
        }
41
        if (!$this->headerRow) {
42
            throw new DataSourceException("Failed to get header row");
43
        }
44
    }
45
46
    /**
47
     * @return array
48
     */
49
    public function getSkippedRows()
50
    {
51
        return $this->skippedRows;
52
    }
53
54
    /**
55
     * @return array
56
     * @throws DataSourceException
57
     */
58
    public function getNextLine()
59
    {
60
        $row = $this->getRow();
61
        $colNum = 0;
62
        $obj = [];
63
        foreach ($this->headerRow as $fieldName) {
64
            $obj[$fieldName] = $row[$colNum++];
65
        }
66
        return $obj;
67
    }
68
69
    /**
70
     * @return bool
71
     * @throws DataSourceException
72
     */
73
    public function isEof()
74
    {
75
        try {
76
            return feof($this->resource);
77
        } catch (\Exception $e) {
78
            throw new DataSourceException($e->getMessage(), $this->curRowNum);
79
        }
80
81
    }
82
83
    /**
84
     * @throws DataSourceException
85
     */
86
    public function close()
87
    {
88
        try {
89
            fclose($this->resource);
90
        } catch (\Exception $e) {
91
            throw new DataSourceException($e->getMessage(), $this->curRowNum);
92
        }
93
94
    }
95
96
    protected $resource;
97
    protected $headerRow;
98
    protected $skippedRows;
99
    protected $curRowNum;
100
101
    /**
102
     * @return array
103
     * @throws DataSourceException
104
     */
105
    protected function getRow()
106
    {
107
        $this->curRowNum++;
108
        try {
109
            return fgetcsv($this->resource);
110
        } catch (\Exception $e) {
111
            throw new DataSourceException($e->getMessage(), $this->curRowNum);
112
        }
113
    }
114
}
115