diff --git a/appveyor.yml b/appveyor.yml index dc799e7..1c6cd8a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,4 +4,13 @@ build_script: - ps: .\build.ps1 test: off artifacts: -- path: 'src\**\*.nupkg' \ No newline at end of file +- path: 'src\**\*.nupkg' +deploy: + - provider: NuGet + on: + branch: master + APPVEYOR_REPO_TAG: true + symbol_server: https://ci.appveyor.com/nuget/josdeweger-7u3d88pyya90/api/v2/package + api_key: + secure: d1CMBHpVrKHJOZxYueO4x/ROshtrPzJ8vPqKjxCT0NI= + artifact: /.*\.symbols\.nupkg/ \ No newline at end of file diff --git a/src/Common.props b/src/Common.props index 297935f..32af634 100644 --- a/src/Common.props +++ b/src/Common.props @@ -1,5 +1,5 @@ - 2.3.0 + 2.4.0 diff --git a/src/SheetToObjects.Core/MaybeExtensions.cs b/src/SheetToObjects.Core/MaybeExtensions.cs new file mode 100644 index 0000000..33c3617 --- /dev/null +++ b/src/SheetToObjects.Core/MaybeExtensions.cs @@ -0,0 +1,24 @@ +using System; +using CSharpFunctionalExtensions; + +namespace SheetToObjects.Core +{ + internal static class MaybeExtensions + { + public static Maybe OnEmpty(this Maybe maybe, Func resultFunc) + { + if(maybe.HasNoValue) + return Maybe.From(resultFunc()); + + return maybe; + } + + public static Maybe OnValue(this Maybe maybe, Func resultFunc) + { + if(maybe.HasNoValue) + return Maybe.None; + + return Maybe.From(resultFunc(maybe.Value)); + } + } +} diff --git a/src/SheetToObjects.Core/SheetToObjects.Core.csproj b/src/SheetToObjects.Core/SheetToObjects.Core.csproj index 60615a5..f196f4a 100644 --- a/src/SheetToObjects.Core/SheetToObjects.Core.csproj +++ b/src/SheetToObjects.Core/SheetToObjects.Core.csproj @@ -13,8 +13,8 @@ true https://github.com/josdeweger/SheetToObjects - + diff --git a/src/SheetToObjects.Lib/Extensions/ResultExtensions.cs b/src/SheetToObjects.Lib/Extensions/ResultExtensions.cs new file mode 100644 index 0000000..7be47d8 --- /dev/null +++ b/src/SheetToObjects.Lib/Extensions/ResultExtensions.cs @@ -0,0 +1,26 @@ +using System; +using CSharpFunctionalExtensions; + +namespace SheetToObjects.Lib.Extensions +{ + internal static class ResultExtensions + { + public static Result OnValidationSuccess(this Result result, Func func) + where TError : class + { + if (result.IsSuccess) + return Result.Ok(func(result.Value)); + + return Result.Fail(result.Error); + } + + public static Result OnValidationFailure(this Result result, Func func) + where TError : class + { + if (result.IsFailure) + return Result.Fail(func(result.Error)); + + return Result.Ok(result.Value); + } + } +} diff --git a/src/SheetToObjects.Lib/IMapRow.cs b/src/SheetToObjects.Lib/IMapRow.cs index 6ee43f0..149e6af 100644 --- a/src/SheetToObjects.Lib/IMapRow.cs +++ b/src/SheetToObjects.Lib/IMapRow.cs @@ -7,7 +7,7 @@ namespace SheetToObjects.Lib { public interface IMapRow { - Result, List> Map(Row row, MappingConfig mappingConfig) + Result, List> Map(Row row, MappingConfig mappingConfig) where TModel : new(); } } \ No newline at end of file diff --git a/src/SheetToObjects.Lib/IMapValue.cs b/src/SheetToObjects.Lib/IMapValue.cs index 7919e37..345a336 100644 --- a/src/SheetToObjects.Lib/IMapValue.cs +++ b/src/SheetToObjects.Lib/IMapValue.cs @@ -10,7 +10,6 @@ internal interface IMapValue Result Map( string value, Type propertyType, - int columnIndex, int rowIndex, ColumnMapping columnMapping); } diff --git a/src/SheetToObjects.Lib/MappingResult.cs b/src/SheetToObjects.Lib/MappingResult.cs index 1021f6c..532da14 100644 --- a/src/SheetToObjects.Lib/MappingResult.cs +++ b/src/SheetToObjects.Lib/MappingResult.cs @@ -7,19 +7,19 @@ namespace SheetToObjects.Lib public class MappingResult where T : new() { - public List> ParsedModels { get; set; } + public List> ParsedModels { get; set; } public List ValidationErrors { get; set; } public bool IsFailure => ValidationErrors.Any(); public bool IsSuccess => !IsFailure; - private MappingResult(List> parsedModels, List validationErrors) + private MappingResult(List> parsedModels, List validationErrors) { ParsedModels = parsedModels; ValidationErrors = validationErrors; } - public static MappingResult Create(List> parsedModels,List validationErrors) + public static MappingResult Create(List> parsedModels,List validationErrors) { return new MappingResult(parsedModels, validationErrors); } diff --git a/src/SheetToObjects.Lib/ParsedModel.cs b/src/SheetToObjects.Lib/ParsedModel.cs new file mode 100644 index 0000000..089bf38 --- /dev/null +++ b/src/SheetToObjects.Lib/ParsedModel.cs @@ -0,0 +1,14 @@ +namespace SheetToObjects.Lib +{ + public class ParsedModel where TModel : new() + { + public TModel Value { get; } + public int RowIndex { get; } + + public ParsedModel(TModel value, int rowIndex) + { + Value = value; + RowIndex = rowIndex; + } + } +} \ No newline at end of file diff --git a/src/SheetToObjects.Lib/ParsedModelResult.cs b/src/SheetToObjects.Lib/ParsedModelResult.cs deleted file mode 100644 index 2e75932..0000000 --- a/src/SheetToObjects.Lib/ParsedModelResult.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace SheetToObjects.Lib -{ - public class ParsedModelResult where TModel : new() - { - public TModel ParsedModel { get; } - public int RowIndex { get; } - - public ParsedModelResult(TModel parsedModel, int rowIndex) - { - ParsedModel = parsedModel; - RowIndex = rowIndex; - } - } -} \ No newline at end of file diff --git a/src/SheetToObjects.Lib/RowMapper.cs b/src/SheetToObjects.Lib/RowMapper.cs index 42cad3c..670ee97 100644 --- a/src/SheetToObjects.Lib/RowMapper.cs +++ b/src/SheetToObjects.Lib/RowMapper.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Reflection; using CSharpFunctionalExtensions; using SheetToObjects.Core; using SheetToObjects.Lib.FluentConfiguration; @@ -16,55 +17,71 @@ public RowMapper(IMapValue valueMapper) _valueMapper = valueMapper; } - public Result, List> Map(Row row, MappingConfig mappingConfig) - where TModel : new() + public Result, List> Map(Row row, MappingConfig mappingConfig) + where T : new() { - var rowIValidationErrors = new List(); - var obj = new TModel(); + var rowValidationErrors = new List(); + var obj = new T(); var properties = obj.GetType().GetProperties().ToList(); properties.ForEach(property => { - var columnMapping = mappingConfig.GetColumnMappingByPropertyName(property.Name); + rowValidationErrors.AddRange(MapRow(row, mappingConfig, property, obj)); + }); - if (columnMapping.IsNull()) - return; + if (rowValidationErrors.Any()) + return Result.Fail, List>(rowValidationErrors); + + return Result.Ok, List>(new ParsedModel(obj, row.RowIndex)); + } - var cell = row.GetCellByColumnIndex(columnMapping.ColumnIndex); + private IEnumerable MapRow( + Row row, + MappingConfig mappingConfig, + PropertyInfo property, + TModel obj) where TModel : new() + { + var columnMapping = mappingConfig.GetColumnMappingByPropertyName(property.Name); - if (cell == null) - { - var parsingValidationError = ParsingValidationError.CellNotFound(columnMapping.ColumnIndex, row.RowIndex, - columnMapping.DisplayName, property.Name); + if (columnMapping.IsNull()) + return new List(); - if (columnMapping.IsRequired) - rowIValidationErrors.Add(parsingValidationError); + var cell = row.GetCellByColumnIndex(columnMapping.ColumnIndex); - return; - } + if (cell == null) + { + return HandleEmptyCell(columnMapping, row.RowIndex, property.Name) + .OnValue(error => new List { error }) + .OnEmpty(() => new List()) + .Unwrap(); + } - _valueMapper.Map( - cell.Value.ToString(), - property.PropertyType, - columnMapping.ColumnIndex, - row.RowIndex, - columnMapping) - .OnSuccess(value => - { - if (value.ToString().IsNotNullOrEmpty()) - { - property.SetValue(obj, value); - } - }) - .OnFailure(validationError => { rowIValidationErrors.Add(validationError); }); - }); + var validationErrors = new List(); - if (rowIValidationErrors.Any()) - return Result.Fail, List>(rowIValidationErrors); + _valueMapper + .Map(cell.Value.ToString(), property.PropertyType, row.RowIndex, columnMapping) + .OnSuccess(value => + { + if (value.ToString().IsNotNullOrEmpty()) + property.SetValue(obj, value); + }) + .OnFailure(validationError => { validationErrors.Add(validationError); }); + + return validationErrors; + } + + private static Maybe HandleEmptyCell(ColumnMapping columnMapping, int rowIndex, string propertyName) + { + if (!columnMapping.IsRequired) + return Maybe.None; - var parsedModelResult = new ParsedModelResult(obj, row.RowIndex); + var parsingValidationError = ParsingValidationError.CellNotFound( + columnMapping.ColumnIndex, + rowIndex, + columnMapping.DisplayName, + propertyName); - return Result.Ok, List>(parsedModelResult); + return Maybe.From(parsingValidationError); } } } \ No newline at end of file diff --git a/src/SheetToObjects.Lib/SheetMapper.cs b/src/SheetToObjects.Lib/SheetMapper.cs index 93961bc..5872903 100644 --- a/src/SheetToObjects.Lib/SheetMapper.cs +++ b/src/SheetToObjects.Lib/SheetMapper.cs @@ -45,7 +45,7 @@ public SheetMapper AddConfigFor(Func, MappingConfigBu public MappingResult Map(Sheet sheet) where T : new() { - var parsedModels = new List>(); + var parsedModels = new List>(); var validationErrors = new List(); var mappingConfig = GetMappingConfig(); @@ -72,7 +72,7 @@ public MappingResult Map(Sheet sheet) ); } - private void MapRows(Sheet sheet, MappingConfig mappingConfig, List> parsedModels, List validationErrors) + private void MapRows(Sheet sheet, MappingConfig mappingConfig, List> parsedModels, List validationErrors) where T : new() { var dataRows = mappingConfig.HasHeaders ? sheet.Rows.Skip(1).ToList() : sheet.Rows; diff --git a/src/SheetToObjects.Lib/SheetToObjects.Lib.csproj b/src/SheetToObjects.Lib/SheetToObjects.Lib.csproj index b2ac7f3..8d0b911 100644 --- a/src/SheetToObjects.Lib/SheetToObjects.Lib.csproj +++ b/src/SheetToObjects.Lib/SheetToObjects.Lib.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/SheetToObjects.Lib/Validation/IValidateColumn.cs b/src/SheetToObjects.Lib/Validation/IValidateColumn.cs index 96facf8..cdac596 100644 --- a/src/SheetToObjects.Lib/Validation/IValidateColumn.cs +++ b/src/SheetToObjects.Lib/Validation/IValidateColumn.cs @@ -5,8 +5,8 @@ namespace SheetToObjects.Lib.Validation { internal interface IValidateColumn { - ValidationResult> Validate( - List> parsedModels, + ValidationResult> Validate( + List> parsedModels, List columnMappings) where TModel : new(); } diff --git a/src/SheetToObjects.Lib/Validation/IValidateModels.cs b/src/SheetToObjects.Lib/Validation/IValidateModels.cs index 0810442..7316411 100644 --- a/src/SheetToObjects.Lib/Validation/IValidateModels.cs +++ b/src/SheetToObjects.Lib/Validation/IValidateModels.cs @@ -5,8 +5,8 @@ namespace SheetToObjects.Lib.Validation { internal interface IValidateModels { - ValidationResult> Validate( - List> parsedModels, + ValidationResult> Validate( + List> parsedModels, List columnMappings) where TModel : new(); } diff --git a/src/SheetToObjects.Lib/Validation/ModelValidator.cs b/src/SheetToObjects.Lib/Validation/ModelValidator.cs index c6a6bcb..08f1750 100644 --- a/src/SheetToObjects.Lib/Validation/ModelValidator.cs +++ b/src/SheetToObjects.Lib/Validation/ModelValidator.cs @@ -9,12 +9,12 @@ namespace SheetToObjects.Lib.Validation { internal class ModelValidator : IValidateModels { - public ValidationResult> Validate( - List> parsedModels, + public ValidationResult> Validate( + List> parsedModels, List columnMappings) where TModel : new() { - var validatedModels = new List>(); + var validatedModels = new List>(); var validationErrors = new List(); var properties = typeof(TModel).GetProperties(); @@ -22,14 +22,14 @@ public ValidationResult> Validate( validationErrors.AddRange(ValidateColumnRules(parsedModels, columnMappings, properties)); - return new ValidationResult>(validatedModels, validationErrors); + return new ValidationResult>(validatedModels, validationErrors); } private static List ValidatePropertyRules( - List> parsedModels, + List> parsedModels, List columnMappings, PropertyInfo[] properties, - List> validatedModels) where TModel : new() + List> validatedModels) where TModel : new() { var validationErrors = new List(); @@ -56,7 +56,7 @@ private static List ValidatePropertyRules( } private static List ValidateColumnRules( - List> parsedModels, + List> parsedModels, List columnMappings, PropertyInfo[] properties) where TModel : new() { @@ -75,7 +75,7 @@ private static List ValidateColumnRules( .Validate( columnMapping.ColumnIndex, columnMapping.DisplayName, - parsedModels.Select(p => propertyInfo.GetValue(p.ParsedModel)).ToList() + parsedModels.Select(p => propertyInfo.GetValue(p.Value)).ToList() ) .OnFailure(validationErrors.Add)); } @@ -85,29 +85,29 @@ private static List ValidateColumnRules( private static List ValidateRules( PropertyInfo property, - ParsedModelResult parsedModelResult, + ParsedModel parsedModel, ColumnMapping columnMapping) where TModel : new() { var modelValidationErrors = new List(); - var propertyValue = property.GetValue(parsedModelResult.ParsedModel); + var propertyValue = property.GetValue(parsedModel.Value); GetRulesOfType(columnMapping) .ForEach(genericRule => genericRule - .Validate(columnMapping.ColumnIndex, parsedModelResult.RowIndex, columnMapping.DisplayName, property.Name, + .Validate(columnMapping.ColumnIndex, parsedModel.RowIndex, columnMapping.DisplayName, property.Name, propertyValue) .OnFailure(modelValidationErrors.Add)); GetRulesOfType(columnMapping) .ForEach(comparableRule => comparableRule - .Validate(columnMapping.ColumnIndex, parsedModelResult.RowIndex, columnMapping.DisplayName, property.Name, + .Validate(columnMapping.ColumnIndex, parsedModel.RowIndex, columnMapping.DisplayName, property.Name, propertyValue) .OnFailure(modelValidationErrors.Add)); GetRulesOfType(columnMapping) .ForEach(customRule => customRule - .Validate(columnMapping.ColumnIndex, parsedModelResult.RowIndex, columnMapping.DisplayName, property.Name, + .Validate(columnMapping.ColumnIndex, parsedModel.RowIndex, columnMapping.DisplayName, property.Name, propertyValue) .OnFailure(modelValidationErrors.Add)); diff --git a/src/SheetToObjects.Lib/ValueMapper.cs b/src/SheetToObjects.Lib/ValueMapper.cs index 4fcf6b9..1fce2f7 100644 --- a/src/SheetToObjects.Lib/ValueMapper.cs +++ b/src/SheetToObjects.Lib/ValueMapper.cs @@ -1,6 +1,7 @@ using System; using CSharpFunctionalExtensions; using SheetToObjects.Core; +using SheetToObjects.Lib.Extensions; using SheetToObjects.Lib.FluentConfiguration; using SheetToObjects.Lib.Parsing; using SheetToObjects.Lib.Validation; @@ -16,16 +17,11 @@ public ValueMapper(IProvideParsingStrategy valueParser) _valueParser = valueParser; } - public Result Map( - string value, - Type propertyType, - int columnIndex, - int rowIndex, - ColumnMapping columnMapping) + public Result Map(string value, Type propertyType, int rowIndex, ColumnMapping columnMapping) { if (string.IsNullOrEmpty(value)) { - return HandleEmptyValue(columnIndex, rowIndex, columnMapping); + return HandleEmptyValue(columnMapping.ColumnIndex, rowIndex, columnMapping); } if (columnMapping.CustomValueParser.IsNotNull()) @@ -38,7 +34,7 @@ public Result Map( catch (Exception) { var parsingValidationError = ParsingValidationError.CouldNotParseValue( - columnIndex, + columnMapping.ColumnIndex, rowIndex, columnMapping.DisplayName, columnMapping.PropertyName); @@ -47,20 +43,14 @@ public Result Map( } } - var parsingResult = _valueParser.Parse(propertyType, value, columnMapping.Format); - - if (!parsingResult.IsSuccess) - { - var validationError = ParsingValidationError.CouldNotParseValue( - columnIndex, + return _valueParser + .Parse(propertyType, value, columnMapping.Format) + .OnValidationSuccess(parsedValue => parsedValue) + .OnValidationFailure(error => ParsingValidationError.CouldNotParseValue( + columnMapping.ColumnIndex, rowIndex, columnMapping.DisplayName, - columnMapping.PropertyName); - - return Result.Fail(validationError); - } - - return Result.Ok(parsingResult.Value); + columnMapping.PropertyName)); } private static Result HandleEmptyValue(int columnIndex, int rowIndex, ColumnMapping columnMapping) diff --git a/src/SheetToObjects.Specs/Lib/SheetMapperSpecs.cs b/src/SheetToObjects.Specs/Lib/SheetMapperSpecs.cs index f69ddbd..07b2516 100644 --- a/src/SheetToObjects.Specs/Lib/SheetMapperSpecs.cs +++ b/src/SheetToObjects.Specs/Lib/SheetMapperSpecs.cs @@ -56,7 +56,7 @@ public void GivenSheet_WhenMappingModelDoubleProperty_ItSetsPropertyOnModel() .Map(_sheetData); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.Single().ParsedModel.DoubleProperty.Should().Be(_doubleValue); + result.ParsedModels.Single().Value.DoubleProperty.Should().Be(_doubleValue); } [Fact] @@ -69,7 +69,7 @@ public void GivenSheet_WhenMappingModelIntProperty_ItSetsPropertyOnModel() .Map(_sheetData); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.Single().ParsedModel.IntProperty.Should().Be(_intValue); + result.ParsedModels.Single().Value.IntProperty.Should().Be(_intValue); } [Fact] @@ -82,7 +82,7 @@ public void GivenSheet_WhenMappingModelBoolProperty_ItSetsPropertyOnModel() .Map(_sheetData); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.Single().ParsedModel.BoolProperty.Should().Be(_boolValue); + result.ParsedModels.Single().Value.BoolProperty.Should().Be(_boolValue); } [Fact] @@ -95,7 +95,7 @@ public void GivenSheet_WhenMappingModelEnumProperty_ItSetsPropertyOnModel() .Map(_sheetData); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.Single().ParsedModel.EnumProperty.Should().Be(_enumValue); + result.ParsedModels.Single().Value.EnumProperty.Should().Be(_enumValue); } [Fact] @@ -112,7 +112,7 @@ public void GivenSheet_WhenMappingModelDateTimeProperty_ItSetsPropertyOnModel() .Map(_sheetData); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.Single().ParsedModel.DateTimeProperty.Should().Be(_dateTimeValue); + result.ParsedModels.Single().Value.DateTimeProperty.Should().Be(_dateTimeValue); } [Fact] @@ -127,7 +127,7 @@ public void GivenSheet_WhenMappingModelStringProperty_ItSetsPropertyOnModel() .Map(_sheetData); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.Single().ParsedModel.StringProperty.Should().Be(_stringValue); + result.ParsedModels.Single().Value.StringProperty.Should().Be(_stringValue); } [Fact] @@ -211,10 +211,10 @@ public void GivenSheetMapper_WhenCreatingTwoConfigs_TheyBothExist() var resultModelTwo = sheetMapper.Map(sheetDataModelTwo); resultModelOne.IsSuccess.Should().BeTrue(); - resultModelOne.ParsedModels.Single().ParsedModel.ModelOnePropertyOne.Should().Be("SomeValue"); + resultModelOne.ParsedModels.Single().Value.ModelOnePropertyOne.Should().Be("SomeValue"); resultModelTwo.IsSuccess.Should().BeTrue(); - resultModelTwo.ParsedModels.Single().ParsedModel.ModelTwoPropertyOne.Should().Be(1); + resultModelTwo.ParsedModels.Single().Value.ModelTwoPropertyOne.Should().Be(1); } [Fact] @@ -239,7 +239,7 @@ public void GivenSheet_WhenMappingEmptyNonNullableValueTypeWhichIsNotRequired_It .Map(sheetData); result.IsSuccess.Should().BeTrue(); - result.ParsedModels.Single().ParsedModel.IntProperty.Should().Be(defaultAge); + result.ParsedModels.Single().Value.IntProperty.Should().Be(defaultAge); } [Fact] @@ -264,7 +264,7 @@ public void GivenSheet_WhenMappingEmptyStringWhichIsNotRequired_ItShouldSetDefau .Map(sheetData); result.IsSuccess.Should().BeTrue(); - result.ParsedModels.Single().ParsedModel.StringProperty.Should().Be(defaultLabel); + result.ParsedModels.Single().Value.StringProperty.Should().Be(defaultLabel); } [Fact] @@ -377,7 +377,7 @@ public void GivenSheet_WhenCustomBooleanParserIsProvided_ValueIsConvertedToBoole result.IsSuccess.Should().BeTrue(); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.First().ParsedModel.BoolProperty.Should().BeTrue(); + result.ParsedModels.First().Value.BoolProperty.Should().BeTrue(); } [Fact] @@ -409,7 +409,7 @@ public void GivenSheet_WhenCustomEnumParserIsProvided_ValueIsConvertedToEnum() result.IsSuccess.Should().BeTrue(); result.ParsedModels.Should().HaveCount(1); - result.ParsedModels.First().ParsedModel.EnumProperty.Should().Be(EnumModel.Second); + result.ParsedModels.First().Value.EnumProperty.Should().Be(EnumModel.Second); } [Fact] diff --git a/src/SheetToObjects.Specs/Lib/ValueMapperSpecs.cs b/src/SheetToObjects.Specs/Lib/ValueMapperSpecs.cs index b85c221..3eb1659 100644 --- a/src/SheetToObjects.Specs/Lib/ValueMapperSpecs.cs +++ b/src/SheetToObjects.Specs/Lib/ValueMapperSpecs.cs @@ -24,7 +24,6 @@ public void GivenNotRequiredEmptyValue_WhenMapping_ItIsSetToDefaultValue() var result = mapper.Map( value: string.Empty, propertyType: typeof(int), - columnIndex: 0, rowIndex: 0, columnMapping: columnMapping); @@ -49,7 +48,6 @@ public void GivenRequiredEmptyValue_WhenMapping_ValidationFails() var result = mapper.Map( value: string.Empty, propertyType: typeof(int), - columnIndex: 0, rowIndex: 0, columnMapping: columnMapping); @@ -70,7 +68,6 @@ public void GivenValidValue_WhenParsingIsSuccesful_ItSucceeds() var result = mapper.Map( value: value.ToString(), propertyType: typeof(int), - columnIndex: 0, rowIndex: 0, columnMapping: columnMapping); @@ -92,7 +89,6 @@ public void GivenInvalidValue_WhenParsingFails_FailureIsReturned() var result = mapper.Map( value: value, propertyType: typeof(int), - columnIndex: 0, rowIndex: 0, columnMapping: columnMapping);