diff --git a/rados/ioctx.go b/rados/ioctx.go index 76b4dd3..903ebf8 100644 --- a/rados/ioctx.go +++ b/rados/ioctx.go @@ -30,6 +30,19 @@ import ( "unsafe" ) +// CreateOption is passed to IOContext.Create() and should be one of +// CreateExclusive or CreateIdempotent. +type CreateOption int + +const ( + // CreateExclusive if used with IOContext.Create() and the object + // already exists, the function will return an error. + CreateExclusive = C.LIBRADOS_CREATE_EXCLUSIVE + // CreateIdempotent if used with IOContext.Create() and the object + // already exists, the function will not return an error. + CreateIdempotent = C.LIBRADOS_CREATE_IDEMPOTENT +) + // PoolStat represents Ceph pool statistics. type PoolStat struct { // space used in bytes @@ -93,6 +106,23 @@ func (ioctx *IOContext) SetNamespace(namespace string) { C.rados_ioctx_set_namespace(ioctx.ioctx, c_ns) } +// Create a new object with key oid. +// +// Implements: +// void rados_write_op_create(rados_write_op_t write_op, int exclusive, +// const char* category) +func (ioctx *IOContext) Create(oid string, exclusive CreateOption) error { + c_oid := C.CString(oid) + defer C.free(unsafe.Pointer(c_oid)) + + op := C.rados_create_write_op() + C.rados_write_op_create(op, C.int(exclusive), nil) + ret := C.rados_write_op_operate(op, ioctx.ioctx, c_oid, nil, 0) + C.rados_release_write_op(op) + + return getRadosError(int(ret)) +} + // Write writes len(data) bytes to the object with key oid starting at byte // offset offset. It returns an error, if any. func (ioctx *IOContext) Write(oid string, data []byte, offset uint64) error { diff --git a/rados/rados.go b/rados/rados.go index e23e8c0..686cc88 100644 --- a/rados/rados.go +++ b/rados/rados.go @@ -34,6 +34,8 @@ var ( RadosErrorNotFound = RadosError(-C.ENOENT) // RadosErrorPermissionDenied indicates a permissions issue. RadosErrorPermissionDenied = RadosError(-C.EPERM) + // ErrObjectExists indicates that an exclusive object creation failed. + ErrObjectExists = RadosError(-C.EEXIST) ) func getRadosError(err int) error { diff --git a/rados/rados_test.go b/rados/rados_test.go index b8281ef..f4c1971 100644 --- a/rados/rados_test.go +++ b/rados/rados_test.go @@ -447,6 +447,20 @@ func (suite *RadosTestSuite) TestWaitForLatestOSDMap() { assert.NoError(suite.T(), err) } +func (suite *RadosTestSuite) TestCreate() { + suite.SetupConnection() + + err := suite.ioctx.Create("unique", CreateExclusive) + assert.NoError(suite.T(), err) + + err = suite.ioctx.Create("unique", CreateExclusive) + assert.Error(suite.T(), err) + assert.Equal(suite.T(), err, ErrObjectExists) + + err = suite.ioctx.Create("unique", CreateIdempotent) + assert.NoError(suite.T(), err) +} + func (suite *RadosTestSuite) TestReadWrite() { suite.SetupConnection()