Skip to content

Commit 64cc0fc

Browse files
committed
Skip Notification Event
1 parent c9d8800 commit 64cc0fc

File tree

7 files changed

+101
-0
lines changed

7 files changed

+101
-0
lines changed

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,27 @@ val tsvReader = csvReader {
175175
| ~~skipMissMatchedRow~~ | `false` | Deprecated. Replace with appropriate values in `excessFieldsRowBehaviour` and `insufficientFieldsRowBehaviour`, e.g. both set to `IGNORE`. ~~Whether to skip an invalid row. If `ignoreExcessCols` is true, only rows with less than the expected number of columns will be skipped.~~ |
176176
| excessFieldsRowBehaviour | `ERROR` | Behaviour to use when a row has more fields (columns) than expected. `ERROR` (default), `IGNORE` (skip the row) or `TRIM` (remove the excess fields at the end of the row to match the expected number of fields). |
177177
| insufficientFieldsRowBehaviour | `ERROR` | Behaviour to use when a row has fewer fields (columns) than expected. `ERROR` (default), `IGNORE` (skip the row) or `EMPTY_STRING` (replace missing fields with an empty string). |
178+
| onSkippedEvent | `null` | A pluggable Interface on listening when skipping either an insufficient or an excess number of fields. |
179+
180+
#### Interface Listing to Skipped Row Events`
181+
```kotlin
182+
csvReader {
183+
excessFieldsRowBehaviour = ExcessFieldsRowBehaviour.IGNORE
184+
insufficientFieldsRowBehaviour = InsufficientFieldsRowBehaviour.IGNORE
185+
onSkippedEvent = skipNotification {
186+
listeners["id"] = SkipNotify { println(it) }
187+
}
188+
}
189+
```
190+
191+
* skipNotification - builder function for creating notification listener
192+
* listeners `Mutable<String, ISkippedRow>` - map of listener function that will be triggered
193+
* `SkipNotify` - functional interface template
194+
```kotlin
195+
fun interface SkipNotify {
196+
fun onSkipped(row: SkippedRow)
197+
}
198+
```
178199

179200
### CSV Write examples
180201

src/commonMain/kotlin/com/github/doyaaaaaken/kotlincsv/dsl/context/CsvReaderContext.kt

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.doyaaaaaken.kotlincsv.dsl.context
22

3+
import com.github.doyaaaaaken.kotlincsv.event.skip.INotifySkippedEvent
34
import com.github.doyaaaaaken.kotlincsv.util.Const
45
import com.github.doyaaaaaken.kotlincsv.util.CsvDslMarker
56
import com.github.doyaaaaaken.kotlincsv.util.logger.Logger
@@ -88,6 +89,11 @@ interface ICsvReaderContext {
8889
* If a row exceeds have the expected number of fields (columns), how, and if, the reader should proceed
8990
*/
9091
val excessFieldsRowBehaviour: ExcessFieldsRowBehaviour
92+
93+
/**
94+
* A pluggable Interface on listening when skipping either an insufficient or an excess number of fields
95+
*/
96+
val onSkippedEvent: INotifySkippedEvent?
9197
}
9298

9399
enum class InsufficientFieldsRowBehaviour {
@@ -142,4 +148,5 @@ class CsvReaderContext : ICsvReaderContext {
142148
override var autoRenameDuplicateHeaders: Boolean = false
143149
override var insufficientFieldsRowBehaviour: InsufficientFieldsRowBehaviour = InsufficientFieldsRowBehaviour.ERROR
144150
override var excessFieldsRowBehaviour: ExcessFieldsRowBehaviour = ExcessFieldsRowBehaviour.ERROR
151+
override var onSkippedEvent: INotifySkippedEvent? = null
145152
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.doyaaaaaken.kotlincsv.event.skip
2+
3+
4+
fun interface SkipNotify {
5+
fun onSkipped(row: SkippedRow)
6+
}
7+
8+
/**
9+
* interface function that will be triggered when skipping either insufficient or excess number of fields
10+
*/
11+
fun interface INotifySkippedEvent {
12+
fun notify(skippedRow: SkippedRow)
13+
}
14+
15+
16+
fun skipNotification(block: NotifySkipEvent.() -> Unit): INotifySkippedEvent {
17+
return NotifySkipEvent().apply(block)
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.github.doyaaaaaken.kotlincsv.event.skip
2+
3+
class NotifySkipEvent: INotifySkippedEvent {
4+
val listeners = mutableMapOf<String, SkipNotify>()
5+
override fun notify(skippedRow: SkippedRow) {
6+
listeners.forEach { (_, value) -> value.onSkipped(skippedRow) }
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.github.doyaaaaaken.kotlincsv.event.skip
2+
enum class SkipType {
3+
InsufficientFieldsRowBehaviour,
4+
ExcessFieldsRowBehaviour
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.github.doyaaaaaken.kotlincsv.event.skip
2+
3+
/**
4+
* data class containing relevant information
5+
*/
6+
data class SkippedRow(
7+
/**
8+
* row index in the csv file
9+
*/
10+
val idx: Int,
11+
/**
12+
* row values
13+
*/
14+
val row: List<String>,
15+
/**
16+
* reason for skipping
17+
*/
18+
val message: String,
19+
/**
20+
* type of skip
21+
*/
22+
val skipType: SkipType
23+
24+
)

src/jvmTest/kotlin/com/github/doyaaaaaken/kotlincsv/client/CsvReaderTest.kt

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.github.doyaaaaaken.kotlincsv.dsl.context.CsvReaderContext
44
import com.github.doyaaaaaken.kotlincsv.dsl.context.ExcessFieldsRowBehaviour
55
import com.github.doyaaaaaken.kotlincsv.dsl.context.InsufficientFieldsRowBehaviour
66
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader
7+
import com.github.doyaaaaaken.kotlincsv.event.skip.SkipNotify
8+
import com.github.doyaaaaaken.kotlincsv.event.skip.skipNotification
79
import com.github.doyaaaaaken.kotlincsv.util.CSVFieldNumDifferentException
810
import com.github.doyaaaaaken.kotlincsv.util.CSVParseFormatException
911
import com.github.doyaaaaaken.kotlincsv.util.Const
@@ -206,6 +208,22 @@ class CsvReaderTest : WordSpec({
206208
actual.size shouldBe 1
207209
}
208210
}
211+
"it should be be possible to listen to to skip events for insufficient or excess fields " {
212+
val expected = listOf(listOf("a", "b"))
213+
val actual =
214+
csvReader {
215+
excessFieldsRowBehaviour = ExcessFieldsRowBehaviour.IGNORE
216+
insufficientFieldsRowBehaviour = InsufficientFieldsRowBehaviour.IGNORE
217+
onSkippedEvent = skipNotification {
218+
listeners["id"] = SkipNotify { println(it) }
219+
}
220+
}.readAll(readTestDataFile("varying-column-lengths.csv"))
221+
222+
assertSoftly {
223+
actual shouldBe expected
224+
actual.size shouldBe 1
225+
}
226+
}
209227
"it should be be possible to replace insufficient fields with strings and skip rows with excess fields" {
210228
val expected = listOf(listOf("a", "b"), listOf("c", ""))
211229
val actual =

0 commit comments

Comments
 (0)