Compare commits

...

4 Commits

Author SHA1 Message Date
335ef4d8e8 v0.0.523 ringbuffer
Some checks failed
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m23s
2024-10-05 01:28:46 +02:00
61801ff20d v0.0.522
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 2m53s
2024-10-05 01:12:00 +02:00
361dca5c85 v0.0.521 ctxext
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 2m56s
2024-10-05 01:06:36 +02:00
9f85a243e8 v0.0.520
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 4m7s
2024-10-05 01:02:25 +02:00
7 changed files with 177 additions and 46 deletions

View File

@@ -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
View 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
}
}

92
dataext/ringBuffer.go Normal file
View 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
}
}
}
}

View File

@@ -1,5 +1,5 @@
package goext package goext
const GoextVersion = "0.0.519" const GoextVersion = "0.0.523"
const GoextVersionTimestamp = "2024-10-05T00:58:15+0200" const GoextVersionTimestamp = "2024-10-05T01:28:46+0200"

View File

@@ -61,7 +61,7 @@ func (db *database) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Resul
t0 := time.Now() t0 := time.Now()
preMeta := PreExecMeta{} preMeta := PreExecMeta{Context: ctx, TransactionConstructorContext: nil}
for _, v := range db.lstr { for _, v := range db.lstr {
err := v.PreExec(ctx, nil, &sqlstr, &prep, preMeta) err := v.PreExec(ctx, nil, &sqlstr, &prep, preMeta)
if err != nil { if err != nil {
@@ -73,9 +73,9 @@ func (db *database) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Resul
res, err := db.db.NamedExecContext(ctx, sqlstr, prep) res, err := db.db.NamedExecContext(ctx, sqlstr, prep)
postMeta := PostExecMeta{Init: t0, Start: t1, End: time.Now()} 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, postMeta) v.PostExec(nil, origsql, sqlstr, prep, err, postMeta)
} }
if err != nil { if err != nil {
@@ -90,7 +90,7 @@ func (db *database) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx.Ro
t0 := time.Now() t0 := time.Now()
preMeta := PreQueryMeta{} preMeta := PreQueryMeta{Context: ctx, TransactionConstructorContext: nil}
for _, v := range db.lstr { for _, v := range db.lstr {
err := v.PreQuery(ctx, nil, &sqlstr, &prep, preMeta) err := v.PreQuery(ctx, nil, &sqlstr, &prep, preMeta)
if err != nil { if err != nil {
@@ -102,9 +102,9 @@ func (db *database) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx.Ro
rows, err := sqlx.NamedQueryContext(ctx, db.db, sqlstr, prep) rows, err := sqlx.NamedQueryContext(ctx, db.db, sqlstr, prep)
postMeta := PostQueryMeta{Init: t0, Start: t1, End: time.Now()} 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, postMeta) v.PostQuery(nil, origsql, sqlstr, prep, err, postMeta)
} }
if err != nil { if err != nil {
@@ -118,7 +118,7 @@ func (db *database) Ping(ctx context.Context) error {
t0 := time.Now() t0 := time.Now()
preMeta := PrePingMeta{} preMeta := PrePingMeta{Context: ctx}
for _, v := range db.lstr { for _, v := range db.lstr {
err := v.PrePing(ctx, preMeta) err := v.PrePing(ctx, preMeta)
if err != nil { if err != nil {
@@ -130,7 +130,7 @@ func (db *database) Ping(ctx context.Context) error {
err := db.db.PingContext(ctx) err := db.db.PingContext(ctx)
postMeta := PostPingMeta{Init: t0, Start: t1, End: time.Now()} postMeta := PostPingMeta{Context: ctx, Init: t0, Start: t1, End: time.Now()}
for _, v := range db.lstr { for _, v := range db.lstr {
v.PostPing(err, postMeta) v.PostPing(err, postMeta)
} }
@@ -151,7 +151,7 @@ func (db *database) BeginTransaction(ctx context.Context, iso sql.IsolationLevel
db.txctr += 1 // with overflow ! db.txctr += 1 // with overflow !
db.lock.Unlock() db.lock.Unlock()
preMeta := PreTxBeginMeta{} preMeta := PreTxBeginMeta{Context: ctx}
for _, v := range db.lstr { for _, v := range db.lstr {
err := v.PreTxBegin(ctx, txid, preMeta) err := v.PreTxBegin(ctx, txid, preMeta)
if err != nil { if err != nil {
@@ -163,7 +163,7 @@ func (db *database) BeginTransaction(ctx context.Context, iso sql.IsolationLevel
xtx, err := db.db.BeginTxx(ctx, &sql.TxOptions{Isolation: iso}) xtx, err := db.db.BeginTxx(ctx, &sql.TxOptions{Isolation: iso})
postMeta := PostTxBeginMeta{Init: t0, Start: t1, End: time.Now()} postMeta := PostTxBeginMeta{Context: ctx, Init: t0, Start: t1, End: time.Now()}
for _, v := range db.lstr { for _, v := range db.lstr {
v.PostTxBegin(txid, err, postMeta) v.PostTxBegin(txid, err, postMeta)
} }

View File

@@ -6,9 +6,11 @@ import (
) )
type PrePingMeta struct { type PrePingMeta struct {
Context context.Context
} }
type PreTxBeginMeta struct { type PreTxBeginMeta struct {
Context context.Context
ConstructorContext context.Context ConstructorContext context.Context
} }
@@ -21,22 +23,27 @@ type PreTxRollbackMeta struct {
} }
type PreQueryMeta struct { type PreQueryMeta struct {
Context context.Context
TransactionConstructorContext context.Context
} }
type PreExecMeta struct { type PreExecMeta struct {
Context context.Context
TransactionConstructorContext context.Context
} }
type PostPingMeta struct { type PostPingMeta struct {
Init time.Time Context context.Context
Start time.Time Init time.Time
End time.Time Start time.Time
End time.Time
} }
type PostTxBeginMeta struct { type PostTxBeginMeta struct {
ConstructorContext context.Context Context context.Context
Init time.Time Init time.Time
Start time.Time Start time.Time
End time.Time End time.Time
} }
type PostTxCommitMeta struct { type PostTxCommitMeta struct {
@@ -58,15 +65,19 @@ type PostTxRollbackMeta struct {
} }
type PostQueryMeta struct { type PostQueryMeta struct {
Init time.Time Context context.Context
Start time.Time TransactionConstructorContext context.Context
End time.Time Init time.Time
Start time.Time
End time.Time
} }
type PostExecMeta struct { type PostExecMeta struct {
Init time.Time Context context.Context
Start time.Time TransactionConstructorContext context.Context
End time.Time Init time.Time
Start time.Time
End time.Time
} }
type Listener interface { type Listener interface {
@@ -81,8 +92,8 @@ type Listener interface {
PostTxBegin(txid uint16, result error, meta PostTxBeginMeta) PostTxBegin(txid uint16, result error, meta PostTxBeginMeta)
PostTxCommit(txid uint16, result error, meta PostTxCommitMeta) PostTxCommit(txid uint16, result error, meta PostTxCommitMeta)
PostTxRollback(txid uint16, result error, meta PostTxRollbackMeta) PostTxRollback(txid uint16, result error, meta PostTxRollbackMeta)
PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostQueryMeta) PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta)
PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostExecMeta) PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta)
} }
type genListener struct { type genListener struct {
@@ -96,8 +107,8 @@ type genListener struct {
postTxBegin func(txid uint16, result error, meta PostTxBeginMeta) postTxBegin func(txid uint16, result error, meta PostTxBeginMeta)
postTxCommit func(txid uint16, result error, meta PostTxCommitMeta) postTxCommit func(txid uint16, result error, meta PostTxCommitMeta)
postTxRollback func(txid uint16, result error, meta PostTxRollbackMeta) postTxRollback func(txid uint16, result error, meta PostTxRollbackMeta)
postQuery func(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostQueryMeta) postQuery func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostQueryMeta)
postExec func(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostExecMeta) postExec func(txID *uint16, sqlOriginal string, sqlReal string, params PP, result error, meta PostExecMeta)
} }
func (g genListener) PrePing(ctx context.Context, meta PrePingMeta) error { func (g genListener) PrePing(ctx context.Context, meta PrePingMeta) error {
@@ -172,15 +183,15 @@ func (g genListener) PostTxRollback(txid uint16, result error, meta PostTxRollba
} }
} }
func (g genListener) PostQuery(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostQueryMeta) { 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, meta) g.postQuery(txID, sqlOriginal, sqlReal, params, result, meta)
} }
} }
func (g genListener) PostExec(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostExecMeta) { 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, meta) g.postExec(txID, sqlOriginal, sqlReal, params, result, meta)
} }
} }
@@ -235,21 +246,21 @@ func NewPostTxRollbackListener(f func(txid uint16, result error, meta PostTxRoll
return genListener{postTxRollback: f} return genListener{postTxRollback: f}
} }
func NewPostQueryListener(f func(txID *uint16, sqlOriginal string, sqlReal string, params PP, meta PostQueryMeta)) 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, meta PostExecMeta)) 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, meta PostExecMeta) { 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, meta PostQueryMeta) { 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)
}, },
} }
} }

View File

@@ -109,7 +109,7 @@ func (tx *transaction) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Re
t0 := time.Now() t0 := time.Now()
preMeta := PreExecMeta{} 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, preMeta) err := v.PreExec(ctx, langext.Ptr(tx.id), &sqlstr, &prep, preMeta)
if err != nil { if err != nil {
@@ -126,9 +126,9 @@ func (tx *transaction) Exec(ctx context.Context, sqlstr string, prep PP) (sql.Re
tx.status = TxStatusActive tx.status = TxStatusActive
} }
postMeta := PostExecMeta{Init: t0, Start: t1, End: time.Now()} 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, postMeta) v.PostExec(langext.Ptr(tx.id), origsql, sqlstr, prep, err, postMeta)
} }
if err != nil { if err != nil {
@@ -142,7 +142,7 @@ func (tx *transaction) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx
t0 := time.Now() t0 := time.Now()
preMeta := PreQueryMeta{} 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, preMeta) err := v.PreQuery(ctx, langext.Ptr(tx.id), &sqlstr, &prep, preMeta)
if err != nil { if err != nil {
@@ -159,9 +159,9 @@ func (tx *transaction) Query(ctx context.Context, sqlstr string, prep PP) (*sqlx
tx.status = TxStatusActive tx.status = TxStatusActive
} }
postMeta := PostQueryMeta{Init: t0, Start: t1, End: time.Now()} 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, postMeta) v.PostQuery(langext.Ptr(tx.id), origsql, sqlstr, prep, err, postMeta)
} }
if err != nil { if err != nil {