@@ -17,6 +17,13 @@ export interface MSAccessConstructorOptions extends MDBOptions {
17
17
* `"csv"` generates a quad per table per column per row value.
18
18
*/
19
19
quadMode : "facade-x" | "csv" ;
20
+ /**
21
+ * Datatypes can simplify querying.
22
+ *
23
+ * `"original"` (default) are most similar to the Access column datatypes
24
+ * `"easy-sparql"`: maps to xsd:integer, xsd:decimal (with .) and xsd:double (with E)
25
+ */
26
+ datatypeMode : "original" | "easy-sparql" ;
20
27
/** Base URI, required for the Façade-X ontology. */
21
28
baseIRI : string ;
22
29
/** Used to create all the data model instances */
@@ -26,6 +33,7 @@ export interface MSAccessConstructorOptions extends MDBOptions {
26
33
export class MSAccess extends Readable implements RDF . Stream {
27
34
#db: MDBReader ;
28
35
#quadMode: MSAccessConstructorOptions [ "quadMode" ] ;
36
+ #datatypeMode: MSAccessConstructorOptions [ "datatypeMode" ] ;
29
37
#baseURI: string ;
30
38
#df: RDF . DataFactory ;
31
39
shouldRead : boolean ;
@@ -47,6 +55,7 @@ export class MSAccess extends Readable implements RDF.Stream {
47
55
48
56
// Default mode is facade-x
49
57
this . #quadMode = options . quadMode ?? "facade-x" ;
58
+ this . #datatypeMode = options . datatypeMode ?? "original" ;
50
59
this . #baseURI =
51
60
options . baseIRI ?? database instanceof Buffer
52
61
? "http://example.org/data#"
@@ -90,6 +99,8 @@ export class MSAccess extends Readable implements RDF.Stream {
90
99
91
100
/** Generate quads with a model akin to Facade-X. */
92
101
private * facadeXQuads ( ) {
102
+ const valueFunc = this . #datatypeMode == "original" ? this . originalValue : this . easySparqlValue ;
103
+
93
104
const TABLE = this . #baseURI;
94
105
95
106
for ( const tableName of this . #db. getTableNames ( ) ) {
@@ -111,7 +122,7 @@ export class MSAccess extends Readable implements RDF.Stream {
111
122
const columnType = tableData . getColumn ( column ) . type ;
112
123
113
124
const predicate = XYZ ( encodeURI ( column ) ) ;
114
- const object = this . mdbValueToObject ( value , columnType ) ;
125
+ const object = this . mdbValueToObject ( value , columnType , valueFunc ) ;
115
126
116
127
yield this . #df. quad ( row , predicate , object , graph ) ;
117
128
}
@@ -122,6 +133,8 @@ export class MSAccess extends Readable implements RDF.Stream {
122
133
123
134
/** Generate <csv:> quads. */
124
135
private * csvQuads ( ) {
136
+ const valueFunc = this . #datatypeMode == "original" ? this . originalValue : this . easySparqlValue ;
137
+
125
138
for ( const tableName of this . #db. getTableNames ( ) ) {
126
139
const table = this . #db. getTable ( tableName ) ;
127
140
// Each table is a used as a graph
@@ -137,7 +150,7 @@ export class MSAccess extends Readable implements RDF.Stream {
137
150
138
151
const subject = CSVNS ( `table/${ encodeURI ( tableName ) } /row/${ i_row } ` ) ;
139
152
const predicate = CSVNS ( encodeURI ( column ) ) ;
140
- const object = this . mdbValueToObject ( value , columnType ) ;
153
+ const object = this . mdbValueToObject ( value , columnType , valueFunc ) ;
141
154
142
155
yield this . #df. quad ( subject , predicate , object , context ) ;
143
156
}
@@ -146,9 +159,38 @@ export class MSAccess extends Readable implements RDF.Stream {
146
159
}
147
160
}
148
161
162
+ private easySparqlValue ( value : Value , columnType : ColumnType ) : [ string , N3 . NamedNode ] {
163
+ const conv : Record < ColumnType , ( v : Value ) => [ string , N3 . NamedNode ] > = {
164
+ [ ColumnType . Binary ] : ( v : Buffer ) => [ v . toString ( "base64" ) , XSD ( "base64Binary" ) ] ,
165
+ [ ColumnType . OLE ] : ( v : Buffer ) => [ v . toString ( "base64" ) , XSD ( "base64Binary" ) ] ,
166
+
167
+ [ ColumnType . Boolean ] : ( v : boolean ) => [ v ? "true" : "false" , XSD ( "boolean" ) ] ,
168
+
169
+ [ ColumnType . DateTime ] : ( v : Date ) => [ v . toISOString ( ) , XSD ( "dateTime" ) ] ,
170
+
171
+ [ ColumnType . Double ] : ( v : number ) => [ v . toString ( ) , XSD ( "double" ) ] ,
172
+
173
+ [ ColumnType . Float ] : ( v : number ) => [ v . toString ( ) , XSD ( "decimal" ) ] ,
174
+
175
+ [ ColumnType . BigInt ] : ( v : bigint ) => [ v . toString ( ) , XSD ( "integer" ) ] ,
176
+ [ ColumnType . Byte ] : ( v : number ) => [ v . toString ( ) , XSD ( "integer" ) ] ,
177
+ [ ColumnType . Integer ] : ( v : number ) => [ v . toFixed ( 0 ) , XSD ( "integer" ) ] ,
178
+ [ ColumnType . Complex ] : ( v : number ) => [ v . toString ( ) , XSD ( "integer" ) ] ,
179
+ [ ColumnType . Long ] : ( v : number ) => [ v . toFixed ( 0 ) , XSD ( "integer" ) ] ,
180
+
181
+ [ ColumnType . Currency ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
182
+ [ ColumnType . DateTimeExtended ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
183
+ [ ColumnType . Memo ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
184
+ [ ColumnType . Numeric ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
185
+ [ ColumnType . RepID ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
186
+ [ ColumnType . Text ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
187
+ } ;
188
+ return conv [ columnType ] ( value ) ;
189
+ }
190
+
149
191
/** Convert a MDB value to a RDF value with a specific datatype */
150
- mdbValueToObject ( value : Value , columnType : ColumnType ) : RDF . Literal {
151
- // TODO: Not all datatypes have been checked with what Access produces
192
+ private originalValue ( value : Value , columnType : ColumnType ) : [ string , N3 . NamedNode ] {
193
+ // Alphabetical order, ColumnTypes from mdb-reader
152
194
const conv : Record < ColumnType , ( v : Value ) => [ string , N3 . NamedNode ] > = {
153
195
[ ColumnType . BigInt ] : ( v : bigint ) => [ v . toString ( ) , XSD ( "integer" ) ] ,
154
196
[ ColumnType . Binary ] : ( v : Buffer ) => [ v . toString ( "base64" ) , XSD ( "base64Binary" ) ] ,
@@ -168,9 +210,17 @@ export class MSAccess extends Readable implements RDF.Stream {
168
210
[ ColumnType . RepID ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
169
211
[ ColumnType . Text ] : ( v : string ) => [ v , XSD ( "string" ) ] ,
170
212
} ;
213
+ return conv [ columnType ] ( value ) ;
214
+ }
171
215
216
+ mdbValueToObject (
217
+ value : Value ,
218
+ columnType : ColumnType ,
219
+ valueFunc : ( value : Value , columnType : ColumnType ) => [ string , N3 . NamedNode ] | undefined
220
+ ) : RDF . Literal {
221
+ valueFunc = valueFunc ?? this . originalValue ;
172
222
try {
173
- const [ nativeValue , languageOrDatatype ] = conv [ columnType ] ( value ) ;
223
+ const [ nativeValue , languageOrDatatype ] = valueFunc ( columnType , value ) ;
174
224
return this . #df. literal ( nativeValue , languageOrDatatype ) ;
175
225
} catch ( e ) {
176
226
return this . #df. literal ( value as string ) ;
0 commit comments