1
1
package org.jetbrains.kotlinx.dataframe.impl.api
2
2
3
+ import io.github.oshai.kotlinlogging.KotlinLogging
3
4
import org.jetbrains.kotlinx.dataframe.AnyFrame
4
5
import org.jetbrains.kotlinx.dataframe.AnyRow
5
6
import org.jetbrains.kotlinx.dataframe.ColumnsSelector
@@ -47,6 +48,8 @@ import kotlin.reflect.KType
47
48
import kotlin.reflect.full.withNullability
48
49
import kotlin.reflect.jvm.jvmErasure
49
50
51
+ private val logger = KotlinLogging .logger {}
52
+
50
53
private open class Converter (val transform : ConverterScope .(Any? ) -> Any? , val skipNulls : Boolean )
51
54
52
55
private class Filler (val columns : ColumnsSelector <* , * >, val expr : RowExpression <* , * >)
@@ -262,6 +265,7 @@ internal fun AnyFrame.convertToImpl(
262
265
try {
263
266
newColumns + = targetColumn.createNullFilledColumn(name, size)
264
267
} catch (e: IllegalStateException ) {
268
+ logger.debug(e) { " " }
265
269
// if this could not be done automatically, they need to be filled manually
266
270
missingPaths.add(path + name)
267
271
}
@@ -274,20 +278,39 @@ internal fun AnyFrame.convertToImpl(
274
278
val marker = MarkersExtractor .get(clazz)
275
279
var result = convertToSchema(marker.schema, emptyPath())
276
280
281
+ /*
282
+ * Here we handle all registered fillers of the user.
283
+ * Fillers are registered in the DSL like:
284
+ * ```kt
285
+ * df.convertTo<Target> {
286
+ * fill { col1 and col2 }.with { something }
287
+ * fill { col3 }.with { somethingElse }
288
+ * }
289
+ * ```
290
+ * Users can use this to fill up any column that was missing during the conversion.
291
+ * They can also fill up and thus overwrite any existing column here.
292
+ */
277
293
dsl.fillers.forEach { filler ->
294
+ // get all paths from the `fill { col1 and col2 }` part
278
295
val paths = result.getColumnPaths(UnresolvedColumnsPolicy .Create , filler.columns).toSet()
296
+
297
+ // split the paths into those that are already in the df and those that are missing
279
298
val (newPaths, existingPaths) = paths.partition { it in missingPaths }
280
- missingPaths - = paths
281
299
282
- // first fill cols that are already in the df
300
+ // first fill cols that are already in the df using the `with {}` part of the dsl
283
301
result = result.update { existingPaths.toColumnSet() }.with { filler.expr(this , this ) }
284
302
285
- // then create any missing ones by filling
303
+ // then create any missing ones by filling using the `with {}` part of the dsl
286
304
result = newPaths.fold(result) { df, newPath ->
287
305
df.add(newPath, Infer .Type ) { filler.expr(this , this ) }
288
306
}
307
+
308
+ // remove the paths that are now filled
309
+ missingPaths - = paths
289
310
}
290
311
312
+ // Inform the user which target columns could not be created in the conversion
313
+ // The user will need to supply extra information for these, like `fill {}` them.
291
314
if (missingPaths.isNotEmpty()) {
292
315
throw IllegalArgumentException (
293
316
" The following columns were not found in DataFrame: ${
0 commit comments