Merge pull request #2209 from mtrmac/c-image-main

Update github.com/containers/image/v5 to post-v5.29.2 main
This commit is contained in:
Miloslav Trmač 2024-01-31 19:22:40 +01:00 committed by GitHub
commit e779ef5eb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
59 changed files with 6912 additions and 3258 deletions

10
go.mod
View File

@ -4,7 +4,7 @@ go 1.19
require ( require (
github.com/containers/common v0.57.2 github.com/containers/common v0.57.2
github.com/containers/image/v5 v5.29.2-0.20240119225553-e6e119441091 github.com/containers/image/v5 v5.29.3-0.20240131175401-a63f4a542670
github.com/containers/ocicrypt v1.1.9 github.com/containers/ocicrypt v1.1.9
github.com/containers/storage v1.52.0 github.com/containers/storage v1.52.0
github.com/docker/distribution v2.8.3+incompatible github.com/docker/distribution v2.8.3+incompatible
@ -39,7 +39,7 @@ require (
github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/reference v0.5.0 // indirect github.com/distribution/reference v0.5.0 // indirect
github.com/docker/docker v25.0.0+incompatible // indirect github.com/docker/docker v25.0.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.1 // indirect github.com/docker/docker-credential-helpers v0.8.1 // indirect
github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect
@ -56,7 +56,7 @@ require (
github.com/go-openapi/runtime v0.26.0 // indirect github.com/go-openapi/runtime v0.26.0 // indirect
github.com/go-openapi/spec v0.20.9 // indirect github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/strfmt v0.22.0 // indirect github.com/go-openapi/strfmt v0.22.0 // indirect
github.com/go-openapi/swag v0.22.7 // indirect github.com/go-openapi/swag v0.22.9 // indirect
github.com/go-openapi/validate v0.22.1 // indirect github.com/go-openapi/validate v0.22.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@ -72,13 +72,13 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/compress v1.17.5 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect github.com/klauspost/pgzip v1.2.6 // indirect
github.com/letsencrypt/boulder v0.0.0-20230907030200-6d76a0f91e1e // indirect github.com/letsencrypt/boulder v0.0.0-20230907030200-6d76a0f91e1e // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/mattn/go-sqlite3 v1.14.19 // indirect github.com/mattn/go-sqlite3 v1.14.21 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect

22
go.sum
View File

@ -36,8 +36,8 @@ github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
github.com/containers/common v0.57.2 h1:50Zp9VuXt2u5uNTKEc4aU2+PfWzFNAulD9JX43VihyI= github.com/containers/common v0.57.2 h1:50Zp9VuXt2u5uNTKEc4aU2+PfWzFNAulD9JX43VihyI=
github.com/containers/common v0.57.2/go.mod h1:ZG9ab1bEssX98ZBclWFIyzx4+MyUN8dXj1oSEugp7N0= github.com/containers/common v0.57.2/go.mod h1:ZG9ab1bEssX98ZBclWFIyzx4+MyUN8dXj1oSEugp7N0=
github.com/containers/image/v5 v5.29.2-0.20240119225553-e6e119441091 h1:sAu48Kd2gfw6QxfZb/58tbMNj0bfClSj9CojnI1XfgA= github.com/containers/image/v5 v5.29.3-0.20240131175401-a63f4a542670 h1:EjaG74rMIAv0icDhefI4DTnK4KY5gwBIlW/7lqvnBVQ=
github.com/containers/image/v5 v5.29.2-0.20240119225553-e6e119441091/go.mod h1:OnS8tVWtDcn5AIB6qkS7xjM5HO1hNw2NzmHe9H35CCY= github.com/containers/image/v5 v5.29.3-0.20240131175401-a63f4a542670/go.mod h1:0OOeUAHBL3svD8r681/A0lY+XrwokWYH2Zcg7mhIS2s=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.1.9 h1:2Csfba4jse85Raxk5HIyEk8OwZNjRvfkhEGijOjIdEM= github.com/containers/ocicrypt v1.1.9 h1:2Csfba4jse85Raxk5HIyEk8OwZNjRvfkhEGijOjIdEM=
@ -57,11 +57,11 @@ 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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v25.0.0+incompatible h1:zaimaQdnX7fYWFqzN88exE9LDEvRslexpFowZBX6GoQ= github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbTO1lpcGSkU=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v25.0.0+incompatible h1:g9b6wZTblhMgzOT2tspESstfw6ySZ9kdm94BLDKaZac= github.com/docker/docker v25.0.1+incompatible h1:k5TYd5rIVQRSqcTwCID+cyVA0yRg86+Pcrz1ls0/frA=
github.com/docker/docker v25.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v25.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@ -120,8 +120,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-rod/rod v0.114.5 h1:1x6oqnslwFVuXJbJifgxspJUd3O4ntaGhRLHt+4Er9c= github.com/go-rod/rod v0.114.5 h1:1x6oqnslwFVuXJbJifgxspJUd3O4ntaGhRLHt+4Er9c=
@ -222,8 +222,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.5 h1:d4vBd+7CHydUqpFBgUEKkSdtSugf9YFmSkvUYPquI5E=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.5/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
@ -251,8 +251,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.21 h1:IXocQLOykluc3xPE0Lvy8FtggMz1G+U3mEjg+0zGizc=
github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.21/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=

View File

@ -9,11 +9,6 @@ import (
"github.com/docker/go-connections/tlsconfig" "github.com/docker/go-connections/tlsconfig"
) )
const (
// The default API version to be used in case none is explicitly specified
defaultAPIVersion = "1.22"
)
// NewDockerClient initializes a new API client based on the passed SystemContext. // NewDockerClient initializes a new API client based on the passed SystemContext.
func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) { func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) {
host := dockerclient.DefaultDockerHost host := dockerclient.DefaultDockerHost
@ -23,7 +18,7 @@ func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) {
opts := []dockerclient.Opt{ opts := []dockerclient.Opt{
dockerclient.WithHost(host), dockerclient.WithHost(host),
dockerclient.WithVersion(defaultAPIVersion), dockerclient.WithAPIVersionNegotiation(),
} }
// We conditionalize building the TLS configuration only to TLS sockets: // We conditionalize building the TLS configuration only to TLS sockets:

View File

@ -6,9 +6,9 @@ const (
// VersionMajor is for an API incompatible changes // VersionMajor is for an API incompatible changes
VersionMajor = 5 VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner // VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 29 VersionMinor = 30
// VersionPatch is for backwards-compatible bug fixes // VersionPatch is for backwards-compatible bug fixes
VersionPatch = 2 VersionPatch = 0
// VersionDev indicates development branch. Releases will be empty string. // VersionDev indicates development branch. Releases will be empty string.
VersionDev = "-dev" VersionDev = "-dev"

52
vendor/github.com/go-openapi/swag/BENCHMARK.md generated vendored Normal file
View File

@ -0,0 +1,52 @@
# Benchmarks
## Name mangling utilities
```bash
go test -bench XXX -run XXX -benchtime 30s
```
### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df
```
goos: linux
goarch: amd64
pkg: github.com/go-openapi/swag
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
BenchmarkToXXXName/ToGoName-4 862623 44101 ns/op 10450 B/op 732 allocs/op
BenchmarkToXXXName/ToVarName-4 853656 40728 ns/op 10468 B/op 734 allocs/op
BenchmarkToXXXName/ToFileName-4 1268312 27813 ns/op 9785 B/op 617 allocs/op
BenchmarkToXXXName/ToCommandName-4 1276322 27903 ns/op 9785 B/op 617 allocs/op
BenchmarkToXXXName/ToHumanNameLower-4 895334 40354 ns/op 10472 B/op 731 allocs/op
BenchmarkToXXXName/ToHumanNameTitle-4 882441 40678 ns/op 10566 B/op 749 allocs/op
```
### Benchmarks after PR #79
~ x10 performance improvement and ~ /100 memory allocations.
```
goos: linux
goarch: amd64
pkg: github.com/go-openapi/swag
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
BenchmarkToXXXName/ToGoName-4 9595830 3991 ns/op 42 B/op 5 allocs/op
BenchmarkToXXXName/ToVarName-4 9194276 3984 ns/op 62 B/op 7 allocs/op
BenchmarkToXXXName/ToFileName-4 17002711 2123 ns/op 147 B/op 7 allocs/op
BenchmarkToXXXName/ToCommandName-4 16772926 2111 ns/op 147 B/op 7 allocs/op
BenchmarkToXXXName/ToHumanNameLower-4 9788331 3749 ns/op 92 B/op 6 allocs/op
BenchmarkToXXXName/ToHumanNameTitle-4 9188260 3941 ns/op 104 B/op 6 allocs/op
```
```
goos: linux
goarch: amd64
pkg: github.com/go-openapi/swag
cpu: AMD Ryzen 7 5800X 8-Core Processor
BenchmarkToXXXName/ToGoName-16 18527378 1972 ns/op 42 B/op 5 allocs/op
BenchmarkToXXXName/ToVarName-16 15552692 2093 ns/op 62 B/op 7 allocs/op
BenchmarkToXXXName/ToFileName-16 32161176 1117 ns/op 147 B/op 7 allocs/op
BenchmarkToXXXName/ToCommandName-16 32256634 1137 ns/op 147 B/op 7 allocs/op
BenchmarkToXXXName/ToHumanNameLower-16 18599661 1946 ns/op 92 B/op 6 allocs/op
BenchmarkToXXXName/ToHumanNameTitle-16 17581353 2054 ns/op 105 B/op 6 allocs/op
```

View File

@ -16,9 +16,130 @@ package swag
import ( import (
"sort" "sort"
"strings"
"sync" "sync"
) )
var (
// commonInitialisms are common acronyms that are kept as whole uppercased words.
commonInitialisms *indexOfInitialisms
// initialisms is a slice of sorted initialisms
initialisms []string
// a copy of initialisms pre-baked as []rune
initialismsRunes [][]rune
initialismsUpperCased [][]rune
isInitialism func(string) bool
maxAllocMatches int
)
func init() {
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
configuredInitialisms := map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTPS": true,
"HTTP": true,
"ID": true,
"IP": true,
"IPv4": true,
"IPv6": true,
"JSON": true,
"LHS": true,
"OAI": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}
// a thread-safe index of initialisms
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
initialisms = commonInitialisms.sorted()
initialismsRunes = asRunes(initialisms)
initialismsUpperCased = asUpperCased(initialisms)
maxAllocMatches = maxAllocHeuristic(initialismsRunes)
// a test function
isInitialism = commonInitialisms.isInitialism
}
func asRunes(in []string) [][]rune {
out := make([][]rune, len(in))
for i, initialism := range in {
out[i] = []rune(initialism)
}
return out
}
func asUpperCased(in []string) [][]rune {
out := make([][]rune, len(in))
for i, initialism := range in {
out[i] = []rune(upper(trim(initialism)))
}
return out
}
func maxAllocHeuristic(in [][]rune) int {
heuristic := make(map[rune]int)
for _, initialism := range in {
heuristic[initialism[0]]++
}
var maxAlloc int
for _, val := range heuristic {
if val > maxAlloc {
maxAlloc = val
}
}
return maxAlloc
}
// AddInitialisms add additional initialisms
func AddInitialisms(words ...string) {
for _, word := range words {
// commonInitialisms[upper(word)] = true
commonInitialisms.add(upper(word))
}
// sort again
initialisms = commonInitialisms.sorted()
initialismsRunes = asRunes(initialisms)
initialismsUpperCased = asUpperCased(initialisms)
}
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. // indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
// Since go1.9, this may be implemented with sync.Map. // Since go1.9, this may be implemented with sync.Map.
type indexOfInitialisms struct { type indexOfInitialisms struct {
@ -63,3 +184,19 @@ func (m *indexOfInitialisms) sorted() (result []string) {
sort.Sort(sort.Reverse(byInitialism(result))) sort.Sort(sort.Reverse(byInitialism(result)))
return return
} }
type byInitialism []string
func (s byInitialism) Len() int {
return len(s)
}
func (s byInitialism) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s byInitialism) Less(i, j int) bool {
if len(s[i]) != len(s[j]) {
return len(s[i]) < len(s[j])
}
return strings.Compare(s[i], s[j]) > 0
}

View File

@ -14,74 +14,80 @@
package swag package swag
import "unicode" import (
"unicode"
"unicode/utf8"
)
type ( type (
nameLexem interface { lexemKind uint8
GetUnsafeGoName() string
GetOriginal() string
IsInitialism() bool
}
initialismNameLexem struct { nameLexem struct {
original string original string
matchedInitialism string matchedInitialism string
} kind lexemKind
casualNameLexem struct {
original string
} }
) )
func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem { const (
return &initialismNameLexem{ lexemKindCasualName lexemKind = iota
lexemKindInitialismName
)
func newInitialismNameLexem(original, matchedInitialism string) nameLexem {
return nameLexem{
kind: lexemKindInitialismName,
original: original, original: original,
matchedInitialism: matchedInitialism, matchedInitialism: matchedInitialism,
} }
} }
func newCasualNameLexem(original string) *casualNameLexem { func newCasualNameLexem(original string) nameLexem {
return &casualNameLexem{ return nameLexem{
kind: lexemKindCasualName,
original: original, original: original,
} }
} }
func (l *initialismNameLexem) GetUnsafeGoName() string { func (l nameLexem) GetUnsafeGoName() string {
return l.matchedInitialism if l.kind == lexemKindInitialismName {
} return l.matchedInitialism
}
var (
first rune
rest string
)
func (l *casualNameLexem) GetUnsafeGoName() string {
var first rune
var rest string
for i, orig := range l.original { for i, orig := range l.original {
if i == 0 { if i == 0 {
first = orig first = orig
continue continue
} }
if i > 0 { if i > 0 {
rest = l.original[i:] rest = l.original[i:]
break break
} }
} }
if len(l.original) > 1 { if len(l.original) > 1 {
return string(unicode.ToUpper(first)) + lower(rest) b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest))
defer func() {
poolOfBuffers.RedeemBuffer(b)
}()
b.WriteRune(unicode.ToUpper(first))
b.WriteString(lower(rest))
return b.String()
} }
return l.original return l.original
} }
func (l *initialismNameLexem) GetOriginal() string { func (l nameLexem) GetOriginal() string {
return l.original return l.original
} }
func (l *casualNameLexem) GetOriginal() string { func (l nameLexem) IsInitialism() bool {
return l.original return l.kind == lexemKindInitialismName
}
func (l *initialismNameLexem) IsInitialism() bool {
return true
}
func (l *casualNameLexem) IsInitialism() bool {
return false
} }

View File

@ -15,124 +15,269 @@
package swag package swag
import ( import (
"bytes"
"sync"
"unicode" "unicode"
"unicode/utf8"
) )
var nameReplaceTable = map[rune]string{
'@': "At ",
'&': "And ",
'|': "Pipe ",
'$': "Dollar ",
'!': "Bang ",
'-': "",
'_': "",
}
type ( type (
splitter struct { splitter struct {
postSplitInitialismCheck bool
initialisms []string initialisms []string
initialismsRunes [][]rune
initialismsUpperCased [][]rune // initialisms cached in their trimmed, upper-cased version
postSplitInitialismCheck bool
} }
splitterOption func(*splitter) *splitter splitterOption func(*splitter)
initialismMatch struct {
body []rune
start, end int
complete bool
}
initialismMatches []initialismMatch
) )
// split calls the splitter; splitter provides more control and post options type (
func split(str string) []string { // memory pools of temporary objects.
lexems := newSplitter().split(str) //
result := make([]string, 0, len(lexems)) // These are used to recycle temporarily allocated objects
// and relieve the GC from undue pressure.
for _, lexem := range lexems { matchesPool struct {
*sync.Pool
}
buffersPool struct {
*sync.Pool
}
lexemsPool struct {
*sync.Pool
}
splittersPool struct {
*sync.Pool
}
)
var (
// poolOfMatches holds temporary slices for recycling during the initialism match process
poolOfMatches = matchesPool{
Pool: &sync.Pool{
New: func() any {
s := make(initialismMatches, 0, maxAllocMatches)
return &s
},
},
}
poolOfBuffers = buffersPool{
Pool: &sync.Pool{
New: func() any {
return new(bytes.Buffer)
},
},
}
poolOfLexems = lexemsPool{
Pool: &sync.Pool{
New: func() any {
s := make([]nameLexem, 0, maxAllocMatches)
return &s
},
},
}
poolOfSplitters = splittersPool{
Pool: &sync.Pool{
New: func() any {
s := newSplitter()
return &s
},
},
}
)
// nameReplaceTable finds a word representation for special characters.
func nameReplaceTable(r rune) (string, bool) {
switch r {
case '@':
return "At ", true
case '&':
return "And ", true
case '|':
return "Pipe ", true
case '$':
return "Dollar ", true
case '!':
return "Bang ", true
case '-':
return "", true
case '_':
return "", true
default:
return "", false
}
}
// split calls the splitter.
//
// Use newSplitter for more control and options
func split(str string) []string {
s := poolOfSplitters.BorrowSplitter()
lexems := s.split(str)
result := make([]string, 0, len(*lexems))
for _, lexem := range *lexems {
result = append(result, lexem.GetOriginal()) result = append(result, lexem.GetOriginal())
} }
poolOfLexems.RedeemLexems(lexems)
poolOfSplitters.RedeemSplitter(s)
return result return result
} }
func (s *splitter) split(str string) []nameLexem { func newSplitter(options ...splitterOption) splitter {
return s.toNameLexems(str) s := splitter{
}
func newSplitter(options ...splitterOption) *splitter {
splitter := &splitter{
postSplitInitialismCheck: false, postSplitInitialismCheck: false,
initialisms: initialisms, initialisms: initialisms,
initialismsRunes: initialismsRunes,
initialismsUpperCased: initialismsUpperCased,
} }
for _, option := range options { for _, option := range options {
splitter = option(splitter) option(&s)
} }
return splitter
}
// withPostSplitInitialismCheck allows to catch initialisms after main split process
func withPostSplitInitialismCheck(s *splitter) *splitter {
s.postSplitInitialismCheck = true
return s return s
} }
type ( // withPostSplitInitialismCheck allows to catch initialisms after main split process
initialismMatch struct { func withPostSplitInitialismCheck(s *splitter) {
start, end int s.postSplitInitialismCheck = true
body []rune }
complete bool
}
initialismMatches []*initialismMatch
)
func (s *splitter) toNameLexems(name string) []nameLexem { func (p matchesPool) BorrowMatches() *initialismMatches {
s := p.Get().(*initialismMatches)
*s = (*s)[:0] // reset slice, keep allocated capacity
return s
}
func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer {
s := p.Get().(*bytes.Buffer)
s.Reset()
if s.Cap() < size {
s.Grow(size)
}
return s
}
func (p lexemsPool) BorrowLexems() *[]nameLexem {
s := p.Get().(*[]nameLexem)
*s = (*s)[:0] // reset slice, keep allocated capacity
return s
}
func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter {
s := p.Get().(*splitter)
s.postSplitInitialismCheck = false // reset options
for _, apply := range options {
apply(s)
}
return s
}
func (p matchesPool) RedeemMatches(s *initialismMatches) {
p.Put(s)
}
func (p buffersPool) RedeemBuffer(s *bytes.Buffer) {
p.Put(s)
}
func (p lexemsPool) RedeemLexems(s *[]nameLexem) {
p.Put(s)
}
func (p splittersPool) RedeemSplitter(s *splitter) {
p.Put(s)
}
func (m initialismMatch) isZero() bool {
return m.start == 0 && m.end == 0
}
func (s splitter) split(name string) *[]nameLexem {
nameRunes := []rune(name) nameRunes := []rune(name)
matches := s.gatherInitialismMatches(nameRunes) matches := s.gatherInitialismMatches(nameRunes)
if matches == nil {
return poolOfLexems.BorrowLexems()
}
return s.mapMatchesToNameLexems(nameRunes, matches) return s.mapMatchesToNameLexems(nameRunes, matches)
} }
func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches { func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches {
matches := make(initialismMatches, 0) var matches *initialismMatches
for currentRunePosition, currentRune := range nameRunes { for currentRunePosition, currentRune := range nameRunes {
newMatches := make(initialismMatches, 0, len(matches)) // recycle these allocations as we loop over runes
// with such recycling, only 2 slices should be allocated per call
// instead of o(n).
newMatches := poolOfMatches.BorrowMatches()
// check current initialism matches // check current initialism matches
for _, match := range matches { if matches != nil { // skip first iteration
if keepCompleteMatch := match.complete; keepCompleteMatch { for _, match := range *matches {
newMatches = append(newMatches, match) if keepCompleteMatch := match.complete; keepCompleteMatch {
continue *newMatches = append(*newMatches, match)
} continue
// drop failed match
currentMatchRune := match.body[currentRunePosition-match.start]
if !s.initialismRuneEqual(currentMatchRune, currentRune) {
continue
}
// try to complete ongoing match
if currentRunePosition-match.start == len(match.body)-1 {
// we are close; the next step is to check the symbol ahead
// if it is a small letter, then it is not the end of match
// but beginning of the next word
if currentRunePosition < len(nameRunes)-1 {
nextRune := nameRunes[currentRunePosition+1]
if newWord := unicode.IsLower(nextRune); newWord {
// oh ok, it was the start of a new word
continue
}
} }
match.complete = true // drop failed match
match.end = currentRunePosition currentMatchRune := match.body[currentRunePosition-match.start]
} if currentMatchRune != currentRune {
continue
}
newMatches = append(newMatches, match) // try to complete ongoing match
if currentRunePosition-match.start == len(match.body)-1 {
// we are close; the next step is to check the symbol ahead
// if it is a small letter, then it is not the end of match
// but beginning of the next word
if currentRunePosition < len(nameRunes)-1 {
nextRune := nameRunes[currentRunePosition+1]
if newWord := unicode.IsLower(nextRune); newWord {
// oh ok, it was the start of a new word
continue
}
}
match.complete = true
match.end = currentRunePosition
}
*newMatches = append(*newMatches, match)
}
} }
// check for new initialism matches // check for new initialism matches
for _, initialism := range s.initialisms { for i := range s.initialisms {
initialismRunes := []rune(initialism) initialismRunes := s.initialismsRunes[i]
if s.initialismRuneEqual(initialismRunes[0], currentRune) { if initialismRunes[0] == currentRune {
newMatches = append(newMatches, &initialismMatch{ *newMatches = append(*newMatches, initialismMatch{
start: currentRunePosition, start: currentRunePosition,
body: initialismRunes, body: initialismRunes,
complete: false, complete: false,
@ -140,24 +285,28 @@ func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
} }
} }
if matches != nil {
poolOfMatches.RedeemMatches(matches)
}
matches = newMatches matches = newMatches
} }
// up to the caller to redeem this last slice
return matches return matches
} }
func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem { func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem {
nameLexems := make([]nameLexem, 0) nameLexems := poolOfLexems.BorrowLexems()
var lastAcceptedMatch *initialismMatch var lastAcceptedMatch initialismMatch
for _, match := range matches { for _, match := range *matches {
if !match.complete { if !match.complete {
continue continue
} }
if firstMatch := lastAcceptedMatch == nil; firstMatch { if firstMatch := lastAcceptedMatch.isZero(); firstMatch {
nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...) s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start])
nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
lastAcceptedMatch = match lastAcceptedMatch = match
@ -169,63 +318,66 @@ func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMa
} }
middle := nameRunes[lastAcceptedMatch.end+1 : match.start] middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
nameLexems = append(nameLexems, s.breakCasualString(middle)...) s.appendBrokenDownCasualString(nameLexems, middle)
nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
lastAcceptedMatch = match lastAcceptedMatch = match
} }
// we have not found any accepted matches // we have not found any accepted matches
if lastAcceptedMatch == nil { if lastAcceptedMatch.isZero() {
return s.breakCasualString(nameRunes) *nameLexems = (*nameLexems)[:0]
s.appendBrokenDownCasualString(nameLexems, nameRunes)
} else if lastAcceptedMatch.end+1 != len(nameRunes) {
rest := nameRunes[lastAcceptedMatch.end+1:]
s.appendBrokenDownCasualString(nameLexems, rest)
} }
if lastAcceptedMatch.end+1 != len(nameRunes) { poolOfMatches.RedeemMatches(matches)
rest := nameRunes[lastAcceptedMatch.end+1:]
nameLexems = append(nameLexems, s.breakCasualString(rest)...)
}
return nameLexems return nameLexems
} }
func (s *splitter) initialismRuneEqual(a, b rune) bool { func (s splitter) breakInitialism(original string) nameLexem {
return a == b
}
func (s *splitter) breakInitialism(original string) nameLexem {
return newInitialismNameLexem(original, original) return newInitialismNameLexem(original, original)
} }
func (s *splitter) breakCasualString(str []rune) []nameLexem { func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) {
segments := make([]nameLexem, 0) currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused
currentSegment := "" defer func() {
poolOfBuffers.RedeemBuffer(currentSegment)
}()
addCasualNameLexem := func(original string) { addCasualNameLexem := func(original string) {
segments = append(segments, newCasualNameLexem(original)) *segments = append(*segments, newCasualNameLexem(original))
} }
addInitialismNameLexem := func(original, match string) { addInitialismNameLexem := func(original, match string) {
segments = append(segments, newInitialismNameLexem(original, match)) *segments = append(*segments, newInitialismNameLexem(original, match))
} }
addNameLexem := func(original string) { var addNameLexem func(string)
if s.postSplitInitialismCheck { if s.postSplitInitialismCheck {
for _, initialism := range s.initialisms { addNameLexem = func(original string) {
if upper(initialism) == upper(original) { for i := range s.initialisms {
addInitialismNameLexem(original, initialism) if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) {
addInitialismNameLexem(original, s.initialisms[i])
return return
} }
} }
}
addCasualNameLexem(original) addCasualNameLexem(original)
}
} else {
addNameLexem = addCasualNameLexem
} }
for _, rn := range string(str) { for _, rn := range str {
if replace, found := nameReplaceTable[rn]; found { if replace, found := nameReplaceTable(rn); found {
if currentSegment != "" { if currentSegment.Len() > 0 {
addNameLexem(currentSegment) addNameLexem(currentSegment.String())
currentSegment = "" currentSegment.Reset()
} }
if replace != "" { if replace != "" {
@ -236,27 +388,121 @@ func (s *splitter) breakCasualString(str []rune) []nameLexem {
} }
if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) { if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
if currentSegment != "" { if currentSegment.Len() > 0 {
addNameLexem(currentSegment) addNameLexem(currentSegment.String())
currentSegment = "" currentSegment.Reset()
} }
continue continue
} }
if unicode.IsUpper(rn) { if unicode.IsUpper(rn) {
if currentSegment != "" { if currentSegment.Len() > 0 {
addNameLexem(currentSegment) addNameLexem(currentSegment.String())
} }
currentSegment = "" currentSegment.Reset()
} }
currentSegment += string(rn) currentSegment.WriteRune(rn)
} }
if currentSegment != "" { if currentSegment.Len() > 0 {
addNameLexem(currentSegment) addNameLexem(currentSegment.String())
} }
}
return segments
// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but
// it ignores leading and trailing blank spaces in the compared
// string.
//
// base is assumed to be composed of upper-cased runes, and be already
// trimmed.
//
// This code is heavily inspired from strings.EqualFold.
func isEqualFoldIgnoreSpace(base []rune, str string) bool {
var i, baseIndex int
// equivalent to b := []byte(str), but without data copy
b := hackStringBytes(str)
for i < len(b) {
if c := b[i]; c < utf8.RuneSelf {
// fast path for ASCII
if c != ' ' && c != '\t' {
break
}
i++
continue
}
// unicode case
r, size := utf8.DecodeRune(b[i:])
if !unicode.IsSpace(r) {
break
}
i += size
}
if i >= len(b) {
return len(base) == 0
}
for _, baseRune := range base {
if i >= len(b) {
break
}
if c := b[i]; c < utf8.RuneSelf {
// single byte rune case (ASCII)
if baseRune >= utf8.RuneSelf {
return false
}
baseChar := byte(baseRune)
if c != baseChar &&
!('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) {
return false
}
baseIndex++
i++
continue
}
// unicode case
r, size := utf8.DecodeRune(b[i:])
if unicode.ToUpper(r) != baseRune {
return false
}
baseIndex++
i += size
}
if baseIndex != len(base) {
return false
}
// all passed: now we should only have blanks
for i < len(b) {
if c := b[i]; c < utf8.RuneSelf {
// fast path for ASCII
if c != ' ' && c != '\t' {
return false
}
i++
continue
}
// unicode case
r, size := utf8.DecodeRune(b[i:])
if !unicode.IsSpace(r) {
return false
}
i += size
}
return true
} }

22
vendor/github.com/go-openapi/swag/string_bytes.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
package swag
import "unsafe"
type internalString struct {
Data unsafe.Pointer
Len int
}
// hackStringBytes returns the (unsafe) underlying bytes slice of a string.
func hackStringBytes(str string) []byte {
p := (*internalString)(unsafe.Pointer(&str)).Data
return unsafe.Slice((*byte)(p), len(str))
}
/*
* go1.20 version (for when go mod moves to a go1.20 requirement):
func hackStringBytes(str string) []byte {
return unsafe.Slice(unsafe.StringData(str), len(str))
}
*/

View File

@ -18,76 +18,25 @@ import (
"reflect" "reflect"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8"
) )
// commonInitialisms are common acronyms that are kept as whole uppercased words.
var commonInitialisms *indexOfInitialisms
// initialisms is a slice of sorted initialisms
var initialisms []string
var isInitialism func(string) bool
// GoNamePrefixFunc sets an optional rule to prefix go names // GoNamePrefixFunc sets an optional rule to prefix go names
// which do not start with a letter. // which do not start with a letter.
// //
// The prefix function is assumed to return a string that starts with an upper case letter.
//
// e.g. to help convert "123" into "{prefix}123" // e.g. to help convert "123" into "{prefix}123"
// //
// The default is to prefix with "X" // The default is to prefix with "X"
var GoNamePrefixFunc func(string) string var GoNamePrefixFunc func(string) string
func init() { func prefixFunc(name, in string) string {
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 if GoNamePrefixFunc == nil {
var configuredInitialisms = map[string]bool{ return "X" + in
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTPS": true,
"HTTP": true,
"ID": true,
"IP": true,
"IPv4": true,
"IPv6": true,
"JSON": true,
"LHS": true,
"OAI": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
} }
// a thread-safe index of initialisms return GoNamePrefixFunc(name) + in
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
initialisms = commonInitialisms.sorted()
// a test function
isInitialism = commonInitialisms.isInitialism
} }
const ( const (
@ -156,22 +105,6 @@ func SplitByFormat(data, format string) []string {
return result return result
} }
type byInitialism []string
func (s byInitialism) Len() int {
return len(s)
}
func (s byInitialism) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s byInitialism) Less(i, j int) bool {
if len(s[i]) != len(s[j]) {
return len(s[i]) < len(s[j])
}
return strings.Compare(s[i], s[j]) > 0
}
// Removes leading whitespaces // Removes leading whitespaces
func trim(str string) string { func trim(str string) string {
return strings.TrimSpace(str) return strings.TrimSpace(str)
@ -188,15 +121,20 @@ func lower(str string) string {
} }
// Camelize an uppercased word // Camelize an uppercased word
func Camelize(word string) (camelized string) { func Camelize(word string) string {
camelized := poolOfBuffers.BorrowBuffer(len(word))
defer func() {
poolOfBuffers.RedeemBuffer(camelized)
}()
for pos, ru := range []rune(word) { for pos, ru := range []rune(word) {
if pos > 0 { if pos > 0 {
camelized += string(unicode.ToLower(ru)) camelized.WriteRune(unicode.ToLower(ru))
} else { } else {
camelized += string(unicode.ToUpper(ru)) camelized.WriteRune(unicode.ToUpper(ru))
} }
} }
return return camelized.String()
} }
// ToFileName lowercases and underscores a go type name // ToFileName lowercases and underscores a go type name
@ -224,26 +162,31 @@ func ToCommandName(name string) string {
// ToHumanNameLower represents a code name as a human series of words // ToHumanNameLower represents a code name as a human series of words
func ToHumanNameLower(name string) string { func ToHumanNameLower(name string) string {
in := newSplitter(withPostSplitInitialismCheck).split(name) s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
out := make([]string, 0, len(in)) in := s.split(name)
poolOfSplitters.RedeemSplitter(s)
out := make([]string, 0, len(*in))
for _, w := range in { for _, w := range *in {
if !w.IsInitialism() { if !w.IsInitialism() {
out = append(out, lower(w.GetOriginal())) out = append(out, lower(w.GetOriginal()))
} else { } else {
out = append(out, trim(w.GetOriginal())) out = append(out, trim(w.GetOriginal()))
} }
} }
poolOfLexems.RedeemLexems(in)
return strings.Join(out, " ") return strings.Join(out, " ")
} }
// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized // ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
func ToHumanNameTitle(name string) string { func ToHumanNameTitle(name string) string {
in := newSplitter(withPostSplitInitialismCheck).split(name) s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
in := s.split(name)
poolOfSplitters.RedeemSplitter(s)
out := make([]string, 0, len(in)) out := make([]string, 0, len(*in))
for _, w := range in { for _, w := range *in {
original := trim(w.GetOriginal()) original := trim(w.GetOriginal())
if !w.IsInitialism() { if !w.IsInitialism() {
out = append(out, Camelize(original)) out = append(out, Camelize(original))
@ -251,6 +194,8 @@ func ToHumanNameTitle(name string) string {
out = append(out, original) out = append(out, original)
} }
} }
poolOfLexems.RedeemLexems(in)
return strings.Join(out, " ") return strings.Join(out, " ")
} }
@ -283,35 +228,70 @@ func ToVarName(name string) string {
// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes // ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
func ToGoName(name string) string { func ToGoName(name string) string {
lexems := newSplitter(withPostSplitInitialismCheck).split(name) s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
lexems := s.split(name)
poolOfSplitters.RedeemSplitter(s)
defer func() {
poolOfLexems.RedeemLexems(lexems)
}()
lexemes := *lexems
result := "" if len(lexemes) == 0 {
for _, lexem := range lexems { return ""
}
result := poolOfBuffers.BorrowBuffer(len(name))
defer func() {
poolOfBuffers.RedeemBuffer(result)
}()
// check if not starting with a letter, upper case
firstPart := lexemes[0].GetUnsafeGoName()
if lexemes[0].IsInitialism() {
firstPart = upper(firstPart)
}
if c := firstPart[0]; c < utf8.RuneSelf {
// ASCII
switch {
case 'A' <= c && c <= 'Z':
result.WriteString(firstPart)
case 'a' <= c && c <= 'z':
result.WriteByte(c - 'a' + 'A')
result.WriteString(firstPart[1:])
default:
result.WriteString(prefixFunc(name, firstPart))
// NOTE: no longer check if prefixFunc returns a string that starts with uppercase:
// assume this is always the case
}
} else {
// unicode
firstRune, _ := utf8.DecodeRuneInString(firstPart)
switch {
case !unicode.IsLetter(firstRune):
result.WriteString(prefixFunc(name, firstPart))
case !unicode.IsUpper(firstRune):
result.WriteString(prefixFunc(name, firstPart))
/*
result.WriteRune(unicode.ToUpper(firstRune))
result.WriteString(firstPart[offset:])
*/
default:
result.WriteString(firstPart)
}
}
for _, lexem := range lexemes[1:] {
goName := lexem.GetUnsafeGoName() goName := lexem.GetUnsafeGoName()
// to support old behavior // to support old behavior
if lexem.IsInitialism() { if lexem.IsInitialism() {
goName = upper(goName) goName = upper(goName)
} }
result += goName result.WriteString(goName)
} }
if len(result) > 0 { return result.String()
// Only prefix with X when the first character isn't an ascii letter
first := []rune(result)[0]
if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) {
if GoNamePrefixFunc == nil {
return "X" + result
}
result = GoNamePrefixFunc(name) + result
}
first = []rune(result)[0]
if unicode.IsLetter(first) && !unicode.IsUpper(first) {
result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...))
}
}
return result
} }
// ContainsStrings searches a slice of strings for a case-sensitive match // ContainsStrings searches a slice of strings for a case-sensitive match
@ -376,16 +356,6 @@ func IsZero(data interface{}) bool {
} }
} }
// AddInitialisms add additional initialisms
func AddInitialisms(words ...string) {
for _, word := range words {
// commonInitialisms[upper(word)] = true
commonInitialisms.add(upper(word))
}
// sort again
initialisms = commonInitialisms.sorted()
}
// CommandLineOptionsGroup represents a group of user-defined command line options // CommandLineOptionsGroup represents a group of user-defined command line options
type CommandLineOptionsGroup struct { type CommandLineOptionsGroup struct {
ShortDescription string ShortDescription string

View File

@ -16,6 +16,18 @@ This package provides various compression algorithms.
# changelog # changelog
* Dec 1st, 2023 - [v1.17.4](https://github.com/klauspost/compress/releases/tag/v1.17.4)
* huff0: Speed up symbol counting by @greatroar in https://github.com/klauspost/compress/pull/887
* huff0: Remove byteReader by @greatroar in https://github.com/klauspost/compress/pull/886
* gzhttp: Allow overriding decompression on transport https://github.com/klauspost/compress/pull/892
* gzhttp: Clamp compression level https://github.com/klauspost/compress/pull/890
* gzip: Error out if reserved bits are set https://github.com/klauspost/compress/pull/891
* Nov 15th, 2023 - [v1.17.3](https://github.com/klauspost/compress/releases/tag/v1.17.3)
* fse: Fix max header size https://github.com/klauspost/compress/pull/881
* zstd: Improve better/best compression https://github.com/klauspost/compress/pull/877
* gzhttp: Fix missing content type on Close https://github.com/klauspost/compress/pull/883
* Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2) * Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2)
* zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876 * zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876
@ -554,7 +566,7 @@ For direct deflate use, NewStatelessWriter and StatelessDeflate are available. S
A `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer: A `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer:
``` ```go
// replace 'ioutil.Discard' with your output. // replace 'ioutil.Discard' with your output.
gzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression) gzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression)
if err != nil { if err != nil {

View File

@ -212,7 +212,7 @@ func (d *compressor) writeBlockSkip(tok *tokens, index int, eof bool) error {
// Should only be used after a start/reset. // Should only be used after a start/reset.
func (d *compressor) fillWindow(b []byte) { func (d *compressor) fillWindow(b []byte) {
// Do not fill window if we are in store-only or huffman mode. // Do not fill window if we are in store-only or huffman mode.
if d.level <= 0 { if d.level <= 0 && d.level > -MinCustomWindowSize {
return return
} }
if d.fast != nil { if d.fast != nil {

View File

@ -1,4 +1,4 @@
module github.com/klauspost/compress module github.com/klauspost/compress
go 1.16 go 1.19

View File

@ -95,42 +95,54 @@ type Header struct {
// If there isn't enough input, io.ErrUnexpectedEOF is returned. // If there isn't enough input, io.ErrUnexpectedEOF is returned.
// The FirstBlock.OK will indicate if enough information was available to decode the first block header. // The FirstBlock.OK will indicate if enough information was available to decode the first block header.
func (h *Header) Decode(in []byte) error { func (h *Header) Decode(in []byte) error {
_, err := h.DecodeAndStrip(in)
return err
}
// DecodeAndStrip will decode the header from the beginning of the stream
// and on success return the remaining bytes.
// This will decode the frame header and the first block header if enough bytes are provided.
// It is recommended to provide at least HeaderMaxSize bytes.
// If the frame header cannot be read an error will be returned.
// If there isn't enough input, io.ErrUnexpectedEOF is returned.
// The FirstBlock.OK will indicate if enough information was available to decode the first block header.
func (h *Header) DecodeAndStrip(in []byte) (remain []byte, err error) {
*h = Header{} *h = Header{}
if len(in) < 4 { if len(in) < 4 {
return io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
h.HeaderSize += 4 h.HeaderSize += 4
b, in := in[:4], in[4:] b, in := in[:4], in[4:]
if string(b) != frameMagic { if string(b) != frameMagic {
if string(b[1:4]) != skippableFrameMagic || b[0]&0xf0 != 0x50 { if string(b[1:4]) != skippableFrameMagic || b[0]&0xf0 != 0x50 {
return ErrMagicMismatch return nil, ErrMagicMismatch
} }
if len(in) < 4 { if len(in) < 4 {
return io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
h.HeaderSize += 4 h.HeaderSize += 4
h.Skippable = true h.Skippable = true
h.SkippableID = int(b[0] & 0xf) h.SkippableID = int(b[0] & 0xf)
h.SkippableSize = binary.LittleEndian.Uint32(in) h.SkippableSize = binary.LittleEndian.Uint32(in)
return nil return in[4:], nil
} }
// Read Window_Descriptor // Read Window_Descriptor
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor
if len(in) < 1 { if len(in) < 1 {
return io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
fhd, in := in[0], in[1:] fhd, in := in[0], in[1:]
h.HeaderSize++ h.HeaderSize++
h.SingleSegment = fhd&(1<<5) != 0 h.SingleSegment = fhd&(1<<5) != 0
h.HasCheckSum = fhd&(1<<2) != 0 h.HasCheckSum = fhd&(1<<2) != 0
if fhd&(1<<3) != 0 { if fhd&(1<<3) != 0 {
return errors.New("reserved bit set on frame header") return nil, errors.New("reserved bit set on frame header")
} }
if !h.SingleSegment { if !h.SingleSegment {
if len(in) < 1 { if len(in) < 1 {
return io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
var wd byte var wd byte
wd, in = in[0], in[1:] wd, in = in[0], in[1:]
@ -148,7 +160,7 @@ func (h *Header) Decode(in []byte) error {
size = 4 size = 4
} }
if len(in) < int(size) { if len(in) < int(size) {
return io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
b, in = in[:size], in[size:] b, in = in[:size], in[size:]
h.HeaderSize += int(size) h.HeaderSize += int(size)
@ -178,7 +190,7 @@ func (h *Header) Decode(in []byte) error {
if fcsSize > 0 { if fcsSize > 0 {
h.HasFCS = true h.HasFCS = true
if len(in) < fcsSize { if len(in) < fcsSize {
return io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
b, in = in[:fcsSize], in[fcsSize:] b, in = in[:fcsSize], in[fcsSize:]
h.HeaderSize += int(fcsSize) h.HeaderSize += int(fcsSize)
@ -199,7 +211,7 @@ func (h *Header) Decode(in []byte) error {
// Frame Header done, we will not fail from now on. // Frame Header done, we will not fail from now on.
if len(in) < 3 { if len(in) < 3 {
return nil return in, nil
} }
tmp := in[:3] tmp := in[:3]
bh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16) bh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16)
@ -209,7 +221,7 @@ func (h *Header) Decode(in []byte) error {
cSize := int(bh >> 3) cSize := int(bh >> 3)
switch blockType { switch blockType {
case blockTypeReserved: case blockTypeReserved:
return nil return in, nil
case blockTypeRLE: case blockTypeRLE:
h.FirstBlock.Compressed = true h.FirstBlock.Compressed = true
h.FirstBlock.DecompressedSize = cSize h.FirstBlock.DecompressedSize = cSize
@ -225,5 +237,25 @@ func (h *Header) Decode(in []byte) error {
} }
h.FirstBlock.OK = true h.FirstBlock.OK = true
return nil return in, nil
}
// AppendTo will append the encoded header to the dst slice.
// There is no error checking performed on the header values.
func (h *Header) AppendTo(dst []byte) ([]byte, error) {
if h.Skippable {
magic := [4]byte{0x50, 0x2a, 0x4d, 0x18}
magic[0] |= byte(h.SkippableID & 0xf)
dst = append(dst, magic[:]...)
f := h.SkippableSize
return append(dst, uint8(f), uint8(f>>8), uint8(f>>16), uint8(f>>24)), nil
}
f := frameHeader{
ContentSize: h.FrameContentSize,
WindowSize: uint32(h.WindowSize),
SingleSegment: h.SingleSegment,
Checksum: h.HasCheckSum,
DictID: h.DictionaryID,
}
return f.appendTo(dst), nil
} }

View File

@ -94,7 +94,7 @@ func WithEncoderConcurrency(n int) EOption {
// The value must be a power of two between MinWindowSize and MaxWindowSize. // The value must be a power of two between MinWindowSize and MaxWindowSize.
// A larger value will enable better compression but allocate more memory and, // A larger value will enable better compression but allocate more memory and,
// for above-default values, take considerably longer. // for above-default values, take considerably longer.
// The default value is determined by the compression level. // The default value is determined by the compression level and max 8MB.
func WithWindowSize(n int) EOption { func WithWindowSize(n int) EOption {
return func(o *encoderOptions) error { return func(o *encoderOptions) error {
switch { switch {
@ -232,9 +232,9 @@ func WithEncoderLevel(l EncoderLevel) EOption {
case SpeedDefault: case SpeedDefault:
o.windowSize = 8 << 20 o.windowSize = 8 << 20
case SpeedBetterCompression: case SpeedBetterCompression:
o.windowSize = 16 << 20 o.windowSize = 8 << 20
case SpeedBestCompression: case SpeedBestCompression:
o.windowSize = 32 << 20 o.windowSize = 8 << 20
} }
} }
if !o.customALEntropy { if !o.customALEntropy {

View File

@ -76,7 +76,7 @@ func (f frameHeader) appendTo(dst []byte) []byte {
if f.SingleSegment { if f.SingleSegment {
dst = append(dst, uint8(f.ContentSize)) dst = append(dst, uint8(f.ContentSize))
} }
// Unless SingleSegment is set, framessizes < 256 are nto stored. // Unless SingleSegment is set, framessizes < 256 are not stored.
case 1: case 1:
f.ContentSize -= 256 f.ContentSize -= 256
dst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8)) dst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8))

View File

@ -20,10 +20,9 @@ func (s *fseDecoder) buildDtable() error {
if v == -1 { if v == -1 {
s.dt[highThreshold].setAddBits(uint8(i)) s.dt[highThreshold].setAddBits(uint8(i))
highThreshold-- highThreshold--
symbolNext[i] = 1 v = 1
} else {
symbolNext[i] = uint16(v)
} }
symbolNext[i] = uint16(v)
} }
} }
@ -35,10 +34,12 @@ func (s *fseDecoder) buildDtable() error {
for ss, v := range s.norm[:s.symbolLen] { for ss, v := range s.norm[:s.symbolLen] {
for i := 0; i < int(v); i++ { for i := 0; i < int(v); i++ {
s.dt[position].setAddBits(uint8(ss)) s.dt[position].setAddBits(uint8(ss))
position = (position + step) & tableMask for {
for position > highThreshold {
// lowprob area // lowprob area
position = (position + step) & tableMask position = (position + step) & tableMask
if position <= highThreshold {
break
}
} }
} }
} }

View File

@ -157,8 +157,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
// Update Literal Length State // Update Literal Length State
MOVBQZX DI, R14 MOVBQZX DI, R14
SHRQ $0x10, DI SHRL $0x10, DI
MOVWQZX DI, DI
LEAQ (BX)(R14*1), CX LEAQ (BX)(R14*1), CX
MOVQ DX, R15 MOVQ DX, R15
MOVQ CX, BX MOVQ CX, BX
@ -177,8 +176,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
// Update Match Length State // Update Match Length State
MOVBQZX R8, R14 MOVBQZX R8, R14
SHRQ $0x10, R8 SHRL $0x10, R8
MOVWQZX R8, R8
LEAQ (BX)(R14*1), CX LEAQ (BX)(R14*1), CX
MOVQ DX, R15 MOVQ DX, R15
MOVQ CX, BX MOVQ CX, BX
@ -197,8 +195,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
// Update Offset State // Update Offset State
MOVBQZX R9, R14 MOVBQZX R9, R14
SHRQ $0x10, R9 SHRL $0x10, R9
MOVWQZX R9, R9
LEAQ (BX)(R14*1), CX LEAQ (BX)(R14*1), CX
MOVQ DX, R15 MOVQ DX, R15
MOVQ CX, BX MOVQ CX, BX
@ -459,8 +456,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
// Update Literal Length State // Update Literal Length State
MOVBQZX DI, R14 MOVBQZX DI, R14
SHRQ $0x10, DI SHRL $0x10, DI
MOVWQZX DI, DI
LEAQ (BX)(R14*1), CX LEAQ (BX)(R14*1), CX
MOVQ DX, R15 MOVQ DX, R15
MOVQ CX, BX MOVQ CX, BX
@ -479,8 +475,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
// Update Match Length State // Update Match Length State
MOVBQZX R8, R14 MOVBQZX R8, R14
SHRQ $0x10, R8 SHRL $0x10, R8
MOVWQZX R8, R8
LEAQ (BX)(R14*1), CX LEAQ (BX)(R14*1), CX
MOVQ DX, R15 MOVQ DX, R15
MOVQ CX, BX MOVQ CX, BX
@ -499,8 +494,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
// Update Offset State // Update Offset State
MOVBQZX R9, R14 MOVBQZX R9, R14
SHRQ $0x10, R9 SHRL $0x10, R9
MOVWQZX R9, R9
LEAQ (BX)(R14*1), CX LEAQ (BX)(R14*1), CX
MOVQ DX, R15 MOVQ DX, R15
MOVQ CX, BX MOVQ CX, BX
@ -772,11 +766,10 @@ sequenceDecs_decode_bmi2_fill_2_end:
BZHIQ R14, R15, R15 BZHIQ R14, R15, R15
// Update Offset State // Update Offset State
BZHIQ R8, R15, CX BZHIQ R8, R15, CX
SHRXQ R8, R15, R15 SHRXQ R8, R15, R15
MOVQ $0x00001010, R14 SHRL $0x10, R8
BEXTRQ R14, R8, R8 ADDQ CX, R8
ADDQ CX, R8
// Load ctx.ofTable // Load ctx.ofTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -784,11 +777,10 @@ sequenceDecs_decode_bmi2_fill_2_end:
MOVQ (CX)(R8*8), R8 MOVQ (CX)(R8*8), R8
// Update Match Length State // Update Match Length State
BZHIQ DI, R15, CX BZHIQ DI, R15, CX
SHRXQ DI, R15, R15 SHRXQ DI, R15, R15
MOVQ $0x00001010, R14 SHRL $0x10, DI
BEXTRQ R14, DI, DI ADDQ CX, DI
ADDQ CX, DI
// Load ctx.mlTable // Load ctx.mlTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -796,10 +788,9 @@ sequenceDecs_decode_bmi2_fill_2_end:
MOVQ (CX)(DI*8), DI MOVQ (CX)(DI*8), DI
// Update Literal Length State // Update Literal Length State
BZHIQ SI, R15, CX BZHIQ SI, R15, CX
MOVQ $0x00001010, R14 SHRL $0x10, SI
BEXTRQ R14, SI, SI ADDQ CX, SI
ADDQ CX, SI
// Load ctx.llTable // Load ctx.llTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -1032,11 +1023,10 @@ sequenceDecs_decode_56_bmi2_fill_end:
BZHIQ R14, R15, R15 BZHIQ R14, R15, R15
// Update Offset State // Update Offset State
BZHIQ R8, R15, CX BZHIQ R8, R15, CX
SHRXQ R8, R15, R15 SHRXQ R8, R15, R15
MOVQ $0x00001010, R14 SHRL $0x10, R8
BEXTRQ R14, R8, R8 ADDQ CX, R8
ADDQ CX, R8
// Load ctx.ofTable // Load ctx.ofTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -1044,11 +1034,10 @@ sequenceDecs_decode_56_bmi2_fill_end:
MOVQ (CX)(R8*8), R8 MOVQ (CX)(R8*8), R8
// Update Match Length State // Update Match Length State
BZHIQ DI, R15, CX BZHIQ DI, R15, CX
SHRXQ DI, R15, R15 SHRXQ DI, R15, R15
MOVQ $0x00001010, R14 SHRL $0x10, DI
BEXTRQ R14, DI, DI ADDQ CX, DI
ADDQ CX, DI
// Load ctx.mlTable // Load ctx.mlTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -1056,10 +1045,9 @@ sequenceDecs_decode_56_bmi2_fill_end:
MOVQ (CX)(DI*8), DI MOVQ (CX)(DI*8), DI
// Update Literal Length State // Update Literal Length State
BZHIQ SI, R15, CX BZHIQ SI, R15, CX
MOVQ $0x00001010, R14 SHRL $0x10, SI
BEXTRQ R14, SI, SI ADDQ CX, SI
ADDQ CX, SI
// Load ctx.llTable // Load ctx.llTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -1967,8 +1955,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
// Update Literal Length State // Update Literal Length State
MOVBQZX DI, R13 MOVBQZX DI, R13
SHRQ $0x10, DI SHRL $0x10, DI
MOVWQZX DI, DI
LEAQ (BX)(R13*1), CX LEAQ (BX)(R13*1), CX
MOVQ DX, R14 MOVQ DX, R14
MOVQ CX, BX MOVQ CX, BX
@ -1987,8 +1974,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
// Update Match Length State // Update Match Length State
MOVBQZX R8, R13 MOVBQZX R8, R13
SHRQ $0x10, R8 SHRL $0x10, R8
MOVWQZX R8, R8
LEAQ (BX)(R13*1), CX LEAQ (BX)(R13*1), CX
MOVQ DX, R14 MOVQ DX, R14
MOVQ CX, BX MOVQ CX, BX
@ -2007,8 +1993,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
// Update Offset State // Update Offset State
MOVBQZX R9, R13 MOVBQZX R9, R13
SHRQ $0x10, R9 SHRL $0x10, R9
MOVWQZX R9, R9
LEAQ (BX)(R13*1), CX LEAQ (BX)(R13*1), CX
MOVQ DX, R14 MOVQ DX, R14
MOVQ CX, BX MOVQ CX, BX
@ -2514,11 +2499,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
BZHIQ R13, R14, R14 BZHIQ R13, R14, R14
// Update Offset State // Update Offset State
BZHIQ R8, R14, CX BZHIQ R8, R14, CX
SHRXQ R8, R14, R14 SHRXQ R8, R14, R14
MOVQ $0x00001010, R13 SHRL $0x10, R8
BEXTRQ R13, R8, R8 ADDQ CX, R8
ADDQ CX, R8
// Load ctx.ofTable // Load ctx.ofTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -2526,11 +2510,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
MOVQ (CX)(R8*8), R8 MOVQ (CX)(R8*8), R8
// Update Match Length State // Update Match Length State
BZHIQ DI, R14, CX BZHIQ DI, R14, CX
SHRXQ DI, R14, R14 SHRXQ DI, R14, R14
MOVQ $0x00001010, R13 SHRL $0x10, DI
BEXTRQ R13, DI, DI ADDQ CX, DI
ADDQ CX, DI
// Load ctx.mlTable // Load ctx.mlTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -2538,10 +2521,9 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
MOVQ (CX)(DI*8), DI MOVQ (CX)(DI*8), DI
// Update Literal Length State // Update Literal Length State
BZHIQ SI, R14, CX BZHIQ SI, R14, CX
MOVQ $0x00001010, R13 SHRL $0x10, SI
BEXTRQ R13, SI, SI ADDQ CX, SI
ADDQ CX, SI
// Load ctx.llTable // Load ctx.llTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -3055,8 +3037,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
// Update Literal Length State // Update Literal Length State
MOVBQZX DI, R13 MOVBQZX DI, R13
SHRQ $0x10, DI SHRL $0x10, DI
MOVWQZX DI, DI
LEAQ (BX)(R13*1), CX LEAQ (BX)(R13*1), CX
MOVQ DX, R14 MOVQ DX, R14
MOVQ CX, BX MOVQ CX, BX
@ -3075,8 +3056,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
// Update Match Length State // Update Match Length State
MOVBQZX R8, R13 MOVBQZX R8, R13
SHRQ $0x10, R8 SHRL $0x10, R8
MOVWQZX R8, R8
LEAQ (BX)(R13*1), CX LEAQ (BX)(R13*1), CX
MOVQ DX, R14 MOVQ DX, R14
MOVQ CX, BX MOVQ CX, BX
@ -3095,8 +3075,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
// Update Offset State // Update Offset State
MOVBQZX R9, R13 MOVBQZX R9, R13
SHRQ $0x10, R9 SHRL $0x10, R9
MOVWQZX R9, R9
LEAQ (BX)(R13*1), CX LEAQ (BX)(R13*1), CX
MOVQ DX, R14 MOVQ DX, R14
MOVQ CX, BX MOVQ CX, BX
@ -3704,11 +3683,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
BZHIQ R13, R14, R14 BZHIQ R13, R14, R14
// Update Offset State // Update Offset State
BZHIQ R8, R14, CX BZHIQ R8, R14, CX
SHRXQ R8, R14, R14 SHRXQ R8, R14, R14
MOVQ $0x00001010, R13 SHRL $0x10, R8
BEXTRQ R13, R8, R8 ADDQ CX, R8
ADDQ CX, R8
// Load ctx.ofTable // Load ctx.ofTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -3716,11 +3694,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
MOVQ (CX)(R8*8), R8 MOVQ (CX)(R8*8), R8
// Update Match Length State // Update Match Length State
BZHIQ DI, R14, CX BZHIQ DI, R14, CX
SHRXQ DI, R14, R14 SHRXQ DI, R14, R14
MOVQ $0x00001010, R13 SHRL $0x10, DI
BEXTRQ R13, DI, DI ADDQ CX, DI
ADDQ CX, DI
// Load ctx.mlTable // Load ctx.mlTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX
@ -3728,10 +3705,9 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
MOVQ (CX)(DI*8), DI MOVQ (CX)(DI*8), DI
// Update Literal Length State // Update Literal Length State
BZHIQ SI, R14, CX BZHIQ SI, R14, CX
MOVQ $0x00001010, R13 SHRL $0x10, SI
BEXTRQ R13, SI, SI ADDQ CX, SI
ADDQ CX, SI
// Load ctx.llTable // Load ctx.llTable
MOVQ ctx+16(FP), CX MOVQ ctx+16(FP), CX

View File

@ -100,13 +100,13 @@ func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db
// Use handles to avoid passing Go pointers to C. // Use handles to avoid passing Go pointers to C.
type handleVal struct { type handleVal struct {
db *SQLiteConn db *SQLiteConn
val interface{} val any
} }
var handleLock sync.Mutex var handleLock sync.Mutex
var handleVals = make(map[unsafe.Pointer]handleVal) var handleVals = make(map[unsafe.Pointer]handleVal)
func newHandle(db *SQLiteConn, v interface{}) unsafe.Pointer { func newHandle(db *SQLiteConn, v any) unsafe.Pointer {
handleLock.Lock() handleLock.Lock()
defer handleLock.Unlock() defer handleLock.Unlock()
val := handleVal{db: db, val: v} val := handleVal{db: db, val: v}
@ -124,7 +124,7 @@ func lookupHandleVal(handle unsafe.Pointer) handleVal {
return handleVals[handle] return handleVals[handle]
} }
func lookupHandle(handle unsafe.Pointer) interface{} { func lookupHandle(handle unsafe.Pointer) any {
return lookupHandleVal(handle).val return lookupHandleVal(handle).val
} }
@ -238,7 +238,7 @@ func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
switch typ.Kind() { switch typ.Kind() {
case reflect.Interface: case reflect.Interface:
if typ.NumMethod() != 0 { if typ.NumMethod() != 0 {
return nil, errors.New("the only supported interface type is interface{}") return nil, errors.New("the only supported interface type is any")
} }
return callbackArgGeneric, nil return callbackArgGeneric, nil
case reflect.Slice: case reflect.Slice:
@ -360,11 +360,11 @@ func callbackRetGeneric(ctx *C.sqlite3_context, v reflect.Value) error {
} }
cb, err := callbackRet(v.Elem().Type()) cb, err := callbackRet(v.Elem().Type())
if err != nil { if err != nil {
return err return err
} }
return cb(ctx, v.Elem()) return cb(ctx, v.Elem())
} }
func callbackRet(typ reflect.Type) (callbackRetConverter, error) { func callbackRet(typ reflect.Type) (callbackRetConverter, error) {

View File

@ -23,7 +23,7 @@ var errNilPtr = errors.New("destination pointer is nil") // embedded in descript
// convertAssign copies to dest the value in src, converting it if possible. // convertAssign copies to dest the value in src, converting it if possible.
// An error is returned if the copy would result in loss of information. // An error is returned if the copy would result in loss of information.
// dest should be a pointer type. // dest should be a pointer type.
func convertAssign(dest, src interface{}) error { func convertAssign(dest, src any) error {
// Common cases, without reflect. // Common cases, without reflect.
switch s := src.(type) { switch s := src.(type) {
case string: case string:
@ -55,7 +55,7 @@ func convertAssign(dest, src interface{}) error {
} }
*d = string(s) *d = string(s)
return nil return nil
case *interface{}: case *any:
if d == nil { if d == nil {
return errNilPtr return errNilPtr
} }
@ -97,7 +97,7 @@ func convertAssign(dest, src interface{}) error {
} }
case nil: case nil:
switch d := dest.(type) { switch d := dest.(type) {
case *interface{}: case *any:
if d == nil { if d == nil {
return errNilPtr return errNilPtr
} }
@ -149,7 +149,7 @@ func convertAssign(dest, src interface{}) error {
*d = bv.(bool) *d = bv.(bool)
} }
return err return err
case *interface{}: case *any:
*d = src *d = src
return nil return nil
} }
@ -256,7 +256,7 @@ func cloneBytes(b []byte) []byte {
return c return c
} }
func asString(src interface{}) string { func asString(src any) string {
switch v := src.(type) { switch v := src.(type) {
case string: case string:
return v return v

View File

@ -5,63 +5,63 @@ This works as a driver for database/sql.
Installation Installation
go get github.com/mattn/go-sqlite3 go get github.com/mattn/go-sqlite3
Supported Types # Supported Types
Currently, go-sqlite3 supports the following data types. Currently, go-sqlite3 supports the following data types.
+------------------------------+ +------------------------------+
|go | sqlite3 | |go | sqlite3 |
|----------|-------------------| |----------|-------------------|
|nil | null | |nil | null |
|int | integer | |int | integer |
|int64 | integer | |int64 | integer |
|float64 | float | |float64 | float |
|bool | integer | |bool | integer |
|[]byte | blob | |[]byte | blob |
|string | text | |string | text |
|time.Time | timestamp/datetime| |time.Time | timestamp/datetime|
+------------------------------+ +------------------------------+
SQLite3 Extension # SQLite3 Extension
You can write your own extension module for sqlite3. For example, below is an You can write your own extension module for sqlite3. For example, below is an
extension for a Regexp matcher operation. extension for a Regexp matcher operation.
#include <pcre.h> #include <pcre.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <sqlite3ext.h> #include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1 SQLITE_EXTENSION_INIT1
static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) { static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) {
if (argc >= 2) { if (argc >= 2) {
const char *target = (const char *)sqlite3_value_text(argv[1]); const char *target = (const char *)sqlite3_value_text(argv[1]);
const char *pattern = (const char *)sqlite3_value_text(argv[0]); const char *pattern = (const char *)sqlite3_value_text(argv[0]);
const char* errstr = NULL; const char* errstr = NULL;
int erroff = 0; int erroff = 0;
int vec[500]; int vec[500];
int n, rc; int n, rc;
pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL); pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL);
rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500);
if (rc <= 0) { if (rc <= 0) {
sqlite3_result_error(context, errstr, 0); sqlite3_result_error(context, errstr, 0);
return; return;
} }
sqlite3_result_int(context, 1); sqlite3_result_int(context, 1);
} }
} }
#ifdef _WIN32 #ifdef _WIN32
__declspec(dllexport) __declspec(dllexport)
#endif #endif
int sqlite3_extension_init(sqlite3 *db, char **errmsg, int sqlite3_extension_init(sqlite3 *db, char **errmsg,
const sqlite3_api_routines *api) { const sqlite3_api_routines *api) {
SQLITE_EXTENSION_INIT2(api); SQLITE_EXTENSION_INIT2(api);
return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8,
(void*)db, regexp_func, NULL, NULL); (void*)db, regexp_func, NULL, NULL);
} }
It needs to be built as a so/dll shared library. And you need to register It needs to be built as a so/dll shared library. And you need to register
the extension module like below. the extension module like below.
@ -77,7 +77,7 @@ Then, you can use this extension.
rows, err := db.Query("select text from mytable where name regexp '^golang'") rows, err := db.Query("select text from mytable where name regexp '^golang'")
Connection Hook # Connection Hook
You can hook and inject your code when the connection is established by setting You can hook and inject your code when the connection is established by setting
ConnectHook to get the SQLiteConn. ConnectHook to get the SQLiteConn.
@ -95,13 +95,13 @@ You can also use database/sql.Conn.Raw (Go >= 1.13):
conn, err := db.Conn(context.Background()) conn, err := db.Conn(context.Background())
// if err != nil { ... } // if err != nil { ... }
defer conn.Close() defer conn.Close()
err = conn.Raw(func (driverConn interface{}) error { err = conn.Raw(func (driverConn any) error {
sqliteConn := driverConn.(*sqlite3.SQLiteConn) sqliteConn := driverConn.(*sqlite3.SQLiteConn)
// ... use sqliteConn // ... use sqliteConn
}) })
// if err != nil { ... } // if err != nil { ... }
Go SQlite3 Extensions # Go SQlite3 Extensions
If you want to register Go functions as SQLite extension functions If you want to register Go functions as SQLite extension functions
you can make a custom driver by calling RegisterFunction from you can make a custom driver by calling RegisterFunction from
@ -130,6 +130,5 @@ You can then use the custom driver by passing its name to sql.Open.
} }
See the documentation of RegisterFunc for more details. See the documentation of RegisterFunc for more details.
*/ */
package sqlite3 package sqlite3

File diff suppressed because it is too large Load Diff

View File

@ -147,9 +147,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.44.0" #define SQLITE_VERSION "3.45.1"
#define SQLITE_VERSION_NUMBER 3044000 #define SQLITE_VERSION_NUMBER 3045001
#define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" #define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -3955,15 +3955,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename);
** </ul> ** </ul>
** **
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively. ** text that describes the error, as either UTF-8 or UTF-16 respectively,
** or NULL if no error message is available.
** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** (See how SQLite handles [invalid UTF] for exceptions to this rule.)
** ^(Memory to hold the error message string is managed internally. ** ^(Memory to hold the error message string is managed internally.
** The application does not need to worry about freeing the result. ** The application does not need to worry about freeing the result.
** However, the error string might be overwritten or deallocated by ** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^ ** subsequent calls to other SQLite interface functions.)^
** **
** ^The sqlite3_errstr() interface returns the English-language text ** ^The sqlite3_errstr(E) interface returns the English-language text
** that describes the [result code], as UTF-8. ** that describes the [result code] E, as UTF-8, or NULL if E is not an
** result code for which a text error message is available.
** ^(Memory to hold the error message string is managed internally ** ^(Memory to hold the error message string is managed internally
** and must not be freed by the application)^. ** and must not be freed by the application)^.
** **
@ -5574,13 +5576,27 @@ SQLITE_API int sqlite3_create_window_function(
** </dd> ** </dd>
** **
** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call ** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
** Specifying this flag makes no difference for scalar or aggregate user ** This flag instructs SQLite to omit some corner-case optimizations that
** functions. However, if it is not specified for a user-defined window ** might disrupt the operation of the [sqlite3_value_subtype()] function,
** function, then any sub-types belonging to arguments passed to the window ** causing it to return zero rather than the correct subtype().
** function may be discarded before the window function is called (i.e. ** SQL functions that invokes [sqlite3_value_subtype()] should have this
** sqlite3_value_subtype() will always return 0). ** property. If the SQLITE_SUBTYPE property is omitted, then the return
** value from [sqlite3_value_subtype()] might sometimes be zero even though
** a non-zero subtype was specified by the function argument expression.
**
** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd>
** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call
** [sqlite3_result_subtype()] to cause a sub-type to be associated with its
** result.
** Every function that invokes [sqlite3_result_subtype()] should have this
** property. If it does not, then the call to [sqlite3_result_subtype()]
** might become a no-op if the function is used as term in an
** [expression index]. On the other hand, SQL functions that never invoke
** [sqlite3_result_subtype()] should avoid setting this property, as the
** purpose of this property is to disable certain optimizations that are
** incompatible with subtypes.
** </dd> ** </dd>
** </dl> ** </dl>
*/ */
@ -5588,6 +5604,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000 #define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_INNOCUOUS 0x000200000
#define SQLITE_RESULT_SUBTYPE 0x001000000
/* /*
** CAPI3REF: Deprecated Functions ** CAPI3REF: Deprecated Functions
@ -5784,6 +5801,12 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
** information can be used to pass a limited amount of context from ** information can be used to pass a limited amount of context from
** one SQL function to another. Use the [sqlite3_result_subtype()] ** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function. ** routine to set the subtype for the return value of an SQL function.
**
** Every [application-defined SQL function] that invoke this interface
** should include the [SQLITE_SUBTYPE] property in the text
** encoding argument when the function is [sqlite3_create_function|registered].
** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype()
** might return zero instead of the upstream subtype in some corner cases.
*/ */
SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
@ -5914,14 +5937,22 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** <li> ^(when sqlite3_set_auxdata() is invoked again on the same ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
** parameter)^, or ** parameter)^, or
** <li> ^(during the original sqlite3_set_auxdata() call when a memory ** <li> ^(during the original sqlite3_set_auxdata() call when a memory
** allocation error occurs.)^ </ul> ** allocation error occurs.)^
** <li> ^(during the original sqlite3_set_auxdata() call if the function
** is evaluated during query planning instead of during query execution,
** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul>
** **
** Note the last bullet in particular. The destructor X in ** Note the last two bullets in particular. The destructor X in
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the ** should be called near the end of the function implementation and the
** function implementation should not make any use of P after ** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called. ** sqlite3_set_auxdata() has been called. Furthermore, a call to
** sqlite3_get_auxdata() that occurs immediately after a corresponding call
** to sqlite3_set_auxdata() might still return NULL if an out-of-memory
** condition occurred during the sqlite3_set_auxdata() call or if the
** function is being evaluated during query planning rather than during
** query execution.
** **
** ^(In practice, auxiliary data is preserved between function calls for ** ^(In practice, auxiliary data is preserved between function calls for
** function parameters that are compile-time constants, including literal ** function parameters that are compile-time constants, including literal
@ -6195,6 +6226,20 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
** higher order bits are discarded. ** higher order bits are discarded.
** The number of subtype bytes preserved by SQLite might increase ** The number of subtype bytes preserved by SQLite might increase
** in future releases of SQLite. ** in future releases of SQLite.
**
** Every [application-defined SQL function] that invokes this interface
** should include the [SQLITE_RESULT_SUBTYPE] property in its
** text encoding argument when the SQL function is
** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE]
** property is omitted from the function that invokes sqlite3_result_subtype(),
** then in some cases the sqlite3_result_subtype() might fail to set
** the result subtype.
**
** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any
** SQL function that invokes the sqlite3_result_subtype() interface
** and that does not have the SQLITE_RESULT_SUBTYPE property will raise
** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1
** by default.
*/ */
SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
@ -7995,9 +8040,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** **
** ^(Some systems (for example, Windows 95) do not support the operation ** ^(Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
** will always return SQLITE_BUSY. The SQLite core only ever uses ** will always return SQLITE_BUSY. In most cases the SQLite core only uses
** sqlite3_mutex_try() as an optimization so this is acceptable ** sqlite3_mutex_try() as an optimization, so this is acceptable
** behavior.)^ ** behavior. The exceptions are unix builds that set the
** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working
** sqlite3_mutex_try() is required.)^
** **
** ^The sqlite3_mutex_leave() routine exits a mutex that was ** ^The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. The behavior ** previously entered by the same thread. The behavior
@ -8256,6 +8303,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ASSERT 12
#define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
@ -12769,8 +12817,11 @@ struct Fts5PhraseIter {
** created with the "columnsize=0" option. ** created with the "columnsize=0" option.
** **
** xColumnText: ** xColumnText:
** This function attempts to retrieve the text of column iCol of the ** If parameter iCol is less than zero, or greater than or equal to the
** current document. If successful, (*pz) is set to point to a buffer ** number of columns in the table, SQLITE_RANGE is returned.
**
** Otherwise, this function attempts to retrieve the text of column iCol of
** the current document. If successful, (*pz) is set to point to a buffer
** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
** if an error occurs, an SQLite error code is returned and the final values ** if an error occurs, an SQLite error code is returned and the final values
@ -12780,8 +12831,10 @@ struct Fts5PhraseIter {
** Returns the number of phrases in the current query expression. ** Returns the number of phrases in the current query expression.
** **
** xPhraseSize: ** xPhraseSize:
** Returns the number of tokens in phrase iPhrase of the query. Phrases ** If parameter iCol is less than zero, or greater than or equal to the
** are numbered starting from zero. ** number of phrases in the current query, as returned by xPhraseCount,
** 0 is returned. Otherwise, this function returns the number of tokens in
** phrase iPhrase of the query. Phrases are numbered starting from zero.
** **
** xInstCount: ** xInstCount:
** Set *pnInst to the total number of occurrences of all phrases within ** Set *pnInst to the total number of occurrences of all phrases within
@ -12797,12 +12850,13 @@ struct Fts5PhraseIter {
** Query for the details of phrase match iIdx within the current row. ** Query for the details of phrase match iIdx within the current row.
** Phrase matches are numbered starting from zero, so the iIdx argument ** Phrase matches are numbered starting from zero, so the iIdx argument
** should be greater than or equal to zero and smaller than the value ** should be greater than or equal to zero and smaller than the value
** output by xInstCount(). ** output by xInstCount(). If iIdx is less than zero or greater than
** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned.
** **
** Usually, output parameter *piPhrase is set to the phrase number, *piCol ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the ** to the column in which it occurs and *piOff the token offset of the
** first token of the phrase. Returns SQLITE_OK if successful, or an error ** first token of the phrase. SQLITE_OK is returned if successful, or an
** code (i.e. SQLITE_NOMEM) if an error occurs. ** error code (i.e. SQLITE_NOMEM) if an error occurs.
** **
** This API can be quite slow if used with an FTS5 table created with the ** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. ** "detail=none" or "detail=column" option.
@ -12828,6 +12882,10 @@ struct Fts5PhraseIter {
** Invoking Api.xUserData() returns a copy of the pointer passed as ** Invoking Api.xUserData() returns a copy of the pointer passed as
** the third argument to pUserData. ** the third argument to pUserData.
** **
** If parameter iPhrase is less than zero, or greater than or equal to
** the number of phrases in the query, as returned by xPhraseCount(),
** this function returns SQLITE_RANGE.
**
** If the callback function returns any value other than SQLITE_OK, the ** If the callback function returns any value other than SQLITE_OK, the
** query is abandoned and the xQueryPhrase function returns immediately. ** query is abandoned and the xQueryPhrase function returns immediately.
** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
@ -12942,9 +13000,42 @@ struct Fts5PhraseIter {
** **
** xPhraseNextColumn() ** xPhraseNextColumn()
** See xPhraseFirstColumn above. ** See xPhraseFirstColumn above.
**
** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)
** This is used to access token iToken of phrase iPhrase of the current
** query. Before returning, output parameter *ppToken is set to point
** to a buffer containing the requested token, and *pnToken to the
** size of this buffer in bytes.
**
** If iPhrase or iToken are less than zero, or if iPhrase is greater than
** or equal to the number of phrases in the query as reported by
** xPhraseCount(), or if iToken is equal to or greater than the number of
** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken
are both zeroed.
**
** The output text is not a copy of the query text that specified the
** token. It is the output of the tokenizer module. For tokendata=1
** tables, this includes any embedded 0x00 and trailing data.
**
** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)
** This is used to access token iToken of phrase hit iIdx within the
** current row. If iIdx is less than zero or greater than or equal to the
** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise,
** output variable (*ppToken) is set to point to a buffer containing the
** matching document token, and (*pnToken) to the size of that buffer in
** bytes. This API is not available if the specified token matches a
** prefix query term. In that case both output variables are always set
** to 0.
**
** The output text is not a copy of the document text that was tokenized.
** It is the output of the tokenizer module. For tokendata=1 tables, this
** includes any embedded 0x00 and trailing data.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
*/ */
struct Fts5ExtensionApi { struct Fts5ExtensionApi {
int iVersion; /* Currently always set to 2 */ int iVersion; /* Currently always set to 3 */
void *(*xUserData)(Fts5Context*); void *(*xUserData)(Fts5Context*);
@ -12979,6 +13070,13 @@ struct Fts5ExtensionApi {
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
/* Below this point are iVersion>=3 only */
int (*xQueryToken)(Fts5Context*,
int iPhrase, int iToken,
const char **ppToken, int *pnToken
);
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
}; };
/* /*

View File

@ -607,10 +607,9 @@ func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, strin
// RegisterFunc makes a Go function available as a SQLite function. // RegisterFunc makes a Go function available as a SQLite function.
// //
// The Go function can have arguments of the following types: any // The Go function can have arguments of the following types: any
// numeric type except complex, bool, []byte, string and // numeric type except complex, bool, []byte, string and any.
// interface{}. interface{} arguments are given the direct translation // any arguments are given the direct translation of the SQLite data type:
// of the SQLite data type: int64 for INTEGER, float64 for FLOAT, // int64 for INTEGER, float64 for FLOAT, []byte for BLOB, string for TEXT.
// []byte for BLOB, string for TEXT.
// //
// The function can additionally be variadic, as long as the type of // The function can additionally be variadic, as long as the type of
// the variadic argument is one of the above. // the variadic argument is one of the above.
@ -620,7 +619,7 @@ func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, strin
// optimizations in its queries. // optimizations in its queries.
// //
// See _example/go_custom_funcs for a detailed example. // See _example/go_custom_funcs for a detailed example.
func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) error { func (c *SQLiteConn) RegisterFunc(name string, impl any, pure bool) error {
var fi functionInfo var fi functionInfo
fi.f = reflect.ValueOf(impl) fi.f = reflect.ValueOf(impl)
t := fi.f.Type() t := fi.f.Type()
@ -702,7 +701,7 @@ func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTe
// return an error in addition to their other return values. // return an error in addition to their other return values.
// //
// See _example/go_custom_funcs for a detailed example. // See _example/go_custom_funcs for a detailed example.
func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { func (c *SQLiteConn) RegisterAggregator(name string, impl any, pure bool) error {
var ai aggInfo var ai aggInfo
ai.constructor = reflect.ValueOf(impl) ai.constructor = reflect.ValueOf(impl)
t := ai.constructor.Type() t := ai.constructor.Type()
@ -976,103 +975,104 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
// The argument is may be either in parentheses or it may be separated from // The argument is may be either in parentheses or it may be separated from
// the pragma name by an equal sign. The two syntaxes yield identical results. // the pragma name by an equal sign. The two syntaxes yield identical results.
// In many pragmas, the argument is a boolean. The boolean can be one of: // In many pragmas, the argument is a boolean. The boolean can be one of:
// 1 yes true on //
// 0 no false off // 1 yes true on
// 0 no false off
// //
// You can specify a DSN string using a URI as the filename. // You can specify a DSN string using a URI as the filename.
// test.db
// file:test.db?cache=shared&mode=memory
// :memory:
// file::memory:
// //
// mode // test.db
// Access mode of the database. // file:test.db?cache=shared&mode=memory
// https://www.sqlite.org/c3ref/open.html // :memory:
// Values: // file::memory:
// - ro
// - rw
// - rwc
// - memory
// //
// cache // mode
// SQLite Shared-Cache Mode // Access mode of the database.
// https://www.sqlite.org/sharedcache.html // https://www.sqlite.org/c3ref/open.html
// Values: // Values:
// - shared // - ro
// - private // - rw
// - rwc
// - memory
// //
// immutable=Boolean // cache
// The immutable parameter is a boolean query parameter that indicates // SQLite Shared-Cache Mode
// that the database file is stored on read-only media. When immutable is set, // https://www.sqlite.org/sharedcache.html
// SQLite assumes that the database file cannot be changed, // Values:
// even by a process with higher privilege, // - shared
// and so the database is opened read-only and all locking and change detection is disabled. // - private
// Caution: Setting the immutable property on a database file that //
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors. // immutable=Boolean
// The immutable parameter is a boolean query parameter that indicates
// that the database file is stored on read-only media. When immutable is set,
// SQLite assumes that the database file cannot be changed,
// even by a process with higher privilege,
// and so the database is opened read-only and all locking and change detection is disabled.
// Caution: Setting the immutable property on a database file that
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors.
// //
// go-sqlite3 adds the following query parameters to those used by SQLite: // go-sqlite3 adds the following query parameters to those used by SQLite:
// _loc=XXX
// Specify location of time format. It's possible to specify "auto".
// //
// _mutex=XXX // _loc=XXX
// Specify mutex mode. XXX can be "no", "full". // Specify location of time format. It's possible to specify "auto".
// //
// _txlock=XXX // _mutex=XXX
// Specify locking behavior for transactions. XXX can be "immediate", // Specify mutex mode. XXX can be "no", "full".
// "deferred", "exclusive".
// //
// _auto_vacuum=X | _vacuum=X // _txlock=XXX
// 0 | none - Auto Vacuum disabled // Specify locking behavior for transactions. XXX can be "immediate",
// 1 | full - Auto Vacuum FULL // "deferred", "exclusive".
// 2 | incremental - Auto Vacuum Incremental
// //
// _busy_timeout=XXX"| _timeout=XXX // _auto_vacuum=X | _vacuum=X
// Specify value for sqlite3_busy_timeout. // 0 | none - Auto Vacuum disabled
// 1 | full - Auto Vacuum FULL
// 2 | incremental - Auto Vacuum Incremental
// //
// _case_sensitive_like=Boolean | _cslike=Boolean // _busy_timeout=XXX"| _timeout=XXX
// https://www.sqlite.org/pragma.html#pragma_case_sensitive_like // Specify value for sqlite3_busy_timeout.
// Default or disabled the LIKE operation is case-insensitive.
// When enabling this options behaviour of LIKE will become case-sensitive.
// //
// _defer_foreign_keys=Boolean | _defer_fk=Boolean // _case_sensitive_like=Boolean | _cslike=Boolean
// Defer Foreign Keys until outermost transaction is committed. // https://www.sqlite.org/pragma.html#pragma_case_sensitive_like
// Default or disabled the LIKE operation is case-insensitive.
// When enabling this options behaviour of LIKE will become case-sensitive.
// //
// _foreign_keys=Boolean | _fk=Boolean // _defer_foreign_keys=Boolean | _defer_fk=Boolean
// Enable or disable enforcement of foreign keys. // Defer Foreign Keys until outermost transaction is committed.
// //
// _ignore_check_constraints=Boolean // _foreign_keys=Boolean | _fk=Boolean
// This pragma enables or disables the enforcement of CHECK constraints. // Enable or disable enforcement of foreign keys.
// The default setting is off, meaning that CHECK constraints are enforced by default.
// //
// _journal_mode=MODE | _journal=MODE // _ignore_check_constraints=Boolean
// Set journal mode for the databases associated with the current connection. // This pragma enables or disables the enforcement of CHECK constraints.
// https://www.sqlite.org/pragma.html#pragma_journal_mode // The default setting is off, meaning that CHECK constraints are enforced by default.
// //
// _locking_mode=X | _locking=X // _journal_mode=MODE | _journal=MODE
// Sets the database connection locking-mode. // Set journal mode for the databases associated with the current connection.
// The locking-mode is either NORMAL or EXCLUSIVE. // https://www.sqlite.org/pragma.html#pragma_journal_mode
// https://www.sqlite.org/pragma.html#pragma_locking_mode
// //
// _query_only=Boolean // _locking_mode=X | _locking=X
// The query_only pragma prevents all changes to database files when enabled. // Sets the database connection locking-mode.
// The locking-mode is either NORMAL or EXCLUSIVE.
// https://www.sqlite.org/pragma.html#pragma_locking_mode
// //
// _recursive_triggers=Boolean | _rt=Boolean // _query_only=Boolean
// Enable or disable recursive triggers. // The query_only pragma prevents all changes to database files when enabled.
// //
// _secure_delete=Boolean|FAST // _recursive_triggers=Boolean | _rt=Boolean
// When secure_delete is on, SQLite overwrites deleted content with zeros. // Enable or disable recursive triggers.
// https://www.sqlite.org/pragma.html#pragma_secure_delete
// //
// _synchronous=X | _sync=X // _secure_delete=Boolean|FAST
// Change the setting of the "synchronous" flag. // When secure_delete is on, SQLite overwrites deleted content with zeros.
// https://www.sqlite.org/pragma.html#pragma_synchronous // https://www.sqlite.org/pragma.html#pragma_secure_delete
//
// _writable_schema=Boolean
// When this pragma is on, the SQLITE_MASTER tables in which database
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
// Warning: misuse of this pragma can easily result in a corrupt database file.
// //
// _synchronous=X | _sync=X
// Change the setting of the "synchronous" flag.
// https://www.sqlite.org/pragma.html#pragma_synchronous
// //
// _writable_schema=Boolean
// When this pragma is on, the SQLITE_MASTER tables in which database
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
// Warning: misuse of this pragma can easily result in a corrupt database file.
func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
if C.sqlite3_threadsafe() == 0 { if C.sqlite3_threadsafe() == 0 {
return nil, errors.New("sqlite library was not compiled for thread-safe operation") return nil, errors.New("sqlite library was not compiled for thread-safe operation")

View File

@ -50,15 +50,15 @@ import (
// perhaps using a cryptographic hash function like SHA1. // perhaps using a cryptographic hash function like SHA1.
// CryptEncoderSHA1 encodes a password with SHA1 // CryptEncoderSHA1 encodes a password with SHA1
func CryptEncoderSHA1(pass []byte, hash interface{}) []byte { func CryptEncoderSHA1(pass []byte, hash any) []byte {
h := sha1.Sum(pass) h := sha1.Sum(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA1 encodes a password with SHA1 with the // CryptEncoderSSHA1 encodes a password with SHA1 with the
// configured salt. // configured salt.
func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA1(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha1.Sum(p) h := sha1.Sum(p)
@ -67,15 +67,15 @@ func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte {
} }
// CryptEncoderSHA256 encodes a password with SHA256 // CryptEncoderSHA256 encodes a password with SHA256
func CryptEncoderSHA256(pass []byte, hash interface{}) []byte { func CryptEncoderSHA256(pass []byte, hash any) []byte {
h := sha256.Sum256(pass) h := sha256.Sum256(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA256 encodes a password with SHA256 // CryptEncoderSSHA256 encodes a password with SHA256
// with the configured salt // with the configured salt
func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA256(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha256.Sum256(p) h := sha256.Sum256(p)
@ -84,15 +84,15 @@ func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte
} }
// CryptEncoderSHA384 encodes a password with SHA384 // CryptEncoderSHA384 encodes a password with SHA384
func CryptEncoderSHA384(pass []byte, hash interface{}) []byte { func CryptEncoderSHA384(pass []byte, hash any) []byte {
h := sha512.Sum384(pass) h := sha512.Sum384(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA384 encodes a password with SHA384 // CryptEncoderSSHA384 encodes a password with SHA384
// with the configured salt // with the configured salt
func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA384(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha512.Sum384(p) h := sha512.Sum384(p)
@ -101,15 +101,15 @@ func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte
} }
// CryptEncoderSHA512 encodes a password with SHA512 // CryptEncoderSHA512 encodes a password with SHA512
func CryptEncoderSHA512(pass []byte, hash interface{}) []byte { func CryptEncoderSHA512(pass []byte, hash any) []byte {
h := sha512.Sum512(pass) h := sha512.Sum512(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA512 encodes a password with SHA512 // CryptEncoderSSHA512 encodes a password with SHA512
// with the configured salt // with the configured salt
func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA512(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha512.Sum512(p) h := sha512.Sum512(p)

View File

@ -3,8 +3,8 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build cgo //go:build cgo && go1.8
// +build go1.8 // +build cgo,go1.8
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build libsqlite3
// +build libsqlite3 // +build libsqlite3
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !sqlite_omit_load_extension
// +build !sqlite_omit_load_extension // +build !sqlite_omit_load_extension
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_omit_load_extension
// +build sqlite_omit_load_extension // +build sqlite_omit_load_extension
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_allow_uri_authority
// +build sqlite_allow_uri_authority // +build sqlite_allow_uri_authority
package sqlite3 package sqlite3

View File

@ -4,8 +4,8 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !windows //go:build !windows && sqlite_app_armor
// +build sqlite_app_armor // +build !windows,sqlite_app_armor
package sqlite3 package sqlite3

View File

@ -1,3 +1,4 @@
//go:build sqlite_column_metadata
// +build sqlite_column_metadata // +build sqlite_column_metadata
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_foreign_keys
// +build sqlite_foreign_keys // +build sqlite_foreign_keys
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_fts5 || fts5
// +build sqlite_fts5 fts5 // +build sqlite_fts5 fts5
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_icu || icu
// +build sqlite_icu icu // +build sqlite_icu icu
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_introspect
// +build sqlite_introspect // +build sqlite_introspect
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_math_functions
// +build sqlite_math_functions // +build sqlite_math_functions
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build cgo
// +build cgo // +build cgo
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_preupdate_hook
// +build sqlite_preupdate_hook // +build sqlite_preupdate_hook
package sqlite3 package sqlite3
@ -54,10 +55,10 @@ func (d *SQLitePreUpdateData) Count() int {
return int(C.sqlite3_preupdate_count(d.Conn.db)) return int(C.sqlite3_preupdate_count(d.Conn.db))
} }
func (d *SQLitePreUpdateData) row(dest []interface{}, new bool) error { func (d *SQLitePreUpdateData) row(dest []any, new bool) error {
for i := 0; i < d.Count() && i < len(dest); i++ { for i := 0; i < d.Count() && i < len(dest); i++ {
var val *C.sqlite3_value var val *C.sqlite3_value
var src interface{} var src any
// Initially I tried making this just a function pointer argument, but // Initially I tried making this just a function pointer argument, but
// it's absurdly complicated to pass C function pointers. // it's absurdly complicated to pass C function pointers.
@ -95,7 +96,7 @@ func (d *SQLitePreUpdateData) row(dest []interface{}, new bool) error {
// Old populates dest with the row data to be replaced. This works similar to // Old populates dest with the row data to be replaced. This works similar to
// database/sql's Rows.Scan() // database/sql's Rows.Scan()
func (d *SQLitePreUpdateData) Old(dest ...interface{}) error { func (d *SQLitePreUpdateData) Old(dest ...any) error {
if d.Op == SQLITE_INSERT { if d.Op == SQLITE_INSERT {
return errors.New("There is no old row for INSERT operations") return errors.New("There is no old row for INSERT operations")
} }
@ -104,7 +105,7 @@ func (d *SQLitePreUpdateData) Old(dest ...interface{}) error {
// New populates dest with the replacement row data. This works similar to // New populates dest with the replacement row data. This works similar to
// database/sql's Rows.Scan() // database/sql's Rows.Scan()
func (d *SQLitePreUpdateData) New(dest ...interface{}) error { func (d *SQLitePreUpdateData) New(dest ...any) error {
if d.Op == SQLITE_DELETE { if d.Op == SQLITE_DELETE {
return errors.New("There is no new row for DELETE operations") return errors.New("There is no new row for DELETE operations")
} }

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !sqlite_preupdate_hook && cgo
// +build !sqlite_preupdate_hook,cgo // +build !sqlite_preupdate_hook,cgo
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_secure_delete
// +build sqlite_secure_delete // +build sqlite_secure_delete
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_secure_delete_fast
// +build sqlite_secure_delete_fast // +build sqlite_secure_delete_fast
package sqlite3 package sqlite3

View File

@ -1,3 +1,4 @@
//go:build !libsqlite3 || sqlite_serialize
// +build !libsqlite3 sqlite_serialize // +build !libsqlite3 sqlite_serialize
package sqlite3 package sqlite3

View File

@ -1,3 +1,4 @@
//go:build libsqlite3 && !sqlite_serialize
// +build libsqlite3,!sqlite_serialize // +build libsqlite3,!sqlite_serialize
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_stat4
// +build sqlite_stat4 // +build sqlite_stat4
package sqlite3 package sqlite3

View File

@ -3,8 +3,8 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build cgo //go:build cgo && sqlite_unlock_notify
// +build sqlite_unlock_notify // +build cgo,sqlite_unlock_notify
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_userauth
// +build sqlite_userauth // +build sqlite_userauth
package sqlite3 package sqlite3
@ -79,7 +80,7 @@ var (
// If a database contains the SQLITE_USER table, then the // If a database contains the SQLITE_USER table, then the
// call to Authenticate must be invoked with an // call to Authenticate must be invoked with an
// appropriate username and password prior to enable read and write // appropriate username and password prior to enable read and write
//access to the database. // access to the database.
// //
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password // Return SQLITE_OK on success or SQLITE_ERROR if the username/password
// combination is incorrect or unknown. // combination is incorrect or unknown.
@ -103,9 +104,10 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authenticate(username, password string) int { func (c *SQLiteConn) authenticate(username, password string) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -155,9 +157,10 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int { func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -207,9 +210,10 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserChange(username, password string, admin int) int { func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -249,9 +253,10 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserDelete(username string) int { func (c *SQLiteConn) authUserDelete(username string) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -280,8 +285,9 @@ func (c *SQLiteConn) AuthEnabled() (exists bool) {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// 0 - Disabled //
// 1 - Enabled // 0 - Disabled
// 1 - Enabled
func (c *SQLiteConn) authEnabled() int { func (c *SQLiteConn) authEnabled() int {
return int(C._sqlite3_auth_enabled(c.db)) return int(C._sqlite3_auth_enabled(c.db))
} }

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !sqlite_userauth
// +build !sqlite_userauth // +build !sqlite_userauth
package sqlite3 package sqlite3
@ -17,7 +18,7 @@ import (
// If a database contains the SQLITE_USER table, then the // If a database contains the SQLITE_USER table, then the
// call to Authenticate must be invoked with an // call to Authenticate must be invoked with an
// appropriate username and password prior to enable read and write // appropriate username and password prior to enable read and write
//access to the database. // access to the database.
// //
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password // Return SQLITE_OK on success or SQLITE_ERROR if the username/password
// combination is incorrect or unknown. // combination is incorrect or unknown.
@ -34,9 +35,10 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authenticate(username, password string) int { func (c *SQLiteConn) authenticate(username, password string) int {
// NOOP // NOOP
return 0 return 0
@ -65,9 +67,10 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int { func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// NOOP // NOOP
return 0 return 0
@ -96,9 +99,10 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserChange(username, password string, admin int) int { func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
// NOOP // NOOP
return 0 return 0
@ -122,9 +126,10 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserDelete(username string) int { func (c *SQLiteConn) authUserDelete(username string) int {
// NOOP // NOOP
return 0 return 0
@ -142,8 +147,9 @@ func (c *SQLiteConn) AuthEnabled() (exists bool) {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// 0 - Disabled //
// 1 - Enabled // 0 - Disabled
// 1 - Enabled
func (c *SQLiteConn) authEnabled() int { func (c *SQLiteConn) authEnabled() int {
// NOOP // NOOP
return 0 return 0

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_vacuum_full
// +build sqlite_vacuum_full // +build sqlite_vacuum_full
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_vacuum_incr
// +build sqlite_vacuum_incr // +build sqlite_vacuum_incr
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_vtable || vtable
// +build sqlite_vtable vtable // +build sqlite_vtable vtable
package sqlite3 package sqlite3
@ -516,7 +517,7 @@ func goMDestroy(pClientData unsafe.Pointer) {
func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char { func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char {
vtc := lookupHandle(pCursor).(*sqliteVTabCursor) vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
vals := make([]interface{}, 0, argc) vals := make([]any, 0, argc)
for _, v := range args { for _, v := range args {
conv, err := callbackArgGeneric(v) conv, err := callbackArgGeneric(v)
if err != nil { if err != nil {
@ -588,7 +589,7 @@ func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid
if v, ok := vt.vTab.(VTabUpdater); ok { if v, ok := vt.vTab.(VTabUpdater); ok {
// convert argv // convert argv
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
vals := make([]interface{}, 0, argc) vals := make([]any, 0, argc)
for _, v := range args { for _, v := range args {
conv, err := callbackArgGeneric(v) conv, err := callbackArgGeneric(v)
if err != nil { if err != nil {
@ -662,9 +663,9 @@ type VTab interface {
// deleted. // deleted.
// See: https://sqlite.org/vtab.html#xupdate // See: https://sqlite.org/vtab.html#xupdate
type VTabUpdater interface { type VTabUpdater interface {
Delete(interface{}) error Delete(any) error
Insert(interface{}, []interface{}) (int64, error) Insert(any, []any) (int64, error)
Update(interface{}, []interface{}) error Update(any, []any) error
} }
// VTabCursor describes cursors that point into the virtual table and are used // VTabCursor describes cursors that point into the virtual table and are used
@ -673,7 +674,7 @@ type VTabCursor interface {
// http://sqlite.org/vtab.html#xclose // http://sqlite.org/vtab.html#xclose
Close() error Close() error
// http://sqlite.org/vtab.html#xfilter // http://sqlite.org/vtab.html#xfilter
Filter(idxNum int, idxStr string, vals []interface{}) error Filter(idxNum int, idxStr string, vals []any) error
// http://sqlite.org/vtab.html#xnext // http://sqlite.org/vtab.html#xnext
Next() error Next() error
// http://sqlite.org/vtab.html#xeof // http://sqlite.org/vtab.html#xeof

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !windows
// +build !windows // +build !windows
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build solaris
// +build solaris // +build solaris
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_trace || trace
// +build sqlite_trace trace // +build sqlite_trace trace
package sqlite3 package sqlite3

View File

@ -74,7 +74,7 @@ func scanType(cdt string) reflect.Type {
case SQLITE_TIME: case SQLITE_TIME:
return reflect.TypeOf(sql.NullTime{}) return reflect.TypeOf(sql.NullTime{})
} }
return reflect.TypeOf(new(interface{})) return reflect.TypeOf(new(any))
} }
func databaseTypeConvSqlite(t string) int { func databaseTypeConvSqlite(t string) int {

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build cgo
// +build cgo // +build cgo
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build windows
// +build windows // +build windows
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !cgo
// +build !cgo // +build !cgo
package sqlite3 package sqlite3
@ -28,10 +29,10 @@ type (
) )
func (SQLiteDriver) Open(s string) (driver.Conn, error) { return nil, errorMsg } func (SQLiteDriver) Open(s string) (driver.Conn, error) { return nil, errorMsg }
func (c *SQLiteConn) RegisterAggregator(string, interface{}, bool) error { return errorMsg } func (c *SQLiteConn) RegisterAggregator(string, any, bool) error { return errorMsg }
func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {} func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {}
func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg } func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg }
func (c *SQLiteConn) RegisterCommitHook(func() int) {} func (c *SQLiteConn) RegisterCommitHook(func() int) {}
func (c *SQLiteConn) RegisterFunc(string, interface{}, bool) error { return errorMsg } func (c *SQLiteConn) RegisterFunc(string, any, bool) error { return errorMsg }
func (c *SQLiteConn) RegisterRollbackHook(func()) {} func (c *SQLiteConn) RegisterRollbackHook(func()) {}
func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64)) {} func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64)) {}

12
vendor/modules.txt vendored
View File

@ -73,7 +73,7 @@ github.com/containers/common/pkg/password
github.com/containers/common/pkg/report github.com/containers/common/pkg/report
github.com/containers/common/pkg/report/camelcase github.com/containers/common/pkg/report/camelcase
github.com/containers/common/pkg/retry github.com/containers/common/pkg/retry
# github.com/containers/image/v5 v5.29.2-0.20240119225553-e6e119441091 # github.com/containers/image/v5 v5.29.3-0.20240131175401-a63f4a542670
## explicit; go 1.19 ## explicit; go 1.19
github.com/containers/image/v5/copy github.com/containers/image/v5/copy
github.com/containers/image/v5/directory github.com/containers/image/v5/directory
@ -234,7 +234,7 @@ github.com/distribution/reference
github.com/docker/distribution/registry/api/errcode github.com/docker/distribution/registry/api/errcode
github.com/docker/distribution/registry/api/v2 github.com/docker/distribution/registry/api/v2
github.com/docker/distribution/registry/client/auth/challenge github.com/docker/distribution/registry/client/auth/challenge
# github.com/docker/docker v25.0.0+incompatible # github.com/docker/docker v25.0.1+incompatible
## explicit ## explicit
github.com/docker/docker/api github.com/docker/docker/api
github.com/docker/docker/api/types github.com/docker/docker/api/types
@ -326,7 +326,7 @@ github.com/go-openapi/spec
# github.com/go-openapi/strfmt v0.22.0 # github.com/go-openapi/strfmt v0.22.0
## explicit; go 1.19 ## explicit; go 1.19
github.com/go-openapi/strfmt github.com/go-openapi/strfmt
# github.com/go-openapi/swag v0.22.7 # github.com/go-openapi/swag v0.22.9
## explicit; go 1.19 ## explicit; go 1.19
github.com/go-openapi/swag github.com/go-openapi/swag
# github.com/go-openapi/validate v0.22.1 # github.com/go-openapi/validate v0.22.1
@ -381,7 +381,7 @@ github.com/josharian/intern
# github.com/json-iterator/go v1.1.12 # github.com/json-iterator/go v1.1.12
## explicit; go 1.12 ## explicit; go 1.12
github.com/json-iterator/go github.com/json-iterator/go
# github.com/klauspost/compress v1.17.4 # github.com/klauspost/compress v1.17.5
## explicit; go 1.19 ## explicit; go 1.19
github.com/klauspost/compress github.com/klauspost/compress
github.com/klauspost/compress/flate github.com/klauspost/compress/flate
@ -413,8 +413,8 @@ github.com/mattn/go-runewidth
# github.com/mattn/go-shellwords v1.0.12 # github.com/mattn/go-shellwords v1.0.12
## explicit; go 1.13 ## explicit; go 1.13
github.com/mattn/go-shellwords github.com/mattn/go-shellwords
# github.com/mattn/go-sqlite3 v1.14.19 # github.com/mattn/go-sqlite3 v1.14.21
## explicit; go 1.16 ## explicit; go 1.19
github.com/mattn/go-sqlite3 github.com/mattn/go-sqlite3
# github.com/miekg/pkcs11 v1.1.1 # github.com/miekg/pkcs11 v1.1.1
## explicit; go 1.12 ## explicit; go 1.12