From 8c27f0be854f69067856f40cba8da0d3703c801f Mon Sep 17 00:00:00 2001 From: Seth Shelnutt Date: Wed, 1 Jun 2022 13:47:07 -0400 Subject: [PATCH 1/2] NewContext should use tiledb_ctx_alloc_with_error This allows capturing any errors on alloc of the context. --- context.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/context.go b/context.go index 184e8b5b..a0dc0fca 100644 --- a/context.go +++ b/context.go @@ -4,6 +4,7 @@ package tiledb #cgo LDFLAGS: -ltiledb #cgo linux LDFLAGS: -ldl #include +#include #include */ import "C" @@ -28,13 +29,25 @@ type Context struct { func NewContext(config *Config) (*Context, error) { var context Context var ret C.int32_t + var tdbErr *C.tiledb_error_t if config != nil { - ret = C.tiledb_ctx_alloc(config.tiledbConfig, &context.tiledbContext) + ret = C.tiledb_ctx_alloc_with_error(config.tiledbConfig, &context.tiledbContext, &tdbErr) } else { - ret = C.tiledb_ctx_alloc(nil, &context.tiledbContext) + ret = C.tiledb_ctx_alloc_with_error(nil, &context.tiledbContext, &tdbErr) } if ret != C.TILEDB_OK { - return nil, fmt.Errorf("error creating tiledb context: %w", context.LastError()) + // If the error isn't null report this + if tdbErr != nil { + var msg *C.char + C.tiledb_error_message(tdbErr, &msg) + defer C.tiledb_error_free(&tdbErr) + return nil, fmt.Errorf("error creating tiledb context: %s", C.GoString(msg)) + } + // If the context is not null see if the error exists there + if context.tiledbContext != nil { + return nil, fmt.Errorf("error creating tiledb context: %w", context.LastError()) + } + return nil, fmt.Errorf("error creating tiledb context: unknown error") } // Set finalizer for free C pointer on gc From 53e5e08b77681a4029174b58bda25beef98729f3 Mon Sep 17 00:00:00 2001 From: Paul Fisher Date: Wed, 22 Jun 2022 12:39:07 -0400 Subject: [PATCH 2/2] Create experimental and non-experimental makeContext functions. --- context.go | 30 +++++----------------------- context_new.go | 30 ++++++++++++++++++++++++++++ context_new_experimental.go | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 context_new.go create mode 100644 context_new_experimental.go diff --git a/context.go b/context.go index a0dc0fca..24f93720 100644 --- a/context.go +++ b/context.go @@ -27,40 +27,20 @@ type Context struct { // NewContext creates a TileDB context with the given configuration // If the configuration passed is null it is created with default config func NewContext(config *Config) (*Context, error) { - var context Context - var ret C.int32_t - var tdbErr *C.tiledb_error_t - if config != nil { - ret = C.tiledb_ctx_alloc_with_error(config.tiledbConfig, &context.tiledbContext, &tdbErr) - } else { - ret = C.tiledb_ctx_alloc_with_error(nil, &context.tiledbContext, &tdbErr) - } - if ret != C.TILEDB_OK { - // If the error isn't null report this - if tdbErr != nil { - var msg *C.char - C.tiledb_error_message(tdbErr, &msg) - defer C.tiledb_error_free(&tdbErr) - return nil, fmt.Errorf("error creating tiledb context: %s", C.GoString(msg)) - } - // If the context is not null see if the error exists there - if context.tiledbContext != nil { - return nil, fmt.Errorf("error creating tiledb context: %w", context.LastError()) - } - return nil, fmt.Errorf("error creating tiledb context: unknown error") + context, err := makeContext(config) + if err != nil { + return nil, err } - // Set finalizer for free C pointer on gc runtime.SetFinalizer(&context, func(context *Context) { context.Free() }) - err := context.setDefaultTags() - if err != nil { + if err := context.setDefaultTags(); err != nil { return nil, fmt.Errorf("error creating tiledb context: %w", err) } - return &context, nil + return context, nil } // NewContextFromMap creates a TileDB context with the given configuration. diff --git a/context_new.go b/context_new.go new file mode 100644 index 00000000..9b111866 --- /dev/null +++ b/context_new.go @@ -0,0 +1,30 @@ +//go:build !experimental + +package tiledb + +/* +#cgo LDFLAGS: -ltiledb +#cgo linux LDFLAGS: -ldl +#include +#include +*/ +import "C" +import "fmt" + +// makeContext wraps the internals of context making. It is separated out +// so the functions which use experimental APIs are separate from those +// that do not. +func makeContext(config *Config) (*Context, error) { + context := &Context{} + var ret C.int32_t + + if config != nil { + ret = C.tiledb_ctx_alloc(config.tiledbConfig, &context.tiledbContext) + } else { + ret = C.tiledb_ctx_alloc(nil, &context.tiledbContext) + } + if ret != C.TILEDB_OK { + return nil, fmt.Errorf("error creating tiledb context: %w", context.LastError()) + } + return context, nil +} diff --git a/context_new_experimental.go b/context_new_experimental.go new file mode 100644 index 00000000..d2db47c5 --- /dev/null +++ b/context_new_experimental.go @@ -0,0 +1,39 @@ +//go:build experimental + +package tiledb + +/* +#cgo LDFLAGS: -ltiledb +#cgo linux LDFLAGS: -ldl +#include +#include +#include +*/ +import "C" +import "fmt" + +func makeContext(config *Config) (*Context, error) { + context := &Context{} + var ret C.int32_t + var tdbErr *C.tiledb_error_t + if config != nil { + ret = C.tiledb_ctx_alloc_with_error(config.tiledbConfig, &context.tiledbContext, &tdbErr) + } else { + ret = C.tiledb_ctx_alloc_with_error(nil, &context.tiledbContext, &tdbErr) + } + if ret != C.TILEDB_OK { + // If the error isn't null report this + if tdbErr != nil { + var msg *C.char + C.tiledb_error_message(tdbErr, &msg) + defer C.tiledb_error_free(&tdbErr) + return nil, fmt.Errorf("error creating tiledb context: %s", C.GoString(msg)) + } + // If the context is not null see if the error exists there + if context.tiledbContext != nil { + return nil, fmt.Errorf("error creating tiledb context: %w", context.LastError()) + } + return nil, fmt.Errorf("error creating tiledb context: unknown error") + } + return context, nil +}