Completed
Push — master ( a4deca...b10287 )
by Ori
01:31
created

CsvDataSource::open()   C

Complexity

Conditions 7
Paths 9

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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