@@ -5,6 +5,7 @@ const attributeTypes = require('./types/attribute-types');
55const guesser = require ( './types/guesser' ) ;
66const store = require ( "./session_store" )
77const errorTypes = require ( './util/errors' ) ;
8+ const Range = require ( './util/range' ) ;
89
910// An implementation of the interface described in https://struct.register-dynamics.co.uk/trac/wiki/DataImporter/API
1011
@@ -78,13 +79,12 @@ exports.SessionGetSheets = (sid) => {
7879exports . SessionSetHeaderRange = ( sid , range ) => {
7980 assert ( range != null , "Null range passed to SessionSetHeaderRange" ) ;
8081 assert ( range . sheet != null , "Range with null sheet passed to SessionSetHeaderRange" ) ;
81-
8282 sessionStore . apply ( sid , ( s ) => { s . headerRanges [ range . sheet ] = range ; } )
8383} ;
8484
8585exports . SessionGetHeaderRange = ( sid , sheetName ) => {
8686 let session = sessionStore . get ( sid ) ;
87- return session . headerRanges [ sheetName ]
87+ return session . headerRanges [ sheetName ] ;
8888} ;
8989
9090exports . SessionSetFooterRange = ( sid , range ) => {
@@ -95,7 +95,7 @@ exports.SessionSetFooterRange = (sid, range) => {
9595
9696exports . SessionGetFooterRange = ( sid , sheetName ) => {
9797 let session = sessionStore . get ( sid ) ;
98- return session . footerRanges [ sheetName ]
98+ return session . footerRanges [ sheetName ] ;
9999} ;
100100
101101function getDimensions ( sid ) {
@@ -237,46 +237,28 @@ exports.SessionSuggestDataRange = (sid, headerRange, footerRange) => {
237237 // the header.
238238
239239 // Header and footer, so just go from the row below the header to the row above the footer
240- return {
241- sheet : sheetName ,
242- start : {
243- row : headerRange . start . row + 1 ,
244- column : headerRange . start . column
245- } ,
246- end : {
247- row : footerRange . start . row ,
248- column : headerRange . end . column
249- }
250- } ;
240+ return new Range (
241+ sheetName ,
242+ { row : headerRange . start . row + 1 , column : headerRange . start . column } ,
243+ { row : footerRange . start . row , column : headerRange . end . column }
244+ ) ;
251245 } else {
252246 // Header, but no footer, so just go from the row below the header to the end
253- return {
254- sheet : sheetName ,
255- start : {
256- row : headerRange . start . row + 1 ,
257- column : headerRange . start . column
258- } ,
259- end : {
260- row : sheetDimensions . rows - 1 ,
261- column : headerRange . end . column
262- }
263- } ;
247+ return new Range (
248+ sheetName ,
249+ { row : headerRange . start . row + 1 , column : headerRange . start . column } ,
250+ { row : sheetDimensions . rows - 1 , column : headerRange . end . column }
251+ ) ;
264252 }
265253 } else {
266254 // No header range specified, so take all but the first row of the first sheet
267255 const sheetName = sessionStore . get ( sid ) . sheetNames [ 0 ] ; // Find the first sheet
268256 const sheetDimensions = dimensions . sheetDimensions . get ( sheetName ) ;
269- return {
270- sheet : sheetName ,
271- start : {
272- row : 1 ,
273- column : 0
274- } ,
275- end : {
276- row : sheetDimensions . rows - 1 ,
277- column : sheetDimensions . columns - 1
278- }
279- } ;
257+ return new Range (
258+ sheetName ,
259+ { row : 1 , column : 0 } ,
260+ { row : sheetDimensions . rows - 1 , column : sheetDimensions . columns - 1 }
261+ ) ;
280262 }
281263}
282264
@@ -375,7 +357,8 @@ function cellsToSamples(row) {
375357 return row . map ( cellToSample ) ;
376358}
377359
378- // Returns a sample of rows in a range. range is of the form {sheet: 'Foo', start:{row: X, column: Y}, end:{row: X, column: Y} }.
360+ // Returns a sample of rows in a range. range is and instance of the Range class and
361+ // is of the form {sheet: 'Foo', start:{row: X, column: Y}, end:{row: X, column: Y} }.
379362
380363// Returns three arrays - one with startCount rows from the top of the range,
381364// one with a random selectino of middleCount rows from the middle, and another
@@ -385,15 +368,15 @@ function cellsToSamples(row) {
385368exports . SessionGetInputSampleRows = ( sid , range , startCount , middleCount , endCount ) => {
386369 assert ( range != null , "Null range passed to SessionGetInputSampleRows" ) ;
387370 assert ( sessionStore . has ( sid ) , `No such session ${ sid } when getting input sample rows` ) ;
388- assert ( sessionStore . get ( sid ) . wb . Sheets [ range . sheet ] , `No such sheet ${ range . sheet } in session ${ sid } when getting input sample rows` ) ;
371+ assert ( sessionStore . get ( sid ) . wb . Sheets [ range . sheet ] , `No such sheet ${ range . sheet } in session ${ sid } when getting input values` ) ;
372+
389373 if ( range . end . row < range . start . row || range . end . column < range . start . column ) {
390374 // Range is empty
391375 return [ [ ] , [ ] , [ ] ] ;
392376 }
393377 // If the caller asked for more rows than we have, or if the start/middle/end would overlap, clamp the counts
394378 const totalRowsInRange = ( range . end . row - range . start . row + 1 ) ;
395379 [ startCount , middleCount , endCount ] = clampCounts ( startCount , middleCount , endCount , totalRowsInRange ) ;
396-
397380 const sheet = sessionStore . get ( sid ) . wb . Sheets [ range . sheet ] ;
398381 const data = sheet [ "!data" ] ;
399382 const merges = sheet [ "!merges" ] ;
@@ -418,7 +401,6 @@ exports.SessionGetInputSampleRows = (sid, range, startCount, middleCount, endCou
418401 let endRows = extractColsFromRows ( getMergedRows ( sheet , range . end . row - endCount + 1 , range . end . row ) ,
419402 range . start . column , range . end . column + 1 ) ;
420403
421-
422404 // Given an index generate a function that we can use to map across an array to turn it into
423405 // an object with both index and the array data.
424406 const mapWithIndex = ( arr , startIndex ) => {
@@ -430,12 +412,6 @@ exports.SessionGetInputSampleRows = (sid, range, startCount, middleCount, endCou
430412 }
431413 }
432414
433- // FIXME: Work out how the xlsx library represents styles and
434- // rowspan/colspan and make sure that what we return does something useful
435- // with that information. We DO want styling information to be available in
436- // the preview, so that users can see their spreadsheet in a more familiar
437- // form, and because styling information might be a significant part of the
438- // data.
439415 return [
440416 startRows . map ( mapWithIndex ( startRows , range . start . row ) ) ,
441417 middleRows . map ( mapWithIndex ( middleRows , middleStart ) ) ,
@@ -532,8 +508,8 @@ exports.SessionGuessTypes = (sid, range) => {
532508// objects with string fields "displayName" and "description", and an optional Map
533509// field "formats" that maps from format names (as returned by SessionGetTypes)
534510// to objects with strings field "displayName" and "description".
535- exports . SessionGetSupportedTypes = ( sid ) => {
536- return types . supportedTypes ;
511+ exports . SessionGetSupportedTypes = ( _sid ) => {
512+ return attributeTypes . supportedTypes ;
537513} ;
538514
539515// Given guesses as returned by SessionGuessTypes and a list of domain-model
@@ -573,8 +549,7 @@ exports.SessionSuggestFields = (sid, typeGuesses, domainModelFields) => {
573549exports . SessionGetInputValues = ( sid , range , maxValues ) => {
574550 assert ( sessionStore . get ( sid ) , `No such session ${ sid } when getting input values` ) ;
575551 assert ( sessionStore . get ( sid ) . wb . Sheets [ range . sheet ] , `No such sheet ${ range . sheet } in session ${ sid } when getting input values` ) ;
576- assert ( range . end . row >= range . start . row , `End row (${ range . end . row } ) must be >= start row (${ range . start . row } ) to get input values` ) ;
577- assert ( range . end . column >= range . start . column , `End column (${ range . end . column } ) must be >= start column (${ range . start . column } ) to get input values` ) ;
552+ assert ( range . isValid ( ) , `Range is invalid: end (${ JSON . stringify ( range . end ) } ) must be >= start (${ JSON . stringify ( range . start ) } ) to get input values` ) ;
578553
579554 const sheet = sessionStore . get ( sid ) . wb . Sheets [ range . sheet ] ;
580555 const data = sheet [ "!data" ] ;
@@ -679,7 +654,7 @@ exports.SessionPerformMappingJob = (sid, range, mapping, includeErrorRow = false
679654 validateMapping ( range , mapping ) ;
680655
681656 const records = new Array ( ) ; // Array of output records
682- const errors = new Array ( ) ; ;
657+ const errors = new Array ( ) ;
683658 const warnings = new Array ( ) ;
684659
685660 const sheet = sessionStore . get ( sid ) . wb . Sheets [ range . sheet ] ;
@@ -688,15 +663,14 @@ exports.SessionPerformMappingJob = (sid, range, mapping, includeErrorRow = false
688663 const attrMap = Object . entries ( mapping . attributeMappings ) ;
689664 const attrTypes = mapping . attributeTypes || { } ;
690665
691-
692- // TODO: Replace this with a map/sum once range is a real type.
666+ // Use Range.applyRows to determine expectedColumnCount
693667 let expectedColumnCount = 0 ;
694- for ( let rowIdx = range . start . row ; rowIdx <= range . end . row ; rowIdx ++ ) {
668+ range . applyRows ( ( rowIdx ) => {
695669 let row = getMergedRow ( data , merges , rowIdx ) ;
696670 if ( row && row . length > expectedColumnCount ) expectedColumnCount = row . length ;
697- }
671+ } ) ;
698672
699- for ( let rowIdx = range . start . row ; rowIdx <= range . end . row ; rowIdx ++ ) {
673+ range . applyRows ( ( rowIdx ) => {
700674 let rowErrorCount = 0 ;
701675 let row = getMergedRow ( data , merges , rowIdx ) ;
702676 let recordCells = { } ;
@@ -706,7 +680,7 @@ exports.SessionPerformMappingJob = (sid, range, mapping, includeErrorRow = false
706680 // Ensure we exclude footer rows from the validation as they may not
707681 // have the same number of columns as the header row.
708682 if ( rowIdx == range . end . row && footerRange ) {
709- continue ;
683+ return ;
710684 }
711685
712686 if ( row . length < expectedColumnCount ) {
@@ -777,7 +751,7 @@ exports.SessionPerformMappingJob = (sid, range, mapping, includeErrorRow = false
777751 } else {
778752 warnings . push ( { row : rowIdx , type : errorTypes . ValidationError . EmptyRow ( { } ) } )
779753 }
780- }
754+ } ) ;
781755
782756 let jid = makeAccessToken ( "j" ) ;
783757 let job = new JobResult ( records , errors , warnings ) ;
0 commit comments