https://github.com/kjh03160/go-mongo/pull/25/files

이전에 고민했던 부분을 어느정도 정리를 했다.

error check하는 것을 reflect 방식 vs Is~Err() 방식으로 할지

우선 결론을 말하자면 Is~Err() 방식을 취하기로 했다.

func IsDBInternalErr(err error) bool {
	switch err.(type) {
	case *internalError,
		*timeoutError,
		*mongoClientError:
		return true
	default:
		return false
	}
}

not matched, not modified error 정리

이것은 not matched는 남겨두기로 했고, not modified는 삭제하기로 했다.

cursor decode 방식

cursor.All() / reflect 방식을 고민했었는데, go 버전이 1.18로 되면서 generic이 추가되었고, generic을 사용하면 앞의 2가지 방식을 고민할 필요가 없었다.

// mongo/operation.go
type Collection[T any] struct {
	*mongo.Collection
}

func MakeCollection[T any](mongoManager *Client, databaseName, collectionName string) *Collection[T] {
	collection := mongoManager.GetCollection(databaseName, collectionName)
	return &Collection[T]{Collection: collection}
}
// mongo/decode.go

func DecodeCursor[T any](cursor *mongo.Cursor) ([]T, error) {
	defer cursor.Close(context.Background())
	var slice []T
	for cursor.Next(context.Background()) {
		var doc T
		if err := cursor.Decode(&doc); err != nil {
			return nil, err
		}
		slice = append(slice, doc)
	}
	return slice, nil
}
// mongo/wrapper.go
func (col *Collection[T]) FindAll(filter interface{}, opts ...*options.FindOptions) ([]T, error) {
	ctx, ctxCancel := context.WithTimeout(context.Background(), DB_TIMEOUT)
	defer ctxCancel()
	cursor, err := col.findAll(ctx, filter, opts...)
	if err != nil {
		return nil, errorType.ParseAndReturnDBError(err, col.Name(), filter, nil, nil)
	}
	resultSlice, err := DecodeCursor[T](cursor)
	if err != nil {
		return nil, errorType.DecodeError(col.Name(), filter, nil, nil, err)
	}
	return resultSlice, nil
}