diff --git a/src/DataFrame-IO-Tests/DataFrameCsvWriterTest.class.st b/src/DataFrame-IO-Tests/DataFrameCsvWriterTest.class.st index 12aaa6cb..19bb8b95 100644 --- a/src/DataFrame-IO-Tests/DataFrameCsvWriterTest.class.st +++ b/src/DataFrame-IO-Tests/DataFrameCsvWriterTest.class.st @@ -55,6 +55,36 @@ DataFrameCsvWriterTest >> testWriteToCsvLineEndLf [ self assert: actual lines equals: expected lines ] +{ #category : #tests } +DataFrameCsvWriterTest >> testWriteToCsvWithRawFieldWriter [ + + | file writer actual expected | + file := FileSystem memory workingDirectory / 'testData' / 'raw.csv'. + file ensureCreateFile. + writer := DataFrameCsvWriter new. + writer useRawFieldWriter. + dataFrame writeTo: file using: writer. + actual := self readFile: file. + expected := TestCsvStrings commaCsvString. + self assert: actual lines equals: expected lines +] + +{ #category : #tests } +DataFrameCsvWriterTest >> testWriteToCsvWithRawFieldWriterWithoutRowName [ + + | file writer actual expected | + file := FileSystem memory workingDirectory / 'testData' / 'raw.csv'. + file ensureCreateFile. + writer := DataFrameCsvWriter new. + writer + useRawFieldWriter; + disableRowName. + dataFrame writeTo: file using: writer. + actual := self readFile: file. + expected := TestCsvStrings commaCsvWithoutRowNameString. + self assert: actual lines equals: expected lines +] + { #category : #tests } DataFrameCsvWriterTest >> testWriteToCsvWithSeparatorTab [ | actual expected | diff --git a/src/DataFrame-IO-Tests/TestCsvStrings.class.st b/src/DataFrame-IO-Tests/TestCsvStrings.class.st index 06505c92..23c57e7c 100644 --- a/src/DataFrame-IO-Tests/TestCsvStrings.class.st +++ b/src/DataFrame-IO-Tests/TestCsvStrings.class.st @@ -15,6 +15,17 @@ TestCsvStrings class >> commaCsvString [ ' ] +{ #category : #running } +TestCsvStrings class >> commaCsvWithoutRowNameString [ + ^ 'temperature,precipitation,type +2.4,true,rain +0.5,true,rain +-1.2,true,snow +-2.3,false,- +3.2,true,rain +' +] + { #category : #running } TestCsvStrings class >> commaQuoteCsvString [ ^ '"","temperature","precipitation","type" diff --git a/src/DataFrame-IO/DataFrameCsvWriter.class.st b/src/DataFrame-IO/DataFrameCsvWriter.class.st index 1b114fd5..cbc1d9e4 100644 --- a/src/DataFrame-IO/DataFrameCsvWriter.class.st +++ b/src/DataFrame-IO/DataFrameCsvWriter.class.st @@ -3,11 +3,19 @@ Class { #superclass : #DataFrameWriter, #instVars : [ 'separator', - 'lineEndConvention' + 'lineEndConvention', + 'fieldWriter', + 'rowNameEnabled' ], #category : #'DataFrame-IO-Core' } +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> defaultFieldWriter [ + + ^ nil +] + { #category : #accessing } DataFrameCsvWriter >> defaultLineEndConvention [ ^ { @@ -17,16 +25,49 @@ DataFrameCsvWriter >> defaultLineEndConvention [ } asDictionary at: Smalltalk os lineEnding ] +{ #category : #accessing } +DataFrameCsvWriter >> defaultRowIndexEnabled [ + + ^ true +] + { #category : #accessing } DataFrameCsvWriter >> defaultSeparator [ ^ $, ] +{ #category : #'enable/disable' } +DataFrameCsvWriter >> disableRowName [ + + self rowNameEnabled: false +] + +{ #category : #'enable/disable' } +DataFrameCsvWriter >> enableRowName [ + + self rowNameEnabled: true +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> fieldWriter [ + + ^ fieldWriter +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> fieldWriter: aSymbol [ + + fieldWriter := aSymbol +] + { #category : #initialization } DataFrameCsvWriter >> initialize [ + super initialize. separator := self defaultSeparator. - lineEndConvention := self defaultLineEndConvention + lineEndConvention := self defaultLineEndConvention. + fieldWriter := self defaultFieldWriter. + rowNameEnabled := self defaultRowIndexEnabled ] { #category : #accessing } @@ -43,6 +84,42 @@ DataFrameCsvWriter >> lineEndConvention: aSymbol [ lineEndConvention := aSymbol ] +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> objectFieldWriter [ + + ^ #object +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> optionalQuotedFieldWriter [ + + ^ #optionalQuoted +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> quotedFieldWriter [ + + ^ #quoted +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> rawFieldWriter [ + + ^ #raw +] + +{ #category : #accessing } +DataFrameCsvWriter >> rowNameEnabled [ + + ^ rowNameEnabled +] + +{ #category : #accessing } +DataFrameCsvWriter >> rowNameEnabled: aBoolean [ + + rowNameEnabled := aBoolean = true +] + { #category : #accessing } DataFrameCsvWriter >> separator [ ^ separator @@ -53,25 +130,55 @@ DataFrameCsvWriter >> separator: anObject [ separator := anObject ] +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> useObjectFieldWriter [ + + self fieldWriter: self objectFieldWriter +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> useOptionalQuotedFieldWriter [ + + self fieldWriter: self optionalQuotedFieldWriter +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> useQuotedFieldWriter [ + + self fieldWriter: self quotedFieldWriter +] + +{ #category : #'accessing - field writers' } +DataFrameCsvWriter >> useRawFieldWriter [ + + self fieldWriter: self rawFieldWriter +] + { #category : #writing } DataFrameCsvWriter >> write: aDataFrame to: aFileReference [ + | stream writer | stream := aFileReference writeStream. writer := NeoCSVWriter on: stream. + fieldWriter ifNotNil: [ writer fieldWriter: fieldWriter ]. writer separator: self separator. writer lineEndConvention: self lineEndConvention. - writer - writeField: ''; - writeSeparator; - writeHeader: aDataFrame columnNames. - - aDataFrame do: [ :row | + self rowNameEnabled ifTrue: [ writer - writeField: row name; - writeSeparator; - nextPut: row ]. + writeField: ''; + writeSeparator ]. + writer writeHeader: aDataFrame columnNames. + + self rowNameEnabled + ifTrue: [ + aDataFrame do: [ :row | + writer + writeField: row name; + writeSeparator; + nextPut: row ] ] + ifFalse: [ aDataFrame do: [ :row | writer nextPut: row ] ]. writer close ]