Katie Horn has submitted this change and it was merged.

Change subject: A Streaming CSV Reader for SmashPig
......................................................................


A Streaming CSV Reader for SmashPig

These classes allow the stream processing of CSV files in a 'nicely'
wrapped way.

These were needed so that I could process Adyen reports.

Change-Id: I6cf6656bac25c557f724ea6b296a3adab0243e52
---
A Core/DataFiles/CsvReader.php
A Core/DataFiles/DataFileException.php
A Core/DataFiles/HeadedCsvReader.php
3 files changed, 149 insertions(+), 0 deletions(-)

Approvals:
  Katie Horn: Verified; Looks good to me, approved



diff --git a/Core/DataFiles/CsvReader.php b/Core/DataFiles/CsvReader.php
new file mode 100644
index 0000000..d3affad
--- /dev/null
+++ b/Core/DataFiles/CsvReader.php
@@ -0,0 +1,96 @@
+<?php namespace SmashPig\Core\DataFiles;
+
+class CsvReader implements \Iterator {
+       /**
+        * @var int Maximum length of line to read from the CSV file.
+        */
+       protected $maxRowLength = 4096;
+       
+       /**
+        * @var resource The pointer to the cvs file.
+        */
+       protected $filePointer = null;
+
+       /**
+        * @var array The current element, which will be returned on each 
iteration.
+        */
+       protected $currentElement = null;
+
+       /**
+        * @var int Number of rows read so far.
+        */
+       protected $rowCounter = null;
+
+       /**
+        * @var string Delimiter for the csv file.
+        */
+       private $delimiter = null;
+
+       /**
+        * Create an iterative CSV file reader.
+        *
+        * @param string $file Path to file
+        * @param string $delimiter Delimiter to use between CSV fields
+        * @param int    $maxRowLength Maximum length a field can take (affects 
buffering)
+        *
+        * @throws DataFileException on non open-able file.
+        */
+       public function __construct( $file, $delimiter = ',', $maxRowLength = 
4098 ) {
+               $this->filePointer = fopen( $file, 'r' );
+               if ( !$this->filePointer ) {
+                       throw new DataFileException( "Could not open file 
'{$file}' for reading." );
+               }
+
+               $this->delimiter = $delimiter;
+               $this->maxRowLength = $maxRowLength;
+
+               // Read the first row
+               $this->next();
+       }
+
+       /**
+        * Close the file pointer
+        */
+       public function __destruct() {
+               fclose( $this->filePointer );
+       }
+
+       /**
+        * Rewind to the first element.
+        */
+       public function rewind() {
+               $this->rowCounter = 0;
+               rewind( $this->filePointer );
+       }
+
+       /**
+        * @return mixed[] The currently buffered CSV row.
+        * @throws DataFileException If no data has been loaded.
+        */
+       public function current() {
+               return $this->currentElement;
+       }
+
+       /**
+        * @return int The current row number
+        */
+       public function key() {
+               return $this->rowCounter;
+       }
+
+       /**
+        * Load the next rows into memory
+        */
+       public function next() {
+               $this->currentElement = fgetcsv( $this->filePointer, 
$this->maxRowLength, $this->delimiter );
+               $this->rowCounter++;
+       }
+
+       /**
+        * Check to see if we have any valid data yet to retrieve
+        * @return bool
+        */
+       public function valid() {
+               return ( $this->currentElement !== false ) && !feof( 
$this->filePointer );
+       }
+}
diff --git a/Core/DataFiles/DataFileException.php 
b/Core/DataFiles/DataFileException.php
new file mode 100644
index 0000000..061d9c4
--- /dev/null
+++ b/Core/DataFiles/DataFileException.php
@@ -0,0 +1,7 @@
+<?php namespace SmashPig\Core\DataFiles;
+
+use SmashPig\Core\SmashPigException;
+
+class DataFileException extends SmashPigException {
+
+}
\ No newline at end of file
diff --git a/Core/DataFiles/HeadedCsvReader.php 
b/Core/DataFiles/HeadedCsvReader.php
new file mode 100644
index 0000000..1e84730
--- /dev/null
+++ b/Core/DataFiles/HeadedCsvReader.php
@@ -0,0 +1,46 @@
+<?php namespace SmashPig\Core\DataFiles;
+
+/**
+ * Iteratively reads a CSV file that contains a data header
+ *
+ * @package SmashPig\Core\DataFiles
+ */
+class HeadedCsvReader extends CsvReader {
+       /** @var string[] */
+       protected $colNames;
+
+       public function __construct( $file, $delimiter = ',', $maxRowLength = 
4098 ) {
+               parent::__construct( $file, $delimiter, $maxRowLength );
+
+               // Extract the header information
+               $this->colNames = parent::current();
+               parent::next();
+       }
+
+       /**
+        * Extract the contents of the given column name.
+        *
+        * This is slightly backwards because it did not seem worth the effort
+        * to create a fully functional ArrayObject class to return from 
current()
+        *
+        * @param $colName string Name of the column to extract
+        * @param $row string[] A row returned from current() **FROM THIS FILE**
+        *
+        * @throws DataFileException if the column name does not exist.
+        * @return string Contents of the column
+        */
+       public function extractCol( $colName, &$row ) {
+               $col = array_search( $colName, $this->colNames );
+               if ( $col === false ) {
+                       throw new DataFileException( "Column name 
{$this->colNames} not found!" );
+               }
+               return $row[$col];
+       }
+
+       /**
+        * @return string[] CSV file headers in order of columns
+        */
+       public function headers() {
+               return $this->colNames;
+       }
+}
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/90283
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I6cf6656bac25c557f724ea6b296a3adab0243e52
Gerrit-PatchSet: 2
Gerrit-Project: wikimedia/fundraising/SmashPig
Gerrit-Branch: master
Gerrit-Owner: Mwalker <[email protected]>
Gerrit-Reviewer: Adamw <[email protected]>
Gerrit-Reviewer: Katie Horn <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to