Skip to content

Commit

Permalink
Merge pull request #103 from TileDB-Inc/ss/unsafe-set-buffer
Browse files Browse the repository at this point in the history
Add new function for setting buffers directly with pointers
  • Loading branch information
Shelnutt2 authored Feb 11, 2020
2 parents d2e04f2 + 0210977 commit aff5641
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 3 deletions.
40 changes: 40 additions & 0 deletions enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ package tiledb
#include <tiledb/tiledb.h>
#include <tiledb/tiledb_enum.h>
#include <tiledb/tiledb_serialization.h>
#include <stdlib.h>
*/
import "C"

import (
"encoding/json"
"fmt"
"reflect"
"unsafe"
Expand Down Expand Up @@ -94,6 +96,44 @@ const (
TILEDB_DATETIME_AS Datatype = C.TILEDB_DATETIME_AS
)

// String returns string representation
func (d Datatype) String() string {
var cname *C.char
defer C.free(unsafe.Pointer(cname))
C.tiledb_datatype_to_str(C.tiledb_datatype_t(d), &cname)
return C.GoString(cname)
}

// MarshalJSON interface for marshaling to json
func (d Datatype) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}

// UnmarshalJSON interface for unmarshaling from json
func (d *Datatype) UnmarshalJSON(bytes []byte) error {
return d.FromString(string(bytes))
}

// FromString converts from a datatype string to enum
func (d *Datatype) FromString(s string) error {
cname := C.CString(s)
defer C.free(unsafe.Pointer(cname))
var cDatatype C.tiledb_datatype_t
ret := C.tiledb_datatype_from_str(cname, &cDatatype)
if ret != C.TILEDB_OK {
return fmt.Errorf("%s is not a recognized tiledb_datatype_t", s)
}
*d = Datatype(cDatatype)
return nil
}

// DatatypeFromString converts from a datatype string to enum
func DatatypeFromString(s string) Datatype {
var d Datatype
d.FromString(s)
return d
}

// ReflectKind returns the reflect kind given a datatype
func (d Datatype) ReflectKind() reflect.Kind {
switch d {
Expand Down
54 changes: 51 additions & 3 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,30 @@ func (q *Query) SetSubArray(subArray interface{}) error {
return nil
}

// SetBufferUnsafe Sets the buffer for a fixed-sized attribute to a query
// This takes an unsafe pointer which is passsed straight to tiledb c_api
// for advanced useage
func (q *Query) SetBufferUnsafe(attribute string, buffer unsafe.Pointer, bufferSize uint64) (*uint64, error) {
cAttribute := C.CString(attribute)
defer C.free(unsafe.Pointer(cAttribute))

ret := C.tiledb_query_set_buffer(
q.context.tiledbContext,
q.tiledbQuery,
cAttribute,
buffer,
(*C.uint64_t)(unsafe.Pointer(&bufferSize)))

if ret != C.TILEDB_OK {
return nil, fmt.Errorf(
"Error setting query buffer: %s", q.context.LastError())
}

q.resultBufferElements[attribute] = [2]*uint64{nil, &bufferSize}

return &bufferSize, nil
}

// SetBuffer Sets the buffer for a fixed-sized attribute to a query
// The buffer must be an initialized slice
func (q *Query) SetBuffer(attribute string, buffer interface{}) (*uint64,
Expand Down Expand Up @@ -777,10 +801,34 @@ func (q *Query) Buffer(attributeName string) (interface{}, error) {
return buffer, nil
}

// SetBufferVar Sets the buffer for a fixed-sized attribute to a query
// SetBufferVarUnsafe Sets the buffer for a variable sized attribute to a query
// This takes unsafe pointers which is passsed straight to tiledb c_api
// for advanced useage
func (q *Query) SetBufferVarUnsafe(attribute string, offset unsafe.Pointer, offsetSize uint64, buffer unsafe.Pointer, bufferSize uint64) (*uint64, *uint64, error) {
cAttribute := C.CString(attribute)
defer C.free(unsafe.Pointer(cAttribute))

ret := C.tiledb_query_set_buffer_var(
q.context.tiledbContext,
q.tiledbQuery,
cAttribute,
(*C.uint64_t)(offset),
(*C.uint64_t)(unsafe.Pointer(&offsetSize)),
buffer,
(*C.uint64_t)(unsafe.Pointer(&bufferSize)))

if ret != C.TILEDB_OK {
return nil, nil, fmt.Errorf("Error setting query var buffer: %s", q.context.LastError())
}

q.resultBufferElements[attribute] = [2]*uint64{&offsetSize, &bufferSize}

return &offsetSize, &bufferSize, nil
}

// SetBufferVar Sets the buffer for a variable sized attribute to a query
// The buffer must be an initialized slice
func (q *Query) SetBufferVar(attribute string, offset []uint64,
buffer interface{}) (*uint64, *uint64, error) {
func (q *Query) SetBufferVar(attribute string, offset []uint64, buffer interface{}) (*uint64, *uint64, error) {
bufferReflectType := reflect.TypeOf(buffer)
bufferReflectValue := reflect.ValueOf(buffer)
if bufferReflectValue.Kind() != reflect.Slice {
Expand Down

0 comments on commit aff5641

Please sign in to comment.