From 739d1026c50780d3d290f2ba60894c3b5b1bd857 Mon Sep 17 00:00:00 2001
From: CHIKAMATSU Naohiro <n.chika156@gmail.com>
Date: Wed, 1 May 2024 12:36:52 +0900
Subject: [PATCH 1/4] Change SQLite3 driver from mattn/go-sqlite3 to
 modernc.org/sqlite (without cgo)

---
 .goreleaser.yml |  6 +++---
 Makefile        |  2 +-
 config/db.go    | 40 +++++++++++++++++++++++++++++++++++++++-
 go.mod          | 18 +++++++++++++++---
 go.sum          | 41 +++++++++++++++++++++++++++++++++++++----
 main.go         |  3 ++-
 main_test.go    | 17 -----------------
 7 files changed, 97 insertions(+), 30 deletions(-)

diff --git a/.goreleaser.yml b/.goreleaser.yml
index faac7c6..ccdb0f0 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -10,11 +10,11 @@ builds:
     ldflags:
       - -s -w -X 'github.com/nao1215/sqly/config.Version=v{{ .Version }}'
     env:
-      - CGO_ENABLED=1
+      - CGO_ENABLED=0
     goos:
       - linux
-      #- windows
-      #- darwin
+      - windows
+      - darwin
     goarch:
       - amd64
 archives:
diff --git a/Makefile b/Makefile
index 488b78d..1d4e9c5 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ GO_PACKAGES = $(shell $(GO_LIST) $(GO_PKGROOT))
 GO_LDFLAGS  = -ldflags '-X github.com/nao1215/sqly/config.Version=${VERSION}'
 
 build:  ## Build binary
-	env GO111MODULE=on CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO_BUILD) $(GO_LDFLAGS) -o $(APP) main.go
+	env GO111MODULE=on CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO_BUILD) $(GO_LDFLAGS) -o $(APP) main.go
 
 clean: ## Clean project
 	-rm -rf $(APP) cover.out cover.html
diff --git a/config/db.go b/config/db.go
index cddb9e6..c23f005 100644
--- a/config/db.go
+++ b/config/db.go
@@ -1,6 +1,13 @@
 package config
 
-import "database/sql"
+import (
+	"database/sql"
+	"database/sql/driver"
+	"fmt"
+	"sync"
+
+	"modernc.org/sqlite"
+)
 
 // MemoryDB is *sql.DB for excuting sql.
 type MemoryDB *sql.DB
@@ -27,3 +34,34 @@ func NewHistoryDB(c *Config) (HistoryDB, func(), error) {
 	}
 	return HistoryDB(db), func() { db.Close() }, nil
 }
+
+// InitSQLite3 registers the sqlite3 driver.
+func InitSQLite3() {
+	var once sync.Once
+	once.Do(func() {
+		sql.Register("sqlite3", sqliteDriver{Driver: &sqlite.Driver{}})
+	})
+}
+
+// sqliteDriver is a driver that enables foreign keys.
+type sqliteDriver struct {
+	*sqlite.Driver
+}
+
+// Open opens a database specified by its database driver name and a driver-specific data source name.
+func (d sqliteDriver) Open(name string) (driver.Conn, error) {
+	conn, err := d.Driver.Open(name)
+	if err != nil {
+		return conn, err
+	}
+	c := conn.(interface {
+		Exec(stmt string, args []driver.Value) (driver.Result, error)
+	})
+	if _, err := c.Exec("PRAGMA foreign_keys = on;", nil); err != nil {
+		if err := conn.Close(); err != nil {
+			return nil, fmt.Errorf("failed to close connection: %w", err)
+		}
+		return nil, fmt.Errorf("failed to enable enable foreign keys: %w", err)
+	}
+	return conn, nil
+}
diff --git a/go.mod b/go.mod
index 688d050..f26b5c3 100644
--- a/go.mod
+++ b/go.mod
@@ -14,25 +14,37 @@ require (
 	github.com/olekukonko/tablewriter v0.0.5
 	github.com/spf13/pflag v1.0.5
 	github.com/xuri/excelize/v2 v2.8.1
+	modernc.org/sqlite v1.29.8
 )
 
 require (
+	github.com/dustin/go-humanize v1.0.1 // indirect
 	github.com/google/subcommands v1.2.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.9 // indirect
 	github.com/mattn/go-tty v0.0.4 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+	github.com/ncruces/go-strftime v0.1.9 // indirect
 	github.com/pkg/term v1.2.0-beta.2 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
 	github.com/richardlehane/mscfb v1.0.4 // indirect
 	github.com/richardlehane/msoleps v1.0.3 // indirect
 	github.com/sergi/go-diff v1.2.0 // indirect
 	github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
 	github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
 	golang.org/x/crypto v0.21.0 // indirect
-	golang.org/x/mod v0.14.0 // indirect
+	golang.org/x/mod v0.16.0 // indirect
 	golang.org/x/net v0.23.0 // indirect
-	golang.org/x/sys v0.18.0 // indirect
+	golang.org/x/sys v0.19.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
-	golang.org/x/tools v0.17.0 // indirect
+	golang.org/x/tools v0.19.0 // indirect
+	modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
+	modernc.org/libc v1.49.3 // indirect
+	modernc.org/mathutil v1.6.0 // 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 f8ecbb4..8e0d9ba 100644
--- a/go.sum
+++ b/go.sum
@@ -5,15 +5,22 @@ github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
 github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
 github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
 github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
 github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
+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/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
 github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
+github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -40,12 +47,16 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
 github.com/nao1215/gorky v0.2.1 h1:kxXYhCNBbtGru9CCSYx+QC0JZfZJ1csY3uLbb5n2WKA=
 github.com/nao1215/gorky v0.2.1/go.mod h1:fJNLiXzn3YkteARC8xghfHjkt+C5xtHOaRgmVnJEMOs=
+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/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw=
 github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
 github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
 github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
 github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
@@ -75,8 +86,9 @@ golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
 golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
+golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -111,8 +123,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
+golang.org/x/sys v0.19.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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -132,11 +144,32 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
-golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
 golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
+golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
+golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk=
+modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA=
+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-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
+modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
+modernc.org/libc v1.49.3 h1:j2MRCRdwJI2ls/sGbeSk0t2bypOG/uvPZUsGQFDulqg=
+modernc.org/libc v1.49.3/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo=
+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.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.29.8 h1:nGKglNx9K5v0As+zF0/Gcl1kMkmaU1XynYyq92PbsC8=
+modernc.org/sqlite v1.29.8/go.mod h1:lQPm27iqa4UNZpmr4Aor0MH0HkCLbt1huYDfWylLZFk=
+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=
+modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
diff --git a/main.go b/main.go
index 09da66e..5b3d194 100644
--- a/main.go
+++ b/main.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"os"
 
-	_ "github.com/mattn/go-sqlite3"
+	"github.com/nao1215/sqly/config"
 	"github.com/nao1215/sqly/di"
 )
 
@@ -15,6 +15,7 @@ var osExit = os.Exit
 
 // main is entry point for sqly command.
 func main() {
+	config.InitSQLite3()
 	osExit(run(os.Args))
 }
 
diff --git a/main_test.go b/main_test.go
index 51a42fc..9c9f3c7 100644
--- a/main_test.go
+++ b/main_test.go
@@ -11,23 +11,6 @@ import (
 	"github.com/nao1215/sqly/config"
 )
 
-func Test_main(t *testing.T) {
-	t.Run("show version message", func(t *testing.T) {
-		osExit = func(code int) {}
-		os.Args = []string{"sqly", "-v"}
-		defer func() {
-			osExit = os.Exit
-			os.Args = []string{}
-		}()
-
-		got := getStdout(t, main)
-
-		g := golden.New(t,
-			golden.WithFixtureDir(filepath.Join("testdata", "golden")))
-		g.Assert(t, "version", got)
-	})
-}
-
 func Test_run(t *testing.T) {
 	t.Run("show version message", func(t *testing.T) {
 		args := []string{"sqly", "--version"}

From 4ee668f1f04d4d5609e094ff44d3b12c34562f8e Mon Sep 17 00:00:00 2001
From: CHIKAMATSU Naohiro <n.chika156@gmail.com>
Date: Wed, 1 May 2024 12:41:53 +0900
Subject: [PATCH 2/4] Update go version

---
 .golangci.yml | 2 +-
 go.mod        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.golangci.yml b/.golangci.yml
index 3de310c..c741cb7 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,5 +1,5 @@
 run:
-  go: "1.20"
+  go: "1.21"
 
 issues:
   exclude-use-default: false
diff --git a/go.mod b/go.mod
index f26b5c3..6de1287 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/nao1215/sqly
 
-go 1.20
+go 1.21
 
 require (
 	github.com/c-bata/go-prompt v0.2.6

From 643adca0a28172e1bb5b8bc553fad91777cb2625 Mon Sep 17 00:00:00 2001
From: CHIKAMATSU Naohiro <n.chika156@gmail.com>
Date: Wed, 1 May 2024 12:49:44 +0900
Subject: [PATCH 3/4] Fix reviewdog

---
 .golangci.yml                           | 4 ----
 config/argument_test.go                 | 2 +-
 config/db.go                            | 4 ++--
 infrastructure/memory/sqlite3.go        | 2 +-
 infrastructure/persistence/csv_test.go  | 2 +-
 infrastructure/persistence/ltsv_test.go | 2 +-
 infrastructure/persistence/tsv_test.go  | 2 +-
 main_test.go                            | 4 ++--
 shell/shell_test.go                     | 6 +++---
 usecase/csv.go                          | 4 ++--
 usecase/json.go                         | 2 +-
 usecase/ltsv.go                         | 4 ++--
 usecase/tsv.go                          | 4 ++--
 13 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/.golangci.yml b/.golangci.yml
index c741cb7..d6e784a 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -7,16 +7,13 @@ issues:
 linters:
   disable-all: true
   enable:
-    - deadcode
     - errcheck
     - gosimple
     - govet
     - ineffassign
     - staticcheck
-    - structcheck
     - typecheck
     - unused
-    - varcheck
     - asciicheck
     - bodyclose
     - dogsled
@@ -30,7 +27,6 @@ linters:
     - gocritic
     - goimports
     - gosec
-    - ifshort
     - misspell
     - nakedret
     - noctx
diff --git a/config/argument_test.go b/config/argument_test.go
index 7150096..59244a5 100644
--- a/config/argument_test.go
+++ b/config/argument_test.go
@@ -174,7 +174,7 @@ func getStdout(t *testing.T, f func()) string {
 	Stdout = w
 
 	f()
-	w.Close()
+	w.Close() //nolint:errcheck
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
diff --git a/config/db.go b/config/db.go
index c23f005..a48aec4 100644
--- a/config/db.go
+++ b/config/db.go
@@ -22,7 +22,7 @@ func NewInMemDB() (MemoryDB, func(), error) {
 	if err != nil {
 		return nil, nil, err
 	}
-	return MemoryDB(db), func() { db.Close() }, nil
+	return MemoryDB(db), func() { db.Close() }, nil //nolint:errcheck
 }
 
 // NewHistoryDB create *sql.DB for history.
@@ -32,7 +32,7 @@ func NewHistoryDB(c *Config) (HistoryDB, func(), error) {
 	if err != nil {
 		return nil, nil, err
 	}
-	return HistoryDB(db), func() { db.Close() }, nil
+	return HistoryDB(db), func() { db.Close() }, nil //nolint:errcheck
 }
 
 // InitSQLite3 registers the sqlite3 driver.
diff --git a/infrastructure/memory/sqlite3.go b/infrastructure/memory/sqlite3.go
index 61a7739..0986808 100644
--- a/infrastructure/memory/sqlite3.go
+++ b/infrastructure/memory/sqlite3.go
@@ -121,7 +121,7 @@ func (r *sqlite3Repository) Query(ctx context.Context, query string) (*model.Tab
 	if err != nil {
 		return nil, err
 	}
-	defer rows.Close()
+	defer rows.Close() //nolint:errcheck
 
 	header, err := rows.Columns()
 	if err != nil {
diff --git a/infrastructure/persistence/csv_test.go b/infrastructure/persistence/csv_test.go
index b6af04e..3a03770 100644
--- a/infrastructure/persistence/csv_test.go
+++ b/infrastructure/persistence/csv_test.go
@@ -16,7 +16,7 @@ func Test_csvRepository_List(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close()
+		defer f.Close() //nolint:errcheck
 
 		csv, err := cr.List(f)
 		if err != nil {
diff --git a/infrastructure/persistence/ltsv_test.go b/infrastructure/persistence/ltsv_test.go
index 86ccb87..18622c8 100644
--- a/infrastructure/persistence/ltsv_test.go
+++ b/infrastructure/persistence/ltsv_test.go
@@ -77,7 +77,7 @@ func Test_ltsvRepository_List(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close()
+		defer f.Close() //nolint:errcheck
 
 		ltsv, err := r.List(f)
 		if err != nil {
diff --git a/infrastructure/persistence/tsv_test.go b/infrastructure/persistence/tsv_test.go
index ba05a4c..97727a0 100644
--- a/infrastructure/persistence/tsv_test.go
+++ b/infrastructure/persistence/tsv_test.go
@@ -16,7 +16,7 @@ func Test_tsvRepository_List(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close()
+		defer f.Close() //nolint:errcheck
 
 		tsv, err := r.List(f)
 		if err != nil {
diff --git a/main_test.go b/main_test.go
index 9c9f3c7..be47380 100644
--- a/main_test.go
+++ b/main_test.go
@@ -162,7 +162,7 @@ func getStdoutForRunFunc(t *testing.T, f func([]string) int, list []string) []by
 	config.Stdout = w
 
 	f(list)
-	w.Close()
+	w.Close() //nolint:errcheck
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
@@ -185,7 +185,7 @@ func getStdout(t *testing.T, f func()) []byte {
 	config.Stdout = w
 
 	f()
-	w.Close()
+	w.Close() //nolint:errcheck
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
diff --git a/shell/shell_test.go b/shell/shell_test.go
index fe2e228..6d9a0ad 100644
--- a/shell/shell_test.go
+++ b/shell/shell_test.go
@@ -811,7 +811,7 @@ func getStdoutForRunFunc(t *testing.T, f func() error) []byte {
 	if err := f(); err != nil {
 		t.Fatal(err)
 	}
-	w.Close()
+	w.Close() //nolint:errcheck
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
@@ -834,7 +834,7 @@ func getStdout(t *testing.T, f func()) []byte {
 	config.Stdout = w
 
 	f()
-	w.Close()
+	w.Close() //nolint:errcheck
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
@@ -857,7 +857,7 @@ func getExecStdOutput(t *testing.T, f func(string) error, arg string) ([]byte, e
 	config.Stdout = w
 
 	execErr := f(arg)
-	w.Close()
+	w.Close() //nolint:errcheck
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
diff --git a/usecase/csv.go b/usecase/csv.go
index b3c6264..fdfaaf7 100644
--- a/usecase/csv.go
+++ b/usecase/csv.go
@@ -25,7 +25,7 @@ func (ci *CSVInteractor) List(csvFilePath string) (*model.CSV, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	csv, err := ci.Repository.List(f)
 	if err != nil {
@@ -41,7 +41,7 @@ func (ci *CSVInteractor) Dump(csvFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	return ci.Repository.Dump(f, table)
 }
diff --git a/usecase/json.go b/usecase/json.go
index 946dcd0..d4209a0 100644
--- a/usecase/json.go
+++ b/usecase/json.go
@@ -28,7 +28,7 @@ func (i *JSONInteractor) Dump(jsonFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	return i.Repository.Dump(f, table)
 }
diff --git a/usecase/ltsv.go b/usecase/ltsv.go
index f11549f..8c3b2e1 100644
--- a/usecase/ltsv.go
+++ b/usecase/ltsv.go
@@ -23,7 +23,7 @@ func (li *LTSVInteractor) List(ltsvFilePath string) (*model.LTSV, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	TSV, err := li.Repository.List(f)
 	if err != nil {
@@ -38,7 +38,7 @@ func (li *LTSVInteractor) Dump(ltsvFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	return li.Repository.Dump(f, table)
 }
diff --git a/usecase/tsv.go b/usecase/tsv.go
index d24011e..2cbc558 100644
--- a/usecase/tsv.go
+++ b/usecase/tsv.go
@@ -25,7 +25,7 @@ func (ti *TSVInteractor) List(TSVFilePath string) (*model.TSV, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	TSV, err := ti.Repository.List(f)
 	if err != nil {
@@ -40,7 +40,7 @@ func (ti *TSVInteractor) Dump(tsvFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close()
+	defer f.Close() //nolint:errcheck
 
 	return ti.Repository.Dump(f, table)
 }

From 712a01a3177707bd65374dd41d18bfe9aaa1c263 Mon Sep 17 00:00:00 2001
From: CHIKAMATSU Naohiro <n.chika156@gmail.com>
Date: Wed, 1 May 2024 12:56:26 +0900
Subject: [PATCH 4/4] Fix reviewdog

---
 config/argument_test.go                 |  2 +-
 config/db.go                            | 11 ++++++++---
 infrastructure/memory/sqlite3.go        |  2 +-
 infrastructure/persistence/csv_test.go  |  2 +-
 infrastructure/persistence/ltsv_test.go |  2 +-
 infrastructure/persistence/tsv_test.go  |  2 +-
 main_test.go                            |  4 ++--
 shell/shell_test.go                     |  6 +++---
 usecase/csv.go                          |  4 ++--
 usecase/json.go                         |  2 +-
 usecase/ltsv.go                         |  4 ++--
 usecase/tsv.go                          |  4 ++--
 12 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/config/argument_test.go b/config/argument_test.go
index 59244a5..dc6cc42 100644
--- a/config/argument_test.go
+++ b/config/argument_test.go
@@ -174,7 +174,7 @@ func getStdout(t *testing.T, f func()) string {
 	Stdout = w
 
 	f()
-	w.Close() //nolint:errcheck
+	w.Close() //nolint
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
diff --git a/config/db.go b/config/db.go
index a48aec4..ecb50e8 100644
--- a/config/db.go
+++ b/config/db.go
@@ -22,7 +22,7 @@ func NewInMemDB() (MemoryDB, func(), error) {
 	if err != nil {
 		return nil, nil, err
 	}
-	return MemoryDB(db), func() { db.Close() }, nil //nolint:errcheck
+	return MemoryDB(db), func() { db.Close() }, nil //nolint
 }
 
 // NewHistoryDB create *sql.DB for history.
@@ -32,7 +32,7 @@ func NewHistoryDB(c *Config) (HistoryDB, func(), error) {
 	if err != nil {
 		return nil, nil, err
 	}
-	return HistoryDB(db), func() { db.Close() }, nil //nolint:errcheck
+	return HistoryDB(db), func() { db.Close() }, nil //nolint
 }
 
 // InitSQLite3 registers the sqlite3 driver.
@@ -54,14 +54,19 @@ func (d sqliteDriver) Open(name string) (driver.Conn, error) {
 	if err != nil {
 		return conn, err
 	}
-	c := conn.(interface {
+	c, ok := conn.(interface {
 		Exec(stmt string, args []driver.Value) (driver.Result, error)
 	})
+	if !ok {
+		return nil, fmt.Errorf("connection does not support Exec method")
+	}
+
 	if _, err := c.Exec("PRAGMA foreign_keys = on;", nil); err != nil {
 		if err := conn.Close(); err != nil {
 			return nil, fmt.Errorf("failed to close connection: %w", err)
 		}
 		return nil, fmt.Errorf("failed to enable enable foreign keys: %w", err)
 	}
+
 	return conn, nil
 }
diff --git a/infrastructure/memory/sqlite3.go b/infrastructure/memory/sqlite3.go
index 0986808..68d2062 100644
--- a/infrastructure/memory/sqlite3.go
+++ b/infrastructure/memory/sqlite3.go
@@ -121,7 +121,7 @@ func (r *sqlite3Repository) Query(ctx context.Context, query string) (*model.Tab
 	if err != nil {
 		return nil, err
 	}
-	defer rows.Close() //nolint:errcheck
+	defer rows.Close() //nolint
 
 	header, err := rows.Columns()
 	if err != nil {
diff --git a/infrastructure/persistence/csv_test.go b/infrastructure/persistence/csv_test.go
index 3a03770..e4e97c4 100644
--- a/infrastructure/persistence/csv_test.go
+++ b/infrastructure/persistence/csv_test.go
@@ -16,7 +16,7 @@ func Test_csvRepository_List(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close() //nolint:errcheck
+		defer f.Close() //nolint
 
 		csv, err := cr.List(f)
 		if err != nil {
diff --git a/infrastructure/persistence/ltsv_test.go b/infrastructure/persistence/ltsv_test.go
index 18622c8..a7d90f6 100644
--- a/infrastructure/persistence/ltsv_test.go
+++ b/infrastructure/persistence/ltsv_test.go
@@ -77,7 +77,7 @@ func Test_ltsvRepository_List(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close() //nolint:errcheck
+		defer f.Close() //nolint
 
 		ltsv, err := r.List(f)
 		if err != nil {
diff --git a/infrastructure/persistence/tsv_test.go b/infrastructure/persistence/tsv_test.go
index 97727a0..e036ae9 100644
--- a/infrastructure/persistence/tsv_test.go
+++ b/infrastructure/persistence/tsv_test.go
@@ -16,7 +16,7 @@ func Test_tsvRepository_List(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close() //nolint:errcheck
+		defer f.Close() //nolint
 
 		tsv, err := r.List(f)
 		if err != nil {
diff --git a/main_test.go b/main_test.go
index be47380..7dc5dea 100644
--- a/main_test.go
+++ b/main_test.go
@@ -162,7 +162,7 @@ func getStdoutForRunFunc(t *testing.T, f func([]string) int, list []string) []by
 	config.Stdout = w
 
 	f(list)
-	w.Close() //nolint:errcheck
+	w.Close() //nolint
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
@@ -185,7 +185,7 @@ func getStdout(t *testing.T, f func()) []byte {
 	config.Stdout = w
 
 	f()
-	w.Close() //nolint:errcheck
+	w.Close() //nolint
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
diff --git a/shell/shell_test.go b/shell/shell_test.go
index 6d9a0ad..10c0b81 100644
--- a/shell/shell_test.go
+++ b/shell/shell_test.go
@@ -811,7 +811,7 @@ func getStdoutForRunFunc(t *testing.T, f func() error) []byte {
 	if err := f(); err != nil {
 		t.Fatal(err)
 	}
-	w.Close() //nolint:errcheck
+	w.Close() //nolint
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
@@ -834,7 +834,7 @@ func getStdout(t *testing.T, f func()) []byte {
 	config.Stdout = w
 
 	f()
-	w.Close() //nolint:errcheck
+	w.Close() //nolint
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
@@ -857,7 +857,7 @@ func getExecStdOutput(t *testing.T, f func(string) error, arg string) ([]byte, e
 	config.Stdout = w
 
 	execErr := f(arg)
-	w.Close() //nolint:errcheck
+	w.Close() //nolint
 
 	var buffer bytes.Buffer
 	if _, err := buffer.ReadFrom(r); err != nil {
diff --git a/usecase/csv.go b/usecase/csv.go
index fdfaaf7..0b5143e 100644
--- a/usecase/csv.go
+++ b/usecase/csv.go
@@ -25,7 +25,7 @@ func (ci *CSVInteractor) List(csvFilePath string) (*model.CSV, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	csv, err := ci.Repository.List(f)
 	if err != nil {
@@ -41,7 +41,7 @@ func (ci *CSVInteractor) Dump(csvFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	return ci.Repository.Dump(f, table)
 }
diff --git a/usecase/json.go b/usecase/json.go
index d4209a0..73b92c2 100644
--- a/usecase/json.go
+++ b/usecase/json.go
@@ -28,7 +28,7 @@ func (i *JSONInteractor) Dump(jsonFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	return i.Repository.Dump(f, table)
 }
diff --git a/usecase/ltsv.go b/usecase/ltsv.go
index 8c3b2e1..9ca688c 100644
--- a/usecase/ltsv.go
+++ b/usecase/ltsv.go
@@ -23,7 +23,7 @@ func (li *LTSVInteractor) List(ltsvFilePath string) (*model.LTSV, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	TSV, err := li.Repository.List(f)
 	if err != nil {
@@ -38,7 +38,7 @@ func (li *LTSVInteractor) Dump(ltsvFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	return li.Repository.Dump(f, table)
 }
diff --git a/usecase/tsv.go b/usecase/tsv.go
index 2cbc558..afed17a 100644
--- a/usecase/tsv.go
+++ b/usecase/tsv.go
@@ -25,7 +25,7 @@ func (ti *TSVInteractor) List(TSVFilePath string) (*model.TSV, error) {
 	if err != nil {
 		return nil, err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	TSV, err := ti.Repository.List(f)
 	if err != nil {
@@ -40,7 +40,7 @@ func (ti *TSVInteractor) Dump(tsvFilePath string, table *model.Table) error {
 	if err != nil {
 		return err
 	}
-	defer f.Close() //nolint:errcheck
+	defer f.Close() //nolint
 
 	return ti.Repository.Dump(f, table)
 }