-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0be9991
commit 1707863
Showing
29 changed files
with
344 additions
and
313 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package pointer | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestToValue(t *testing.T) { | ||
t.Run("non-nil pointer", func(t *testing.T) { | ||
value := 42 | ||
ptr := &value | ||
defaultValue := 0 | ||
|
||
result := ToValue(ptr, defaultValue) | ||
|
||
assert.Equal(t, value, result, "ToValue should return the pointed-to value for non-nil pointers") | ||
}) | ||
|
||
t.Run("nil pointer", func(t *testing.T) { | ||
var ptr *int | ||
defaultValue := 10 | ||
|
||
result := ToValue(ptr, defaultValue) | ||
|
||
assert.Equal(t, defaultValue, result, "ToValue should return the default value for nil pointers") | ||
}) | ||
} | ||
|
||
func TestFromValue(t *testing.T) { | ||
t.Run("integer value", func(t *testing.T) { | ||
value := 42 | ||
|
||
result := FromValue(value) | ||
|
||
assert.NotNil(t, result, "FromValue should return a non-nil pointer") | ||
assert.Equal(t, value, *result, "FromValue should return a pointer to the correct value") | ||
}) | ||
|
||
t.Run("string value", func(t *testing.T) { | ||
value := "hello" | ||
|
||
result := FromValue(value) | ||
|
||
assert.NotNil(t, result, "FromValue should return a non-nil pointer") | ||
assert.Equal(t, value, *result, "FromValue should return a pointer to the correct value") | ||
}) | ||
|
||
t.Run("struct value", func(t *testing.T) { | ||
type TestStruct struct { | ||
Field string | ||
} | ||
value := TestStruct{Field: "test"} | ||
|
||
result := FromValue(value) | ||
|
||
assert.NotNil(t, result, "FromValue should return a non-nil pointer") | ||
assert.Equal(t, value, *result, "FromValue should return a pointer to the correct value") | ||
}) | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Empty file.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package sqldb | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net/http" | ||
|
||
"github.com/jackc/pgx/v5/pgxpool" | ||
"go.inout.gg/foundations/http/httpmiddleware" | ||
) | ||
|
||
type ctxKey struct{} | ||
|
||
var kCtxKey = ctxKey{} | ||
|
||
var ErrDBPoolNotFound = errors.New("foundations/sqldb: failed to retrieve db pool from context.") | ||
|
||
// WithContext returns a new context with the given pool. | ||
func WithContext(ctx context.Context, pool *pgxpool.Pool) context.Context { | ||
return context.WithValue(ctx, kCtxKey, pool) | ||
} | ||
|
||
// FromContext returns the pool associated with the given context. | ||
func FromContext(ctx context.Context) (*pgxpool.Pool, error) { | ||
if pool, ok := ctx.Value(kCtxKey).(*pgxpool.Pool); ok { | ||
return pool, nil | ||
} | ||
|
||
return nil, ErrDBPoolNotFound | ||
} | ||
|
||
// FromRequest returns the pool associated with the given http request. | ||
func FromRequest(req *http.Request) (*pgxpool.Pool, error) { | ||
return FromContext(req.Context()) | ||
} | ||
|
||
// Middleware returns a middleware that injects the given pool into the request context. | ||
func Middleware(db *pgxpool.Pool) httpmiddleware.MiddlewareFunc { | ||
return func(next http.Handler) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { | ||
next.ServeHTTP(w, req.WithContext(WithContext(req.Context(), db))) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package sqldb | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/jackc/pgx/v5" | ||
"github.com/jackc/pgx/v5/pgxpool" | ||
"go.inout.gg/foundations/must" | ||
"go.inout.gg/foundations/sqldb/internal/pgxuuid" | ||
) | ||
|
||
// WithTracer sets the query tracer for the database pool. | ||
func WithTracer(t pgx.QueryTracer) func(c *pgxpool.Config) { | ||
return func(c *pgxpool.Config) { c.ConnConfig.Tracer = t } | ||
} | ||
|
||
// WithUUID adds native support for converting between Postgres UUID and google/uuid. | ||
func WithUUID() func(c *pgxpool.Config) { | ||
return func(c *pgxpool.Config) { | ||
origAfterConnect := c.AfterConnect | ||
c.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error { | ||
pgxuuid.Register(conn.TypeMap()) | ||
if origAfterConnect != nil { | ||
return origAfterConnect(ctx, conn) | ||
} | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
// MustPool creates a new connection pool and panics on error. | ||
func MustPool(ctx context.Context, connString string, cfgs ...func(*pgxpool.Config)) *pgxpool.Pool { | ||
return must.Must(NewPool(ctx, connString, cfgs...)) | ||
} | ||
|
||
// NewPool creates a new connection pool using the provided connection string. | ||
// | ||
// Optional cfgs like WithUUID or WithTracer can be provided. | ||
func NewPool(ctx context.Context, connString string, cfgs ...func(*pgxpool.Config)) (pool *pgxpool.Pool, err error) { | ||
config, err := pgxpool.ParseConfig(connString) | ||
if err != nil { | ||
return nil, fmt.Errorf("foundations/sqldb: failed to parse database connection string: %w", err) | ||
} | ||
for _, f := range cfgs { | ||
f(config) | ||
} | ||
|
||
pool, err = pgxpool.NewWithConfig(ctx, config) | ||
if err != nil { | ||
return nil, fmt.Errorf("foundations/sqldb: failed to create a new database pool: %w", err) | ||
} | ||
defer func() { | ||
if err != nil { | ||
if pool != nil { | ||
pool.Close() | ||
} | ||
} | ||
}() | ||
|
||
if err = pool.Ping(ctx); err != nil { | ||
return nil, fmt.Errorf("foundations/sqldb: failed to connect to the database at %s: %w", connString, err) | ||
} | ||
|
||
return pool, nil | ||
} |
File renamed without changes.
File renamed without changes.
Oops, something went wrong.