Files
ezbookkeeping/pkg/converters/ezbookkeeping_transaction_data_plain_text_data_table.go
T
2024-09-11 01:40:42 +08:00

205 lines
6.5 KiB
Go

package converters
import (
"fmt"
"strings"
"time"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
// ezBookKeepingTransactionPlainTextDataTable defines the structure of ezbookkeeping transaction plain text data table
type ezBookKeepingTransactionPlainTextDataTable struct {
columnSeparator string
lineSeparator string
allLines []string
headerLineColumnNames []string
}
// ezBookKeepingTransactionPlainTextDataRow defines the structure of ezbookkeeping transaction plain text data row
type ezBookKeepingTransactionPlainTextDataRow struct {
allItems []string
}
// ezBookKeepingTransactionPlainTextDataRowIterator defines the structure of ezbookkeeping transaction plain text data row iterator
type ezBookKeepingTransactionPlainTextDataRowIterator struct {
dataTable *ezBookKeepingTransactionPlainTextDataTable
currentIndex int
}
// ezBookKeepingTransactionPlainTextDataTableBuilder defines the structure of ezbookkeeping transaction plain text data table builder
type ezBookKeepingTransactionPlainTextDataTableBuilder struct {
columnSeparator string
lineSeparator string
columns []DataTableColumn
dataColumnNameMapping map[DataTableColumn]string
dataLineFormat string
builder *strings.Builder
}
// DataRowCount returns the total count of data row
func (t *ezBookKeepingTransactionPlainTextDataTable) DataRowCount() int {
if len(t.allLines) < 1 {
return 0
}
return len(t.allLines) - 1
}
// HeaderLineColumnNames returns the header column name list
func (t *ezBookKeepingTransactionPlainTextDataTable) HeaderLineColumnNames() []string {
return t.headerLineColumnNames
}
// DataRowIterator returns the iterator of data row
func (t *ezBookKeepingTransactionPlainTextDataTable) DataRowIterator() ImportedDataRowIterator {
return &ezBookKeepingTransactionPlainTextDataRowIterator{
dataTable: t,
currentIndex: 0,
}
}
// ColumnCount returns the total count of column in this data row
func (r *ezBookKeepingTransactionPlainTextDataRow) ColumnCount() int {
return len(r.allItems)
}
// GetData returns the data in the specified column index
func (r *ezBookKeepingTransactionPlainTextDataRow) GetData(columnIndex int) string {
return r.allItems[columnIndex]
}
// GetTime returns the time in the specified column index
func (r *ezBookKeepingTransactionPlainTextDataRow) GetTime(columnIndex int, timezoneOffset int16) (time.Time, error) {
return utils.ParseFromLongDateTime(r.GetData(columnIndex), timezoneOffset)
}
// GetTimezoneOffset returns the time zone offset in the specified column index
func (r *ezBookKeepingTransactionPlainTextDataRow) GetTimezoneOffset(columnIndex int) (*time.Location, error) {
return utils.ParseFromTimezoneOffset(r.GetData(columnIndex))
}
// HasNext returns whether the iterator does not reach the end
func (t *ezBookKeepingTransactionPlainTextDataRowIterator) HasNext() bool {
return t.currentIndex+1 < len(t.dataTable.allLines)
}
// Next returns the next imported data row
func (t *ezBookKeepingTransactionPlainTextDataRowIterator) Next() ImportedDataRow {
if t.currentIndex+1 >= len(t.dataTable.allLines) {
return nil
}
t.currentIndex++
rowContent := t.dataTable.allLines[t.currentIndex]
rowItems := strings.Split(rowContent, t.dataTable.columnSeparator)
return &ezBookKeepingTransactionPlainTextDataRow{
allItems: rowItems,
}
}
// AppendTransaction appends the specified transaction to data builder
func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) AppendTransaction(data map[DataTableColumn]string) {
dataRowParams := make([]any, len(b.columns))
for i := 0; i < len(b.columns); i++ {
dataRowParams[i] = data[b.columns[i]]
}
b.builder.WriteString(fmt.Sprintf(b.dataLineFormat, dataRowParams...))
}
// ReplaceDelimiters returns the text after removing the delimiters
func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) ReplaceDelimiters(text string) string {
text = strings.Replace(text, "\r\n", " ", -1)
text = strings.Replace(text, "\r", " ", -1)
text = strings.Replace(text, "\n", " ", -1)
text = strings.Replace(text, b.columnSeparator, " ", -1)
text = strings.Replace(text, b.lineSeparator, " ", -1)
return text
}
// String returns the textual representation of this data
func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) String() string {
return b.builder.String()
}
func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) generateHeaderLine() string {
var ret strings.Builder
for i := 0; i < len(b.columns); i++ {
if ret.Len() > 0 {
ret.WriteString(b.columnSeparator)
}
dataColumn := b.columns[i]
columnName := b.dataColumnNameMapping[dataColumn]
ret.WriteString(columnName)
}
ret.WriteString(b.lineSeparator)
return ret.String()
}
func (b *ezBookKeepingTransactionPlainTextDataTableBuilder) generateDataLineFormat() string {
var ret strings.Builder
for i := 0; i < len(b.columns); i++ {
if ret.Len() > 0 {
ret.WriteString(b.columnSeparator)
}
ret.WriteString("%s")
}
ret.WriteString(b.lineSeparator)
return ret.String()
}
func createNewezbookkeepingTransactionPlainTextDataTable(content string, columnSeparator string, lineSeparator string) (*ezBookKeepingTransactionPlainTextDataTable, error) {
allLines := strings.Split(content, lineSeparator)
if len(allLines) < 2 {
return nil, errs.ErrNotFoundTransactionDataInFile
}
headerLine := allLines[0]
headerLine = strings.ReplaceAll(headerLine, "\r", "")
headerLineItems := strings.Split(headerLine, columnSeparator)
return &ezBookKeepingTransactionPlainTextDataTable{
columnSeparator: columnSeparator,
lineSeparator: lineSeparator,
allLines: allLines,
headerLineColumnNames: headerLineItems,
}, nil
}
func createNewezbookkeepingTransactionPlainTextDataTableBuilder(transactionCount int, columns []DataTableColumn, dataColumnNameMapping map[DataTableColumn]string, columnSeparator string, lineSeparator string) *ezBookKeepingTransactionPlainTextDataTableBuilder {
var builder strings.Builder
builder.Grow(transactionCount * 100)
dataTableBuilder := &ezBookKeepingTransactionPlainTextDataTableBuilder{
columnSeparator: columnSeparator,
lineSeparator: lineSeparator,
columns: columns,
dataColumnNameMapping: dataColumnNameMapping,
builder: &builder,
}
headerLine := dataTableBuilder.generateHeaderLine()
dataLineFormat := dataTableBuilder.generateDataLineFormat()
dataTableBuilder.builder.WriteString(headerLine)
dataTableBuilder.dataLineFormat = dataLineFormat
return dataTableBuilder
}