Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions pkg/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package database

import (
"context"
"fmt"

"github.com/go-playground/validator/v10"
)
Expand All @@ -10,15 +11,22 @@ type DatabaseInterface interface {
Ping(context.Context) error
Find(ctx context.Context, db string, collection string, filter any, opts ...any) (any, error)
FindOne(ctx context.Context, db string, collection string, filter any, opts ...any) (any, error)
Disconnect(ctx context.Context) error
InsertOne(ctx context.Context, db string, collection string, document any, opts ...any) (any, error)
InsertMany(ctx context.Context, db string, collection string, documents []any, opts ...any) (any, error)
}

type DatabaseOptions interface {
Validate() error
}

// Database represents a database client instance
type Database struct {
Options *MongoOptions
Options DatabaseOptions
Client DatabaseInterface
}

func New(opts *MongoOptions, client ...DatabaseInterface) (*Database, error) {
func New(opts DatabaseOptions, client ...DatabaseInterface) (*Database, error) {
// Validate Database configuration
validate := validator.New()
err := validate.Struct(opts)
Expand All @@ -29,7 +37,12 @@ func New(opts *MongoOptions, client ...DatabaseInterface) (*Database, error) {
// If no client provided, create default production client
var m DatabaseInterface
if len(client) == 0 {
m, err = NewMongoClient(opts)
// Type assert to RabbitOptions for creating RabbitMQ client
if mongoOpts, ok := opts.(*MongoOptions); ok {
m, err = NewMongoClient(mongoOpts)
} else {
return nil, fmt.Errorf("unsupported queue options type")
}
} else {
m, err = client[0], nil
}
Expand Down
15 changes: 15 additions & 0 deletions pkg/database/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ func (m *MockDatabase) Ping(ctx context.Context) error {
return nil
}

// Disconnect implements DatabaseInterface
func (m *MockDatabase) Disconnect(ctx context.Context) error {
return nil
}

// Find implements DatabaseInterface
func (m *MockDatabase) Find(ctx context.Context, db string, collection string, filter any, opts ...any) (any, error) {
m.FindCalls = append(m.FindCalls, FindCall{
Expand Down Expand Up @@ -154,6 +159,16 @@ func (m *MockDatabase) FindOne(ctx context.Context, db string, collection string
return nil, fmt.Errorf("no document found")
}

// InsertOne implements DatabaseInterface
func (m *MockDatabase) InsertOne(ctx context.Context, db string, collection string, document any, opts ...any) (any, error) {
return nil, fmt.Errorf("InsertOne not implemented in MockDatabase")
}

// InsertMany implements DatabaseInterface
func (m *MockDatabase) InsertMany(ctx context.Context, db string, collection string, documents []any, opts ...any) (any, error) {
return nil, fmt.Errorf("InsertMany not implemented in MockDatabase")
}

// Reset clears all recorded calls
func (m *MockDatabase) Reset() {
m.PingCalls = []PingCall{}
Expand Down
36 changes: 36 additions & 0 deletions pkg/database/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"time"

"github.com/go-playground/validator/v10"
"go.mongodb.org/mongo-driver/mongo"
moptions "go.mongodb.org/mongo-driver/mongo/options"
"go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo"
Expand All @@ -23,6 +24,12 @@ type MongoOptions struct {
RetryWrites bool
}

// Validate validates the MongoOptions configuration
func (m *MongoOptions) Validate() error {
validate := validator.New()
return validate.Struct(m)
}

// MongoOptionsBuilder provides a fluent interface for building Mongo options
type MongoOptionsBuilder struct {
options *MongoOptions
Expand Down Expand Up @@ -173,6 +180,11 @@ func (m *MongoClient) Ping(ctx context.Context) error {
return err
}

// Disconnect disconnects the MongoDB client
func (m *MongoClient) Disconnect(ctx context.Context) error {
return m.Client.Disconnect(ctx)
}

// Find executes a find query on the specified database and collection
func (m *MongoClient) Find(ctx context.Context, db string, collection string, filter any, opts ...any) (any, error) {
coll := m.Client.Database(db).Collection(collection)
Expand Down Expand Up @@ -219,3 +231,27 @@ func (m *MongoClient) FindOne(ctx context.Context, db string, collection string,

return result, nil
}

// InsertOne inserts a single document into the specified database and collection
func (m *MongoClient) InsertOne(ctx context.Context, db string, collection string, document any, opts ...any) (any, error) {
coll := m.Client.Database(db).Collection(collection)

result, err := coll.InsertOne(ctx, document)
if err != nil {
return nil, err
}

return result.InsertedID, nil
}

// InsertMany inserts multiple documents into the specified database and collection
func (m *MongoClient) InsertMany(ctx context.Context, db string, collection string, documents []any, opts ...any) (any, error) {
coll := m.Client.Database(db).Collection(collection)

result, err := coll.InsertMany(ctx, documents)
if err != nil {
return nil, err
}

return result.InsertedIDs, nil
}
8 changes: 6 additions & 2 deletions pkg/database/mongodb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ func TestMongodbLiveIntegration(t *testing.T) {
t.Fatalf("failed to create database instance: %v", err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(db.Options.Timeout)*time.Millisecond)
options := db.Options.(*MongoOptions)

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(options.Timeout)*time.Millisecond)
defer cancel()

err = db.Client.Ping(ctx)
Expand Down Expand Up @@ -301,7 +303,9 @@ func TestFindIntegration(t *testing.T) {
t.Fatalf("failed to create database instance: %v", err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(db.Options.Timeout)*time.Millisecond)
options := db.Options.(*MongoOptions)

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(options.Timeout)*time.Millisecond)
defer cancel()

// Test Find with username filter
Expand Down
Loading