Compare commits

..

10 Commits

Author SHA1 Message Date
Mikescher dad0e3240d v0.0.636 Remove remaining traces of v1 mongo driver
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m36s
2026-04-26 14:53:24 +02:00
Mikescher a5cece2bc7 v0.0.635 mongo driver v2 (Viktor)
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m41s
2026-04-26 14:47:05 +02:00
Mikescher cdce955887 Merge remote-tracking branch 'origin/feature/mongo-driver-v2'
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m34s
2026-04-26 14:42:53 +02:00
Mikescher 90862ed3f5 Merge branch 'feature/upgrade-go'
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m35s
2026-04-26 14:31:48 +02:00
Mikescher 18c172d69a Revert gojson changes
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m34s
2026-04-26 14:29:28 +02:00
Mikescher 80cea13437 v0.0.634 add ReplyTo to googleapi.SendMail
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m37s
2026-04-24 13:38:00 +02:00
viktor f9576a2fec go mod tidy
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m39s
2026-04-21 18:45:52 +02:00
viktor 26d542c9a2 added mongo-driver v2
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m33s
2026-04-21 18:41:32 +02:00
viktor d30e778bd4 fixed test
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m35s
2026-04-21 16:54:52 +02:00
viktor 73e867f75a fixed test to properly wait for goroutine completion 2026-04-21 16:54:28 +02:00
44 changed files with 152 additions and 96 deletions
+9 -10
View File
@@ -2,9 +2,7 @@
package {{.PkgName}}
import "go.mongodb.org/mongo-driver/bson"
import "go.mongodb.org/mongo-driver/bson/bsontype"
import "go.mongodb.org/mongo-driver/bson/primitive"
import "go.mongodb.org/mongo-driver/v2/bson"
import "git.blackforestbytes.com/BlackForestBytes/goext/exerr"
const ChecksumIDGenerator = "{{.Checksum}}" // GoExtVersion: {{.GoextVersion}}
@@ -13,9 +11,10 @@ const ChecksumIDGenerator = "{{.Checksum}}" // GoExtVersion: {{.GoextVersion}}
// ================================ {{.Name}} ({{.FileRelative}}) ================================
func (i {{.Name}}) MarshalBSONValue() (bsontype.Type, []byte, error) {
if objId, err := primitive.ObjectIDFromHex(string(i)); err == nil {
return bson.MarshalValue(objId)
func (i {{.Name}}) MarshalBSONValue() (byte, []byte, error) {
if objId, err := bson.ObjectIDFromHex(string(i)); err == nil {
tp, data, err := bson.MarshalValue(objId)
return byte(tp), data, err
} else {
return 0, nil, exerr.New(exerr.TypeMarshalEntityID, "Failed to marshal {{.Name}}("+i.String()+") to ObjectId").Str("value", string(i)).Type("type", i).Build()
}
@@ -25,12 +24,12 @@ func (i {{.Name}}) String() string {
return string(i)
}
func (i {{.Name}}) ObjID() (primitive.ObjectID, error) {
return primitive.ObjectIDFromHex(string(i))
func (i {{.Name}}) ObjID() (bson.ObjectID, error) {
return bson.ObjectIDFromHex(string(i))
}
func (i {{.Name}}) Valid() bool {
_, err := primitive.ObjectIDFromHex(string(i))
_, err := bson.ObjectIDFromHex(string(i))
return err == nil
}
@@ -50,7 +49,7 @@ func (i {{.Name}}) IsZero() bool {
}
func New{{.Name}}() {{.Name}} {
return {{.Name}}(primitive.NewObjectID().Hex())
return {{.Name}}(bson.NewObjectID().Hex())
}
{{end}}
+1
View File
@@ -2,6 +2,7 @@ package cursortoken
import (
"context"
"go.mongodb.org/mongo-driver/v2/mongo"
)
+2 -1
View File
@@ -3,8 +3,9 @@ package cursortoken
import (
"encoding/base32"
"encoding/json"
"go.mongodb.org/mongo-driver/v2/bson"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type CTKeySort struct {
+3 -2
View File
@@ -3,11 +3,12 @@ package exerr
import (
"encoding/json"
"fmt"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
"maps"
"reflect"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
)
var reflectTypeStr = reflect.TypeFor[string]()
+1
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
)
+1
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
)
+3 -2
View File
@@ -3,11 +3,12 @@ package exerr
import (
"context"
"encoding/json"
"testing"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"testing"
"time"
)
func TestJSONMarshalErrorCategory(t *testing.T) {
+4 -3
View File
@@ -2,12 +2,13 @@ package exerr
import (
"fmt"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/rs/xid"
"github.com/rs/zerolog"
"reflect"
"strings"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/rs/xid"
"github.com/rs/zerolog"
)
type ExErr struct {
+4 -3
View File
@@ -5,13 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/v2/bson"
"math"
"strconv"
"strings"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/v2/bson"
)
// This is a buffed up map[string]any
-3
View File
@@ -20,7 +20,6 @@ require (
github.com/gorilla/websocket v1.5.3
github.com/jung-kurt/gofpdf v1.16.2
github.com/xuri/excelize/v2 v2.10.1
go.mongodb.org/mongo-driver v1.17.9
golang.org/x/sync v0.20.0
)
@@ -37,7 +36,6 @@ require (
github.com/go-playground/validator/v10 v10.30.2 // indirect
github.com/goccy/go-json v0.10.6 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.5 // indirect
@@ -48,7 +46,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/montanaflynn/stats v0.9.0 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/pelletier/go-toml/v2 v2.3.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
-6
View File
@@ -40,8 +40,6 @@ github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -81,8 +79,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.9.0 h1:tsBJ0RXwph9BmAuFoCmqGv6e8xa0MENQ8m0ptKq29mQ=
github.com/montanaflynn/stats v0.9.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM=
@@ -140,8 +136,6 @@ github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/T
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU=
go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ=
go.mongodb.org/mongo-driver/v2 v2.5.1 h1:j2U/Qp+wvueSpqitLCSZPT/+ZpVc1xzuwdHWwl7d8ro=
go.mongodb.org/mongo-driver/v2 v2.5.1/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
+2 -2
View File
@@ -1,5 +1,5 @@
package goext
const GoextVersion = "0.0.633"
const GoextVersion = "0.0.636"
const GoextVersionTimestamp = "2026-04-13T16:12:09+0200"
const GoextVersionTimestamp = "2026-04-26T14:53:24+0200"
+8 -8
View File
@@ -108,11 +108,11 @@ func (u unmarshalerText) MarshalText() ([]byte, error) {
}
func (u *unmarshalerText) UnmarshalText(b []byte) error {
before, after, ok := bytes.Cut(b, []byte{':'})
if !ok {
pos := bytes.IndexByte(b, ':')
if pos == -1 {
return errors.New("missing separator")
}
u.A, u.B = string(before), string(after)
u.A, u.B = string(b[:pos]), string(b[pos+1:])
return nil
}
@@ -126,7 +126,7 @@ type ustructText struct {
type u8marshal uint8
func (u8 u8marshal) MarshalText() ([]byte, error) {
return fmt.Appendf(nil, "u%d", u8), nil
return []byte(fmt.Sprintf("u%d", u8)), nil
}
var errMissingU8Prefix = errors.New("missing 'u' prefix")
@@ -275,7 +275,7 @@ func (unexportedWithMethods) F() {}
type byteWithMarshalJSON byte
func (b byteWithMarshalJSON) MarshalJSON() ([]byte, error) {
return fmt.Appendf(nil, `"Z%.2x"`, byte(b)), nil
return []byte(fmt.Sprintf(`"Z%.2x"`, byte(b))), nil
}
func (b *byteWithMarshalJSON) UnmarshalJSON(data []byte) error {
@@ -303,7 +303,7 @@ func (b *byteWithPtrMarshalJSON) UnmarshalJSON(data []byte) error {
type byteWithMarshalText byte
func (b byteWithMarshalText) MarshalText() ([]byte, error) {
return fmt.Appendf(nil, `Z%.2x`, byte(b)), nil
return []byte(fmt.Sprintf(`Z%.2x`, byte(b))), nil
}
func (b *byteWithMarshalText) UnmarshalText(data []byte) error {
@@ -331,7 +331,7 @@ func (b *byteWithPtrMarshalText) UnmarshalText(data []byte) error {
type intWithMarshalJSON int
func (b intWithMarshalJSON) MarshalJSON() ([]byte, error) {
return fmt.Appendf(nil, `"Z%.2x"`, int(b)), nil
return []byte(fmt.Sprintf(`"Z%.2x"`, int(b))), nil
}
func (b *intWithMarshalJSON) UnmarshalJSON(data []byte) error {
@@ -359,7 +359,7 @@ func (b *intWithPtrMarshalJSON) UnmarshalJSON(data []byte) error {
type intWithMarshalText int
func (b intWithMarshalText) MarshalText() ([]byte, error) {
return fmt.Appendf(nil, `Z%.2x`, int(b)), nil
return []byte(fmt.Sprintf(`Z%.2x`, int(b))), nil
}
func (b *intWithMarshalText) UnmarshalText(data []byte) error {
+13 -5
View File
@@ -177,7 +177,7 @@ type IndentOpt struct {
// MarshalSafeCollections is like Marshal except it will marshal nil maps and
// slices as '{}' and '[]' respectfully instead of 'null'
func MarshalSafeCollections(v any, nilSafeSlices bool, nilSafeMaps bool, indent *IndentOpt, filter *string) ([]byte, error) {
func MarshalSafeCollections(v interface{}, nilSafeSlices bool, nilSafeMaps bool, indent *IndentOpt, filter *string) ([]byte, error) {
e := &encodeState{}
err := e.marshal(v, encOpts{escapeHTML: true, nilSafeSlices: nilSafeSlices, nilSafeMaps: nilSafeMaps, filter: filter})
if err != nil {
@@ -891,7 +891,7 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
// Here we use a struct to memorize the pointer to the first element of the slice
// and its length.
ptr := struct {
ptr any // always an unsafe.Pointer, but avoids a dependency on package unsafe
ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe
len int
}{v.UnsafePointer(), v.Len()}
if _, ok := e.ptrSeen[ptr]; ok {
@@ -923,7 +923,7 @@ type arrayEncoder struct {
func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
e.WriteByte('[')
n := v.Len()
for i := range n {
for i := 0; i < n; i++ {
if i > 0 {
e.WriteByte(',')
}
@@ -1075,7 +1075,10 @@ func appendString[Bytes []byte | string](dst []byte, src Bytes, escapeHTML bool)
// For now, cast only a small portion of byte slices to a string
// so that it can be stack allocated. This slows down []byte slightly
// due to the extra copy, but keeps string performance roughly the same.
n := min(len(src)-i, utf8.UTFMax)
n := len(src) - i
if n > utf8.UTFMax {
n = utf8.UTFMax
}
c, size := utf8.DecodeRuneInString(string(src[i : i+n]))
if c == utf8.RuneError && size == 1 {
dst = append(dst, src[start:i]...)
@@ -1127,7 +1130,12 @@ type field struct {
type jsonfilter []string
func (j jsonfilter) Contains(t string) bool {
return slices.Contains(j, t)
for _, tag := range j {
if t == tag {
return true
}
}
return false
}
// typeFields returns a list of fields that JSON should recognize for the given type.
+15 -14
View File
@@ -41,7 +41,7 @@ type Optionals struct {
Uo uint `json:"uo,omitempty"`
Str struct{} `json:"str"`
Sto struct{} `json:"sto"`
Sto struct{} `json:"sto,omitempty"`
}
func TestOmitEmpty(t *testing.T) {
@@ -1166,7 +1166,8 @@ func TestMarshalUncommonFieldNames(t *testing.T) {
}
func TestMarshalerError(t *testing.T) {
st := reflect.TypeFor[string]()
s := "test variable"
st := reflect.TypeOf(s)
const errText = "json: test error"
tests := []struct {
@@ -1221,18 +1222,18 @@ func TestIssue63379(t *testing.T) {
func TestMarshalSafeCollections(t *testing.T) {
var (
nilSlice []any
pNilSlice *[]any
nilMap map[string]any
pNilMap *map[string]any
nilSlice []interface{}
pNilSlice *[]interface{}
nilMap map[string]interface{}
pNilMap *map[string]interface{}
)
type (
nilSliceStruct struct {
NilSlice []any `json:"nil_slice"`
NilSlice []interface{} `json:"nil_slice"`
}
nilMapStruct struct {
NilMap map[string]any `json:"nil_map"`
NilMap map[string]interface{} `json:"nil_map"`
}
testWithFilter struct {
Test1 string `json:"test1" jsonfilter:"FILTERONE"`
@@ -1241,19 +1242,19 @@ func TestMarshalSafeCollections(t *testing.T) {
)
tests := []struct {
in any
in interface{}
want string
}{
{nilSlice, "[]"},
{[]any{}, "[]"},
{make([]any, 0), "[]"},
{[]interface{}{}, "[]"},
{make([]interface{}, 0), "[]"},
{[]int{1, 2, 3}, "[1,2,3]"},
{pNilSlice, "null"},
{nilSliceStruct{}, "{\"nil_slice\":[]}"},
{nilMap, "{}"},
{map[string]any{}, "{}"},
{make(map[string]any, 0), "{}"},
{map[string]any{"1": 1, "2": 2, "3": 3}, "{\"1\":1,\"2\":2,\"3\":3}"},
{map[string]interface{}{}, "{}"},
{make(map[string]interface{}, 0), "{}"},
{map[string]interface{}{"1": 1, "2": 2, "3": 3}, "{\"1\":1,\"2\":2,\"3\":3}"},
{pNilMap, "null"},
{nilMapStruct{}, "{\"nil_map\":{}}"},
{testWithFilter{}, "{\"test1\":\"\"}"},
+4 -4
View File
@@ -28,10 +28,10 @@ func FuzzUnmarshalJSON(f *testing.F) {
}`))
f.Fuzz(func(t *testing.T, b []byte) {
for _, typ := range []func() any{
func() any { return new(any) },
func() any { return new(map[string]any) },
func() any { return new([]any) },
for _, typ := range []func() interface{}{
func() interface{} { return new(interface{}) },
func() interface{} { return new(map[string]interface{}) },
func() interface{} { return new([]interface{}) },
} {
i := typ()
if err := Unmarshal(b, i); err != nil {
+1 -1
View File
@@ -90,7 +90,7 @@ func appendCompact(dst, src []byte, escape bool) ([]byte, error) {
func appendNewline(dst []byte, prefix, indent string, depth int) []byte {
dst = append(dst, '\n')
dst = append(dst, prefix...)
for range depth {
for i := 0; i < depth; i++ {
dst = append(dst, indent...)
}
return dst
+12 -3
View File
@@ -210,7 +210,10 @@ func diff(t *testing.T, a, b []byte) {
t.Helper()
for i := 0; ; i++ {
if i >= len(a) || i >= len(b) || a[i] != b[i] {
j := max(i-10, 0)
j := i - 10
if j < 0 {
j = 0
}
t.Errorf("diverge at %d: «%s» vs «%s»", i, trim(a[j:]), trim(b[j:]))
return
}
@@ -271,7 +274,10 @@ func genString(stddev float64) string {
}
func genArray(n int) []any {
f := min(int(math.Abs(rand.NormFloat64())*math.Min(10, float64(n/2))), n)
f := int(math.Abs(rand.NormFloat64()) * math.Min(10, float64(n/2)))
if f > n {
f = n
}
if f < 1 {
f = 1
}
@@ -283,7 +289,10 @@ func genArray(n int) []any {
}
func genMap(n int) map[string]any {
f := min(int(math.Abs(rand.NormFloat64())*math.Min(10, float64(n/2))), n)
f := int(math.Abs(rand.NormFloat64()) * math.Min(10, float64(n/2)))
if f > n {
f = n
}
if n > 0 && f == 0 {
f = 1
}
+4 -1
View File
@@ -8,7 +8,7 @@ import (
)
// https://datatracker.ietf.org/doc/html/rfc2822
func encodeMimeMail(from string, recipients []string, cc []string, bcc []string, subject string, body MailBody, attachments []MailAttachment) string {
func encodeMimeMail(from string, recipients []string, cc []string, bcc []string, replyTo []string, subject string, body MailBody, attachments []MailAttachment) string {
data := make([]string, 0, 32)
@@ -22,6 +22,9 @@ func encodeMimeMail(from string, recipients []string, cc []string, bcc []string,
if len(bcc) > 0 {
data = append(data, "Bcc: "+strings.Join(langext.ArrMap(bcc, func(v string) string { return mime.QEncoding.Encode("UTF-8", v) }), ", "))
}
if len(replyTo) > 0 {
data = append(data, "Reply-To: "+strings.Join(langext.ArrMap(replyTo, func(v string) string { return mime.QEncoding.Encode("UTF-8", v) }), ", "))
}
data = append(data, "Subject: "+mime.QEncoding.Encode("UTF-8", subject))
hasInlineAttachments := langext.ArrAny(attachments, func(v MailAttachment) bool { return v.IsInline })
+4
View File
@@ -13,6 +13,7 @@ func TestEncodeMimeMail(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail",
MailBody{Plain: "Plain Text"},
nil)
@@ -27,6 +28,7 @@ func TestEncodeMimeMail2(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail (alternative)",
MailBody{
Plain: "Plain Text",
@@ -44,6 +46,7 @@ func TestEncodeMimeMail3(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail (alternative)",
MailBody{
HTML: "<html><body><u>Non</u> Pl<i>ai</i>n T<b>ex</b>t</body></html>",
@@ -64,6 +67,7 @@ func TestEncodeMimeMail4(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail (inline)",
MailBody{
HTML: "<html><body><u>Non</u> Pl<i>ai</i>n T<b>ex</b>t</body></html>",
+2 -2
View File
@@ -19,9 +19,9 @@ type MailRef struct {
LabelIDs []string `json:"labelIds"`
}
func (c *client) SendMail(ctx context.Context, from string, recipients []string, cc []string, bcc []string, subject string, body MailBody, attachments []MailAttachment) (MailRef, error) {
func (c *client) SendMail(ctx context.Context, from string, recipients []string, cc []string, bcc []string, replyTo []string, subject string, body MailBody, attachments []MailAttachment) (MailRef, error) {
mm := encodeMimeMail(from, recipients, cc, bcc, subject, body, attachments)
mm := encodeMimeMail(from, recipients, cc, bcc, replyTo, subject, body, attachments)
tok, err := c.oauth.AccessToken()
if err != nil {
+4
View File
@@ -36,6 +36,7 @@ func TestSendMail1(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail",
MailBody{Plain: "Plain Text"},
nil)
@@ -66,6 +67,7 @@ func TestSendMail2(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail (alternative)",
MailBody{
Plain: "Plain Text",
@@ -99,6 +101,7 @@ func TestSendMail3(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail (attach)",
MailBody{
HTML: "<html><body><u>Non</u> Pl<i>ai</i>n T<b>ex</b>t</body></html>",
@@ -135,6 +138,7 @@ func TestSendMail4(t *testing.T) {
[]string{"trash@mikescher.de"},
nil,
nil,
nil,
"Hello Test Mail (inline)",
MailBody{
HTML: "<html><body><u>Non</u> Pl<i>ai</i>n T<b>ex</b>t</body></html>",
+1 -1
View File
@@ -6,7 +6,7 @@ import (
)
type GoogleClient interface {
SendMail(ctx context.Context, from string, recipients []string, cc []string, bcc []string, subject string, body MailBody, attachments []MailAttachment) (MailRef, error)
SendMail(ctx context.Context, from string, recipients []string, cc []string, bcc []string, replyTo []string, subject string, body MailBody, attachments []MailAttachment) (MailRef, error)
}
type client struct {
+2 -1
View File
@@ -1,9 +1,10 @@
package mongoext
import (
"go.mongodb.org/mongo-driver/v2/bson"
"reflect"
"strings"
"go.mongodb.org/mongo-driver/v2/bson"
)
// ProjectionFromStruct automatically generated a mongodb projection for a struct
+1
View File
@@ -2,6 +2,7 @@ package pagination
import (
"context"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
)
+3 -2
View File
@@ -3,12 +3,13 @@ package reflectext
import (
"errors"
"fmt"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
"reflect"
"strconv"
"strings"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
)
var primitiveSerializer = map[reflect.Type]genSerializer{
+2 -1
View File
@@ -4,10 +4,11 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
"strconv"
"strings"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type Date struct {
+2 -1
View File
@@ -4,8 +4,9 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type RFC3339NanoTime time.Time
+2 -1
View File
@@ -4,9 +4,10 @@ import (
"encoding/json"
"errors"
"fmt"
"time"
"git.blackforestbytes.com/BlackForestBytes/goext/timeext"
"go.mongodb.org/mongo-driver/v2/bson"
"time"
)
type SecondsF64 time.Duration
+2 -1
View File
@@ -4,9 +4,10 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
"strconv"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type UnixTime time.Time
+2 -1
View File
@@ -4,9 +4,10 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
"strconv"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type UnixMilliTime time.Time
+2 -1
View File
@@ -4,9 +4,10 @@ import (
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/v2/bson"
"strconv"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type UnixNanoTime time.Time
+1 -4
View File
@@ -51,10 +51,7 @@ func GetIsoWeekCount(year int) int {
w2 -= 1
w3 -= 1
w := max(w2, w1)
if w3 > w {
w = w3
}
w := max(w3, max(w2, w1))
return w
}
+2 -1
View File
@@ -2,11 +2,12 @@ package wmo
import (
"context"
"reflect"
ct "git.blackforestbytes.com/BlackForestBytes/goext/cursortoken"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/mongo"
"reflect"
)
type EntityID interface {
+1
View File
@@ -2,6 +2,7 @@ package wmo
import (
"context"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"go.mongodb.org/mongo-driver/v2/bson"
)
+1
View File
@@ -2,6 +2,7 @@ package wmo
import (
"context"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/mongo"
+1
View File
@@ -2,6 +2,7 @@ package wmo
import (
"context"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
+19 -4
View File
@@ -2,12 +2,13 @@ package wmo
import (
"context"
"iter"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"iter"
)
func (c *Coll[TData]) createFindQuery(ctx context.Context, filter bson.M, opts ...*options.FindOptions) (*mongo.Cursor, error) {
@@ -51,18 +52,23 @@ func (c *Coll[TData]) createFindQuery(ctx context.Context, filter bson.M, opts .
}
}
convOpts := make([]options.Lister[options.AggregateOptions], 0, len(opts))
convOpts := make([]*options.AggregateOptionsBuilder, 0, len(opts))
for _, v := range opts {
vConv, err := convertFindOpt(v)
if err != nil {
return nil, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipeline).Str("collection", c.Name()).Build()
}
if vConv != nil {
convOpts = append(convOpts, vConv)
}
convOptsLister := make([]options.Lister[options.AggregateOptions], 0, len(convOpts))
for _, v := range convOpts {
if v != nil {
convOptsLister = append(convOptsLister, v)
}
}
cursor, err := c.coll.Aggregate(ctx, pipeline, convOpts...)
cursor, err := c.coll.Aggregate(ctx, pipeline, convOptsLister...)
if err != nil {
return nil, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipeline).Str("collection", c.Name()).Build()
}
@@ -167,12 +173,21 @@ func convertFindOpt(v *options.FindOptions) (*options.AggregateOptionsBuilder, e
if v.Hint != nil {
r.SetHint(v.Hint)
}
if v.Max != nil {
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'Max' (cannot convert to AggregateOptions)").Build()
}
if v.MaxAwaitTime != nil {
r.SetMaxAwaitTime(*v.MaxAwaitTime)
}
if v.Min != nil {
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'Min' (cannot convert to AggregateOptions)").Build()
}
if v.NoCursorTimeout != nil {
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'NoCursorTimeout' (cannot convert to AggregateOptions)").Build()
}
if v.OplogReplay != nil {
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'OplogReplay' (cannot convert to AggregateOptions)").Build()
}
if v.ReturnKey != nil {
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'ReturnKey' (cannot convert to AggregateOptions)").Build()
}
+1
View File
@@ -3,6 +3,7 @@ package wmo
import (
"context"
"errors"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
+1
View File
@@ -2,6 +2,7 @@ package wmo
import (
"context"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
+2 -1
View File
@@ -2,12 +2,13 @@ package wmo
import (
"context"
"iter"
ct "git.blackforestbytes.com/BlackForestBytes/goext/cursortoken"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"iter"
)
func (c *Coll[TData]) List(ctx context.Context, filter ct.Filter, pageSize *int, inTok ct.CursorToken) ([]TData, ct.CursorToken, error) {
+2 -1
View File
@@ -2,12 +2,13 @@ package wmo
import (
"context"
"iter"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
pag "git.blackforestbytes.com/BlackForestBytes/goext/pagination"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"iter"
)
func (c *Coll[TData]) Paginate(ctx context.Context, filter pag.MongoFilter, page int, limit *int) ([]TData, pag.Pagination, error) {
+1
View File
@@ -2,6 +2,7 @@ package wmo
import (
"context"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
+3 -4
View File
@@ -1,12 +1,11 @@
package wpdf
import (
"regexp"
"strconv"
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
"git.blackforestbytes.com/BlackForestBytes/goext/rext"
"regexp"
"strconv"
)
// Column specifier:
@@ -299,7 +298,7 @@ func (b *TableBuilder) calculateColumns() []float64 {
if remainingWidth > 0.01 {
rmSub := 0.0
for i := range columnDef {
for i, _ := range columnDef {
if frColumnWeights[i] != 0 {
addW := (remainingWidth / float64(frColumnWidthCount)) * frColumnWeights[i]
rmSub += addW