예제 #1
0
    def submit_single(self, c_key, c_len, value, item, key_options,
                      global_options, mres):

        value_format = get_option('format', key_options, global_options)
        if item:
            if self.OPTYPE in (C.LCB_APPEND, C.LCB_PREPEND):
                try:
                    value = key_options['fragment']
                except (KeyError, TypeError):
                    pycbc_exc_args('append/prepend must provide `fragment`')

        try:
            v_enc, flags = self.parent._tc.encode_value(value, value_format)
            if not isinstance(v_enc, bytes):
                raise ValueFormatError.pyexc("Value was not bytes", obj=v_enc)
            s_val = ffi.new('char[]', v_enc)
        except CouchbaseError:
            raise
        except Exception as ex:
            raise ValueFormatError.pyexc(str(value_format), inner=ex)

        C._Cb_set_key(self.c_command, c_key, c_len)
        C._Cb_set_val(self.c_command, s_val, len(v_enc))
        if self.OPTYPE not in (C.LCB_APPEND, C.LCB_PREPEND):
            try:
                self.c_command.flags = flags
            except OverflowError:
                pycbc_exc_enc('Invalid flags value', obj=flags)

        self.c_command.exptime = get_ttl(key_options, global_options, item)
        self.c_command.cas = get_cas(key_options, global_options, item)
        self.c_command.operation = self.OPTYPE
        return C.lcb_store3(self.instance, mres._cdata, self.c_command)
예제 #2
0
    def submit_single(
            self, c_key, c_len, value, item, key_options, global_options, mres):

        value_format = get_option('format', key_options, global_options)
        if item:
            if self.OPTYPE in (C.LCB_APPEND, C.LCB_PREPEND):
                try:
                    value = key_options['fragment']
                except (KeyError, TypeError):
                    pycbc_exc_args('append/prepend must provide `fragment`')


        try:
            v_enc, flags = self.parent._tc.encode_value(value, value_format)
            if not isinstance(v_enc, bytes):
                raise ValueFormatError.pyexc("Value was not bytes", obj=v_enc)
            s_val = ffi.new('char[]', v_enc)
        except CouchbaseError:
            raise
        except Exception as ex:
            raise ValueFormatError.pyexc(str(value_format), inner=ex)

        C._Cb_set_key(self.c_command, c_key, c_len)
        C._Cb_set_val(self.c_command, s_val, len(v_enc))
        if self.OPTYPE not in (C.LCB_APPEND, C.LCB_PREPEND):
            try:
                self.c_command.flags = flags
            except OverflowError:
                pycbc_exc_enc('Invalid flags value', obj=flags)

        self.c_command.exptime = get_ttl(key_options, global_options, item)
        self.c_command.cas = get_cas(key_options, global_options, item)
        self.c_command.operation = self.OPTYPE
        return C.lcb_store3(self.instance, mres._cdata, self.c_command)
예제 #3
0
    def _subdoc_callback(self, instance, cbtype, rb):
        resp = ffi.cast('lcb_RESPSUBDOC*', rb)
        mres = ffi.from_handle(resp.cookie)
        buf = bytes(ffi.buffer(resp.key, resp.nkey))
        try:
            key = self._tc.decode_key(buf)
            result = mres[key]  # type: _SDResult
        except:
            raise pycbc_exc_enc(buf)

        result.rc = resp.rc
        if resp.rc not in (C.LCB_SUCCESS, C.LCB_SUBDOC_MULTI_FAILURE):
            mres._add_bad_rc(resp.rc, result)
            self._chk_op_done(mres)
            return
        else:
            result.cas = resp.cas

        # naming conventions as in the Couchbase C extension
        cur = self._sd_entry
        vii = self._sd_iterpos
        vii[0] = 0  # Reset iterator
        oix = 0

        is_mutate = cbtype == C.LCB_CALLBACK_SDMUTATE
        while C.lcb_sdresult_next(resp, cur, vii) != 0:
            if is_mutate:
                cur_index = cur.index
            else:
                cur_index = oix
                oix += 1
            if cur.status == 0 and cur.nvalue:
                buf = bytes(ffi.buffer(cur.value, cur.nvalue))
                try:
                    value = self._tc.decode_value(buf, FMT_JSON)
                except:
                    raise pycbc_exc_enc(obj=buf)
            else:
                value = None

            cur_tuple = (cur.status, value)
            if cur.status:
                if is_mutate or cur.status != C.LCB_SUBDOC_PATH_ENOENT:
                    spec = result._specs[cur_index]
                    try:
                        raise pycbc_exc_lcb(cur.status, 'Subcommand failure', obj=spec)
                    except PyCBC.default_exception:
                        mres._add_err(sys.exc_info())

            result._add_result(cur_index, cur_tuple)

        if is_mutate and result.success:
            self._set_mutinfo(result, cbtype, rb)
            if mres._dur and self._chain_endure(cbtype, mres, result, mres._dur):
                return

        self._chk_op_done(mres)
예제 #4
0
    def _callback_common(self, _, cbtype, resp, is_mutator=False):
        mres = ffi.from_handle(resp.cookie)
        buf = bytes(ffi.buffer(resp.key, resp.nkey))
        try:
            key = self._tc.decode_key(buf)
            result = mres[key]
        except:
            raise pycbc_exc_enc(buf)

        result.rc = resp.rc
        if resp.rc:
            mres._add_bad_rc(resp.rc, result)
        else:
            result.cas = resp.cas
            if is_mutator:
                self._set_mutinfo(result, cbtype,
                                  ffi.cast('lcb_RESPBASE*', resp))

        if self._dur_testhook:
            self._dur_testhook(result)

        if cbtype != C.LCB_CALLBACK_ENDURE and mres._dur:
            if self._chain_endure(cbtype, mres, result, mres._dur):
                return None, None

        return result, mres
예제 #5
0
    def _execute_single_kv(self, name, key, value, **kwargs):
        try:
            kv = {key: value}
        except TypeError:
            raise pycbc_exc_enc('Bad key-value', obj=(key,value))

        self._do_lock()
        try:
            proc = self._executors[name]
            mres = proc.execute(kv, **kwargs)
            return self._run_single(mres)
        finally:
            self._do_unlock()
예제 #6
0
    def _invoke_submit(self, iterobj, is_dict, is_itmcoll, mres, global_kw):
        """
        Internal function to invoke the actual submit_single function
        :param iterobj: The raw object returned as the next item of the iterator
        :param is_dict: True if iterator is a dictionary
        :param is_itmcoll: True if the iterator contains Item objects
        :param mres: The multi result object
        :param global_kw: The global settings
        :return: The return value of :meth:`submit_single`
        """
        if is_itmcoll:
            item, key_options = next(iterobj)
            key = item.key
            value = item.value
            result = item
        else:
            if is_dict:
                key, value = next(iterobj)
                if not self.VALUES_ALLOWED and not is_itmcoll:
                    raise ArgumentError.pyexc(
                        'Values not allowed for this command', obj=value)
            else:
                key = next(iterobj)
                value = None

            key_options = {}
            item = None
            result = self.make_result(key, value)

        result.rc = -1

        # Attempt to get the encoded key:
        key, value, key_options = self.make_entry_params(
            key, value, key_options)
        c_key, c_len = create_key(self.parent._tc, key)

        rc = self.submit_single(c_key, c_len, value, item, key_options,
                                global_kw, mres)
        if rc:
            raise pycbc_exc_lcb(rc)
        try:
            if key in mres and not self.DUPKEY_OK:
                # For tests:
                self.parent._warn_dupkey(key)

            mres[key] = result
        except TypeError:
            raise pycbc_exc_enc(obj=key)
    def _invoke_submit(self, iterobj, is_dict, is_itmcoll, mres, global_kw):
        """
        Internal function to invoke the actual submit_single function
        :param iterobj: The raw object returned as the next item of the iterator
        :param is_dict: True if iterator is a dictionary
        :param is_itmcoll: True if the iterator contains Item objects
        :param mres: The multi result object
        :param global_kw: The global settings
        :return: The return value of :meth:`submit_single`
        """
        if is_itmcoll:
            item, key_options = next(iterobj)
            if not isinstance(item, Item):
                pycbc_exc_args('Expected item object')
            key = item.key
            value = item.value
            result = item
        else:
            if is_dict:
                key, value = next(iterobj)
                if not self.VALUES_ALLOWED and not is_itmcoll:
                    raise ArgumentError.pyexc(
                        'Values not allowed for this command', obj=value)
            else:
                key = next(iterobj)
                value = None

            key_options = {}
            item = None
            result = self.make_result(key, value)

        result.rc = -1

        # Attempt to get the encoded key:
        key, value, key_options = self.make_entry_params(key, value, key_options)
        c_key, c_len = create_key(self.parent._tc, key)

        rc = self.submit_single(c_key, c_len, value, item, key_options, global_kw, mres)
        if rc:
            raise pycbc_exc_lcb(rc)
        try:
            if key in mres and not self.DUPKEY_OK:
                # For tests:
                self.parent._warn_dupkey(key)

            mres[key] = result
        except TypeError:
            raise pycbc_exc_enc(obj=key)
예제 #8
0
    def _get_callback(self, instance, cbtype, resp):
        result, mres = self._callback_common(instance, cbtype, resp)
        resp = ffi.cast('lcb_RESPGET*', resp)
        result.flags = resp.itmflags

        if not resp.rc:
            buf = bytes(ffi.buffer(resp.value, resp.nvalue))

            if not self.data_passthrough and not mres._no_format:
                try:
                    result.value = self._tc.decode_value(buf, resp.itmflags)
                except:
                    result.value = buf[::]
                    try:
                        raise pycbc_exc_enc(obj=buf)
                    except PyCBC.default_exception:
                        mres._add_err(sys.exc_info())
            else:
                result.value = buf[::]

        self._chk_op_done(mres)
예제 #9
0
    def _callback_common(self, _, cbtype, resp):
        mres = ffi.from_handle(resp.cookie)
        buf = bytes(ffi.buffer(resp.key, resp.nkey))
        try:
            key = self._tc.decode_key(buf)
            result = mres[key]
        except:
            raise pycbc_exc_enc(buf)

        result.rc = resp.rc
        if resp.rc:
            mres._add_bad_rc(resp.rc, result)
        else:
            result.cas = resp.cas

        if self._dur_testhook:
            self._dur_testhook(result)

        if cbtype != C.LCB_CALLBACK_ENDURE and mres._dur:
            if self._chain_endure(cbtype, mres, result, mres._dur):
                return None, None

        return result, mres