upstep bun to v1.0.14 (#291)

This commit is contained in:
tobi 2021-10-24 13:14:37 +02:00 committed by GitHub
parent 84a8a07f38
commit 8b7c3507fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
100 changed files with 5071 additions and 3836 deletions

8
go.mod
View file

@ -28,9 +28,9 @@ require (
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB
github.com/tdewolff/minify/v2 v2.9.21
github.com/uptrace/bun v1.0.9
github.com/uptrace/bun/dialect/pgdialect v1.0.9
github.com/uptrace/bun/dialect/sqlitedialect v1.0.9
github.com/uptrace/bun v1.0.14
github.com/uptrace/bun/dialect/pgdialect v1.0.14
github.com/uptrace/bun/dialect/sqlitedialect v1.0.14
github.com/urfave/cli/v2 v2.3.0
github.com/wagslane/go-password-validator v0.3.0
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
@ -97,7 +97,7 @@ require (
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/mod v0.5.0 // indirect
golang.org/x/net v0.0.0-20210908191846-a5e095526f91 // indirect
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665 // indirect
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac // indirect
golang.org/x/tools v0.1.5 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/appengine v1.6.7 // indirect

16
go.sum
View file

@ -469,12 +469,12 @@ github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/uptrace/bun v1.0.9 h1:2iFZc6gXFKJNejVuPZszQFlONJSeS965+hlnwMsxqBE=
github.com/uptrace/bun v1.0.9/go.mod h1:0EpuI3Zno/OHJBz6rqGGEdduFxrlY49h2ffTeKtw/bo=
github.com/uptrace/bun/dialect/pgdialect v1.0.9 h1:pDzd6H4x3YQJVXE0vaUJI4+lmmfM1TJQhsCc90eUQj4=
github.com/uptrace/bun/dialect/pgdialect v1.0.9/go.mod h1:7XU+yFEyTU+Jf0YD7Nu/Mm8zjUCcTDpQq1C2N+u+qwI=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.9 h1:3DRWkml03BE/P3UsLwT6BfB2VXFDAKbbVTpwMO1LBTI=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.9/go.mod h1:s77Vrp/1SAdXaR+ELNen8WwMlLa3lUdiiiGp7ugu44E=
github.com/uptrace/bun v1.0.14 h1:rwWFTdnwX8/6CMTptxVgxly7h/YgfOO4WK7vrWPJRC0=
github.com/uptrace/bun v1.0.14/go.mod h1:rs7qARtH6aqLtcfmloWM6qn90iyY53N2ScLQssIrevw=
github.com/uptrace/bun/dialect/pgdialect v1.0.14 h1:GnaKZ9k8eek9Y4q4+rt/jklucdai+oQpAW77WhKJEvE=
github.com/uptrace/bun/dialect/pgdialect v1.0.14/go.mod h1:hQr4NoUPcb1tMEj7WTQ+fmKdoglR0xoKQKJ5EYuYJK0=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.14 h1:2S3dHGMpDT9d023Wm94+QdEDqh69xUtDBEJBhDVjmbo=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.14/go.mod h1:c189/WJIZt2ixRLrMYfOS5HUcsxRNfH6mAAnNKQcyrs=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@ -673,8 +673,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665 h1:QOQNt6vCjMpXE7JSK5VvAzJC1byuN3FgTNSBwf+CJgI=
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View file

@ -1,58 +1,141 @@
## [1.0.9](https://github.com/uptrace/bun/compare/v1.0.8...v1.0.9) (2021-09-27)
## [1.0.14](https://github.com/uptrace/bun/compare/v1.0.13...v1.0.14) (2021-10-24)
### Bug Fixes
* change DBStats to use uint32 instead of uint64 to make it work on i386 ([caca2a7](https://github.com/uptrace/bun/commit/caca2a7130288dec49fa26b49c8550140ee52f4c))
* correct binary serialization for mysql ([#259](https://github.com/uptrace/bun/issues/259)) ([e899f50](https://github.com/uptrace/bun/commit/e899f50b22ef6759ef8c029a6cd3f25f2bde17ef))
* correctly escape single quotes in pg arrays ([3010847](https://github.com/uptrace/bun/commit/3010847f5c2c50bce1969689a0b77fd8a6fb7e55))
* use BLOB sql type to encode []byte in MySQL and SQLite ([725ec88](https://github.com/uptrace/bun/commit/725ec8843824a7fc8f4058ead75ab0e62a78192a))
### Features
* add IQuery and QueryEvent.IQuery ([b762942](https://github.com/uptrace/bun/commit/b762942fa3b1d8686d0a559f93f2a6847b83d9c1))
* add QueryEvent.Model ([7688201](https://github.com/uptrace/bun/commit/7688201b485d14d3e393956f09a3200ea4d4e31d))
* **bunotel:** add experimental bun.query.timing metric ([2cdb384](https://github.com/uptrace/bun/commit/2cdb384678631ccadac0fb75f524bd5e91e96ee2))
* **pgdriver:** add Config.ConnParams to session config params ([408caf0](https://github.com/uptrace/bun/commit/408caf0bb579e23e26fc6149efd6851814c22517))
* **pgdriver:** allow specifying timeout in DSN ([7dbc71b](https://github.com/uptrace/bun/commit/7dbc71b3494caddc2e97d113f00067071b9e19da))
* warn when there are args but no placeholders ([06dde21](https://github.com/uptrace/bun/commit/06dde215c8d0bde2b2364597190729a160e536a1))
## [1.0.13](https://github.com/uptrace/bun/compare/v1.0.12...v1.0.13) (2021-10-17)
### Breaking Change
- **pgdriver:** enable TLS by default with InsecureSkipVerify=true
([15ec635](https://github.com/uptrace/bun/commit/15ec6356a04d5cf62d2efbeb189610532dc5eb31))
### Features
- add BeforeAppendModelHook
([0b55de7](https://github.com/uptrace/bun/commit/0b55de77aaffc1ed0894ef16f45df77bca7d93c1))
- **pgdriver:** add support for unix socket DSN
([f398cec](https://github.com/uptrace/bun/commit/f398cec1c3873efdf61ac0b94ebe06c657f0cf91))
## [1.0.12](https://github.com/uptrace/bun/compare/v1.0.11...v1.0.12) (2021-10-14)
### Bug Fixes
- add InsertQuery.ColumnExpr to specify columns
([60ffe29](https://github.com/uptrace/bun/commit/60ffe293b37912d95f28e69734ff51edf4b27da7))
- **bundebug:** change WithVerbose to accept a bool flag
([b2f8b91](https://github.com/uptrace/bun/commit/b2f8b912de1dc29f40c79066de1e9d6379db666c))
- **pgdialect:** fix bytea[] handling
([a5ca013](https://github.com/uptrace/bun/commit/a5ca013742c5a2e947b43d13f9c2fc0cf6a65d9c))
- **pgdriver:** rename DriverOption to Option
([51c1702](https://github.com/uptrace/bun/commit/51c1702431787d7369904b2624e346bf3e59c330))
- support allowzero on the soft delete field
([d0abec7](https://github.com/uptrace/bun/commit/d0abec71a9a546472a83bd70ed4e6a7357659a9b))
### Features
- **bundebug:** allow to configure the hook using env var, for example, BUNDEBUG={0,1,2}
([ce92852](https://github.com/uptrace/bun/commit/ce928524cab9a83395f3772ae9dd5d7732af281d))
- **bunotel:** report DBStats metrics
([b9b1575](https://github.com/uptrace/bun/commit/b9b15750f405cdbd345b776f5a56c6f742bc7361))
- **pgdriver:** add Error.StatementTimeout
([8a7934d](https://github.com/uptrace/bun/commit/8a7934dd788057828bb2b0983732b4394b74e960))
- **pgdriver:** allow setting Network in config
([b24b5d8](https://github.com/uptrace/bun/commit/b24b5d8014195a56ad7a4c634c10681038e6044d))
## [1.0.11](https://github.com/uptrace/bun/compare/v1.0.10...v1.0.11) (2021-10-05)
### Bug Fixes
- **mysqldialect:** remove duplicate AppendTime
([8d42090](https://github.com/uptrace/bun/commit/8d42090af34a1760004482c7fc0923b114d79937))
## [1.0.10](https://github.com/uptrace/bun/compare/v1.0.9...v1.0.10) (2021-10-05)
### Bug Fixes
- add UpdateQuery.OmitZero
([2294db6](https://github.com/uptrace/bun/commit/2294db61d228711435fff1075409a30086b37555))
- make ExcludeColumn work with many-to-many queries
([300e12b](https://github.com/uptrace/bun/commit/300e12b993554ff839ec4fa6bbea97e16aca1b55))
- **mysqldialect:** append time in local timezone
([e763cc8](https://github.com/uptrace/bun/commit/e763cc81eac4b11fff4e074ad3ff6cd970a71697))
- **tagparser:** improve parsing options with brackets
([0daa61e](https://github.com/uptrace/bun/commit/0daa61edc3c4d927ed260332b99ee09f4bb6b42f))
### Features
- add timetz parsing
([6e415c4](https://github.com/uptrace/bun/commit/6e415c4c5fa2c8caf4bb4aed4e5897fe5676f5a5))
## [1.0.9](https://github.com/uptrace/bun/compare/v1.0.8...v1.0.9) (2021-09-27)
### Bug Fixes
- change DBStats to use uint32 instead of uint64 to make it work on i386
([caca2a7](https://github.com/uptrace/bun/commit/caca2a7130288dec49fa26b49c8550140ee52f4c))
### Features
- add IQuery and QueryEvent.IQuery
([b762942](https://github.com/uptrace/bun/commit/b762942fa3b1d8686d0a559f93f2a6847b83d9c1))
- add QueryEvent.Model
([7688201](https://github.com/uptrace/bun/commit/7688201b485d14d3e393956f09a3200ea4d4e31d))
- **bunotel:** add experimental bun.query.timing metric
([2cdb384](https://github.com/uptrace/bun/commit/2cdb384678631ccadac0fb75f524bd5e91e96ee2))
- **pgdriver:** add Config.ConnParams to session config params
([408caf0](https://github.com/uptrace/bun/commit/408caf0bb579e23e26fc6149efd6851814c22517))
- **pgdriver:** allow specifying timeout in DSN
([7dbc71b](https://github.com/uptrace/bun/commit/7dbc71b3494caddc2e97d113f00067071b9e19da))
## [1.0.8](https://github.com/uptrace/bun/compare/v1.0.7...v1.0.8) (2021-09-18)
### Bug Fixes
* don't append soft delete where for insert queries with on conflict clause ([27c477c](https://github.com/uptrace/bun/commit/27c477ce071d4c49c99a2531d638ed9f20e33461))
* improve bun.NullTime to accept string ([73ad6f5](https://github.com/uptrace/bun/commit/73ad6f5640a0a9b09f8df2bc4ab9cb510021c50c))
* make allowzero work with auto-detected primary keys ([82ca87c](https://github.com/uptrace/bun/commit/82ca87c7c49797d507b31fdaacf8343716d4feff))
* support soft deletes on nil model ([0556e3c](https://github.com/uptrace/bun/commit/0556e3c63692a7f4e48659d52b55ffd9cca0202a))
- don't append soft delete where for insert queries with on conflict clause
([27c477c](https://github.com/uptrace/bun/commit/27c477ce071d4c49c99a2531d638ed9f20e33461))
- improve bun.NullTime to accept string
([73ad6f5](https://github.com/uptrace/bun/commit/73ad6f5640a0a9b09f8df2bc4ab9cb510021c50c))
- make allowzero work with auto-detected primary keys
([82ca87c](https://github.com/uptrace/bun/commit/82ca87c7c49797d507b31fdaacf8343716d4feff))
- support soft deletes on nil model
([0556e3c](https://github.com/uptrace/bun/commit/0556e3c63692a7f4e48659d52b55ffd9cca0202a))
## [1.0.7](https://github.com/uptrace/bun/compare/v1.0.6...v1.0.7) (2021-09-15)
### Bug Fixes
* don't append zero time as NULL without nullzero tag ([3b8d9cb](https://github.com/uptrace/bun/commit/3b8d9cb4e39eb17f79a618396bbbe0adbc66b07b))
* **pgdriver:** return PostgreSQL DATE as a string ([40be0e8](https://github.com/uptrace/bun/commit/40be0e8ea85f8932b7a410a6fc2dd3acd2d18ebc))
* specify table alias for soft delete where ([5fff1dc](https://github.com/uptrace/bun/commit/5fff1dc1dd74fa48623a24fa79e358a544dfac0b))
- don't append zero time as NULL without nullzero tag
([3b8d9cb](https://github.com/uptrace/bun/commit/3b8d9cb4e39eb17f79a618396bbbe0adbc66b07b))
- **pgdriver:** return PostgreSQL DATE as a string
([40be0e8](https://github.com/uptrace/bun/commit/40be0e8ea85f8932b7a410a6fc2dd3acd2d18ebc))
- specify table alias for soft delete where
([5fff1dc](https://github.com/uptrace/bun/commit/5fff1dc1dd74fa48623a24fa79e358a544dfac0b))
### Features
* add SelectQuery.Exists helper ([c3e59c1](https://github.com/uptrace/bun/commit/c3e59c1bc58b43c4b8e33e7d170ad33a08fbc3c7))
- add SelectQuery.Exists helper
([c3e59c1](https://github.com/uptrace/bun/commit/c3e59c1bc58b43c4b8e33e7d170ad33a08fbc3c7))
## [1.0.6](https://github.com/uptrace/bun/compare/v1.0.5...v1.0.6) (2021-09-11)
### Bug Fixes
* change unique tag to create a separate unique constraint ([8401615](https://github.com/uptrace/bun/commit/84016155a77ca77613cc054277fefadae3098757))
* improve zero checker for ptr values ([2b3623d](https://github.com/uptrace/bun/commit/2b3623dd665d873911fd20ca707016929921e862))
- change unique tag to create a separate unique constraint
([8401615](https://github.com/uptrace/bun/commit/84016155a77ca77613cc054277fefadae3098757))
- improve zero checker for ptr values
([2b3623d](https://github.com/uptrace/bun/commit/2b3623dd665d873911fd20ca707016929921e862))
## v1.0.5 - Sep 09 2021

View file

@ -12,7 +12,7 @@ cd internal/dbtest
1. Run `release.sh` script which updates versions in go.mod files and pushes a new branch to GitHub:
```shell
./scripts/release.sh -t v1.0.0
TAG=v1.0.0 ./scripts/release.sh
```
2. Open a pull request and wait for the build to finish.
@ -20,11 +20,5 @@ cd internal/dbtest
3. Merge the pull request and run `tag.sh` to create tags for packages:
```shell
./scripts/tag.sh -t v1.0.0
```
4. Push the tags:
```shell
git push origin --tags
TAG=v1.0.0 ./scripts/tag.sh
```

10
vendor/github.com/uptrace/bun/bun.go generated vendored
View file

@ -15,9 +15,17 @@ type (
NullTime = schema.NullTime
BaseModel = schema.BaseModel
Query = schema.Query
BeforeAppendModelHook = schema.BeforeAppendModelHook
BeforeScanRowHook = schema.BeforeScanRowHook
AfterScanRowHook = schema.AfterScanRowHook
// DEPRECATED. Use BeforeScanRowHook instead.
BeforeScanHook = schema.BeforeScanHook
AfterScanHook = schema.AfterScanHook
// DEPRECATED. Use AfterScanRowHook instead.
AfterScanHook = schema.AfterScanHook
)
type BeforeSelectHook interface {

View file

@ -163,7 +163,14 @@ func (db *DB) ScanRow(ctx context.Context, rows *sql.Rows, dest ...interface{})
return rs.ScanRow(ctx, rows)
}
type queryHookIniter interface {
Init(db *DB)
}
func (db *DB) AddQueryHook(hook QueryHook) {
if initer, ok := hook.(queryHookIniter); ok {
initer.Init(db)
}
db.queryHooks = append(db.queryHooks, hook)
}

View file

@ -4,11 +4,9 @@ import (
"encoding/hex"
"math"
"strconv"
"time"
"unicode/utf8"
"github.com/uptrace/bun/internal"
"github.com/uptrace/bun/internal/parser"
)
func AppendError(b []byte, err error) []byte {
@ -78,55 +76,16 @@ func AppendString(b []byte, s string) []byte {
return b
}
func AppendBytes(b []byte, bytes []byte) []byte {
if bytes == nil {
func AppendBytes(b, bs []byte) []byte {
if bs == nil {
return AppendNull(b)
}
b = append(b, `'\x`...)
s := len(b)
b = append(b, make([]byte, hex.EncodedLen(len(bytes)))...)
hex.Encode(b[s:], bytes)
b = append(b, '\'')
return b
}
func AppendTime(b []byte, tm time.Time) []byte {
b = append(b, '\'')
b = tm.UTC().AppendFormat(b, "2006-01-02 15:04:05.999999-07:00")
b = append(b, '\'')
return b
}
func AppendJSON(b, jsonb []byte) []byte {
b = append(b, '\'')
p := parser.New(jsonb)
for p.Valid() {
c := p.Read()
switch c {
case '"':
b = append(b, '"')
case '\'':
b = append(b, "''"...)
case '\000':
continue
case '\\':
if p.SkipBytes([]byte("u0000")) {
b = append(b, `\\u0000`...)
} else {
b = append(b, '\\')
if p.Valid() {
b = append(b, p.Read())
}
}
default:
b = append(b, c)
}
}
b = append(b, make([]byte, hex.EncodedLen(len(bs)))...)
hex.Encode(b[s:], bs)
b = append(b, '\'')

View file

@ -2,6 +2,7 @@ package pgdialect
import (
"database/sql/driver"
"encoding/hex"
"fmt"
"reflect"
"strconv"
@ -28,26 +29,6 @@ var (
sliceFloat64Type = reflect.TypeOf([]float64(nil))
)
func customAppender(typ reflect.Type) schema.AppenderFunc {
switch typ.Kind() {
case reflect.Uint32:
return appendUint32ValueAsInt
case reflect.Uint, reflect.Uint64:
return appendUint64ValueAsInt
}
return nil
}
func appendUint32ValueAsInt(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
return strconv.AppendInt(b, int64(int32(v.Uint())), 10)
}
func appendUint64ValueAsInt(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
return strconv.AppendInt(b, int64(v.Uint()), 10)
}
//------------------------------------------------------------------------------
func arrayAppend(fmter schema.Formatter, b []byte, v interface{}) []byte {
switch v := v.(type) {
case int64:
@ -57,31 +38,25 @@ func arrayAppend(fmter schema.Formatter, b []byte, v interface{}) []byte {
case bool:
return dialect.AppendBool(b, v)
case []byte:
return dialect.AppendBytes(b, v)
return arrayAppendBytes(b, v)
case string:
return arrayAppendString(b, v)
case time.Time:
return dialect.AppendTime(b, v)
return fmter.Dialect().AppendTime(b, v)
default:
err := fmt.Errorf("pgdialect: can't append %T", v)
return dialect.AppendError(b, err)
}
}
func arrayElemAppender(typ reflect.Type) schema.AppenderFunc {
if typ.Kind() == reflect.String {
return arrayAppendStringValue
}
if typ.Implements(driverValuerType) {
return arrayAppendDriverValue
}
return schema.Appender(typ, customAppender)
}
func arrayAppendStringValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
return arrayAppendString(b, v.String())
}
func arrayAppendBytesValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
return arrayAppendBytes(b, v.Bytes())
}
func arrayAppendDriverValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
iface, err := v.Interface().(driver.Valuer).Value()
if err != nil {
@ -92,12 +67,12 @@ func arrayAppendDriverValue(fmter schema.Formatter, b []byte, v reflect.Value) [
//------------------------------------------------------------------------------
func arrayAppender(typ reflect.Type) schema.AppenderFunc {
func (d *Dialect) arrayAppender(typ reflect.Type) schema.AppenderFunc {
kind := typ.Kind()
switch kind {
case reflect.Ptr:
if fn := arrayAppender(typ.Elem()); fn != nil {
if fn := d.arrayAppender(typ.Elem()); fn != nil {
return schema.PtrAppender(fn)
}
case reflect.Slice, reflect.Array:
@ -121,7 +96,7 @@ func arrayAppender(typ reflect.Type) schema.AppenderFunc {
}
}
appendElem := arrayElemAppender(elemType)
appendElem := d.arrayElemAppender(elemType)
if appendElem == nil {
panic(fmt.Errorf("pgdialect: %s is not supported", typ))
}
@ -159,6 +134,21 @@ func arrayAppender(typ reflect.Type) schema.AppenderFunc {
}
}
func (d *Dialect) arrayElemAppender(typ reflect.Type) schema.AppenderFunc {
if typ.Implements(driverValuerType) {
return arrayAppendDriverValue
}
switch typ.Kind() {
case reflect.String:
return arrayAppendStringValue
case reflect.Slice:
if typ.Elem().Kind() == reflect.Uint8 {
return arrayAppendBytesValue
}
}
return schema.Appender(d, typ)
}
func appendStringSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
ss := v.Convert(sliceStringType).Interface().([]string)
return appendStringSlice(b, ss)
@ -273,6 +263,22 @@ func appendFloat64Slice(b []byte, floats []float64) []byte {
//------------------------------------------------------------------------------
func arrayAppendBytes(b []byte, bs []byte) []byte {
if bs == nil {
return dialect.AppendNull(b)
}
b = append(b, `"\\x`...)
s := len(b)
b = append(b, make([]byte, hex.EncodedLen(len(bs)))...)
hex.Encode(b[s:], bs)
b = append(b, '"')
return b
}
func arrayAppendString(b []byte, s string) []byte {
b = append(b, '"')
for _, r := range s {
@ -280,7 +286,7 @@ func arrayAppendString(b []byte, s string) []byte {
case 0:
// ignore
case '\'':
b = append(b, "'''"...)
b = append(b, "''"...)
case '"':
b = append(b, '\\', '"')
case '\\':

View file

@ -30,7 +30,7 @@ func Array(vi interface{}) *ArrayValue {
return &ArrayValue{
v: v,
append: arrayAppender(v.Type()),
append: pgDialect.arrayAppender(v.Type()),
scan: arrayScanner(v.Type()),
}
}

View file

@ -2,6 +2,7 @@ package pgdialect
import (
"bytes"
"encoding/hex"
"fmt"
"io"
)
@ -109,11 +110,29 @@ func (p *arrayParser) readSubstring() ([]byte, error) {
}
continue
}
if c == '\'' && next == '\'' {
p.buf = append(p.buf, next)
c, err = p.readByte()
if err != nil {
return nil, err
}
continue
}
p.buf = append(p.buf, c)
c = next
}
if bytes.HasPrefix(p.buf, []byte("\\x")) && len(p.buf)%2 == 0 {
data := p.buf[2:]
buf := make([]byte, hex.DecodedLen(len(data)))
n, err := hex.Decode(buf, data)
if err != nil {
return nil, err
}
return buf[:n], nil
}
return p.buf, nil
}

View file

@ -2,10 +2,7 @@ package pgdialect
import (
"database/sql"
"reflect"
"strconv"
"sync"
"time"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/feature"
@ -13,12 +10,13 @@ import (
"github.com/uptrace/bun/schema"
)
var pgDialect = New()
type Dialect struct {
schema.BaseDialect
tables *schema.Tables
features feature.Feature
appenderMap sync.Map
scannerMap sync.Map
}
func New() *Dialect {
@ -71,7 +69,7 @@ func (d *Dialect) onField(field *schema.Field) {
}
if field.Tag.HasOption("array") {
field.Append = arrayAppender(field.StructField.Type)
field.Append = d.arrayAppender(field.StructField.Type)
field.Scan = arrayScanner(field.StructField.Type)
}
}
@ -80,72 +78,10 @@ func (d *Dialect) IdentQuote() byte {
return '"'
}
func (d *Dialect) Append(fmter schema.Formatter, b []byte, v interface{}) []byte {
switch v := v.(type) {
case nil:
return dialect.AppendNull(b)
case bool:
return dialect.AppendBool(b, v)
case int:
return strconv.AppendInt(b, int64(v), 10)
case int32:
return strconv.AppendInt(b, int64(v), 10)
case int64:
return strconv.AppendInt(b, v, 10)
case uint:
return strconv.AppendInt(b, int64(v), 10)
case uint32:
return strconv.AppendInt(b, int64(v), 10)
case uint64:
return strconv.AppendInt(b, int64(v), 10)
case float32:
return dialect.AppendFloat32(b, v)
case float64:
return dialect.AppendFloat64(b, v)
case string:
return dialect.AppendString(b, v)
case time.Time:
return dialect.AppendTime(b, v)
case []byte:
return dialect.AppendBytes(b, v)
case schema.QueryAppender:
return schema.AppendQueryAppender(fmter, b, v)
default:
vv := reflect.ValueOf(v)
if vv.Kind() == reflect.Ptr && vv.IsNil() {
return dialect.AppendNull(b)
}
appender := d.Appender(vv.Type())
return appender(fmter, b, vv)
}
func (d *Dialect) AppendUint32(b []byte, n uint32) []byte {
return strconv.AppendInt(b, int64(int32(n)), 10)
}
func (d *Dialect) Appender(typ reflect.Type) schema.AppenderFunc {
if v, ok := d.appenderMap.Load(typ); ok {
return v.(schema.AppenderFunc)
}
fn := schema.Appender(typ, customAppender)
if v, ok := d.appenderMap.LoadOrStore(typ, fn); ok {
return v.(schema.AppenderFunc)
}
return fn
}
func (d *Dialect) FieldAppender(field *schema.Field) schema.AppenderFunc {
return schema.FieldAppender(d, field)
}
func (d *Dialect) Scanner(typ reflect.Type) schema.ScannerFunc {
if v, ok := d.scannerMap.Load(typ); ok {
return v.(schema.ScannerFunc)
}
fn := scanner(typ)
if v, ok := d.scannerMap.LoadOrStore(typ, fn); ok {
return v.(schema.ScannerFunc)
}
return fn
func (d *Dialect) AppendUint64(b []byte, n uint64) []byte {
return strconv.AppendInt(b, int64(n), 10)
}

View file

@ -68,6 +68,10 @@ func fieldSQLType(field *schema.Field) string {
}
}
if field.DiscoveredSQLType == sqltype.Blob {
return pgTypeBytea
}
return sqlType(field.IndirectType)
}

View file

@ -2,8 +2,7 @@ package sqlitedialect
import (
"database/sql"
"reflect"
"sync"
"encoding/hex"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/feature"
@ -12,11 +11,10 @@ import (
)
type Dialect struct {
schema.BaseDialect
tables *schema.Tables
features feature.Feature
appenderMap sync.Map
scannerMap sync.Map
}
func New() *Dialect {
@ -50,48 +48,36 @@ func (d *Dialect) OnTable(table *schema.Table) {
}
func (d *Dialect) onField(field *schema.Field) {
// INTEGER PRIMARY KEY is an alias for the ROWID.
// It is safe to convert all ints to INTEGER, because SQLite types don't have size.
switch field.DiscoveredSQLType {
case sqltype.SmallInt, sqltype.BigInt:
field.DiscoveredSQLType = sqltype.Integer
}
field.DiscoveredSQLType = fieldSQLType(field)
}
func (d *Dialect) IdentQuote() byte {
return '"'
}
func (d *Dialect) Append(fmter schema.Formatter, b []byte, v interface{}) []byte {
return schema.Append(fmter, b, v, nil)
}
func (d *Dialect) Appender(typ reflect.Type) schema.AppenderFunc {
if v, ok := d.appenderMap.Load(typ); ok {
return v.(schema.AppenderFunc)
func (d *Dialect) AppendBytes(b []byte, bs []byte) []byte {
if bs == nil {
return dialect.AppendNull(b)
}
fn := schema.Appender(typ, nil)
b = append(b, `X'`...)
if v, ok := d.appenderMap.LoadOrStore(typ, fn); ok {
return v.(schema.AppenderFunc)
}
return fn
s := len(b)
b = append(b, make([]byte, hex.EncodedLen(len(bs)))...)
hex.Encode(b[s:], bs)
b = append(b, '\'')
return b
}
func (d *Dialect) FieldAppender(field *schema.Field) schema.AppenderFunc {
return schema.FieldAppender(d, field)
}
func (d *Dialect) Scanner(typ reflect.Type) schema.ScannerFunc {
if v, ok := d.scannerMap.Load(typ); ok {
return v.(schema.ScannerFunc)
func fieldSQLType(field *schema.Field) string {
switch field.DiscoveredSQLType {
case sqltype.SmallInt, sqltype.BigInt:
// INTEGER PRIMARY KEY is an alias for the ROWID.
// It is safe to convert all ints to INTEGER, because SQLite types don't have size.
return sqltype.Integer
default:
return field.DiscoveredSQLType
}
fn := scanner(typ)
if v, ok := d.scannerMap.LoadOrStore(typ, fn); ok {
return v.(schema.ScannerFunc)
}
return fn
}

View file

@ -8,6 +8,7 @@ const (
Real = "REAL"
DoublePrecision = "DOUBLE PRECISION"
VarChar = "VARCHAR"
Blob = "BLOB"
Timestamp = "TIMESTAMP"
JSON = "JSON"
JSONB = "JSONB"

View file

@ -3,7 +3,6 @@ package bun
import (
"context"
"database/sql"
"reflect"
"strings"
"sync/atomic"
"time"
@ -11,18 +10,11 @@ import (
"github.com/uptrace/bun/schema"
)
type IQuery interface {
schema.QueryAppender
Operation() string
GetModel() Model
GetTableName() string
}
type QueryEvent struct {
DB *DB
QueryAppender schema.QueryAppender // Deprecated: use IQuery instead
IQuery IQuery
IQuery Query
Query string
QueryArgs []interface{}
Model Model
@ -58,7 +50,7 @@ type QueryHook interface {
func (db *DB) beforeQuery(
ctx context.Context,
iquery IQuery,
iquery Query,
query string,
queryArgs []interface{},
model Model,
@ -116,13 +108,3 @@ func (db *DB) afterQueryFromIndex(ctx context.Context, event *QueryEvent, hookIn
db.queryHooks[hookIndex].AfterQuery(ctx, event)
}
}
//------------------------------------------------------------------------------
func callBeforeScanHook(ctx context.Context, v reflect.Value) error {
return v.Interface().(schema.BeforeScanHook).BeforeScan(ctx)
}
func callAfterScanHook(ctx context.Context, v reflect.Value) error {
return v.Interface().(schema.AfterScanHook).AfterScan(ctx)
}

View file

@ -93,6 +93,8 @@ func (p *parser) parseValue() string {
return p.parseQuotedValue()
case ',':
return p.s[start : p.i-1]
case '(':
p.skipPairs('(', ')')
}
}
@ -125,6 +127,23 @@ func (p *parser) parseQuotedValue() string {
return ""
}
func (p *parser) skipPairs(start, end byte) {
var lvl int
for p.valid() {
switch c := p.read(); c {
case '"':
_ = p.parseQuotedValue()
case start:
lvl++
case end:
if lvl == 0 {
return
}
lvl--
}
}
}
func (p *parser) valid() bool {
return p.i < len(p.s)
}

View file

@ -8,34 +8,54 @@ import (
const (
dateFormat = "2006-01-02"
timeFormat = "15:04:05.999999999"
timetzFormat1 = "15:04:05.999999999-07:00:00"
timetzFormat2 = "15:04:05.999999999-07:00"
timetzFormat3 = "15:04:05.999999999-07"
timestampFormat = "2006-01-02 15:04:05.999999999"
timestamptzFormat = "2006-01-02 15:04:05.999999999-07:00:00"
timestamptzFormat1 = "2006-01-02 15:04:05.999999999-07:00:00"
timestamptzFormat2 = "2006-01-02 15:04:05.999999999-07:00"
timestamptzFormat3 = "2006-01-02 15:04:05.999999999-07"
)
func ParseTime(s string) (time.Time, error) {
switch l := len(s); {
case l < len("15:04:05"):
return time.Time{}, fmt.Errorf("bun: can't parse time=%q", s)
case l <= len(timeFormat):
if s[2] == ':' {
return time.ParseInLocation(timeFormat, s, time.UTC)
}
return time.ParseInLocation(dateFormat, s, time.UTC)
default:
if s[10] == 'T' {
l := len(s)
if l >= len("2006-01-02 15:04:05") {
switch s[10] {
case ' ':
if c := s[l-6]; c == '+' || c == '-' {
return time.Parse(timestamptzFormat2, s)
}
if c := s[l-3]; c == '+' || c == '-' {
return time.Parse(timestamptzFormat3, s)
}
if c := s[l-9]; c == '+' || c == '-' {
return time.Parse(timestamptzFormat1, s)
}
return time.ParseInLocation(timestampFormat, s, time.UTC)
case 'T':
return time.Parse(time.RFC3339Nano, s)
}
if c := s[l-9]; c == '+' || c == '-' {
return time.Parse(timestamptzFormat, s)
}
}
if l >= len("15:04:05-07") {
if c := s[l-6]; c == '+' || c == '-' {
return time.Parse(timestamptzFormat2, s)
return time.Parse(timetzFormat2, s)
}
if c := s[l-3]; c == '+' || c == '-' {
return time.Parse(timestamptzFormat3, s)
return time.Parse(timetzFormat3, s)
}
if c := s[l-9]; c == '+' || c == '-' {
return time.Parse(timetzFormat1, s)
}
return time.ParseInLocation(timestampFormat, s, time.UTC)
}
if l < len("15:04:05") {
return time.Time{}, fmt.Errorf("bun: can't parse time=%q", s)
}
if s[2] == ':' {
return time.ParseInLocation(timeFormat, s, time.UTC)
}
return time.ParseInLocation(dateFormat, s, time.UTC)
}

View file

@ -126,7 +126,11 @@ func init() {
}
`
const sqlTemplate = `SELECT 1
const sqlTemplate = `SET statement_timeout = 0;
--bun:split
SELECT 1
--bun:split

View file

@ -15,10 +15,7 @@ var errNilModel = errors.New("bun: Model(nil)")
var timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
type Model interface {
ScanRows(ctx context.Context, rows *sql.Rows) (int, error)
Value() interface{}
}
type Model = schema.Model
type rowScanner interface {
ScanRow(ctx context.Context, rows *sql.Rows) error
@ -27,8 +24,9 @@ type rowScanner interface {
type TableModel interface {
Model
schema.BeforeScanHook
schema.AfterScanHook
schema.BeforeAppendModelHook
schema.BeforeScanRowHook
schema.AfterScanRowHook
ScanColumn(column string, src interface{}) error
Table() *schema.Table

View file

@ -139,7 +139,7 @@ func (m *mapModel) appendColumnsValues(fmter schema.Formatter, b []byte) []byte
if isTemplate {
b = append(b, '?')
} else {
b = fmter.Dialect().Append(fmter, b, m.m[k])
b = schema.Append(fmter, b, m.m[k])
}
}
@ -167,7 +167,7 @@ func (m *mapModel) appendSet(fmter schema.Formatter, b []byte) []byte {
if isTemplate {
b = append(b, '?')
} else {
b = fmter.Dialect().Append(fmter, b, m.m[k])
b = schema.Append(fmter, b, m.m[k])
}
}

View file

@ -129,7 +129,7 @@ func (m *mapSliceModel) appendValues(fmter schema.Formatter, b []byte) (_ []byte
if j > 0 {
b = append(b, ", "...)
}
b = fmter.Dialect().Append(fmter, b, el[key])
b = schema.Append(fmter, b, el[key])
}
}

View file

@ -4,6 +4,8 @@ import (
"context"
"database/sql"
"reflect"
"github.com/uptrace/bun/schema"
)
type scanModel struct {
@ -49,6 +51,6 @@ func (m *scanModel) Scan(src interface{}) error {
dest := reflect.ValueOf(m.dest[m.scanIndex])
m.scanIndex++
scanner := m.db.dialect.Scanner(dest.Type())
scanner := schema.Scanner(dest.Type())
return scanner(dest, src)
}

View file

@ -91,10 +91,31 @@ func (m *sliceTableModel) ScanRows(ctx context.Context, rows *sql.Rows) (int, er
return n, nil
}
var _ schema.BeforeAppendModelHook = (*sliceTableModel)(nil)
func (m *sliceTableModel) BeforeAppendModel(ctx context.Context, query Query) error {
if !m.table.HasBeforeAppendModelHook() {
return nil
}
sliceLen := m.slice.Len()
for i := 0; i < sliceLen; i++ {
strct := m.slice.Index(i)
if !m.sliceOfPtr {
strct = strct.Addr()
}
err := strct.Interface().(schema.BeforeAppendModelHook).BeforeAppendModel(ctx, query)
if err != nil {
return err
}
}
return nil
}
// Inherit these hooks from structTableModel.
var (
_ schema.BeforeScanHook = (*sliceTableModel)(nil)
_ schema.AfterScanHook = (*sliceTableModel)(nil)
_ schema.BeforeScanRowHook = (*sliceTableModel)(nil)
_ schema.AfterScanRowHook = (*sliceTableModel)(nil)
)
func (m *sliceTableModel) updateSoftDeleteField(tm time.Time) error {

View file

@ -100,38 +100,65 @@ func (m *structTableModel) mountJoins() {
}
}
var _ schema.BeforeScanHook = (*structTableModel)(nil)
var _ schema.BeforeAppendModelHook = (*structTableModel)(nil)
func (m *structTableModel) BeforeScan(ctx context.Context) error {
if !m.table.HasBeforeScanHook() {
func (m *structTableModel) BeforeAppendModel(ctx context.Context, query Query) error {
if !m.table.HasBeforeAppendModelHook() || !m.strct.IsValid() {
return nil
}
return callBeforeScanHook(ctx, m.strct.Addr())
return m.strct.Addr().Interface().(schema.BeforeAppendModelHook).BeforeAppendModel(ctx, query)
}
var _ schema.AfterScanHook = (*structTableModel)(nil)
var _ schema.BeforeScanRowHook = (*structTableModel)(nil)
func (m *structTableModel) AfterScan(ctx context.Context) error {
if !m.table.HasAfterScanHook() || !m.structInited {
func (m *structTableModel) BeforeScanRow(ctx context.Context) error {
if m.table.HasBeforeScanRowHook() {
return m.strct.Addr().Interface().(schema.BeforeScanRowHook).BeforeScanRow(ctx)
}
if m.table.HasBeforeScanHook() {
return m.strct.Addr().Interface().(schema.BeforeScanHook).BeforeScan(ctx)
}
return nil
}
var _ schema.AfterScanRowHook = (*structTableModel)(nil)
func (m *structTableModel) AfterScanRow(ctx context.Context) error {
if !m.structInited {
return nil
}
var firstErr error
if m.table.HasAfterScanRowHook() {
firstErr := m.strct.Addr().Interface().(schema.AfterScanRowHook).AfterScanRow(ctx)
if err := callAfterScanHook(ctx, m.strct.Addr()); err != nil && firstErr == nil {
firstErr = err
}
for _, j := range m.joins {
switch j.Relation.Type {
case schema.HasOneRelation, schema.BelongsToRelation:
if err := j.JoinModel.AfterScan(ctx); err != nil && firstErr == nil {
firstErr = err
for _, j := range m.joins {
switch j.Relation.Type {
case schema.HasOneRelation, schema.BelongsToRelation:
if err := j.JoinModel.AfterScanRow(ctx); err != nil && firstErr == nil {
firstErr = err
}
}
}
return firstErr
}
return firstErr
if m.table.HasAfterScanHook() {
firstErr := m.strct.Addr().Interface().(schema.AfterScanHook).AfterScan(ctx)
for _, j := range m.joins {
switch j.Relation.Type {
case schema.HasOneRelation, schema.BelongsToRelation:
if err := j.JoinModel.AfterScanRow(ctx); err != nil && firstErr == nil {
firstErr = err
}
}
}
return firstErr
}
return nil
}
func (m *structTableModel) getJoin(name string) *relationJoin {
@ -257,7 +284,7 @@ func (m *structTableModel) ScanRow(ctx context.Context, rows *sql.Rows) error {
}
func (m *structTableModel) scanRow(ctx context.Context, rows *sql.Rows, dest []interface{}) error {
if err := m.BeforeScan(ctx); err != nil {
if err := m.BeforeScanRow(ctx); err != nil {
return err
}
@ -266,7 +293,7 @@ func (m *structTableModel) scanRow(ctx context.Context, rows *sql.Rows, dest []i
return err
}
if err := m.AfterScan(ctx); err != nil {
if err := m.AfterScanRow(ctx); err != nil {
return err
}

View file

@ -1,6 +1,6 @@
{
"name": "bun",
"version": "1.0.9",
"version": "1.0.14",
"main": "index.js",
"repository": "git@github.com:uptrace/bun.git",
"author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>",

View file

@ -6,6 +6,7 @@ import (
"database/sql/driver"
"errors"
"fmt"
"time"
"github.com/uptrace/bun/dialect/feature"
"github.com/uptrace/bun/internal"
@ -164,6 +165,13 @@ func (q *baseQuery) getModel(dest []interface{}) (Model, error) {
return newModel(q.db, dest)
}
func (q *baseQuery) beforeAppendModel(ctx context.Context, query Query) error {
if q.tableModel != nil {
return q.tableModel.BeforeAppendModel(ctx, query)
}
return nil
}
//------------------------------------------------------------------------------
func (q *baseQuery) checkSoftDelete() error {
@ -260,6 +268,11 @@ func (q *baseQuery) addColumn(column schema.QueryWithArgs) {
}
func (q *baseQuery) excludeColumn(columns []string) {
if q.table == nil {
q.setErr(errNilModel)
return
}
if q.columns == nil {
for _, f := range q.table.Fields {
q.columns = append(q.columns, schema.UnsafeIdent(f.Name))
@ -456,7 +469,7 @@ func (q *baseQuery) _getFields(omitPK bool) ([]*schema.Field, error) {
func (q *baseQuery) scan(
ctx context.Context,
iquery IQuery,
iquery Query,
query string,
model Model,
hasDest bool,
@ -488,7 +501,7 @@ func (q *baseQuery) scan(
func (q *baseQuery) exec(
ctx context.Context,
iquery IQuery,
iquery Query,
query string,
) (sql.Result, error) {
ctx, event := q.db.beforeQuery(ctx, iquery, query, nil, q.model)
@ -623,11 +636,23 @@ func (q *whereBaseQuery) appendWhere(
b = append(b, q.tableModel.Table().SQLAlias...)
b = append(b, '.')
}
b = append(b, q.tableModel.Table().SoftDeleteField.SQLName...)
if q.flags.Has(deletedFlag) {
b = append(b, " IS NOT NULL"...)
field := q.tableModel.Table().SoftDeleteField
b = append(b, field.SQLName...)
if field.NullZero {
if q.flags.Has(deletedFlag) {
b = append(b, " IS NOT NULL"...)
} else {
b = append(b, " IS NULL"...)
}
} else {
b = append(b, " IS NULL"...)
if q.flags.Has(deletedFlag) {
b = append(b, " != "...)
} else {
b = append(b, " = "...)
}
b = fmter.Dialect().AppendTime(b, time.Time{})
}
}
@ -794,9 +819,11 @@ func (q *returningQuery) addReturningField(field *schema.Field) {
func (q *returningQuery) hasReturning() bool {
if len(q.returning) == 1 {
switch q.returning[0].Query {
case "null", "NULL":
return false
if ret := q.returning[0]; len(ret.Args) == 0 {
switch ret.Query {
case "", "null", "NULL":
return false
}
}
}
return len(q.returning) > 0 || len(q.returningFields) > 0

View file

@ -134,9 +134,6 @@ func (q *DeleteQuery) Operation() string {
}
func (q *DeleteQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, err error) {
if q.err != nil {
return nil, q.err
}
fmter = formatterWithModel(fmter, q)
if q.isSoftDelete() {
@ -209,19 +206,27 @@ func (q *DeleteQuery) softDeleteSet(fmter schema.Formatter, tm time.Time) string
}
b = append(b, q.table.SoftDeleteField.SQLName...)
b = append(b, " = "...)
b = q.db.Dialect().Append(fmter, b, tm)
b = schema.Append(fmter, b, tm)
return internal.String(b)
}
//------------------------------------------------------------------------------
func (q *DeleteQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error) {
if q.err != nil {
return nil, q.err
}
if q.table != nil {
if err := q.beforeDeleteHook(ctx); err != nil {
return nil, err
}
}
if err := q.beforeAppendModel(ctx, q); err != nil {
return nil, err
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return nil, err

View file

@ -84,6 +84,11 @@ func (q *InsertQuery) Column(columns ...string) *InsertQuery {
return q
}
func (q *InsertQuery) ColumnExpr(query string, args ...interface{}) *InsertQuery {
q.addColumn(schema.SafeQuery(query, args))
return q
}
func (q *InsertQuery) ExcludeColumn(columns ...string) *InsertQuery {
q.excludeColumn(columns)
return q
@ -113,7 +118,7 @@ func (q *InsertQuery) WhereOr(query string, args ...interface{}) *InsertQuery {
// Returning adds a RETURNING clause to the query.
//
// To suppress the auto-generated RETURNING clause, use `Returning("NULL")`.
// To suppress the auto-generated RETURNING clause, use `Returning("")`.
func (q *InsertQuery) Returning(query string, args ...interface{}) *InsertQuery {
q.addReturning(schema.SafeQuery(query, args))
return q
@ -147,9 +152,6 @@ func (q *InsertQuery) Operation() string {
}
func (q *InsertQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, err error) {
if q.err != nil {
return nil, q.err
}
fmter = formatterWithModel(fmter, q)
b, err = q.appendWith(fmter, b)
@ -209,7 +211,18 @@ func (q *InsertQuery) appendColumnsValues(
b = append(b, ")"...)
}
b = append(b, " SELECT * FROM "...)
b = append(b, " SELECT "...)
if q.columns != nil {
b, err = q.appendColumns(fmter, b)
if err != nil {
return nil, err
}
} else {
b = append(b, "*"...)
}
b = append(b, " FROM "...)
b, err = q.appendOtherTables(fmter, b)
if err != nil {
return nil, err
@ -429,6 +442,17 @@ func (q *InsertQuery) appendOn(fmter schema.Formatter, b []byte) (_ []byte, err
}
b = q.appendSetExcluded(b, fields)
} else if q.onDuplicateKeyUpdate() {
fields, err := q.getDataFields()
if err != nil {
return nil, err
}
if len(fields) == 0 {
fields = q.tableModel.Table().DataFields
}
b = q.appendSetValues(b, fields)
}
if len(q.where) > 0 {
@ -447,6 +471,10 @@ func (q *InsertQuery) onConflictDoUpdate() bool {
return strings.HasSuffix(strings.ToUpper(q.on.Query), " DO UPDATE")
}
func (q *InsertQuery) onDuplicateKeyUpdate() bool {
return strings.ToUpper(q.on.Query) == "DUPLICATE KEY UPDATE"
}
func (q *InsertQuery) appendSetExcluded(b []byte, fields []*schema.Field) []byte {
b = append(b, " SET "...)
for i, f := range fields {
@ -460,6 +488,20 @@ func (q *InsertQuery) appendSetExcluded(b []byte, fields []*schema.Field) []byte
return b
}
func (q *InsertQuery) appendSetValues(b []byte, fields []*schema.Field) []byte {
b = append(b, " "...)
for i, f := range fields {
if i > 0 {
b = append(b, ", "...)
}
b = append(b, f.SQLName...)
b = append(b, " = VALUES("...)
b = append(b, f.SQLName...)
b = append(b, ")"...)
}
return b
}
//------------------------------------------------------------------------------
func (q *InsertQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error) {
@ -469,6 +511,13 @@ func (q *InsertQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result
}
}
if q.err != nil {
return nil, q.err
}
if err := q.beforeAppendModel(ctx, q); err != nil {
return nil, err
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return nil, err

View file

@ -310,14 +310,14 @@ func (q *SelectQuery) Relation(name string, apply ...func(*SelectQuery) *SelectQ
return q
}
func (q *SelectQuery) forEachHasOneJoin(fn func(*relationJoin) error) error {
func (q *SelectQuery) forEachInlineRelJoin(fn func(*relationJoin) error) error {
if q.tableModel == nil {
return nil
}
return q._forEachHasOneJoin(fn, q.tableModel.getJoins())
return q._forEachInlineRelJoin(fn, q.tableModel.getJoins())
}
func (q *SelectQuery) _forEachHasOneJoin(fn func(*relationJoin) error, joins []relationJoin) error {
func (q *SelectQuery) _forEachInlineRelJoin(fn func(*relationJoin) error, joins []relationJoin) error {
for i := range joins {
j := &joins[i]
switch j.Relation.Type {
@ -325,7 +325,7 @@ func (q *SelectQuery) _forEachHasOneJoin(fn func(*relationJoin) error, joins []r
if err := fn(j); err != nil {
return err
}
if err := q._forEachHasOneJoin(fn, j.JoinModel.getJoins()); err != nil {
if err := q._forEachInlineRelJoin(fn, j.JoinModel.getJoins()); err != nil {
return err
}
}
@ -370,9 +370,6 @@ func (q *SelectQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, e
func (q *SelectQuery) appendQuery(
fmter schema.Formatter, b []byte, count bool,
) (_ []byte, err error) {
if q.err != nil {
return nil, q.err
}
fmter = formatterWithModel(fmter, q)
cteCount := count && (len(q.group) > 0 || q.distinctOn != nil)
@ -423,7 +420,7 @@ func (q *SelectQuery) appendQuery(
}
}
if err := q.forEachHasOneJoin(func(j *relationJoin) error {
if err := q.forEachInlineRelJoin(func(j *relationJoin) error {
b = append(b, ' ')
b, err = j.appendHasOneJoin(fmter, b, q)
return err
@ -553,13 +550,13 @@ func (q *SelectQuery) appendColumns(fmter schema.Formatter, b []byte) (_ []byte,
b = append(b, '*')
}
if err := q.forEachHasOneJoin(func(join *relationJoin) error {
if err := q.forEachInlineRelJoin(func(join *relationJoin) error {
if len(b) != start {
b = append(b, ", "...)
start = len(b)
}
b, err = q.appendHasOneColumns(fmter, b, join)
b, err = q.appendInlineRelColumns(fmter, b, join)
if err != nil {
return err
}
@ -574,7 +571,7 @@ func (q *SelectQuery) appendColumns(fmter schema.Formatter, b []byte) (_ []byte,
return b, nil
}
func (q *SelectQuery) appendHasOneColumns(
func (q *SelectQuery) appendInlineRelColumns(
fmter schema.Formatter, b []byte, join *relationJoin,
) (_ []byte, err error) {
join.applyTo(q)
@ -645,6 +642,14 @@ func (q *SelectQuery) appendOrder(fmter schema.Formatter, b []byte) (_ []byte, e
//------------------------------------------------------------------------------
func (q *SelectQuery) Rows(ctx context.Context) (*sql.Rows, error) {
if q.err != nil {
return nil, q.err
}
if err := q.beforeAppendModel(ctx, q); err != nil {
return nil, err
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return nil, err
@ -655,6 +660,13 @@ func (q *SelectQuery) Rows(ctx context.Context) (*sql.Rows, error) {
}
func (q *SelectQuery) Exec(ctx context.Context) (res sql.Result, err error) {
if q.err != nil {
return nil, q.err
}
if err := q.beforeAppendModel(ctx, q); err != nil {
return nil, err
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return nil, err
@ -671,6 +683,10 @@ func (q *SelectQuery) Exec(ctx context.Context) (res sql.Result, err error) {
}
func (q *SelectQuery) Scan(ctx context.Context, dest ...interface{}) error {
if q.err != nil {
return q.err
}
model, err := q.getModel(dest)
if err != nil {
return err
@ -688,6 +704,10 @@ func (q *SelectQuery) Scan(ctx context.Context, dest ...interface{}) error {
}
}
if err := q.beforeAppendModel(ctx, q); err != nil {
return err
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return err
@ -736,6 +756,10 @@ func (q *SelectQuery) afterSelectHook(ctx context.Context) error {
}
func (q *SelectQuery) Count(ctx context.Context) (int, error) {
if q.err != nil {
return 0, q.err
}
qq := countQuery{q}
queryBytes, err := qq.AppendQuery(q.db.fmter, nil)
@ -795,6 +819,10 @@ func (q *SelectQuery) ScanAndCount(ctx context.Context, dest ...interface{}) (in
}
func (q *SelectQuery) Exists(ctx context.Context) (bool, error) {
if q.err != nil {
return false, q.err
}
qq := existsQuery{q}
queryBytes, err := qq.AppendQuery(q.db.fmter, nil)
@ -854,6 +882,12 @@ type countQuery struct {
}
func (q countQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, err error) {
if q.err != nil {
return nil, q.err
}
// if err := q.beforeAppendModel(q); err != nil {
// return nil, err
// }
return q.appendQuery(fmter, b, true)
}
@ -864,6 +898,13 @@ type existsQuery struct {
}
func (q existsQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, err error) {
if q.err != nil {
return nil, q.err
}
// if err := q.beforeAppendModel(q); err != nil {
// return nil, err
// }
b = append(b, "SELECT EXISTS ("...)
b, err = q.appendQuery(fmter, b, false)

View file

@ -100,6 +100,11 @@ func (q *UpdateQuery) Value(column string, expr string, args ...interface{}) *Up
return q
}
func (q *UpdateQuery) OmitZero() *UpdateQuery {
q.omitZero = true
return q
}
//------------------------------------------------------------------------------
func (q *UpdateQuery) WherePK() *UpdateQuery {
@ -165,9 +170,6 @@ func (q *UpdateQuery) Operation() string {
}
func (q *UpdateQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, err error) {
if q.err != nil {
return nil, q.err
}
fmter = formatterWithModel(fmter, q)
b, err = q.appendWith(fmter, b)
@ -254,7 +256,7 @@ func (q *UpdateQuery) appendSetStruct(
isTemplate := fmter.IsNop()
pos := len(b)
for _, f := range fields {
if q.omitZero && f.NullZero && f.HasZeroValue(model.strct) {
if q.omitZero && f.HasZeroValue(model.strct) {
continue
}
@ -381,12 +383,20 @@ func (db *UpdateQuery) updateSliceWhere(model *sliceTableModel) string {
//------------------------------------------------------------------------------
func (q *UpdateQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error) {
if q.err != nil {
return nil, q.err
}
if q.table != nil {
if err := q.beforeUpdateHook(ctx); err != nil {
return nil, err
}
}
if err := q.beforeAppendModel(ctx, q); err != nil {
return nil, err
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return nil, err

View file

@ -89,27 +89,33 @@ func (j *relationJoin) manyQuery(q *SelectQuery) *SelectQuery {
}
func (j *relationJoin) hasManyColumns(q *SelectQuery) *SelectQuery {
if j.Relation.M2MTable != nil {
q = q.ColumnExpr(string(j.Relation.M2MTable.SQLAlias) + ".*")
}
b := make([]byte, 0, 32)
joinTable := j.JoinModel.Table()
if len(j.columns) > 0 {
for i, col := range j.columns {
if i > 0 {
b = append(b, ", "...)
}
if col.Args == nil {
if field, ok := joinTable.FieldMap[col.Query]; ok {
b = append(b, joinTable.SQLAlias...)
b = append(b, '.')
b = append(b, field.SQLName...)
continue
}
}
var err error
b, err = col.AppendQuery(q.db.fmter, b)
if err != nil {
q.err = err
q.setErr(err)
return q
}
}
} else {
joinTable := j.JoinModel.Table()
b = appendColumns(b, joinTable.SQLAlias, joinTable.Fields)
}
@ -138,6 +144,10 @@ func (j *relationJoin) m2mQuery(q *SelectQuery) *SelectQuery {
index := j.JoinModel.parentIndex()
baseTable := j.BaseModel.Table()
if j.Relation.M2MTable != nil {
q = q.ColumnExpr(string(j.Relation.M2MTable.SQLAlias) + ".*")
}
//nolint
var join []byte
join = append(join, "JOIN "...)

View file

@ -5,13 +5,10 @@ import (
"strconv"
"time"
"github.com/vmihailenco/msgpack/v5"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/internal"
)
func Append(fmter Formatter, b []byte, v interface{}, custom CustomAppender) []byte {
func Append(fmter Formatter, b []byte, v interface{}) []byte {
switch v := v.(type) {
case nil:
return dialect.AppendNull(b)
@ -24,11 +21,11 @@ func Append(fmter Formatter, b []byte, v interface{}, custom CustomAppender) []b
case int64:
return strconv.AppendInt(b, v, 10)
case uint:
return strconv.AppendUint(b, uint64(v), 10)
return strconv.AppendInt(b, int64(v), 10)
case uint32:
return strconv.AppendUint(b, uint64(v), 10)
return fmter.Dialect().AppendUint32(b, v)
case uint64:
return strconv.AppendUint(b, v, 10)
return fmter.Dialect().AppendUint64(b, v)
case float32:
return dialect.AppendFloat32(b, v)
case float64:
@ -36,9 +33,9 @@ func Append(fmter Formatter, b []byte, v interface{}, custom CustomAppender) []b
case string:
return dialect.AppendString(b, v)
case time.Time:
return dialect.AppendTime(b, v)
return fmter.Dialect().AppendTime(b, v)
case []byte:
return dialect.AppendBytes(b, v)
return fmter.Dialect().AppendBytes(b, v)
case QueryAppender:
return AppendQueryAppender(fmter, b, v)
default:
@ -46,33 +43,7 @@ func Append(fmter Formatter, b []byte, v interface{}, custom CustomAppender) []b
if vv.Kind() == reflect.Ptr && vv.IsNil() {
return dialect.AppendNull(b)
}
appender := Appender(vv.Type(), custom)
appender := Appender(fmter.Dialect(), vv.Type())
return appender(fmter, b, vv)
}
}
func appendMsgpack(fmter Formatter, b []byte, v reflect.Value) []byte {
hexEnc := internal.NewHexEncoder(b)
enc := msgpack.GetEncoder()
defer msgpack.PutEncoder(enc)
enc.Reset(hexEnc)
if err := enc.EncodeValue(v); err != nil {
return dialect.AppendError(b, err)
}
if err := hexEnc.Close(); err != nil {
return dialect.AppendError(b, err)
}
return hexEnc.Bytes()
}
func AppendQueryAppender(fmter Formatter, b []byte, app QueryAppender) []byte {
bb, err := app.AppendQuery(fmter, b)
if err != nil {
return dialect.AppendError(b, err)
}
return bb
}

View file

@ -7,12 +7,14 @@ import (
"reflect"
"strconv"
"strings"
"sync"
"time"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/sqltype"
"github.com/uptrace/bun/extra/bunjson"
"github.com/uptrace/bun/internal"
"github.com/vmihailenco/msgpack/v5"
)
type (
@ -30,8 +32,8 @@ var appenders = []AppenderFunc{
reflect.Uint: AppendUintValue,
reflect.Uint8: AppendUintValue,
reflect.Uint16: AppendUintValue,
reflect.Uint32: AppendUintValue,
reflect.Uint64: AppendUintValue,
reflect.Uint32: appendUint32Value,
reflect.Uint64: appendUint64Value,
reflect.Uintptr: nil,
reflect.Float32: AppendFloat32Value,
reflect.Float64: AppendFloat64Value,
@ -49,6 +51,8 @@ var appenders = []AppenderFunc{
reflect.UnsafePointer: nil,
}
var appenderMap sync.Map
func FieldAppender(dialect Dialect, field *Field) AppenderFunc {
if field.Tag.HasOption("msgpack") {
return appendMsgpack
@ -59,10 +63,23 @@ func FieldAppender(dialect Dialect, field *Field) AppenderFunc {
return AppendJSONValue
}
return dialect.Appender(field.StructField.Type)
return Appender(dialect, field.StructField.Type)
}
func Appender(typ reflect.Type, custom CustomAppender) AppenderFunc {
func Appender(dialect Dialect, typ reflect.Type) AppenderFunc {
if v, ok := appenderMap.Load(typ); ok {
return v.(AppenderFunc)
}
fn := appender(dialect, typ)
if v, ok := appenderMap.LoadOrStore(typ, fn); ok {
return v.(AppenderFunc)
}
return fn
}
func appender(dialect Dialect, typ reflect.Type) AppenderFunc {
switch typ {
case bytesType:
return appendBytesValue
@ -80,7 +97,7 @@ func Appender(typ reflect.Type, custom CustomAppender) AppenderFunc {
return appendQueryAppenderValue
}
if typ.Implements(driverValuerType) {
return driverValueAppender(custom)
return appendDriverValue
}
kind := typ.Kind()
@ -88,18 +105,18 @@ func Appender(typ reflect.Type, custom CustomAppender) AppenderFunc {
if kind != reflect.Ptr {
ptr := reflect.PtrTo(typ)
if ptr.Implements(queryAppenderType) {
return addrAppender(appendQueryAppenderValue, custom)
return addrAppender(appendQueryAppenderValue)
}
if ptr.Implements(driverValuerType) {
return addrAppender(driverValueAppender(custom), custom)
return addrAppender(appendDriverValue)
}
}
switch kind {
case reflect.Interface:
return ifaceAppenderFunc(typ, custom)
return ifaceAppenderFunc
case reflect.Ptr:
if fn := Appender(typ.Elem(), custom); fn != nil {
if fn := Appender(dialect, typ.Elem()); fn != nil {
return PtrAppender(fn)
}
case reflect.Slice:
@ -112,23 +129,16 @@ func Appender(typ reflect.Type, custom CustomAppender) AppenderFunc {
}
}
if custom != nil {
if fn := custom(typ); fn != nil {
return fn
}
}
return appenders[typ.Kind()]
}
func ifaceAppenderFunc(typ reflect.Type, custom func(reflect.Type) AppenderFunc) AppenderFunc {
return func(fmter Formatter, b []byte, v reflect.Value) []byte {
if v.IsNil() {
return dialect.AppendNull(b)
}
elem := v.Elem()
appender := Appender(elem.Type(), custom)
return appender(fmter, b, elem)
func ifaceAppenderFunc(fmter Formatter, b []byte, v reflect.Value) []byte {
if v.IsNil() {
return dialect.AppendNull(b)
}
elem := v.Elem()
appender := Appender(fmter.Dialect(), elem.Type())
return appender(fmter, b, elem)
}
func PtrAppender(fn AppenderFunc) AppenderFunc {
@ -152,6 +162,14 @@ func AppendUintValue(fmter Formatter, b []byte, v reflect.Value) []byte {
return strconv.AppendUint(b, v.Uint(), 10)
}
func appendUint32Value(fmter Formatter, b []byte, v reflect.Value) []byte {
return fmter.Dialect().AppendUint32(b, uint32(v.Uint()))
}
func appendUint64Value(fmter Formatter, b []byte, v reflect.Value) []byte {
return fmter.Dialect().AppendUint64(b, v.Uint())
}
func AppendFloat32Value(fmter Formatter, b []byte, v reflect.Value) []byte {
return dialect.AppendFloat32(b, float32(v.Float()))
}
@ -161,17 +179,17 @@ func AppendFloat64Value(fmter Formatter, b []byte, v reflect.Value) []byte {
}
func appendBytesValue(fmter Formatter, b []byte, v reflect.Value) []byte {
return dialect.AppendBytes(b, v.Bytes())
return fmter.Dialect().AppendBytes(b, v.Bytes())
}
func appendArrayBytesValue(fmter Formatter, b []byte, v reflect.Value) []byte {
if v.CanAddr() {
return dialect.AppendBytes(b, v.Slice(0, v.Len()).Bytes())
return fmter.Dialect().AppendBytes(b, v.Slice(0, v.Len()).Bytes())
}
tmp := make([]byte, v.Len())
reflect.Copy(reflect.ValueOf(tmp), v)
b = dialect.AppendBytes(b, tmp)
b = fmter.Dialect().AppendBytes(b, tmp)
return b
}
@ -189,12 +207,12 @@ func AppendJSONValue(fmter Formatter, b []byte, v reflect.Value) []byte {
bb = bb[:len(bb)-1]
}
return dialect.AppendJSON(b, bb)
return fmter.Dialect().AppendJSON(b, bb)
}
func appendTimeValue(fmter Formatter, b []byte, v reflect.Value) []byte {
tm := v.Interface().(time.Time)
return dialect.AppendTime(b, tm)
return fmter.Dialect().AppendTime(b, tm)
}
func appendIPValue(fmter Formatter, b []byte, v reflect.Value) []byte {
@ -219,21 +237,15 @@ func appendQueryAppenderValue(fmter Formatter, b []byte, v reflect.Value) []byte
return AppendQueryAppender(fmter, b, v.Interface().(QueryAppender))
}
func driverValueAppender(custom CustomAppender) AppenderFunc {
return func(fmter Formatter, b []byte, v reflect.Value) []byte {
return appendDriverValue(fmter, b, v.Interface().(driver.Valuer), custom)
}
}
func appendDriverValue(fmter Formatter, b []byte, v driver.Valuer, custom CustomAppender) []byte {
value, err := v.Value()
func appendDriverValue(fmter Formatter, b []byte, v reflect.Value) []byte {
value, err := v.Interface().(driver.Valuer).Value()
if err != nil {
return dialect.AppendError(b, err)
}
return Append(fmter, b, value, custom)
return Append(fmter, b, value)
}
func addrAppender(fn AppenderFunc, custom CustomAppender) AppenderFunc {
func addrAppender(fn AppenderFunc) AppenderFunc {
return func(fmter Formatter, b []byte, v reflect.Value) []byte {
if !v.CanAddr() {
err := fmt.Errorf("bun: Append(nonaddressable %T)", v.Interface())
@ -242,3 +254,29 @@ func addrAppender(fn AppenderFunc, custom CustomAppender) AppenderFunc {
return fn(fmter, b, v.Addr())
}
}
func appendMsgpack(fmter Formatter, b []byte, v reflect.Value) []byte {
hexEnc := internal.NewHexEncoder(b)
enc := msgpack.GetEncoder()
defer msgpack.PutEncoder(enc)
enc.Reset(hexEnc)
if err := enc.EncodeValue(v); err != nil {
return dialect.AppendError(b, err)
}
if err := hexEnc.Close(); err != nil {
return dialect.AppendError(b, err)
}
return hexEnc.Bytes()
}
func AppendQueryAppender(fmter Formatter, b []byte, app QueryAppender) []byte {
bb, err := app.AppendQuery(fmter, b)
if err != nil {
return dialect.AppendError(b, err)
}
return bb
}

View file

@ -2,11 +2,12 @@ package schema
import (
"database/sql"
"reflect"
"sync"
"strconv"
"time"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/feature"
"github.com/uptrace/bun/internal/parser"
)
type Dialect interface {
@ -19,20 +20,76 @@ type Dialect interface {
OnTable(table *Table)
IdentQuote() byte
Append(fmter Formatter, b []byte, v interface{}) []byte
Appender(typ reflect.Type) AppenderFunc
FieldAppender(field *Field) AppenderFunc
Scanner(typ reflect.Type) ScannerFunc
AppendUint32(b []byte, n uint32) []byte
AppendUint64(b []byte, n uint64) []byte
AppendTime(b []byte, tm time.Time) []byte
AppendBytes(b []byte, bs []byte) []byte
AppendJSON(b, jsonb []byte) []byte
}
//------------------------------------------------------------------------------
type BaseDialect struct{}
func (BaseDialect) AppendUint32(b []byte, n uint32) []byte {
return strconv.AppendUint(b, uint64(n), 10)
}
func (BaseDialect) AppendUint64(b []byte, n uint64) []byte {
return strconv.AppendUint(b, n, 10)
}
func (BaseDialect) AppendTime(b []byte, tm time.Time) []byte {
b = append(b, '\'')
b = tm.UTC().AppendFormat(b, "2006-01-02 15:04:05.999999-07:00")
b = append(b, '\'')
return b
}
func (BaseDialect) AppendBytes(b, bs []byte) []byte {
return dialect.AppendBytes(b, bs)
}
func (BaseDialect) AppendJSON(b, jsonb []byte) []byte {
b = append(b, '\'')
p := parser.New(jsonb)
for p.Valid() {
c := p.Read()
switch c {
case '"':
b = append(b, '"')
case '\'':
b = append(b, "''"...)
case '\000':
continue
case '\\':
if p.SkipBytes([]byte("u0000")) {
b = append(b, `\\u0000`...)
} else {
b = append(b, '\\')
if p.Valid() {
b = append(b, p.Read())
}
}
default:
b = append(b, c)
}
}
b = append(b, '\'')
return b
}
//------------------------------------------------------------------------------
type nopDialect struct {
BaseDialect
tables *Tables
features feature.Feature
appenderMap sync.Map
scannerMap sync.Map
}
func newNopDialect() *nopDialect {
@ -63,37 +120,3 @@ func (d *nopDialect) OnTable(table *Table) {}
func (d *nopDialect) IdentQuote() byte {
return '"'
}
func (d *nopDialect) Append(fmter Formatter, b []byte, v interface{}) []byte {
return Append(fmter, b, v, nil)
}
func (d *nopDialect) Appender(typ reflect.Type) AppenderFunc {
if v, ok := d.appenderMap.Load(typ); ok {
return v.(AppenderFunc)
}
fn := Appender(typ, nil)
if v, ok := d.appenderMap.LoadOrStore(typ, fn); ok {
return v.(AppenderFunc)
}
return fn
}
func (d *nopDialect) FieldAppender(field *Field) AppenderFunc {
return FieldAppender(d, field)
}
func (d *nopDialect) Scanner(typ reflect.Type) ScannerFunc {
if v, ok := d.scannerMap.Load(typ); ok {
return v.(ScannerFunc)
}
fn := Scanner(typ)
if v, ok := d.scannerMap.LoadOrStore(typ, fn); ok {
return v.(ScannerFunc)
}
return fn
}

View file

@ -50,7 +50,7 @@ func (f Formatter) AppendValue(b []byte, v reflect.Value) []byte {
if v.Kind() == reflect.Ptr && v.IsNil() {
return dialect.AppendNull(b)
}
appender := f.dialect.Appender(v.Type())
appender := Appender(f.dialect, v.Type())
return appender(f, b, v)
}
@ -167,7 +167,7 @@ func (f Formatter) appendArg(b []byte, arg interface{}) []byte {
}
return bb
default:
return f.dialect.Append(f, b, arg)
return Append(f, b, arg)
}
}

View file

@ -2,9 +2,32 @@ package schema
import (
"context"
"database/sql"
"reflect"
)
type Model interface {
ScanRows(ctx context.Context, rows *sql.Rows) (int, error)
Value() interface{}
}
type Query interface {
QueryAppender
Operation() string
GetModel() Model
GetTableName() string
}
//------------------------------------------------------------------------------
type BeforeAppendModelHook interface {
BeforeAppendModel(ctx context.Context, query Query) error
}
var beforeAppendModelHookType = reflect.TypeOf((*BeforeAppendModelHook)(nil)).Elem()
//------------------------------------------------------------------------------
type BeforeScanHook interface {
BeforeScan(context.Context) error
}
@ -18,3 +41,19 @@ type AfterScanHook interface {
}
var afterScanHookType = reflect.TypeOf((*AfterScanHook)(nil)).Elem()
//------------------------------------------------------------------------------
type BeforeScanRowHook interface {
BeforeScanRow(context.Context) error
}
var beforeScanRowHookType = reflect.TypeOf((*BeforeScanRowHook)(nil)).Elem()
//------------------------------------------------------------------------------
type AfterScanRowHook interface {
AfterScanRow(context.Context) error
}
var afterScanRowHookType = reflect.TypeOf((*AfterScanRowHook)(nil)).Elem()

View file

@ -8,6 +8,7 @@ import (
"reflect"
"strconv"
"strings"
"sync"
"time"
"github.com/vmihailenco/msgpack/v5"
@ -52,6 +53,8 @@ func init() {
}
}
var scannerMap sync.Map
func FieldScanner(dialect Dialect, field *Field) ScannerFunc {
if field.Tag.HasOption("msgpack") {
return scanMsgpack
@ -65,10 +68,23 @@ func FieldScanner(dialect Dialect, field *Field) ScannerFunc {
return scanJSONIntoInterface
}
}
return dialect.Scanner(field.StructField.Type)
return Scanner(field.StructField.Type)
}
func Scanner(typ reflect.Type) ScannerFunc {
if v, ok := scannerMap.Load(typ); ok {
return v.(ScannerFunc)
}
fn := scanner(typ)
if v, ok := scannerMap.LoadOrStore(typ, fn); ok {
return v.(ScannerFunc)
}
return fn
}
func scanner(typ reflect.Type) ScannerFunc {
kind := typ.Kind()
if kind == reflect.Ptr {

View file

@ -1,5 +1,11 @@
package schema
import (
"strings"
"github.com/uptrace/bun/internal"
)
type QueryAppender interface {
AppendQuery(fmter Formatter, b []byte) ([]byte, error)
}
@ -42,8 +48,13 @@ var _ QueryAppender = QueryWithArgs{}
func SafeQuery(query string, args []interface{}) QueryWithArgs {
if args == nil {
args = make([]interface{}, 0)
} else if len(query) > 0 && strings.IndexByte(query, '?') == -1 {
internal.Warn.Printf("query %q has args %v, but no placeholders", query, args)
}
return QueryWithArgs{
Query: query,
Args: args,
}
return QueryWithArgs{Query: query, Args: args}
}
func UnsafeIdent(ident string) QueryWithArgs {

View file

@ -61,6 +61,14 @@ func DiscoverSQLType(typ reflect.Type) string {
case nullStringType:
return sqltype.VarChar
}
switch typ.Kind() {
case reflect.Slice:
if typ.Elem().Kind() == reflect.Uint8 {
return sqltype.Blob
}
}
return sqlTypes[typ.Kind()]
}
@ -99,7 +107,7 @@ func (tm NullTime) AppendQuery(fmter Formatter, b []byte) ([]byte, error) {
if tm.IsZero() {
return dialect.AppendNull(b), nil
}
return dialect.AppendTime(b, tm.Time), nil
return fmter.Dialect().AppendTime(b, tm.Time), nil
}
func (tm *NullTime) Scan(src interface{}) error {

View file

@ -15,8 +15,11 @@ import (
)
const (
beforeScanHookFlag internal.Flag = 1 << iota
beforeAppendModelHookFlag internal.Flag = 1 << iota
beforeScanHookFlag
afterScanHookFlag
beforeScanRowHookFlag
afterScanRowHookFlag
)
var (
@ -84,8 +87,13 @@ func newTable(dialect Dialect, typ reflect.Type) *Table {
typ reflect.Type
flag internal.Flag
}{
{beforeAppendModelHookType, beforeAppendModelHookFlag},
{beforeScanHookType, beforeScanHookFlag},
{afterScanHookType, afterScanHookFlag},
{beforeScanRowHookType, beforeScanRowHookFlag},
{afterScanRowHookType, afterScanRowHookFlag},
}
typ = reflect.PtrTo(t.Type)
@ -95,6 +103,22 @@ func newTable(dialect Dialect, typ reflect.Type) *Table {
}
}
// Deprecated.
deprecatedHooks := []struct {
typ reflect.Type
flag internal.Flag
msg string
}{
{beforeScanHookType, beforeScanHookFlag, "rename BeforeScan hook to BeforeScanRow"},
{afterScanHookType, afterScanHookFlag, "rename AfterScan hook to AfterScanRow"},
}
for _, hook := range deprecatedHooks {
if typ.Implements(hook.typ) {
internal.Deprecated.Printf("%s: %s", t.TypeName, hook.msg)
t.flags = t.flags.Set(hook.flag)
}
}
return t
}
@ -334,15 +358,6 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field {
if tag.HasOption("pk") {
field.markAsPK()
}
if tag.HasOption("allowzero") {
if tag.HasOption("nullzero") {
internal.Warn.Printf(
"%s.%s: nullzero and allowzero options are mutually exclusive",
t.TypeName, f.Name,
)
}
field.NullZero = false
}
if v, ok := tag.Options["unique"]; ok {
// Split the value by comma, this will allow multiple names to be specified.
@ -362,7 +377,7 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field {
field.UserSQLType = s
}
field.DiscoveredSQLType = DiscoverSQLType(field.IndirectType)
field.Append = t.dialect.FieldAppender(field)
field.Append = FieldAppender(t.dialect, field)
field.Scan = FieldScanner(t.dialect, field)
field.IsZero = zeroChecker(field.StructField.Type)
@ -385,6 +400,17 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field {
t.UpdateSoftDeleteField = softDeleteFieldUpdater(field)
}
// Check this in the end to undo NullZero.
if tag.HasOption("allowzero") {
if tag.HasOption("nullzero") {
internal.Warn.Printf(
"%s.%s: nullzero and allowzero options are mutually exclusive",
t.TypeName, f.Name,
)
}
field.NullZero = false
}
return field
}
@ -775,9 +801,18 @@ func (t *Table) inlineFields(field *Field, seen map[reflect.Type]struct{}) {
//------------------------------------------------------------------------------
func (t *Table) Dialect() Dialect { return t.dialect }
func (t *Table) Dialect() Dialect { return t.dialect }
func (t *Table) HasBeforeAppendModelHook() bool { return t.flags.Has(beforeAppendModelHookFlag) }
// DEPRECATED. Use HasBeforeScanRowHook.
func (t *Table) HasBeforeScanHook() bool { return t.flags.Has(beforeScanHookFlag) }
func (t *Table) HasAfterScanHook() bool { return t.flags.Has(afterScanHookFlag) }
// DEPRECATED. Use HasAfterScanRowHook.
func (t *Table) HasAfterScanHook() bool { return t.flags.Has(afterScanHookFlag) }
func (t *Table) HasBeforeScanRowHook() bool { return t.flags.Has(beforeScanRowHookFlag) }
func (t *Table) HasAfterScanRowHook() bool { return t.flags.Has(afterScanRowHookFlag) }
//------------------------------------------------------------------------------

View file

@ -2,5 +2,5 @@ package bun
// Version is the current release version.
func Version() string {
return "1.0.9"
return "1.0.14"
}

View file

@ -54,7 +54,7 @@ includes_AIX='
includes_Darwin='
#define _DARWIN_C_SOURCE
#define KERNEL
#define KERNEL 1
#define _DARWIN_USE_64_BIT_INODE
#define __APPLE_USE_RFC_3542
#include <stdint.h>
@ -75,6 +75,7 @@ includes_Darwin='
#include <sys/utsname.h>
#include <sys/wait.h>
#include <sys/xattr.h>
#include <sys/vsock.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
@ -82,6 +83,9 @@ includes_Darwin='
#include <netinet/in.h>
#include <netinet/ip.h>
#include <termios.h>
// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk.
#define TIOCREMOTE 0x80047469
'
includes_DragonFly='
@ -466,7 +470,6 @@ ccflags="$@"
$2 !~ /^EQUIV_/ &&
$2 !~ /^EXPR_/ &&
$2 !~ /^EVIOC/ &&
$2 !~ /^EV_/ &&
$2 ~ /^E[A-Z0-9_]+$/ ||
$2 ~ /^B[0-9_]+$/ ||
$2 ~ /^(OLD|NEW)DEV$/ ||

View file

@ -48,6 +48,30 @@ func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
}
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables
// bidirectional communication between a hypervisor and its guest virtual
// machines.
type SockaddrVM struct {
// CID and Port specify a context ID and port address for a VM socket.
// Guests have a unique CID, and hosts may have a well-known CID of:
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
// - VMADDR_CID_LOCAL: refers to local communication (loopback).
// - VMADDR_CID_HOST: refers to other processes on the host.
CID uint32
Port uint32
raw RawSockaddrVM
}
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Len = SizeofSockaddrVM
sa.raw.Family = AF_VSOCK
sa.raw.Port = sa.Port
sa.raw.Cid = sa.CID
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_SYSTEM:
@ -58,6 +82,13 @@ func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Unit = pp.Sc_unit
return sa, nil
}
case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
sa := &SockaddrVM{
CID: pp.Cid,
Port: pp.Port,
}
return sa, nil
}
return nil, EAFNOSUPPORT
}
@ -433,6 +464,11 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
/*
* Exposed directly
*/
@ -590,10 +626,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// Msgget
// Msgsnd
// Msgrcv
// Shmat
// Shmctl
// Shmdt
// Shmget
// Shm_open
// Shm_unlink
// Sem_open

View file

@ -145,6 +145,15 @@ func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error
return ppoll(&fds[0], len(fds), timeout, sigmask)
}
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
return Ppoll(fds, ts, nil)
}
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
func Readlink(path string, buf []byte) (n int, err error) {
@ -2310,6 +2319,11 @@ type RemoteIovec struct {
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
/*
* Unimplemented
*/
@ -2391,10 +2405,6 @@ type RemoteIovec struct {
// SetRobustList
// SetThreadArea
// SetTidAddress
// Shmat
// Shmctl
// Shmdt
// Shmget
// Sigaltstack
// Swapoff
// Swapon

View file

@ -352,12 +352,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View file

@ -137,15 +137,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

View file

@ -227,15 +227,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE
func SyncFileRange(fd int, off int64, n int64, flags int) error {

View file

@ -185,18 +185,6 @@ func Pause() error {
return err
}
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

View file

@ -194,12 +194,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View file

@ -206,12 +206,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View file

@ -215,15 +215,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
func SyncFileRange(fd int, off int64, n int64, flags int) error {

View file

@ -101,15 +101,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
func SyncFileRange(fd int, off int64, n int64, flags int) error {

View file

@ -166,18 +166,6 @@ func Pause() error {
return err
}
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
}

View file

@ -297,15 +297,6 @@ func Shutdown(s, how int) error {
return nil
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

View file

@ -117,12 +117,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

21
vendor/golang.org/x/sys/unix/sysvshm_linux.go generated vendored Normal file
View file

@ -0,0 +1,21 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
package unix
import "runtime"
// SysvShmCtl performs control operations on the shared memory segment
// specified by id.
func SysvShmCtl(id, cmd int, desc *SysvShmDesc) (result int, err error) {
if runtime.GOARCH == "arm" ||
runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" {
cmd |= ipc_64
}
return shmctl(id, cmd, desc)
}

61
vendor/golang.org/x/sys/unix/sysvshm_unix.go generated vendored Normal file
View file

@ -0,0 +1,61 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (darwin && !ios) || linux
// +build darwin,!ios linux
package unix
import (
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
// SysvShmAttach attaches the Sysv shared memory segment associated with the
// shared memory identifier id.
func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
addr, errno := shmat(id, addr, flag)
if errno != nil {
return nil, errno
}
// Retrieve the size of the shared memory to enable slice creation
var info SysvShmDesc
_, err := SysvShmCtl(id, IPC_STAT, &info)
if err != nil {
// release the shared memory if we can't find the size
// ignoring error from shmdt as there's nothing sensible to return here
shmdt(addr)
return nil, err
}
// Use unsafe to convert addr into a []byte.
// TODO: convert to unsafe.Slice once we can assume Go 1.17
var b []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
hdr.Data = unsafe.Pointer(addr)
hdr.Cap = int(info.Segsz)
hdr.Len = int(info.Segsz)
return b, nil
}
// SysvShmDetach unmaps the shared memory slice returned from SysvShmAttach.
//
// It is not safe to use the slice after calling this function.
func SysvShmDetach(data []byte) error {
if len(data) == 0 {
return EINVAL
}
return shmdt(uintptr(unsafe.Pointer(&data[0])))
}
// SysvShmGet returns the Sysv shared memory identifier associated with key.
// If the IPC_CREAT flag is specified a new segment is created.
func SysvShmGet(key, size, flag int) (id int, err error) {
return shmget(key, size, flag)
}

14
vendor/golang.org/x/sys/unix/sysvshm_unix_other.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && !ios
// +build darwin,!ios
package unix
// SysvShmCtl performs control operations on the shared memory segment
// specified by id.
func SysvShmCtl(id, cmd int, desc *SysvShmDesc) (result int, err error) {
return shmctl(id, cmd, desc)
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1397,6 +1397,8 @@ const (
MADV_NOHUGEPAGE = 0xf
MADV_NORMAL = 0x0
MADV_PAGEOUT = 0x15
MADV_POPULATE_READ = 0x16
MADV_POPULATE_WRITE = 0x17
MADV_RANDOM = 0x1
MADV_REMOVE = 0x9
MADV_SEQUENTIAL = 0x2

View file

@ -734,6 +734,65 @@ var libc_sendfile_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
r0, _, e1 := syscall_syscall(libc_shmat_trampoline_addr, uintptr(id), uintptr(addr), uintptr(flag))
ret = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmat_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmat shmat "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) {
r0, _, e1 := syscall_syscall(libc_shmctl_trampoline_addr, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf)))
result = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmctl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmctl shmctl "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmdt(addr uintptr) (err error) {
_, _, e1 := syscall_syscall(libc_shmdt_trampoline_addr, uintptr(addr), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmdt_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmdt shmdt "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmget(key int, size int, flag int) (id int, err error) {
r0, _, e1 := syscall_syscall(libc_shmget_trampoline_addr, uintptr(key), uintptr(size), uintptr(flag))
id = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmget_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmget shmget "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Access(path string, mode uint32) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)

View file

@ -264,6 +264,30 @@ TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
DATA ·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB)
TEXT libc_shmat_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmat(SB)
GLOBL ·libc_shmat_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmat_trampoline_addr(SB)/8, $libc_shmat_trampoline<>(SB)
TEXT libc_shmctl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmctl(SB)
GLOBL ·libc_shmctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmctl_trampoline_addr(SB)/8, $libc_shmctl_trampoline<>(SB)
TEXT libc_shmdt_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmdt(SB)
GLOBL ·libc_shmdt_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmdt_trampoline_addr(SB)/8, $libc_shmdt_trampoline<>(SB)
TEXT libc_shmget_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmget(SB)
GLOBL ·libc_shmget_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmget_trampoline_addr(SB)/8, $libc_shmget_trampoline<>(SB)
TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_access(SB)

View file

@ -734,6 +734,65 @@ var libc_sendfile_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
r0, _, e1 := syscall_syscall(libc_shmat_trampoline_addr, uintptr(id), uintptr(addr), uintptr(flag))
ret = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmat_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmat shmat "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) {
r0, _, e1 := syscall_syscall(libc_shmctl_trampoline_addr, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf)))
result = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmctl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmctl shmctl "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmdt(addr uintptr) (err error) {
_, _, e1 := syscall_syscall(libc_shmdt_trampoline_addr, uintptr(addr), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmdt_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmdt shmdt "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmget(key int, size int, flag int) (id int, err error) {
r0, _, e1 := syscall_syscall(libc_shmget_trampoline_addr, uintptr(key), uintptr(size), uintptr(flag))
id = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_shmget_trampoline_addr uintptr
//go:cgo_import_dynamic libc_shmget shmget "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Access(path string, mode uint32) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)

View file

@ -264,6 +264,30 @@ TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
DATA ·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB)
TEXT libc_shmat_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmat(SB)
GLOBL ·libc_shmat_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmat_trampoline_addr(SB)/8, $libc_shmat_trampoline<>(SB)
TEXT libc_shmctl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmctl(SB)
GLOBL ·libc_shmctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmctl_trampoline_addr(SB)/8, $libc_shmctl_trampoline<>(SB)
TEXT libc_shmdt_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmdt(SB)
GLOBL ·libc_shmdt_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmdt_trampoline_addr(SB)/8, $libc_shmdt_trampoline<>(SB)
TEXT libc_shmget_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_shmget(SB)
GLOBL ·libc_shmget_trampoline_addr(SB), RODATA, $8
DATA ·libc_shmget_trampoline_addr(SB)/8, $libc_shmget_trampoline<>(SB)
TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_access(SB)

View file

@ -1974,3 +1974,46 @@ func PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
r0, _, e1 := Syscall(SYS_SHMAT, uintptr(id), uintptr(addr), uintptr(flag))
ret = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) {
r0, _, e1 := Syscall(SYS_SHMCTL, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf)))
result = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmdt(addr uintptr) (err error) {
_, _, e1 := Syscall(SYS_SHMDT, uintptr(addr), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmget(key int, size int, flag int) (id int, err error) {
r0, _, e1 := Syscall(SYS_SHMGET, uintptr(key), uintptr(size), uintptr(flag))
id = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -524,14 +524,3 @@ func utimes(path string, times *[2]Timeval) (err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -679,17 +679,6 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(cmdline)

View file

@ -639,17 +639,6 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func armSyncFileRange(fd int, flags int, off int64, n int64) (err error) {
_, _, e1 := Syscall6(SYS_ARM_SYNC_FILE_RANGE, uintptr(fd), uintptr(flags), uintptr(off), uintptr(off>>32), uintptr(n), uintptr(n>>32))
if e1 != 0 {

View file

@ -702,14 +702,3 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -696,14 +696,3 @@ func stat(path string, st *stat_t) (err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -696,14 +696,3 @@ func stat(path string, st *stat_t) (err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -702,14 +702,3 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -685,17 +685,6 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off>>32), uintptr(off), uintptr(n>>32), uintptr(n))
if e1 != 0 {

View file

@ -731,17 +731,6 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0)
if e1 != 0 {

View file

@ -731,17 +731,6 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0)
if e1 != 0 {

View file

@ -521,17 +521,6 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(cmdline)

View file

@ -697,14 +697,3 @@ func utimes(path string, times *[2]Timeval) (err error) {
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -209,6 +209,92 @@ type RawSockaddrCtl struct {
Sc_reserved [5]uint32
}
type RawSockaddrVM struct {
Len uint8
Family uint8
Reserved1 uint16
Port uint32
Cid uint32
}
type XVSockPCB struct {
Xv_len uint32
Xv_vsockpp uint64
Xvp_local_cid uint32
Xvp_local_port uint32
Xvp_remote_cid uint32
Xvp_remote_port uint32
Xvp_rxcnt uint32
Xvp_txcnt uint32
Xvp_peer_rxhiwat uint32
Xvp_peer_rxcnt uint32
Xvp_last_pid int32
Xvp_gencnt uint64
Xv_socket XSocket
_ [4]byte
}
type XSocket struct {
Xso_len uint32
Xso_so uint32
So_type int16
So_options int16
So_linger int16
So_state int16
So_pcb uint32
Xso_protocol int32
Xso_family int32
So_qlen int16
So_incqlen int16
So_qlimit int16
So_timeo int16
So_error uint16
So_pgid int32
So_oobmark uint32
So_rcv XSockbuf
So_snd XSockbuf
So_uid uint32
}
type XSocket64 struct {
Xso_len uint32
_ [8]byte
So_type int16
So_options int16
So_linger int16
So_state int16
_ [8]byte
Xso_protocol int32
Xso_family int32
So_qlen int16
So_incqlen int16
So_qlimit int16
So_timeo int16
So_error uint16
So_pgid int32
So_oobmark uint32
So_rcv XSockbuf
So_snd XSockbuf
So_uid uint32
}
type XSockbuf struct {
Cc uint32
Hiwat uint32
Mbcnt uint32
Mbmax uint32
Lowat int32
Flags int16
Timeo int16
}
type XVSockPgen struct {
Len uint32
Count uint64
Gen uint64
Sogen uint64
}
type _Socklen uint32
type Xucred struct {
@ -287,6 +373,11 @@ const (
SizeofSockaddrUnix = 0x6a
SizeofSockaddrDatalink = 0x14
SizeofSockaddrCtl = 0x20
SizeofSockaddrVM = 0xc
SizeofXvsockpcb = 0xa8
SizeofXSocket = 0x64
SizeofXSockbuf = 0x18
SizeofXVSockPgen = 0x20
SizeofXucred = 0x4c
SizeofLinger = 0x8
SizeofIovec = 0x10
@ -639,3 +730,39 @@ type Ucred struct {
Ngroups int16
Groups [16]uint32
}
type SysvIpcPerm struct {
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint16
_ uint16
_ int32
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Lpid int32
Cpid int32
Nattch uint16
_ [34]byte
}
const (
IPC_CREAT = 0x200
IPC_EXCL = 0x400
IPC_NOWAIT = 0x800
IPC_PRIVATE = 0x0
)
const (
IPC_RMID = 0x0
IPC_SET = 0x1
IPC_STAT = 0x2
)
const (
SHM_RDONLY = 0x1000
SHM_RND = 0x2000
)

View file

@ -209,6 +209,92 @@ type RawSockaddrCtl struct {
Sc_reserved [5]uint32
}
type RawSockaddrVM struct {
Len uint8
Family uint8
Reserved1 uint16
Port uint32
Cid uint32
}
type XVSockPCB struct {
Xv_len uint32
Xv_vsockpp uint64
Xvp_local_cid uint32
Xvp_local_port uint32
Xvp_remote_cid uint32
Xvp_remote_port uint32
Xvp_rxcnt uint32
Xvp_txcnt uint32
Xvp_peer_rxhiwat uint32
Xvp_peer_rxcnt uint32
Xvp_last_pid int32
Xvp_gencnt uint64
Xv_socket XSocket
_ [4]byte
}
type XSocket struct {
Xso_len uint32
Xso_so uint32
So_type int16
So_options int16
So_linger int16
So_state int16
So_pcb uint32
Xso_protocol int32
Xso_family int32
So_qlen int16
So_incqlen int16
So_qlimit int16
So_timeo int16
So_error uint16
So_pgid int32
So_oobmark uint32
So_rcv XSockbuf
So_snd XSockbuf
So_uid uint32
}
type XSocket64 struct {
Xso_len uint32
_ [8]byte
So_type int16
So_options int16
So_linger int16
So_state int16
_ [8]byte
Xso_protocol int32
Xso_family int32
So_qlen int16
So_incqlen int16
So_qlimit int16
So_timeo int16
So_error uint16
So_pgid int32
So_oobmark uint32
So_rcv XSockbuf
So_snd XSockbuf
So_uid uint32
}
type XSockbuf struct {
Cc uint32
Hiwat uint32
Mbcnt uint32
Mbmax uint32
Lowat int32
Flags int16
Timeo int16
}
type XVSockPgen struct {
Len uint32
Count uint64
Gen uint64
Sogen uint64
}
type _Socklen uint32
type Xucred struct {
@ -287,6 +373,11 @@ const (
SizeofSockaddrUnix = 0x6a
SizeofSockaddrDatalink = 0x14
SizeofSockaddrCtl = 0x20
SizeofSockaddrVM = 0xc
SizeofXvsockpcb = 0xa8
SizeofXSocket = 0x64
SizeofXSockbuf = 0x18
SizeofXVSockPgen = 0x20
SizeofXucred = 0x4c
SizeofLinger = 0x8
SizeofIovec = 0x10
@ -639,3 +730,39 @@ type Ucred struct {
Ngroups int16
Groups [16]uint32
}
type SysvIpcPerm struct {
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint16
_ uint16
_ int32
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Lpid int32
Cpid int32
Nattch uint16
_ [34]byte
}
const (
IPC_CREAT = 0x200
IPC_EXCL = 0x400
IPC_NOWAIT = 0x800
IPC_PRIVATE = 0x0
)
const (
IPC_RMID = 0x0
IPC_SET = 0x1
IPC_STAT = 0x2
)
const (
SHM_RDONLY = 0x1000
SHM_RND = 0x2000
)

View file

@ -3936,3 +3936,23 @@ type LandlockPathBeneathAttr struct {
const (
LANDLOCK_RULE_PATH_BENEATH = 0x1
)
const (
IPC_CREAT = 0x200
IPC_EXCL = 0x400
IPC_NOWAIT = 0x800
IPC_PRIVATE = 0x0
ipc_64 = 0x100
)
const (
IPC_RMID = 0x0
IPC_SET = 0x1
IPC_STAT = 0x2
)
const (
SHM_RDONLY = 0x1000
SHM_RND = 0x2000
)

View file

@ -639,3 +639,32 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint16
_ [2]uint8
Seq uint16
_ uint16
_ uint32
_ uint32
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint32
Atime uint32
Atime_high uint32
Dtime uint32
Dtime_high uint32
Ctime uint32
Ctime_high uint32
Cpid int32
Lpid int32
Nattch uint32
_ uint32
_ uint32
}

View file

@ -657,3 +657,29 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Atime int64
Dtime int64
Ctime int64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -634,3 +634,32 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint16
_ [2]uint8
Seq uint16
_ uint16
_ uint32
_ uint32
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint32
Atime uint32
Atime_high uint32
Dtime uint32
Dtime_high uint32
Ctime uint32
Ctime_high uint32
Cpid int32
Lpid int32
Nattch uint32
_ uint32
_ uint32
}

View file

@ -636,3 +636,29 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Atime int64
Dtime int64
Ctime int64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -640,3 +640,31 @@ const (
const (
PIDFD_NONBLOCK = 0x80
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint32
_ uint32
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint32
Atime uint32
Dtime uint32
Ctime uint32
Cpid int32
Lpid int32
Nattch uint32
Atime_high uint16
Dtime_high uint16
Ctime_high uint16
_ uint16
}

View file

@ -639,3 +639,29 @@ const (
const (
PIDFD_NONBLOCK = 0x80
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Atime int64
Dtime int64
Ctime int64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -639,3 +639,29 @@ const (
const (
PIDFD_NONBLOCK = 0x80
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Atime int64
Dtime int64
Ctime int64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -640,3 +640,31 @@ const (
const (
PIDFD_NONBLOCK = 0x80
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint32
_ uint32
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint32
Atime uint32
Dtime uint32
Ctime uint32
Cpid int32
Lpid int32
Nattch uint32
Atime_high uint16
Dtime_high uint16
Ctime_high uint16
_ uint16
}

View file

@ -646,3 +646,33 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
Seq uint32
_ uint32
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Atime_high uint32
Atime uint32
Dtime_high uint32
Dtime uint32
Ctime_high uint32
Ctime uint32
_ uint32
Segsz uint32
Cpid int32
Lpid int32
Nattch uint32
_ uint32
_ uint32
_ [4]byte
}

View file

@ -646,3 +646,28 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
Seq uint32
_ uint32
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Atime int64
Dtime int64
Ctime int64
Segsz uint64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -646,3 +646,28 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
Seq uint32
_ uint32
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Atime int64
Dtime int64
Ctime int64
Segsz uint64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -664,3 +664,29 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ [0]uint8
Seq uint16
_ uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Atime int64
Dtime int64
Ctime int64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -660,3 +660,28 @@ const (
const (
PIDFD_NONBLOCK = 0x800
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ uint16
Seq uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Segsz uint64
Atime int64
Dtime int64
Ctime int64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -641,3 +641,28 @@ const (
const (
PIDFD_NONBLOCK = 0x4000
)
type SysvIpcPerm struct {
Key int32
Uid uint32
Gid uint32
Cuid uint32
Cgid uint32
Mode uint32
_ uint16
Seq uint16
_ uint64
_ uint64
}
type SysvShmDesc struct {
Perm SysvIpcPerm
Atime int64
Dtime int64
Ctime int64
Segsz uint64
Cpid int32
Lpid int32
Nattch uint64
_ uint64
_ uint64
}

View file

@ -35,3 +35,14 @@ const (
QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008
QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004
)
type MemoryBasicInformation struct {
BaseAddress uintptr
AllocationBase uintptr
AllocationProtect uint32
PartitionId uint16
RegionSize uintptr
State uint32
Protect uint32
Type uint32
}

View file

@ -274,6 +274,11 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc
//sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree
//sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect
//sys VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) = kernel32.VirtualProtectEx
//sys VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery
//sys VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQueryEx
//sys ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) = kernel32.ReadProcessMemory
//sys WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) = kernel32.WriteProcessMemory
//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
//sys FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.FindFirstChangeNotificationW

View file

@ -303,6 +303,7 @@ var (
procReadConsoleW = modkernel32.NewProc("ReadConsoleW")
procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW")
procReadFile = modkernel32.NewProc("ReadFile")
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
procResetEvent = modkernel32.NewProc("ResetEvent")
@ -345,12 +346,16 @@ var (
procVirtualFree = modkernel32.NewProc("VirtualFree")
procVirtualLock = modkernel32.NewProc("VirtualLock")
procVirtualProtect = modkernel32.NewProc("VirtualProtect")
procVirtualProtectEx = modkernel32.NewProc("VirtualProtectEx")
procVirtualQuery = modkernel32.NewProc("VirtualQuery")
procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx")
procVirtualUnlock = modkernel32.NewProc("VirtualUnlock")
procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId")
procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects")
procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
procWriteFile = modkernel32.NewProc("WriteFile")
procWriteProcessMemory = modkernel32.NewProc("WriteProcessMemory")
procAcceptEx = modmswsock.NewProc("AcceptEx")
procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs")
procTransmitFile = modmswsock.NewProc("TransmitFile")
@ -2636,6 +2641,14 @@ func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (
return
}
func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) {
r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func ReleaseMutex(mutex Handle) (err error) {
r1, _, e1 := syscall.Syscall(procReleaseMutex.Addr(), 1, uintptr(mutex), 0, 0)
if r1 == 0 {
@ -2990,6 +3003,30 @@ func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect
return
}
func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procVirtualProtectEx.Addr(), 5, uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procVirtualQuery.Addr(), 3, uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) {
r1, _, e1 := syscall.Syscall6(procVirtualQueryEx.Addr(), 4, uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func VirtualUnlock(addr uintptr, length uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
if r1 == 0 {
@ -3046,6 +3083,14 @@ func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped)
return
}
func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) {
r1, _, e1 := syscall.Syscall6(procWriteProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
if r1 == 0 {

8
vendor/modules.txt vendored
View file

@ -447,7 +447,7 @@ github.com/tmthrgd/go-hex
# github.com/ugorji/go/codec v1.2.6
## explicit; go 1.11
github.com/ugorji/go/codec
# github.com/uptrace/bun v1.0.9
# github.com/uptrace/bun v1.0.14
## explicit; go 1.16
github.com/uptrace/bun
github.com/uptrace/bun/dialect
@ -459,10 +459,10 @@ github.com/uptrace/bun/internal/parser
github.com/uptrace/bun/internal/tagparser
github.com/uptrace/bun/migrate
github.com/uptrace/bun/schema
# github.com/uptrace/bun/dialect/pgdialect v1.0.9
# github.com/uptrace/bun/dialect/pgdialect v1.0.14
## explicit; go 1.16
github.com/uptrace/bun/dialect/pgdialect
# github.com/uptrace/bun/dialect/sqlitedialect v1.0.9
# github.com/uptrace/bun/dialect/sqlitedialect v1.0.14
## explicit; go 1.16
github.com/uptrace/bun/dialect/sqlitedialect
# github.com/urfave/cli/v2 v2.3.0
@ -514,7 +514,7 @@ golang.org/x/net/idna
## explicit; go 1.11
golang.org/x/oauth2
golang.org/x/oauth2/internal
# golang.org/x/sys v0.0.0-20210925032602-92d5a993a665
# golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac
## explicit; go 1.17
golang.org/x/sys/cpu
golang.org/x/sys/execabs