From 1e0f2b7f4a52741de786af90aa269d6fd733a024 Mon Sep 17 00:00:00 2001 From: gogacoder Date: Fri, 14 Mar 2025 23:24:45 +0700 Subject: [PATCH] feat: cgo free sqlite --- build/Taskfile.darwin.yml | 2 +- build/Taskfile.linux.yml | 2 +- build/Taskfile.windows.yml | 4 +-- go.mod | 10 +++++-- go.sum | 23 +++++++++----- internal/database/database.go | 56 +++++++++++++++++++++++++++++++++-- 6 files changed, 80 insertions(+), 17 deletions(-) diff --git a/build/Taskfile.darwin.yml b/build/Taskfile.darwin.yml index 5730e4c..1b1ec28 100644 --- a/build/Taskfile.darwin.yml +++ b/build/Taskfile.darwin.yml @@ -13,7 +13,7 @@ tasks: cmds: - go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}} vars: - BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production sqlite_icu" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" -tags "sqlite_icu"{{end}}' + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" {{end}}' env: GOOS: darwin CGO_ENABLED: 1 diff --git a/build/Taskfile.linux.yml b/build/Taskfile.linux.yml index 9dec3c8..de4c765 100644 --- a/build/Taskfile.linux.yml +++ b/build/Taskfile.linux.yml @@ -13,7 +13,7 @@ tasks: cmds: - go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}} vars: - BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production sqlite_icu" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" -tags "sqlite_icu" {{end}}' + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" {{end}}' env: GOOS: linux CGO_ENABLED: 1 diff --git a/build/Taskfile.windows.yml b/build/Taskfile.windows.yml index d52667f..0a97f09 100644 --- a/build/Taskfile.windows.yml +++ b/build/Taskfile.windows.yml @@ -18,10 +18,10 @@ tasks: - cmd: rm -f *.syso platforms: [linux, darwin] vars: - BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production sqlite_icu" -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l" -tags "sqlite_icu"{{end}}' + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production" -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l" {{end}}' env: GOOS: windows - CGO_ENABLED: 1 + CGO_ENABLED: 0 GOARCH: '{{.ARCH | default ARCH}}' PRODUCTION: '{{.PRODUCTION | default "false"}}' diff --git a/go.mod b/go.mod index 273a28d..0ff30aa 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,12 @@ toolchain go1.24.1 require ( github.com/kuzgoga/fogg v0.1.2 + github.com/ncruces/go-sqlite3 v0.24.1 + github.com/ncruces/go-sqlite3/gormlite v0.24.0 github.com/wailsapp/wails/v3 v3.0.0-alpha.9 github.com/xuri/excelize/v2 v2.9.0 golang.org/x/text v0.23.0 - gorm.io/driver/sqlite v1.5.7 + gorm.io/driver/sqlite v1.5.0 gorm.io/gen v0.3.26 gorm.io/gorm v1.25.12 gorm.io/plugin/dbresolver v1.5.3 @@ -46,6 +48,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/ncruces/julianday v1.0.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect @@ -54,17 +57,18 @@ require ( github.com/samber/lo v1.38.1 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.2.2 // indirect + github.com/tetratelabs/wazero v1.9.0 // indirect github.com/wailsapp/go-webview2 v1.0.19 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.36.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.31.0 // indirect golang.org/x/tools v0.28.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index c9d98cb..b30de7a 100644 --- a/go.sum +++ b/go.sum @@ -105,6 +105,12 @@ github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/ncruces/go-sqlite3 v0.24.1 h1:qHlIz+dlH3Y0wCUErFZXon5hCvw1Kc9eEkZVYYi8p14= +github.com/ncruces/go-sqlite3 v0.24.1/go.mod h1:n6Z7036yFilJx04yV0mi5JWaF66rUmXn1It9Ux8dx68= +github.com/ncruces/go-sqlite3/gormlite v0.24.0 h1:81sHeq3CCdhjoqAB650n5wEdRlLO9VBvosArskcN3+c= +github.com/ncruces/go-sqlite3/gormlite v0.24.0/go.mod h1:vXfVWdBfg7qOgqQqHpzUWl9LLswD0h+8mK4oouaV2oc= +github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= +github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= @@ -137,6 +143,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= +github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU= github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= @@ -157,8 +165,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= @@ -199,15 +207,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -243,9 +251,8 @@ gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A= +gorm.io/driver/sqlite v1.5.0 h1:zKYbzRCpBrT1bNijRnxLDJWPjVfImGEn0lSnUY5gZ+c= gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I= -gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I= -gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= gorm.io/driver/sqlserver v1.5.4 h1:xA+Y1KDNspv79q43bPyjDMUgHoYHLhXYmdFcYPobg8g= gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g= gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY= diff --git a/internal/database/database.go b/internal/database/database.go index d93824b..90da5ec 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -2,12 +2,17 @@ package database import ( "app/internal/dal" + "context" + "github.com/ncruces/go-sqlite3/driver" "log" + "log/slog" "os" "sync" "time" - "gorm.io/driver/sqlite" + _ "github.com/ncruces/go-sqlite3/embed" + "github.com/ncruces/go-sqlite3/ext/unicode" + "github.com/ncruces/go-sqlite3/gormlite" "gorm.io/gorm" "gorm.io/gorm/logger" ) @@ -31,13 +36,14 @@ func initialize() error { Colorful: true, // Disable color }, ) - db, err = gorm.Open(sqlite.Open("file:"+Path+"?_fk=1"), &gorm.Config{ + db, err = gorm.Open(gormlite.Open("file:"+Path+"?_fk=1"), &gorm.Config{ Logger: newLogger, FullSaveAssociations: false, }) if err != nil { return err } + RegisterUnicodeExtension(db) if res := db.Exec(`PRAGMA foreign_keys = ON`); res.Error != nil { return res.Error } @@ -85,3 +91,49 @@ func GetInstance() *gorm.DB { }) return db } + +func RegisterUnicodeExtension(db *gorm.DB) { + sqlDB, err := db.DB() + if err != nil { + panic(err) + } + + ctx := context.Background() + conn, err := sqlDB.Conn(ctx) + if err != nil { + panic(err) + } + defer conn.Close() + + err = conn.Raw(func(driverConn any) error { + c := driverConn.(driver.Conn) + sqliteConn := c.Raw() + + if err := unicode.Register(sqliteConn); err != nil { + return err + } + + if err := sqliteConn.Exec(`SELECT icu_load_collation('ru-RU', 'russian')`); err != nil { + return err + } + + if err := sqliteConn.Exec(`SELECT icu_load_collation('en-US', 'english')`); err != nil { + return err + } + + stmt, _, err := sqliteConn.Prepare(`SELECT 'ы' LIKE 'Ы'`) + if err != nil { + return err + } + defer stmt.Close() + + if stmt.Step() { + slog.Info("ICU test result", "value", stmt.ColumnBool(0)) + } + return stmt.Err() + }) + + if err != nil { + panic(err) + } +}