From 5055c50fd5bd3a2dc633727263996c256ad027ca Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Mon, 21 Oct 2024 17:06:43 +0900 Subject: [PATCH 1/2] Add row number column Optionally add a row number column. This option adds a row number column (num) to the first column. --- cmd/cmd.go | 3 + go.mod | 16 ++-- go.sum | 44 ++++++----- importer.go | 4 + input_row_number.go | 83 ++++++++++++++++++++ input_row_number_test.go | 163 +++++++++++++++++++++++++++++++++++++++ reader.go | 9 +++ 7 files changed, 295 insertions(+), 27 deletions(-) create mode 100644 input_row_number.go create mode 100644 input_row_number_test.go diff --git a/cmd/cmd.go b/cmd/cmd.go index 6323a04..0eba1eb 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -82,6 +82,7 @@ func (cli Cli) Run(args []string) int { inJQuery string inLimitRead int inNull nilString + inRowNumber bool outFlag outputFlag outFile string @@ -130,6 +131,7 @@ func (cli Cli) Run(args []string) int { flags.BoolVar(&inFlag.YAML, "iyaml", false, "YAML format for input.") flags.BoolVar(&inFlag.TBLN, "itbln", false, "TBLN format for input.") flags.BoolVar(&inFlag.WIDTH, "iwidth", false, "width specification format for input.") + flags.BoolVar(&inRowNumber, "inum", false, "add row number column.") flags.StringVar(&outFile, "out", "", "output file name.") flags.BoolVar(&outWithoutGuess, "out-without-guess", false, "output without guessing (when using -out).") @@ -246,6 +248,7 @@ func (cli Cli) Run(args []string) int { trdsql.InJQ(inJQuery), trdsql.InNeedNULL(inNull.valid), trdsql.InNULL(inNull.str), + trdsql.InRowNumber(inRowNumber), ) writer := cli.OutStream diff --git a/go.mod b/go.mod index 5e0c4fd..687896e 100644 --- a/go.mod +++ b/go.mod @@ -9,17 +9,17 @@ require ( github.com/jwalton/gchalk v1.3.0 github.com/klauspost/compress v1.17.8 github.com/lib/pq v1.10.9 - github.com/mattn/go-runewidth v0.0.15 - github.com/mattn/go-sqlite3 v1.14.22 + github.com/mattn/go-runewidth v0.0.16 + github.com/mattn/go-sqlite3 v1.14.24 github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25 - github.com/noborus/guesswidth v0.3.4 + github.com/noborus/guesswidth v0.4.0 github.com/noborus/sqlss v0.1.0 github.com/noborus/tbln v0.0.2 github.com/olekukonko/tablewriter v0.0.5 github.com/pierrec/lz4/v4 v4.1.21 github.com/ulikunitz/xz v0.5.12 - golang.org/x/term v0.21.0 - modernc.org/sqlite v1.29.1 + golang.org/x/term v0.25.0 + modernc.org/sqlite v1.33.1 ) require ( @@ -37,13 +37,13 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect golang.org/x/crypto v0.21.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect - modernc.org/libc v1.41.0 // indirect + modernc.org/libc v1.55.3 // indirect modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.7.2 // indirect + modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index 5644da8..65bbfe4 100644 --- a/go.sum +++ b/go.sum @@ -19,7 +19,7 @@ github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqw github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -49,16 +49,16 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25 h1:bnhGk2UFFPqylhxTEffs1ehDRn4bEZsEoDH53Z4HqA8= github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25/go.mod h1:RrGEZqqiyEcLyTVLDSgtNZVLqJykj0F4vwuuqvMdT60= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/noborus/guesswidth v0.3.4 h1:+iKmbm0iFTS3pksIOKQQvLVZVOKNZHavqJoFK2mPoTQ= -github.com/noborus/guesswidth v0.3.4/go.mod h1:2F1sqiazKIwuSRjQTweQHPFJcjV5375jYUrTik9/V5k= +github.com/noborus/guesswidth v0.4.0 h1:+PPh+Z+GM4mKmVrhYR4lpjeyBuLMSVo2arM+VErdHIc= +github.com/noborus/guesswidth v0.4.0/go.mod h1:ghA6uh9RcK+uSmaDDmBMj/tRZ3BSpspDP6DMF5Xk3bc= github.com/noborus/sqlss v0.1.0 h1:GSrOeBuswHaBn6enegZeMVudPPeyVoYo+LCapTc+b7Q= github.com/noborus/sqlss v0.1.0/go.mod h1:34KdYx3QxMFfD05RhUi7Uw5M1i6KOBQ1NHtMIuNVnWM= github.com/noborus/tbln v0.0.2 h1:pQIv+ZO38KPz52FOuhs/W3inpgmd5qwL8XFDqI+KKyY= @@ -86,7 +86,7 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -95,16 +95,16 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= @@ -112,16 +112,22 @@ gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= -modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= -modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/importer.go b/importer.go index 0373a79..4b32739 100644 --- a/importer.go +++ b/importer.go @@ -257,6 +257,10 @@ func ImportFileContext(ctx context.Context, db *DB, fileName string, readOpts *R } tableName = db.QuotedName(tableName) + if opts.InRowNumber { + reader = newRowNumberReader(reader) + } + columnNames, err := reader.Names() if err != nil { if !errors.Is(err, io.EOF) { diff --git a/input_row_number.go b/input_row_number.go new file mode 100644 index 0000000..8d39c32 --- /dev/null +++ b/input_row_number.go @@ -0,0 +1,83 @@ +package trdsql + +import ( + "strconv" +) + +// rowNumberReader is a Reader that adds a row number column to the input. +type rowNumberReader struct { + reader Reader + originRow []any + lineCount int +} + +// newRowNumberReader creates a new rowNumberReader. +func newRowNumberReader(r Reader) *rowNumberReader { + columnNum := 1 + names, err := r.Names() + if err == nil { + columnNum = len(names) + } + originRow := make([]any, columnNum) + return &rowNumberReader{ + reader: r, + originRow: originRow, + lineCount: 0, + } +} + +// Names returns column names with an additional row number column. +func (r *rowNumberReader) Names() ([]string, error) { + number := "num" + names, err := r.reader.Names() + if err != nil { + return nil, err + } + + for i := 0; i < len(names)+1; i++ { + orig := number + for _, name := range names { + if number == name { + number = orig + strconv.Itoa(i) + i++ + continue + } + } + } + + return append([]string{number}, names...), nil +} + +// Types returns column types with an additional row number column. +func (r *rowNumberReader) Types() ([]string, error) { + types, err := r.reader.Types() + if err != nil { + return nil, err + } + return append([]string{"int"}, types...), nil +} + +// PreReadRow returns pre-read rows with an additional row number column. +func (r *rowNumberReader) PreReadRow() [][]any { + preReadRows := r.reader.PreReadRow() + for i := range preReadRows { + preReadRows[i] = append([]any{r.lineCount + i + 1}, preReadRows[i]...) + } + r.lineCount += len(preReadRows) + return preReadRows +} + +// ReadRow reads the rest of the row with an additional row number column. +func (r *rowNumberReader) ReadRow(row []any) ([]any, error) { + var err error + r.lineCount++ + r.originRow, err = r.reader.ReadRow(r.originRow) + if err != nil { + return nil, err + } + if len(r.originRow) == 0 { + return nil, nil + } + + return append([]any{r.lineCount}, r.originRow...), nil +} diff --git a/input_row_number_test.go b/input_row_number_test.go new file mode 100644 index 0000000..74114eb --- /dev/null +++ b/input_row_number_test.go @@ -0,0 +1,163 @@ +package trdsql + +import ( + "path/filepath" + "reflect" + "testing" +) + +func Test_rowNumberReader_Names(t *testing.T) { + type fields struct { + reader Reader + originRow []any + lineCount int + } + tests := []struct { + name string + fields fields + want []string + wantErr bool + }{ + { + name: "test1", + fields: fields{ + reader: &CSVReader{ + names: []string{"a", "b"}, + types: []string{"text", "text"}, + preRead: [][]string{ + {"1", "2"}, + }, + }, + originRow: []any{}, + lineCount: 0, + }, + want: []string{"num", "a", "b"}, + wantErr: false, + }, + { + name: "test2", + fields: fields{ + reader: &CSVReader{ + names: []string{"num", "num1"}, + types: []string{"text", "text"}, + preRead: [][]string{ + {"1", "2"}, + }, + }, + originRow: []any{}, + lineCount: 0, + }, + want: []string{"num0", "num", "num1"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := newRowNumberReader(tt.fields.reader) + got, err := r.Names() + if (err != nil) != tt.wantErr { + t.Errorf("rowNumberReader.Names() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("rowNumberReader.Names() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_rowNumberReader_Types(t *testing.T) { + type fields struct { + reader Reader + originRow []any + lineCount int + } + tests := []struct { + name string + fields fields + want []string + wantErr bool + }{ + { + name: "test1", + fields: fields{ + reader: &CSVReader{ + names: []string{"a", "b"}, + types: []string{"text", "text"}, + preRead: [][]string{ + {"1", "2"}, + }, + }, + originRow: []any{}, + lineCount: 0, + }, + want: []string{"int", "text", "text"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := newRowNumberReader(tt.fields.reader) + got, err := r.Types() + if (err != nil) != tt.wantErr { + t.Errorf("rowNumberReader.Types() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("rowNumberReader.Types() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_rowNumberReader_ReadRow(t *testing.T) { + type args struct { + row []any + } + tests := []struct { + name string + fileName string + opts *ReadOpts + args args + want1 [][]any + want2 []any + wantErr bool + }{ + { + name: "test.csv", + fileName: "test.csv", + opts: NewReadOpts(), + args: args{row: []any{1}}, + want1: [][]any{ + {1, "1", "Orange"}, + }, + want2: []any{2, "2", "Melon"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + file, err := singleFileOpen(filepath.Join(dataDir, tt.fileName)) + if err != nil { + t.Error(err) + } + r, err := NewCSVReader(file, tt.opts) + if err != nil { + t.Error(err) + } + reader := newRowNumberReader(r) + got1 := reader.PreReadRow() + if !reflect.DeepEqual(got1, tt.want1) { + t.Errorf("rowNumberReader.PreReadRow() = %#v, want %#v", got1, tt.want1) + } + got2, err := reader.ReadRow(tt.args.row) + if (err != nil) != tt.wantErr { + t.Errorf("rowNumberReader.ReadRow() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got2, tt.want2) { + t.Errorf("rowNumberReader.ReadRow() = %v, want %v", got2, tt.want2) + } + }) + } +} diff --git a/reader.go b/reader.go index 46a6e89..321dfea 100644 --- a/reader.go +++ b/reader.go @@ -117,6 +117,9 @@ type ReadOpts struct { // IsTemporary is a flag whether to make temporary table. // default is true. IsTemporary bool + + // InRowNumber is row number. + InRowNumber bool } // NewReadOpts Returns ReadOpts. @@ -212,6 +215,12 @@ func IsTemporary(t bool) ReadOpt { } } +func InRowNumber(t bool) ReadOpt { + return func(args *ReadOpts) { + args.InRowNumber = t + } +} + // NewReader returns an Reader interface // depending on the file to be imported. func NewReader(reader io.Reader, readOpts *ReadOpts) (Reader, error) { From d310df8b45fce5618a75e323bf32b2b5b8b91128 Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Mon, 21 Oct 2024 17:19:47 +0900 Subject: [PATCH 2/2] Change the version of modernce.org/sqlite Change the version of modernce.org/sqlite to go1.20 compatible version. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 687896e..5428dd7 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/pierrec/lz4/v4 v4.1.21 github.com/ulikunitz/xz v0.5.12 golang.org/x/term v0.25.0 - modernc.org/sqlite v1.33.1 + modernc.org/sqlite v1.31.1 ) require ( diff --git a/go.sum b/go.sum index 65bbfe4..3de1454 100644 --- a/go.sum +++ b/go.sum @@ -126,8 +126,8 @@ modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= -modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= -modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= +modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= +modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=