https://github.com/kjh03160/go-mongo/pull/25/files
이전에 고민했던 부분을 어느정도 정리를 했다.
Is~Err()
방식으로 할지우선 결론을 말하자면 Is~Err()
방식을 취하기로 했다.
Is~Err()
방식은 IsInternalErr()
에서 위의 에러들을 type switch로 같이 잡아낼 수 있었다.func IsDBInternalErr(err error) bool {
switch err.(type) {
case *internalError,
*timeoutError,
*mongoClientError:
return true
default:
return false
}
}
이것은 not matched는 남겨두기로 했고, not modified는 삭제하기로 했다.
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
}