Skip to content

Commit e58a936

Browse files
author
Sven Van Caekenberghe
committed
Merge 760628f
2 parents 39e28b7 + 760628f commit e58a936

6 files changed

+411
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
Class {
2+
#name : #MACSVField,
3+
#superclass : #Object,
4+
#instVars : [
5+
'descriptionSource',
6+
'name',
7+
'encoder',
8+
'decoder'
9+
],
10+
#category : #'Neo-CSV-Magritte'
11+
}
12+
13+
{ #category : #accessing }
14+
MACSVField >> configureDescriptionFor: aWriter [
15+
16+
| description |
17+
self descriptionSource isSymbol ifTrue: [
18+
description := aWriter subjectDescription detect: [ :fieldDesc |
19+
fieldDesc definingContext methodSelector = self descriptionSource ] ].
20+
21+
self descriptionSource isBlock ifTrue: [
22+
description := self descriptionSource value.
23+
aWriter subjectDescription add: description ].
24+
25+
description
26+
propertyAt: aWriter fieldNamePropertyKey
27+
put: self name.
28+
29+
self encoder ifNotNil: [ :anEncoder |
30+
description
31+
propertyAt: aWriter fieldWriterPropertyKey
32+
put: anEncoder ].
33+
34+
self decoder ifNotNil: [ :aDecoder |
35+
description
36+
propertyAt: aWriter fieldWriterPropertyKey
37+
put: aDecoder ].
38+
39+
^ description
40+
]
41+
42+
{ #category : #accessing }
43+
MACSVField >> decoder [
44+
^ decoder
45+
]
46+
47+
{ #category : #accessing }
48+
MACSVField >> decoder: anObject [
49+
decoder := anObject
50+
]
51+
52+
{ #category : #accessing }
53+
MACSVField >> descriptionSource [
54+
^ descriptionSource
55+
]
56+
57+
{ #category : #accessing }
58+
MACSVField >> descriptionSource: anObject [
59+
"anObject - either a block returning a description, or the defining selector of a description already defined by the domain objects being written"
60+
61+
descriptionSource := anObject
62+
]
63+
64+
{ #category : #accessing }
65+
MACSVField >> encoder [
66+
^ encoder
67+
]
68+
69+
{ #category : #accessing }
70+
MACSVField >> encoder: anObject [
71+
encoder := anObject
72+
]
73+
74+
{ #category : #accessing }
75+
MACSVField >> name [
76+
^ name
77+
]
78+
79+
{ #category : #accessing }
80+
MACSVField >> name: anObject [
81+
name := anObject
82+
]

repository/Neo-CSV-Magritte/MACSVImporter.class.st

+10-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ MACSVImporter >> fieldNamePropertyKey [
2424
^ #csvFieldName
2525
]
2626

27+
{ #category : #accessing }
28+
MACSVImporter >> fieldReaderPropertyKey [
29+
"The property where the element description stores the field reader. Override to customize. See `MAElementDescription>>#csvReader:` method comment for more info"
30+
31+
^ #csvReader
32+
]
33+
2734
{ #category : #private }
2835
MACSVImporter >> importStream: aStream [
2936

@@ -39,7 +46,9 @@ MACSVImporter >> importStream: aStream [
3946
propertyAt: self fieldNamePropertyKey
4047
ifPresent: [ :fieldName | fieldName = h asString trimmed ]
4148
ifAbsent: [ false ] ]
42-
ifFound: [ :e | self reader addFieldDescribedByMagritte: e ]
49+
ifFound: [ :e |
50+
self flag: 'need a way to customize the reader here'.
51+
self reader addFieldDescribedByMagritte: e ]
4352
ifNone: [ self reader addIgnoredField ] ].
4453
^ self reader upToEnd "or do more processing e.g. `select: [ :record | record lastName isNotNil ]`"
4554
]

repository/Neo-CSV-Magritte/MACSVTestPerson.class.st

+55-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,35 @@ Class {
22
#name : #MACSVTestPerson,
33
#superclass : #Object,
44
#instVars : [
5-
'customReadField',
65
'phoneNumber',
76
'birthdate',
8-
'name'
7+
'name',
8+
'birthplace',
9+
'wikipediaUrl'
910
],
1011
#category : #'Neo-CSV-Magritte-Tests'
1112
}
1213

14+
{ #category : #accessing }
15+
MACSVTestPerson class >> exampleAlanKay [
16+
17+
^ self new
18+
name: 'Alan Kay';
19+
birthdate: '5/17/1940' asDate;
20+
birthplace: 'Springfield, Massachusetts, U.S.';
21+
wikipediaUrl: 'https://en.wikipedia.org/wiki/Alan_Kay' asUrl
22+
yourself
23+
]
24+
25+
{ #category : #'magritte-accessing' }
26+
MACSVTestPerson >> addressDescription [
27+
<magritteDescription>
28+
^ MAStringDescription new
29+
accessor: #address;
30+
priority: 40;
31+
yourself
32+
]
33+
1334
{ #category : #accessing }
1435
MACSVTestPerson >> birthdate [
1536
^ self maLazyInstVarUsing: self birthdateDescription
@@ -26,6 +47,26 @@ MACSVTestPerson >> birthdateDescription [
2647
^ MADateDescription new
2748
accessor: #birthdate;
2849
csvFieldName: 'DOB';
50+
priority: 30;
51+
yourself
52+
]
53+
54+
{ #category : #accessing }
55+
MACSVTestPerson >> birthplace [
56+
^ birthplace
57+
]
58+
59+
{ #category : #accessing }
60+
MACSVTestPerson >> birthplace: anObject [
61+
birthplace := anObject
62+
]
63+
64+
{ #category : #'magritte-accessing' }
65+
MACSVTestPerson >> birthplaceDescription [
66+
<magritteDescription>
67+
^ MAStringDescription new
68+
accessor: #birthplace;
69+
priority: 40;
2970
yourself
3071
]
3172

@@ -45,6 +86,7 @@ MACSVTestPerson >> nameDescription [
4586
^ MAStringDescription new
4687
accessor: #name;
4788
csvFieldName: 'Name';
89+
priority: 10;
4890
yourself
4991
]
5092

@@ -64,6 +106,17 @@ MACSVTestPerson >> phoneNumberDescription [
64106
^ MANumberDescription new
65107
accessor: #phoneNumber;
66108
csvFieldName: 'Phone Number';
109+
priority: 20;
67110
csvReader: [ :s | (s select: #isDigit) asNumber ];
68111
yourself
69112
]
113+
114+
{ #category : #accessing }
115+
MACSVTestPerson >> wikipediaUrl [
116+
^ wikipediaUrl
117+
]
118+
119+
{ #category : #accessing }
120+
MACSVTestPerson >> wikipediaUrl: anObject [
121+
wikipediaUrl := anObject
122+
]

repository/Neo-CSV-Magritte/MACSVTwoStageImporter.class.st

+82-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
Class {
22
#name : #MACSVTwoStageImporter,
33
#superclass : #MACSVImporter,
4+
#instVars : [
5+
'selectBlock',
6+
'preprocessor'
7+
],
48
#category : #'Neo-CSV-Magritte-Visitors'
59
}
610

711
{ #category : #accessing }
812
MACSVTwoStageImporter >> convertToDomainObjects: aCollectionOfDictionaries [
9-
self subclassResponsibility
13+
^ aCollectionOfDictionaries
14+
inject: OrderedCollection new
15+
into: [ :col :rowDict |
16+
| result |
17+
self preprocessor value: rowDict.
18+
(self selectBlock value: rowDict)
19+
ifTrue: [
20+
result := self domainObjectFromDictionary: rowDict.
21+
col add: result ].
22+
col ]
23+
]
24+
25+
{ #category : #accessing }
26+
MACSVTwoStageImporter >> domainObjectFromDictionary: aDictionary [
27+
28+
^ self
29+
initializeDomainObject: self recordClass new
30+
fromRecord: aDictionary
1031
]
1132

1233
{ #category : #accessing }
@@ -20,23 +41,80 @@ MACSVTwoStageImporter >> importStream: aStream [
2041
{ #category : #accessing }
2142
MACSVTwoStageImporter >> initializeDomainObject: anObject fromRecord: aDictionary [
2243
"We needed an instance-side version because some objects may need configuration during instance creation"
23-
anObject magritteDescription do: [ :desc |
44+
45+
^ self
46+
initializeDomainObject: anObject
47+
fromRecord: aDictionary
48+
mapping: [ :builder | ]
49+
]
50+
51+
{ #category : #accessing }
52+
MACSVTwoStageImporter >> initializeDomainObject: anObject fromRecord: aDictionary mapping: aBlock [
53+
54+
^ self
55+
initializeDomainObject: anObject
56+
fromRecord: aDictionary
57+
mapping: aBlock
58+
descriptionDo: #yourself
59+
]
60+
61+
{ #category : #accessing }
62+
MACSVTwoStageImporter >> initializeDomainObject: anObject fromRecord: aDictionary mapping: mapBlock descriptionDo: descriptionBlock [
63+
"
64+
anObject - domain objec to be initialized
65+
aDictionary - keys are CSV column names
66+
mapBlock - use to modify existing descriptions; argument will be an MACSVMappingPragmaBuilder to configure
67+
descriptionBlock - argument is the container description for anObject, for further configuration e.g. adding an element description"
68+
69+
| contDesc builder |
70+
builder := MACSVMappedPragmaBuilder new
71+
fieldNamePropertyKey: self fieldNamePropertyKey;
72+
fieldReaderPropertyKey: self fieldReaderPropertyKey;
73+
yourself.
74+
mapBlock value: builder.
75+
76+
contDesc := builder for: anObject.
77+
descriptionBlock value: contDesc.
78+
contDesc do: [ :desc |
2479
desc
2580
propertyAt: self fieldNamePropertyKey
2681
ifPresent: [ :fieldName |
27-
| stringValue value |
82+
| stringValue value fieldReader |
2883
stringValue := aDictionary at: fieldName.
2984
self flag: 'This next part looks very memento-like'.
3085
stringValue ifNotNil: [
31-
value := desc csvReader value: stringValue.
86+
fieldReader := desc
87+
propertyAt: self fieldReaderPropertyKey
88+
ifAbsent: [ desc csvReader ].
89+
value := fieldReader value: stringValue.
3290
desc write: value to: anObject ] ] ].
3391
^ anObject
3492
]
3593

94+
{ #category : #accessing }
95+
MACSVTwoStageImporter >> preprocessor [
96+
^ preprocessor ifNil: [ #yourself ]
97+
]
98+
99+
{ #category : #accessing }
100+
MACSVTwoStageImporter >> preprocessor: anObject [
101+
preprocessor := anObject
102+
]
103+
36104
{ #category : #accessing }
37105
MACSVTwoStageImporter >> readInput [
38106
^ self reader
39107
emptyFieldValue: #passNil;
40108
namedColumnsConfiguration;
41109
upToEnd.
42110
]
111+
112+
{ #category : #accessing }
113+
MACSVTwoStageImporter >> selectBlock [
114+
^ selectBlock ifNil: [ #isNotNil ]
115+
]
116+
117+
{ #category : #accessing }
118+
MACSVTwoStageImporter >> selectBlock: anObject [
119+
selectBlock := anObject
120+
]

0 commit comments

Comments
 (0)