Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
335ef4d8e8
|
|||
61801ff20d
|
|||
361dca5c85
|
|||
9f85a243e8
|
|||
dc6cb274ee
|
|||
f6b47792a4
|
|||
295b3ef793
|
|||
721c176337
|
@@ -20,6 +20,7 @@ Potentially needs `export GOPRIVATE="gogs.mikescher.com"`
|
|||||||
| zipext | Mike | Utility for zip/gzip/tar etc |
|
| zipext | Mike | Utility for zip/gzip/tar etc |
|
||||||
| reflectext | Mike | Utility for golang reflection |
|
| reflectext | Mike | Utility for golang reflection |
|
||||||
| fsext | Mike | Utility for filesytem access |
|
| fsext | Mike | Utility for filesytem access |
|
||||||
|
| ctxext | Mike | Utility for context.Context |
|
||||||
| | | |
|
| | | |
|
||||||
| mongoext | Mike | Utility/Helper functions for mongodb (kinda abandoned) |
|
| mongoext | Mike | Utility/Helper functions for mongodb (kinda abandoned) |
|
||||||
| cursortoken | Mike | MongoDB cursortoken implementation |
|
| cursortoken | Mike | MongoDB cursortoken implementation |
|
||||||
|
27
ctxext/getter.go
Normal file
27
ctxext/getter.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package ctxext
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
func Value[T any](ctx context.Context, key any) (T, bool) {
|
||||||
|
v := ctx.Value(key)
|
||||||
|
if v == nil {
|
||||||
|
return *new(T), false
|
||||||
|
}
|
||||||
|
if tv, ok := v.(T); !ok {
|
||||||
|
return *new(T), false
|
||||||
|
} else {
|
||||||
|
return tv, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValueOrDefault[T any](ctx context.Context, key any, def T) T {
|
||||||
|
v := ctx.Value(key)
|
||||||
|
if v == nil {
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
if tv, ok := v.(T); !ok {
|
||||||
|
return def
|
||||||
|
} else {
|
||||||
|
return tv
|
||||||
|
}
|
||||||
|
}
|
@@ -57,3 +57,11 @@ func (m JsonOpt[T]) MustValue() T {
|
|||||||
}
|
}
|
||||||
return m.value
|
return m.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m JsonOpt[T]) IfSet(fn func(v T)) bool {
|
||||||
|
if !m.isSet {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fn(m.value)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
92
dataext/ringBuffer.go
Normal file
92
dataext/ringBuffer.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package dataext
|
||||||
|
|
||||||
|
import "iter"
|
||||||
|
|
||||||
|
type RingBuffer[T any] struct {
|
||||||
|
items []T //
|
||||||
|
capacity int // max number of items the buffer can hold
|
||||||
|
size int // how many items are in the buffer
|
||||||
|
head int // ptr to next item
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRingBuffer[T any](capacity int) *RingBuffer[T] {
|
||||||
|
return &RingBuffer[T]{
|
||||||
|
items: make([]T, capacity),
|
||||||
|
capacity: capacity,
|
||||||
|
size: 0,
|
||||||
|
head: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Push(item T) {
|
||||||
|
if rb.size < rb.capacity {
|
||||||
|
rb.size++
|
||||||
|
}
|
||||||
|
rb.items[rb.head] = item
|
||||||
|
rb.head = (rb.head + 1) % rb.capacity
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Peek() (T, bool) {
|
||||||
|
if rb.size == 0 {
|
||||||
|
return *new(T), false
|
||||||
|
}
|
||||||
|
return rb.items[(rb.head-1+rb.capacity)%rb.capacity], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Items() []T {
|
||||||
|
if rb.size < rb.capacity {
|
||||||
|
return rb.items[:rb.size]
|
||||||
|
}
|
||||||
|
return append(rb.items[rb.head:], rb.items[:rb.head]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Size() int {
|
||||||
|
return rb.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Capacity() int {
|
||||||
|
return rb.capacity
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Clear() {
|
||||||
|
rb.size = 0
|
||||||
|
rb.head = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) IsFull() bool {
|
||||||
|
return rb.size == rb.capacity
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) At(i int) T {
|
||||||
|
if i < 0 || i >= rb.size {
|
||||||
|
panic("Index out of bounds")
|
||||||
|
}
|
||||||
|
return rb.items[(rb.head+i)%rb.capacity]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Get(i int) (T, bool) {
|
||||||
|
if i < 0 || i >= rb.size {
|
||||||
|
return *new(T), false
|
||||||
|
}
|
||||||
|
return rb.items[(rb.head+i)%rb.capacity], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Iter() iter.Seq[T] {
|
||||||
|
return func(yield func(T) bool) {
|
||||||
|
for i := 0; i < rb.size; i++ {
|
||||||
|
if !yield(rb.At(i)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rb *RingBuffer[T]) Iter2() iter.Seq2[int, T] {
|
||||||
|
return func(yield func(int, T) bool) {
|
||||||
|
for i := 0; i < rb.size; i++ {
|
||||||
|
if !yield(i, rb.At(i)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -19,6 +19,14 @@ func (s Single[T1]) TupleValues() []any {
|
|||||||
return []any{s.V1}
|
return []any{s.V1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSingle[T1 any](v1 T1) Single[T1] {
|
||||||
|
return Single[T1]{V1: v1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple1[T1 any](v1 T1) Single[T1] {
|
||||||
|
return Single[T1]{V1: v1}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Tuple[T1 any, T2 any] struct {
|
type Tuple[T1 any, T2 any] struct {
|
||||||
@@ -34,6 +42,14 @@ func (t Tuple[T1, T2]) TupleValues() []any {
|
|||||||
return []any{t.V1, t.V2}
|
return []any{t.V1, t.V2}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTuple[T1 any, T2 any](v1 T1, v2 T2) Tuple[T1, T2] {
|
||||||
|
return Tuple[T1, T2]{V1: v1, V2: v2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple2[T1 any, T2 any](v1 T1, v2 T2) Tuple[T1, T2] {
|
||||||
|
return Tuple[T1, T2]{V1: v1, V2: v2}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Triple[T1 any, T2 any, T3 any] struct {
|
type Triple[T1 any, T2 any, T3 any] struct {
|
||||||
@@ -50,6 +66,14 @@ func (t Triple[T1, T2, T3]) TupleValues() []any {
|
|||||||
return []any{t.V1, t.V2, t.V3}
|
return []any{t.V1, t.V2, t.V3}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTriple[T1 any, T2 any, T3 any](v1 T1, v2 T2, v3 T3) Triple[T1, T2, T3] {
|
||||||
|
return Triple[T1, T2, T3]{V1: v1, V2: v2, V3: v3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple3[T1 any, T2 any, T3 any](v1 T1, v2 T2, v3 T3) Triple[T1, T2, T3] {
|
||||||
|
return Triple[T1, T2, T3]{V1: v1, V2: v2, V3: v3}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Quadruple[T1 any, T2 any, T3 any, T4 any] struct {
|
type Quadruple[T1 any, T2 any, T3 any, T4 any] struct {
|
||||||
@@ -67,6 +91,14 @@ func (t Quadruple[T1, T2, T3, T4]) TupleValues() []any {
|
|||||||
return []any{t.V1, t.V2, t.V3, t.V4}
|
return []any{t.V1, t.V2, t.V3, t.V4}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewQuadruple[T1 any, T2 any, T3 any, T4 any](v1 T1, v2 T2, v3 T3, v4 T4) Quadruple[T1, T2, T3, T4] {
|
||||||
|
return Quadruple[T1, T2, T3, T4]{V1: v1, V2: v2, V3: v3, V4: v4}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple4[T1 any, T2 any, T3 any, T4 any](v1 T1, v2 T2, v3 T3, v4 T4) Quadruple[T1, T2, T3, T4] {
|
||||||
|
return Quadruple[T1, T2, T3, T4]{V1: v1, V2: v2, V3: v3, V4: v4}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Quintuple[T1 any, T2 any, T3 any, T4 any, T5 any] struct {
|
type Quintuple[T1 any, T2 any, T3 any, T4 any, T5 any] struct {
|
||||||
@@ -86,6 +118,14 @@ func (t Quintuple[T1, T2, T3, T4, T5]) TupleValues() []any {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewQuintuple[T1 any, T2 any, T3 any, T4 any, T5 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5) Quintuple[T1, T2, T3, T4, T5] {
|
||||||
|
return Quintuple[T1, T2, T3, T4, T5]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple5[T1 any, T2 any, T3 any, T4 any, T5 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5) Quintuple[T1, T2, T3, T4, T5] {
|
||||||
|
return Quintuple[T1, T2, T3, T4, T5]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Sextuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any] struct {
|
type Sextuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any] struct {
|
||||||
@@ -106,6 +146,14 @@ func (t Sextuple[T1, T2, T3, T4, T5, T6]) TupleValues() []any {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSextuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6) Sextuple[T1, T2, T3, T4, T5, T6] {
|
||||||
|
return Sextuple[T1, T2, T3, T4, T5, T6]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6) Sextuple[T1, T2, T3, T4, T5, T6] {
|
||||||
|
return Sextuple[T1, T2, T3, T4, T5, T6]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Septuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any] struct {
|
type Septuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any] struct {
|
||||||
@@ -126,6 +174,14 @@ func (t Septuple[T1, T2, T3, T4, T5, T6, T7]) TupleValues() []any {
|
|||||||
return []any{t.V1, t.V2, t.V3, t.V4, t.V5, t.V6, t.V7}
|
return []any{t.V1, t.V2, t.V3, t.V4, t.V5, t.V6, t.V7}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSeptuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7) Septuple[T1, T2, T3, T4, T5, T6, T7] {
|
||||||
|
return Septuple[T1, T2, T3, T4, T5, T6, T7]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6, V7: v7}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple7[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7) Septuple[T1, T2, T3, T4, T5, T6, T7] {
|
||||||
|
return Septuple[T1, T2, T3, T4, T5, T6, T7]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6, V7: v7}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Octuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any] struct {
|
type Octuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any] struct {
|
||||||
@@ -147,6 +203,14 @@ func (t Octuple[T1, T2, T3, T4, T5, T6, T7, T8]) TupleValues() []any {
|
|||||||
return []any{t.V1, t.V2, t.V3, t.V4, t.V5, t.V6, t.V7, t.V8}
|
return []any{t.V1, t.V2, t.V3, t.V4, t.V5, t.V6, t.V7, t.V8}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewOctuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8) Octuple[T1, T2, T3, T4, T5, T6, T7, T8] {
|
||||||
|
return Octuple[T1, T2, T3, T4, T5, T6, T7, T8]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6, V7: v7, V8: v8}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTuple8[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8) Octuple[T1, T2, T3, T4, T5, T6, T7, T8] {
|
||||||
|
return Octuple[T1, T2, T3, T4, T5, T6, T7, T8]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6, V7: v7, V8: v8}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
type Nonuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any] struct {
|
type Nonuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any] struct {
|
||||||
@@ -168,3 +232,10 @@ func (t Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]) TupleLength() int {
|
|||||||
func (t Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]) TupleValues() []any {
|
func (t Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]) TupleValues() []any {
|
||||||
return []any{t.V1, t.V2, t.V3, t.V4, t.V5, t.V6, t.V7, t.V8, t.V9}
|
return []any{t.V1, t.V2, t.V3, t.V4, t.V5, t.V6, t.V7, t.V8, t.V9}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewNonuple[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, v9 T9) Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
|
||||||
|
return Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6, V7: v7, V8: v8, V9: v9}
|
||||||
|
}
|
||||||
|
func NewTuple9[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, v9 T9) Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
|
||||||
|
return Nonuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]{V1: v1, V2: v2, V3: v3, V4: v4, V5: v5, V6: v6, V7: v7, V8: v8, V9: v9}
|
||||||
|
}
|
||||||
|
20
go.mod
20
go.mod
@@ -8,10 +8,10 @@ require (
|
|||||||
github.com/jmoiron/sqlx v1.4.0
|
github.com/jmoiron/sqlx v1.4.0
|
||||||
github.com/rs/xid v1.6.0
|
github.com/rs/xid v1.6.0
|
||||||
github.com/rs/zerolog v1.33.0
|
github.com/rs/zerolog v1.33.0
|
||||||
go.mongodb.org/mongo-driver v1.16.1
|
go.mongodb.org/mongo-driver v1.17.1
|
||||||
golang.org/x/crypto v0.27.0
|
golang.org/x/crypto v0.28.0
|
||||||
golang.org/x/sys v0.25.0
|
golang.org/x/sys v0.26.0
|
||||||
golang.org/x/term v0.24.0
|
golang.org/x/term v0.25.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -21,7 +21,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bytedance/sonic v1.12.2 // indirect
|
github.com/bytedance/sonic v1.12.3 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||||
@@ -37,7 +37,7 @@ require (
|
|||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/uuid v1.5.0 // indirect
|
github.com/google/uuid v1.5.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // indirect
|
github.com/klauspost/compress v1.17.10 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
@@ -53,10 +53,10 @@ require (
|
|||||||
github.com/xdg-go/scram v1.1.2 // indirect
|
github.com/xdg-go/scram v1.1.2 // indirect
|
||||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||||
golang.org/x/arch v0.10.0 // indirect
|
golang.org/x/arch v0.11.0 // indirect
|
||||||
golang.org/x/image v0.20.0 // indirect
|
golang.org/x/image v0.21.0 // indirect
|
||||||
golang.org/x/net v0.29.0 // indirect
|
golang.org/x/net v0.30.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.19.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
modernc.org/libc v1.37.6 // indirect
|
modernc.org/libc v1.37.6 // indirect
|
||||||
|
22
go.sum
22
go.sum
@@ -30,6 +30,8 @@ github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX2
|
|||||||
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
|
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
|
||||||
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
|
github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU=
|
||||||
|
github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
github.com/bytedance/sonic/loader v0.1.0/go.mod h1:UmRT+IRTGKz/DAkzcEGzyVqQFJ7H9BqwBO3pm9H/+HY=
|
github.com/bytedance/sonic/loader v0.1.0/go.mod h1:UmRT+IRTGKz/DAkzcEGzyVqQFJ7H9BqwBO3pm9H/+HY=
|
||||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
@@ -138,6 +140,8 @@ github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0N
|
|||||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
|
github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
|
||||||
|
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
@@ -244,6 +248,10 @@ go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4B
|
|||||||
go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
||||||
go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8=
|
go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8=
|
||||||
go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.0 h1:Hp4q2MCjvY19ViwimTs00wHi7G4yzxh4/2+nTx8r40k=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.0/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||||
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
@@ -253,6 +261,8 @@ golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
|
|||||||
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
||||||
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
|
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
|
||||||
|
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
@@ -279,6 +289,8 @@ golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
|||||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
|
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||||
|
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||||
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
@@ -292,6 +304,8 @@ golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
|
|||||||
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
|
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
|
||||||
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
|
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
|
||||||
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
|
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
|
||||||
|
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||||
|
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -318,6 +332,8 @@ golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
|||||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||||
|
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
|
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||||
@@ -357,6 +373,8 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
|||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
|
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||||
@@ -377,6 +395,8 @@ golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
|||||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||||
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
||||||
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||||
|
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||||
|
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
@@ -393,6 +413,8 @@ golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
|||||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
|
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||||
|
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
package goext
|
package goext
|
||||||
|
|
||||||
const GoextVersion = "0.0.515"
|
const GoextVersion = "0.0.523"
|
||||||
|
|
||||||
const GoextVersionTimestamp = "2024-09-16T17:39:51+0200"
|
const GoextVersionTimestamp = "2024-10-05T01:28:46+0200"
|
||||||
|
@@ -7,6 +7,7 @@ import (
|
|||||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DB interface {
|
type DB interface {
|
||||||
@@ -57,89 +58,121 @@ func (db *database) AddListener(listener Listener) {
|
|||||||
|
|
||||||
func (db *database) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Result, error) {
|
func (db *database) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Result, error) {
|
||||||
origsql := sqlstr
|
origsql := sqlstr
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PreExecMeta{Context: ctx, TransactionConstructorContext: nil}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
err := v.PreExec(ctx, nil, &sqlstr, &prep)
|
err := v.PreExec(ctx, nil, &sqlstr, &prep, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "failed to call SQL pre-exec listener").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
return nil, exerr.Wrap(err, "failed to call SQL pre-exec listener").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
res, err := db.db.NamedExecContext(ctx, sqlstr, prep)
|
res, err := db.db.NamedExecContext(ctx, sqlstr, prep)
|
||||||
|
|
||||||
|
postMeta := PostExecMeta{Context: ctx, TransactionConstructorContext: nil, Init: t0, Start: t1, End: time.Now()}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
v.PostExec(nil, origsql, sqlstr, prep)
|
v.PostExec(nil, origsql, sqlstr, prep, err, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "Failed to [exec] sql statement").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
return nil, exerr.Wrap(err, "Failed to [exec] sql statement").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx.Rows, error) {
|
func (db *database) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx.Rows, error) {
|
||||||
origsql := sqlstr
|
origsql := sqlstr
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PreQueryMeta{Context: ctx, TransactionConstructorContext: nil}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
err := v.PreQuery(ctx, nil, &sqlstr, &prep)
|
err := v.PreQuery(ctx, nil, &sqlstr, &prep, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "failed to call SQL pre-query listener").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
return nil, exerr.Wrap(err, "failed to call SQL pre-query listener").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
rows, err := sqlx.NamedQueryContext(ctx, db.db, sqlstr, prep)
|
rows, err := sqlx.NamedQueryContext(ctx, db.db, sqlstr, prep)
|
||||||
|
|
||||||
|
postMeta := PostQueryMeta{Context: ctx, TransactionConstructorContext: nil, Init: t0, Start: t1, End: time.Now()}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
v.PostQuery(nil, origsql, sqlstr, prep)
|
v.PostQuery(nil, origsql, sqlstr, prep, err, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "Failed to [query] sql statement").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
return nil, exerr.Wrap(err, "Failed to [query] sql statement").Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows, nil
|
return rows, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) Ping(ctx context.Context) error {
|
func (db *database) Ping(ctx context.Context) error {
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PrePingMeta{Context: ctx}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
err := v.PrePing(ctx)
|
err := v.PrePing(ctx, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
err := db.db.PingContext(ctx)
|
err := db.db.PingContext(ctx)
|
||||||
|
|
||||||
|
postMeta := PostPingMeta{Context: ctx, Init: t0, Start: t1, End: time.Now()}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
v.PostPing(err)
|
v.PostPing(err, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return exerr.Wrap(err, "Failed to [ping] sql database").Build()
|
return exerr.Wrap(err, "Failed to [ping] sql database").Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) BeginTransaction(ctx context.Context, iso sql.IsolationLevel) (Tx, error) {
|
func (db *database) BeginTransaction(ctx context.Context, iso sql.IsolationLevel) (Tx, error) {
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
db.lock.Lock()
|
db.lock.Lock()
|
||||||
txid := db.txctr
|
txid := db.txctr
|
||||||
db.txctr += 1 // with overflow !
|
db.txctr += 1 // with overflow !
|
||||||
db.lock.Unlock()
|
db.lock.Unlock()
|
||||||
|
|
||||||
|
preMeta := PreTxBeginMeta{Context: ctx}
|
||||||
for _, v := range db.lstr {
|
for _, v := range db.lstr {
|
||||||
err := v.PreTxBegin(ctx, txid)
|
err := v.PreTxBegin(ctx, txid, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
xtx, err := db.db.BeginTxx(ctx, &sql.TxOptions{Isolation: iso})
|
xtx, err := db.db.BeginTxx(ctx, &sql.TxOptions{Isolation: iso})
|
||||||
|
|
||||||
|
postMeta := PostTxBeginMeta{Context: ctx, Init: t0, Start: t1, End: time.Now()}
|
||||||
|
for _, v := range db.lstr {
|
||||||
|
v.PostTxBegin(txid, err, postMeta)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "Failed to start sql transaction").Build()
|
return nil, exerr.Wrap(err, "Failed to start sql transaction").Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range db.lstr {
|
return newTransaction(ctx, xtx, txid, db), nil
|
||||||
v.PostTxBegin(txid, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewTransaction(xtx, txid, db), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) Exit() error {
|
func (db *database) Exit() error {
|
||||||
|
214
sq/listener.go
214
sq/listener.go
@@ -1,188 +1,266 @@
|
|||||||
package sq
|
package sq
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrePingMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreTxBeginMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
ConstructorContext context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreTxCommitMeta struct {
|
||||||
|
ConstructorContext context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreTxRollbackMeta struct {
|
||||||
|
ConstructorContext context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreQueryMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
TransactionConstructorContext context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreExecMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
TransactionConstructorContext context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostPingMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
Init time.Time
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostTxBeginMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
Init time.Time
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostTxCommitMeta struct {
|
||||||
|
ConstructorContext context.Context
|
||||||
|
Init time.Time
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
ExecCounter int
|
||||||
|
QueryCounter int
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostTxRollbackMeta struct {
|
||||||
|
ConstructorContext context.Context
|
||||||
|
Init time.Time
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
ExecCounter int
|
||||||
|
QueryCounter int
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostQueryMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
TransactionConstructorContext context.Context
|
||||||
|
Init time.Time
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostExecMeta struct {
|
||||||
|
Context context.Context
|
||||||
|
TransactionConstructorContext context.Context
|
||||||
|
Init time.Time
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
}
|
||||||
|
|
||||||
type Listener interface {
|
type Listener interface {
|
||||||
PrePing(ctx context.Context) error
|
PrePing(ctx context.Context, meta PrePingMeta) error
|
||||||
PreTxBegin(ctx context.Context, txid uint16) error
|
PreTxBegin(ctx context.Context, txid uint16, meta PreTxBeginMeta) error
|
||||||
PreTxCommit(txid uint16) error
|
PreTxCommit(txid uint16, meta PreTxCommitMeta) error
|
||||||
PreTxRollback(txid uint16) error
|
PreTxRollback(txid uint16, meta PreTxRollbackMeta) error
|
||||||
PreQuery(ctx context.Context, txID *uint16, sql *string, params *PP) error
|
PreQuery(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreQueryMeta) error
|
||||||
PreExec(ctx context.Context, txID *uint16, sql *string, params *PP) error
|
PreExec(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreExecMeta) error
|
||||||
|
|
||||||
PostPing(result error)
|
PostPing(result error, meta PostPingMeta)
|
||||||
PostTxBegin(txid uint16, result error)
|
PostTxBegin(txid uint16, result error, meta PostTxBeginMeta)
|
||||||
PostTxCommit(txid uint16, result error)
|
PostTxCommit(txid uint16, result error, meta PostTxCommitMeta)
|
||||||
PostTxRollback(txid uint16, result error)
|
PostTxRollback(txid uint16, result error, meta PostTxRollbackMeta)
|
||||||
PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP)
|
PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta)
|
||||||
PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP)
|
PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
type genListener struct {
|
type genListener struct {
|
||||||
prePing func(ctx context.Context) error
|
prePing func(ctx context.Context, meta PrePingMeta) error
|
||||||
preTxBegin func(ctx context.Context, txid uint16) error
|
preTxBegin func(ctx context.Context, txid uint16, meta PreTxBeginMeta) error
|
||||||
preTxCommit func(txid uint16) error
|
preTxCommit func(txid uint16, meta PreTxCommitMeta) error
|
||||||
preTxRollback func(txid uint16) error
|
preTxRollback func(txid uint16, meta PreTxRollbackMeta) error
|
||||||
preQuery func(ctx context.Context, txID *uint16, sql *string, params *PP) error
|
preQuery func(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreQueryMeta) error
|
||||||
preExec func(ctx context.Context, txID *uint16, sql *string, params *PP) error
|
preExec func(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreExecMeta) error
|
||||||
postPing func(result error)
|
postPing func(result error, meta PostPingMeta)
|
||||||
postTxBegin func(txid uint16, result error)
|
postTxBegin func(txid uint16, result error, meta PostTxBeginMeta)
|
||||||
postTxCommit func(txid uint16, result error)
|
postTxCommit func(txid uint16, result error, meta PostTxCommitMeta)
|
||||||
postTxRollback func(txid uint16, result error)
|
postTxRollback func(txid uint16, result error, meta PostTxRollbackMeta)
|
||||||
postQuery func(txID *uint16, sqlOriginal string, sqlReal string, params PP)
|
postQuery func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta)
|
||||||
postExec func(txID *uint16, sqlOriginal string, sqlReal string, params PP)
|
postExec func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PrePing(ctx context.Context) error {
|
func (g genListener) PrePing(ctx context.Context, meta PrePingMeta) error {
|
||||||
if g.prePing != nil {
|
if g.prePing != nil {
|
||||||
return g.prePing(ctx)
|
return g.prePing(ctx, meta)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PreTxBegin(ctx context.Context, txid uint16) error {
|
func (g genListener) PreTxBegin(ctx context.Context, txid uint16, meta PreTxBeginMeta) error {
|
||||||
if g.preTxBegin != nil {
|
if g.preTxBegin != nil {
|
||||||
return g.preTxBegin(ctx, txid)
|
return g.preTxBegin(ctx, txid, meta)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PreTxCommit(txid uint16) error {
|
func (g genListener) PreTxCommit(txid uint16, meta PreTxCommitMeta) error {
|
||||||
if g.preTxCommit != nil {
|
if g.preTxCommit != nil {
|
||||||
return g.preTxCommit(txid)
|
return g.preTxCommit(txid, meta)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PreTxRollback(txid uint16) error {
|
func (g genListener) PreTxRollback(txid uint16, meta PreTxRollbackMeta) error {
|
||||||
if g.preTxRollback != nil {
|
if g.preTxRollback != nil {
|
||||||
return g.preTxRollback(txid)
|
return g.preTxRollback(txid, meta)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PreQuery(ctx context.Context, txID *uint16, sql *string, params *PP) error {
|
func (g genListener) PreQuery(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreQueryMeta) error {
|
||||||
if g.preQuery != nil {
|
if g.preQuery != nil {
|
||||||
return g.preQuery(ctx, txID, sql, params)
|
return g.preQuery(ctx, txID, sql, params, meta)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PreExec(ctx context.Context, txID *uint16, sql *string, params *PP) error {
|
func (g genListener) PreExec(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreExecMeta) error {
|
||||||
if g.preExec != nil {
|
if g.preExec != nil {
|
||||||
return g.preExec(ctx, txID, sql, params)
|
return g.preExec(ctx, txID, sql, params, meta)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PostPing(result error) {
|
func (g genListener) PostPing(result error, meta PostPingMeta) {
|
||||||
if g.postPing != nil {
|
if g.postPing != nil {
|
||||||
g.postPing(result)
|
g.postPing(result, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PostTxBegin(txid uint16, result error) {
|
func (g genListener) PostTxBegin(txid uint16, result error, meta PostTxBeginMeta) {
|
||||||
if g.postTxBegin != nil {
|
if g.postTxBegin != nil {
|
||||||
g.postTxBegin(txid, result)
|
g.postTxBegin(txid, result, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PostTxCommit(txid uint16, result error) {
|
func (g genListener) PostTxCommit(txid uint16, result error, meta PostTxCommitMeta) {
|
||||||
if g.postTxCommit != nil {
|
if g.postTxCommit != nil {
|
||||||
g.postTxCommit(txid, result)
|
g.postTxCommit(txid, result, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PostTxRollback(txid uint16, result error) {
|
func (g genListener) PostTxRollback(txid uint16, result error, meta PostTxRollbackMeta) {
|
||||||
if g.postTxRollback != nil {
|
if g.postTxRollback != nil {
|
||||||
g.postTxRollback(txid, result)
|
g.postTxRollback(txid, result, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP) {
|
func (g genListener) PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta) {
|
||||||
if g.postQuery != nil {
|
if g.postQuery != nil {
|
||||||
g.postQuery(txID, sqlOriginal, sqlReal, params)
|
g.postQuery(txID, sqlOriginal, sqlReal, params, result, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g genListener) PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP) {
|
func (g genListener) PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta) {
|
||||||
if g.postExec != nil {
|
if g.postExec != nil {
|
||||||
g.postExec(txID, sqlOriginal, sqlReal, params)
|
g.postExec(txID, sqlOriginal, sqlReal, params, result, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPrePingListener(f func(ctx context.Context) error) Listener {
|
func NewPrePingListener(f func(ctx context.Context, meta PrePingMeta) error) Listener {
|
||||||
return genListener{prePing: f}
|
return genListener{prePing: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreTxBeginListener(f func(ctx context.Context, txid uint16) error) Listener {
|
func NewPreTxBeginListener(f func(ctx context.Context, txid uint16, meta PreTxBeginMeta) error) Listener {
|
||||||
return genListener{preTxBegin: f}
|
return genListener{preTxBegin: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreTxCommitListener(f func(txid uint16) error) Listener {
|
func NewPreTxCommitListener(f func(txid uint16, meta PreTxCommitMeta) error) Listener {
|
||||||
return genListener{preTxCommit: f}
|
return genListener{preTxCommit: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreTxRollbackListener(f func(txid uint16) error) Listener {
|
func NewPreTxRollbackListener(f func(txid uint16, meta PreTxRollbackMeta) error) Listener {
|
||||||
return genListener{preTxRollback: f}
|
return genListener{preTxRollback: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreQueryListener(f func(ctx context.Context, txID *uint16, sql *string, params *PP) error) Listener {
|
func NewPreQueryListener(f func(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreQueryMeta) error) Listener {
|
||||||
return genListener{preQuery: f}
|
return genListener{preQuery: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreExecListener(f func(ctx context.Context, txID *uint16, sql *string, params *PP) error) Listener {
|
func NewPreExecListener(f func(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreExecMeta) error) Listener {
|
||||||
return genListener{preExec: f}
|
return genListener{preExec: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreListener(f func(ctx context.Context, cmdtype string, txID *uint16, sql *string, params *PP) error) Listener {
|
func NewPreListener(f func(ctx context.Context, cmdtype string, txID *uint16, sql *string, params *PP) error) Listener {
|
||||||
return genListener{
|
return genListener{
|
||||||
preExec: func(ctx context.Context, txID *uint16, sql *string, params *PP) error {
|
preExec: func(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreExecMeta) error {
|
||||||
return f(ctx, "EXEC", txID, sql, params)
|
return f(ctx, "EXEC", txID, sql, params)
|
||||||
},
|
},
|
||||||
preQuery: func(ctx context.Context, txID *uint16, sql *string, params *PP) error {
|
preQuery: func(ctx context.Context, txID *uint16, sql *string, params *PP, meta PreQueryMeta) error {
|
||||||
return f(ctx, "QUERY", txID, sql, params)
|
return f(ctx, "QUERY", txID, sql, params)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostPingListener(f func(result error)) Listener {
|
func NewPostPingListener(f func(result error, meta PostPingMeta)) Listener {
|
||||||
return genListener{postPing: f}
|
return genListener{postPing: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostTxBeginListener(f func(txid uint16, result error)) Listener {
|
func NewPostTxBeginListener(f func(txid uint16, result error, meta PostTxBeginMeta)) Listener {
|
||||||
return genListener{postTxBegin: f}
|
return genListener{postTxBegin: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostTxCommitListener(f func(txid uint16, result error)) Listener {
|
func NewPostTxCommitListener(f func(txid uint16, result error, meta PostTxCommitMeta)) Listener {
|
||||||
return genListener{postTxCommit: f}
|
return genListener{postTxCommit: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostTxRollbackListener(f func(txid uint16, result error)) Listener {
|
func NewPostTxRollbackListener(f func(txid uint16, result error, meta PostTxRollbackMeta)) Listener {
|
||||||
return genListener{postTxRollback: f}
|
return genListener{postTxRollback: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostQueryListener(f func(txID *uint16, sqlOriginal string, sqlReal string, params PP)) Listener {
|
func NewPostQueryListener(f func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta)) Listener {
|
||||||
return genListener{postQuery: f}
|
return genListener{postQuery: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostExecListener(f func(txID *uint16, sqlOriginal string, sqlReal string, params PP)) Listener {
|
func NewPostExecListener(f func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta)) Listener {
|
||||||
return genListener{postExec: f}
|
return genListener{postExec: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostListener(f func(cmdtype string, txID *uint16, sqlOriginal string, sqlReal string, params PP)) Listener {
|
func NewPostListener(f func(cmdtype string, txID *uint16, sqlOriginal string, sqlReal string, result error, params PP)) Listener {
|
||||||
return genListener{
|
return genListener{
|
||||||
postExec: func(txID *uint16, sqlOriginal string, sqlReal string, params PP) {
|
postExec: func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta) {
|
||||||
f("EXEC", txID, sqlOriginal, sqlReal, params)
|
f("EXEC", txID, sqlOriginal, sqlReal, result, params)
|
||||||
},
|
},
|
||||||
postQuery: func(txID *uint16, sqlOriginal string, sqlReal string, params PP) {
|
postQuery: func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta) {
|
||||||
f("QUERY", txID, sqlOriginal, sqlReal, params)
|
f("QUERY", txID, sqlOriginal, sqlReal, result, params)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TxStatus string
|
type TxStatus string
|
||||||
@@ -26,6 +27,7 @@ type Tx interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type transaction struct {
|
type transaction struct {
|
||||||
|
constructorContext context.Context
|
||||||
tx *sqlx.Tx
|
tx *sqlx.Tx
|
||||||
id uint16
|
id uint16
|
||||||
status TxStatus
|
status TxStatus
|
||||||
@@ -34,8 +36,9 @@ type transaction struct {
|
|||||||
db *database
|
db *database
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransaction(xtx *sqlx.Tx, txid uint16, db *database) Tx {
|
func newTransaction(ctx context.Context, xtx *sqlx.Tx, txid uint16, db *database) Tx {
|
||||||
return &transaction{
|
return &transaction{
|
||||||
|
constructorContext: ctx,
|
||||||
tx: xtx,
|
tx: xtx,
|
||||||
id: txid,
|
id: txid,
|
||||||
status: TxStatusInitial,
|
status: TxStatusInitial,
|
||||||
@@ -46,42 +49,56 @@ func NewTransaction(xtx *sqlx.Tx, txid uint16, db *database) Tx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tx *transaction) Rollback() error {
|
func (tx *transaction) Rollback() error {
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PreTxRollbackMeta{ConstructorContext: tx.constructorContext}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
err := v.PreTxRollback(tx.id)
|
err := v.PreTxRollback(tx.id, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return exerr.Wrap(err, "failed to call SQL pre-rollback listener").Int("tx.id", int(tx.id)).Build()
|
return exerr.Wrap(err, "failed to call SQL pre-rollback listener").Int("tx.id", int(tx.id)).Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
result := tx.tx.Rollback()
|
result := tx.tx.Rollback()
|
||||||
|
|
||||||
if result == nil {
|
if result == nil {
|
||||||
tx.status = TxStatusRollback
|
tx.status = TxStatusRollback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postMeta := PostTxRollbackMeta{ConstructorContext: tx.constructorContext, Init: t0, Start: t1, End: time.Now(), ExecCounter: tx.execCtr, QueryCounter: tx.queryCtr}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
v.PostTxRollback(tx.id, result)
|
v.PostTxRollback(tx.id, result, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *transaction) Commit() error {
|
func (tx *transaction) Commit() error {
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PreTxCommitMeta{ConstructorContext: tx.constructorContext}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
err := v.PreTxCommit(tx.id)
|
err := v.PreTxCommit(tx.id, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return exerr.Wrap(err, "failed to call SQL pre-commit listener").Int("tx.id", int(tx.id)).Build()
|
return exerr.Wrap(err, "failed to call SQL pre-commit listener").Int("tx.id", int(tx.id)).Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
result := tx.tx.Commit()
|
result := tx.tx.Commit()
|
||||||
|
|
||||||
if result == nil {
|
if result == nil {
|
||||||
tx.status = TxStatusComitted
|
tx.status = TxStatusComitted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postMeta := PostTxCommitMeta{ConstructorContext: tx.constructorContext, Init: t0, Start: t1, End: time.Now(), ExecCounter: tx.execCtr, QueryCounter: tx.queryCtr}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
v.PostTxRollback(tx.id, result)
|
v.PostTxCommit(tx.id, result, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -89,21 +106,29 @@ func (tx *transaction) Commit() error {
|
|||||||
|
|
||||||
func (tx *transaction) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Result, error) {
|
func (tx *transaction) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Result, error) {
|
||||||
origsql := sqlstr
|
origsql := sqlstr
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PreExecMeta{Context: ctx, TransactionConstructorContext: tx.constructorContext}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
err := v.PreExec(ctx, langext.Ptr(tx.id), &sqlstr, &prep)
|
err := v.PreExec(ctx, langext.Ptr(tx.id), &sqlstr, &prep, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "failed to call SQL pre-exec listener").Int("tx.id", int(tx.id)).Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
return nil, exerr.Wrap(err, "failed to call SQL pre-exec listener").Int("tx.id", int(tx.id)).Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
res, err := tx.tx.NamedExecContext(ctx, sqlstr, prep)
|
res, err := tx.tx.NamedExecContext(ctx, sqlstr, prep)
|
||||||
|
tx.execCtr++
|
||||||
|
|
||||||
if tx.status == TxStatusInitial && err == nil {
|
if tx.status == TxStatusInitial && err == nil {
|
||||||
tx.status = TxStatusActive
|
tx.status = TxStatusActive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postMeta := PostExecMeta{Context: ctx, TransactionConstructorContext: tx.constructorContext, Init: t0, Start: t1, End: time.Now()}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
v.PostExec(langext.Ptr(tx.id), origsql, sqlstr, prep)
|
v.PostExec(langext.Ptr(tx.id), origsql, sqlstr, prep, err, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -114,21 +139,29 @@ func (tx *transaction) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Re
|
|||||||
|
|
||||||
func (tx *transaction) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx.Rows, error) {
|
func (tx *transaction) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx.Rows, error) {
|
||||||
origsql := sqlstr
|
origsql := sqlstr
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
|
||||||
|
preMeta := PreQueryMeta{Context: ctx, TransactionConstructorContext: tx.constructorContext}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
err := v.PreQuery(ctx, langext.Ptr(tx.id), &sqlstr, &prep)
|
err := v.PreQuery(ctx, langext.Ptr(tx.id), &sqlstr, &prep, preMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "failed to call SQL pre-query listener").Int("tx.id", int(tx.id)).Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
return nil, exerr.Wrap(err, "failed to call SQL pre-query listener").Int("tx.id", int(tx.id)).Str("original_sql", origsql).Str("sql", sqlstr).Any("sql_params", prep).Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
|
||||||
rows, err := sqlx.NamedQueryContext(ctx, tx.tx, sqlstr, prep)
|
rows, err := sqlx.NamedQueryContext(ctx, tx.tx, sqlstr, prep)
|
||||||
|
tx.queryCtr++
|
||||||
|
|
||||||
if tx.status == TxStatusInitial && err == nil {
|
if tx.status == TxStatusInitial && err == nil {
|
||||||
tx.status = TxStatusActive
|
tx.status = TxStatusActive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postMeta := PostQueryMeta{Context: ctx, TransactionConstructorContext: tx.constructorContext, Init: t0, Start: t1, End: time.Now()}
|
||||||
for _, v := range tx.db.lstr {
|
for _, v := range tx.db.lstr {
|
||||||
v.PostQuery(langext.Ptr(tx.id), origsql, sqlstr, prep)
|
v.PostQuery(langext.Ptr(tx.id), origsql, sqlstr, prep, err, postMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user