Skip to content

Commit 5fc328e

Browse files
authored
set limit option to restrict total number of records
Signed-off-by: rahul <[email protected]>
1 parent 73eeddd commit 5fc328e

File tree

4 files changed

+78
-23
lines changed

4 files changed

+78
-23
lines changed

bin/view-csv

+11-4
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,32 @@ use Symfony\Component\Console\Style\SymfonyStyle;
1717
$command = (new SingleCommandApplication())
1818
->addArgument('csvFile', InputArgument::REQUIRED, 'csv file name')
1919
->addOption('hide-column', null, InputOption::VALUE_REQUIRED, 'Columns to hide (comma-separated)')
20+
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'limit number of records')
2021
->setCode(function (InputInterface $input, OutputInterface $output): int {
2122
$io = new SymfonyStyle($input, $output);
2223
$csvFile = $input->getArgument('csvFile');
23-
2424
$hiddenColumns = $input->getOption('hide-column');
25-
26-
$hiddenColumnsArray = explode(',', $hiddenColumns);
25+
$limit = $input->getOption('limit');
2726

2827
if (!file_exists($csvFile)) {
2928
$io->error("{$csvFile} does not exists");
3029
return Command::FAILURE;
3130
}
3231

32+
if (isset($limit) && !is_numeric($limit)) {
33+
$io->error("{$limit} is not numeric");
34+
return Command::FAILURE;
35+
}
36+
37+
$hiddenColumns = $hiddenColumns ? explode(',', $hiddenColumns) : false;
38+
$limit = $limit ? (int)$limit : false;
39+
3340
$serviceContainer = new ServiceContainer();
3441
/** @var CsvFileHandler $csvFileHandler */
3542
$csvFileHandler = $serviceContainer->getContainerBuilder()->get('csv_file_handler');
3643

3744
try {
38-
$data = $csvFileHandler->toArray($csvFile, $hiddenColumnsArray);
45+
$data = $csvFileHandler->toArray($csvFile, $hiddenColumns, $limit);
3946
} catch (FileHandlerException) {
4047
$io->error('invalid csv file');
4148
return Command::FAILURE;

src/CsvFileHandler.php

+34-18
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ public function toJson(string $filename): string|false
5353
* @return array<int,array<string,string>>
5454
* @throws FileHandlerException
5555
*/
56-
public function toArray(string $filename, array|false $hideColumns = false): array
56+
public function toArray(string $filename, array|false $hideColumns = false, int|false $limit = false): array
5757
{
5858
if (!file_exists($filename)) {
5959
throw new FileHandlerException('file not found');
6060
}
6161

62-
return iterator_to_array($this->getRows($filename, $hideColumns));
62+
return iterator_to_array($this->getRows($filename, $hideColumns, $limit));
6363
}
6464

6565
public function findAndReplaceInCsv(
@@ -148,22 +148,22 @@ private function isValidCsvFileFormat(array $row): bool
148148
}
149149

150150
/**
151-
* @param array<string> $row
151+
* @param array<string> $headers
152152
* @param array<string> $hideColumns
153-
* @return array<int<0, max>,int|string>
153+
* @return array<int<0, max>,int>
154154
*/
155-
private function setColumnsToHide(array &$row, array $hideColumns): array
155+
private function setColumnsToHide(array &$headers, array $hideColumns): array
156156
{
157157
$indices = [];
158158
if (!empty($hideColumns)) {
159159
foreach ($hideColumns as $hideColumn) {
160-
$index = array_search($hideColumn, $row);
160+
$index = array_search($hideColumn, $headers);
161161
if ($index !== false) {
162-
$indices[] = $index;
163-
unset($row[$index]);
162+
$indices[] = (int)$index;
163+
unset($headers[$index]);
164164
}
165165
}
166-
$row = array_values($row);
166+
$headers = array_values($headers);
167167
}
168168
return $indices;
169169
}
@@ -174,7 +174,7 @@ private function setColumnsToHide(array &$row, array $hideColumns): array
174174
* @return Generator
175175
* @throws FileHandlerException
176176
*/
177-
private function getRows(string $filename, array|false $hideColumns = false): Generator
177+
private function getRows(string $filename, array|false $hideColumns = false, int|false $limit = false): Generator
178178
{
179179
$csvFile = fopen($filename, 'r');
180180
if (!$csvFile) {
@@ -191,6 +191,7 @@ private function getRows(string $filename, array|false $hideColumns = false): Ge
191191

192192

193193
$isEmptyFile = true;
194+
$count = 0;
194195
try {
195196
while (($row = fgetcsv($csvFile)) !== false) {
196197
$isEmptyFile = false;
@@ -199,18 +200,17 @@ private function getRows(string $filename, array|false $hideColumns = false): Ge
199200
}
200201

201202
if (!empty($indices)) {
202-
foreach ($indices as $index) {
203-
if (isset($row[$index])) {
204-
unset($row[$index]);
205-
}
206-
}
207-
208-
$row = array_values($row);
203+
$this->removeElementByIndex($row, $indices);
209204
}
210205

211-
$item = array_combine($headers, $row);
212206

207+
$item = array_combine($headers, $row);
213208
yield $item;
209+
$count++;
210+
211+
if (is_int($limit) && $limit <= $count) {
212+
break;
213+
}
214214
}
215215
} finally {
216216
fclose($csvFile);
@@ -222,6 +222,22 @@ private function getRows(string $filename, array|false $hideColumns = false): Ge
222222
}
223223
}
224224

225+
/**
226+
* @param array<int,string> $row
227+
* @param array<int<0, max>, int> $indices
228+
* @return void
229+
*/
230+
private function removeElementByIndex(array &$row, array $indices): void
231+
{
232+
foreach ($indices as $index) {
233+
if (isset($row[$index])) {
234+
unset($row[$index]);
235+
}
236+
}
237+
238+
$row = array_values($row);
239+
}
240+
225241
/**
226242
* @param array<string> $row
227243
* @param string $keyword

tests/Integration/ViewCsvCommandTest.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,20 @@ public function viewCsvFileDisplayInformationCorrectly(string $file): void
6262
unlink($file);
6363
}
6464

65+
#[Test]
66+
public function IfLimitIsSetToNonNumericCommandShouldFail(): void
67+
{
68+
$command = "php bin/view-csv movie.csv --limit hello";
69+
exec($command, $output, $exitCode);
70+
$actualOutput = implode("\n", $output);
71+
72+
$this->assertSame(1, $exitCode);
73+
$this->assertStringContainsString("hello is not numeric", $actualOutput);
74+
}
75+
6576
#[Test]
6677
#[DataProvider('InvalidFileProvider')]
67-
public function throwExceptionIfFileIsInvalid(string $file): void
78+
public function commandShouldReturnErrorIfFileIsInvalid(string $file): void
6879
{
6980
$command = "php bin/view-csv {$file}";
7081
exec($command, $output, $exitCode);

tests/unit/CsvFileHandlerTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,17 @@ public function toArrayMethodWithHideColumnsOptionReturnsValidArray(array $colum
125125
$this->assertEquals($expected, $data[0]);
126126
}
127127

128+
#[Test]
129+
#[DataProvider('limitDataProvider')]
130+
public function toArrayMethodShouldRestrictNumberOfRecordsWhenLimitIsSet(int $limit): void
131+
{
132+
$data = $this->csvFileHandler->toArray("movie.csv", ["Year"], $limit);
133+
134+
$count = count($data);
135+
136+
$this->assertSame($count, $limit);
137+
}
138+
128139
#[Test]
129140
public function searchByKeywordAndReturnArray(): void
130141
{
@@ -267,4 +278,14 @@ public static function columnsToHideDataProvider(): iterable
267278
yield [$hideSingleColumn, $expected1];
268279
yield [$hideMultipleColumns, $expected2];
269280
}
281+
282+
/**
283+
* max limit for the test file is 3
284+
* @return iterable<array<int>>
285+
*/
286+
public static function limitDataProvider(): iterable
287+
{
288+
yield [1];
289+
yield [2];
290+
}
270291
}

0 commit comments

Comments
 (0)