Class: Couchbase::Bucket

Inherits:
Object
  • Object
show all
Defined in:
ext/couchbase_ext/couchbase_ext.c,
lib/couchbase/bucket.rb,
ext/couchbase_ext/couchbase_ext.c

Overview

This class in charge of all stuff connected to communication with Couchbase.

Constant Summary

FMT_MASK =

Bitmask for flag bits responsible for format

0x03
FMT_DOCUMENT =

Document format. The (default) format supports most of ruby types which could be mapped to JSON data (hashes, arrays, strings, numbers). Future version will be able to run map/reduce queries on the values in the document form (hashes).

0x00
FMT_MARSHAL =

Marshal format. The format which supports transparent serialization of ruby objects with standard Marshal.dump and Marhal.load methods.

0x01
FMT_PLAIN =

Plain format. The format which force client don’t apply any conversions to the value, but it should be passed as String. It could be useful for building custom algorithms or formats. For example implement set: http://dustin.github.com/2011/02/17/memcached-set.html

0x02

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Bucket) initialize(url, options = {}) - (Bucket) initialize(options = {})

Initialize new Bucket.

Examples:

Initialize connection using default options

Couchbase.new

Select custom bucket

Couchbase.new(:bucket => 'foo')
Couchbase.new('http://localhost:8091/pools/default/buckets/foo')

Connect to protected bucket

Couchbase.new(:bucket => 'protected', :username => 'protected', :password => 'secret')
Couchbase.new('http://localhost:8091/pools/default/buckets/protected',
              :username => 'protected', :password => 'secret')

Use list of nodes, in case some nodes might be dead

Couchbase.new(:node_list => ['example.com:8091', 'example.org:8091', 'example.net'])

Overloads:

  • - (Bucket) initialize(url, options = {})

    Initialize bucket using URI of the cluster and options. It is possible to override some parts of URI using the options keys (e.g. :host or :port)

    Parameters:

    • url (String)

      The full URL of management API of the cluster.

    • options (Hash)

      The options for connection. See options definition below.

  • - (Bucket) initialize(options = {})

    Initialize bucket using options only.

    Parameters:

    • options (Hash)

      The options for operation for connection

    Options Hash (options):

    • :node_list (Array) — default: nil

      the list of nodes to connect to. If specified it takes precedence over :host option. The list must be array of strings in form of host names or host names with ports (in first case port 8091 will be used, see examples).

    • :host (String) — default: "localhost"

      the hostname or IP address of the node

    • :port (Fixnum) — default: 8091

      the port of the managemenent API

    • :pool (String) — default: "default"

      the pool name

    • :bucket (String) — default: "default"

      the bucket name

    • :default_ttl (Fixnum) — default: 0

      the TTL used by default during storing key-value pairs.

    • :default_flags (Fixnum) — default: 0

      the default flags.

    • :default_format (Symbol) — default: :document

      the format, which will be used for values by default. Note that changing format will amend flags. (see #default_format)

    • :username (String) — default: nil

      the user name to connect to the cluster. Used to authenticate on management API.

    • :password (String) — default: nil

      the password of the user.

    • :quiet (Boolean) — default: true

      the flag controlling if raising exception when the client executes operations on unexising keys. If it is true it will raise Error::NotFound exceptions. The default behaviour is to return nil value silently (might be useful in Rails cache).



1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
# File 'ext/couchbase_ext/couchbase_ext.c', line 1321

static VALUE
cb_bucket_init(int argc, VALUE *argv, VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);

    bucket->exception = Qnil;
    bucket->hostname = strdup("localhost");
    bucket->port = 8091;
    bucket->pool = strdup("default");
    bucket->bucket = strdup("default");
    bucket->async = 0;
    bucket->quiet = 1;
    bucket->default_ttl = 0;
    bucket->default_flags = 0;
    bucket->default_format = sym_document;
    bucket->on_error_proc = Qnil;
    bucket->timeout = 0;
    bucket->object_space = rb_hash_new();
    bucket->node_list = NULL;

    do_scan_connection_options(bucket, argc, argv);
    do_connect(bucket);

    return self;
}

Instance Attribute Details

- (String) authority (readonly)

Host with port

Returns:

  • (String)

    host with port



1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
# File 'ext/couchbase_ext/couchbase_ext.c', line 1618

static VALUE
cb_bucket_authority_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    size_t len;

    (void)cb_bucket_hostname_get(self);
    (void)cb_bucket_port_get(self);
    len = strlen(bucket->hostname) + 10;
    bucket->authority = xcalloc(len, sizeof(char));
    if (bucket->authority == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
    }
    snprintf(bucket->authority, len, "%s:%u", bucket->hostname, bucket->port);
    return STR_NEW_CSTR(bucket->authority);
}

- (String) bucket (readonly) Also known as: name

The bucket name

Returns:

  • (String)

    the bucket name



1638
1639
1640
1641
1642
1643
# File 'ext/couchbase_ext/couchbase_ext.c', line 1638

static VALUE
cb_bucket_bucket_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return STR_NEW_CSTR(bucket->bucket);
}

- (Fixnum) default_flags

Note:

Amending format bit will also change #default_format value

Default flags for new values.

The library reserves last two lower bits to store the format of the value. The can be masked via FMT_MASK constant.

Examples:

Selecting format bits

connection.default_flags & Couchbase::Bucket::FMT_MASK

Set user defined bits

connection.default_flags |= 0x6660

Returns:

  • (Fixnum)

    the effective flags



1486
1487
1488
1489
1490
1491
# File 'ext/couchbase_ext/couchbase_ext.c', line 1486

static VALUE
cb_bucket_default_flags_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return ULONG2NUM(bucket->default_flags);
}

- (Symbol) default_format

Note:

Amending default_format will also change #default_flags value

Default format for new values.

It uses flags field to store the format. It accepts either the Symbol (+:document+, :marshal, :plain) or Fixnum (use constants FMT_DOCUMENT, FMT_MARSHAL, FMT_PLAIN) and silently ignores all other value.

Here is some notes regarding how to choose the format:

  • :document (default) format supports most of ruby types which could be mapped to JSON data (hashes, arrays, strings, numbers). Future version will be able to run map/reduce queries on the values in the document form (hashes).
  • :plain format if you no need any conversions to be applied to your data, but your data should be passed as String. It could be useful for building custom algorithms or formats. For example implement set: http://dustin.github.com/2011/02/17/memcached-set.html
  • :marshal format if you’d like to transparently serialize your ruby object with standard Marshal.dump and Marhal.load methods.

Examples:

Selecting plain format using symbol

connection.format = :document

Selecting plain format using Fixnum constant

connection.format = Couchbase::Bucket::FMT_PLAIN

Returns:

  • (Symbol)

    the effective format



1503
1504
1505
1506
1507
1508
# File 'ext/couchbase_ext/couchbase_ext.c', line 1503

static VALUE
cb_bucket_default_format_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return bucket->default_format;
}

- (String) hostname (readonly)

The host name of the management interface (default: "localhost")

Returns:

  • (String)

    the host name of the management interface (default: "localhost")



1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
# File 'ext/couchbase_ext/couchbase_ext.c', line 1585

static VALUE
cb_bucket_hostname_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    if (bucket->handle) {
        if (bucket->hostname) {
            xfree(bucket->hostname);
            bucket->hostname = NULL;
        }
        bucket->hostname = strdup(libcouchbase_get_host(bucket->handle));
        if (bucket->hostname == NULL) {
            rb_raise(eNoMemoryError, "failed to allocate memory for Bucket");
        }
    }
    return STR_NEW_CSTR(bucket->hostname);
}

- (Proc) on_error {|op, key, exc| ... }

Error callback for asynchronous mode.

This callback is using to deliver exceptions in asynchronous mode.

Examples:

Using lambda syntax

connection = Couchbase.new(:async => true)
connection.on_error = lambda {|op, key, exc| ... }
connection.run do |conn|
  conn.set("foo", "bar")
end

Using block syntax

connection = Couchbase.new(:async => true)
connection.on_error {|op, key, exc| ... }
...

Yield Parameters:

  • op (Symbol)

    The operation caused the error

  • key (String)

    The key which cause the error or nil

  • exc (Exception)

    The exception instance

Returns:

  • (Proc)

    the effective callback



1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
# File 'ext/couchbase_ext/couchbase_ext.c', line 1550

static VALUE
cb_bucket_on_error_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);

    if (rb_block_given_p()) {
        return cb_bucket_on_error_set(self, rb_block_proc());
    } else {
        return bucket->on_error_proc;
    }
}

- (String) password (readonly)

The password for protected buckets

Returns:

  • (String)

    the password for protected buckets



1669
1670
1671
1672
1673
1674
# File 'ext/couchbase_ext/couchbase_ext.c', line 1669

static VALUE
cb_bucket_password_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return STR_NEW_CSTR(bucket->password);
}

- (String) pool (readonly)

The pool name (usually "default")

Returns:

  • (String)

    the pool name (usually "default")



1648
1649
1650
1651
1652
1653
# File 'ext/couchbase_ext/couchbase_ext.c', line 1648

static VALUE
cb_bucket_pool_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return STR_NEW_CSTR(bucket->pool);
}

- (Fixnum) port (readonly)

The port number of the management interface (default: 8091)

Returns:

  • (Fixnum)

    the port number of the management interface (default: 8091)



1605
1606
1607
1608
1609
1610
1611
1612
1613
# File 'ext/couchbase_ext/couchbase_ext.c', line 1605

static VALUE
cb_bucket_port_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    if (bucket->handle) {
        bucket->port = atoi(libcouchbase_get_port(bucket->handle));
    }
    return UINT2NUM(bucket->port);
}

- (Boolean) quiet Also known as: quiet?

Flag specifying behaviour for operations on missing keys

If it is true, the operations will silently return nil or false instead of raising Error::NotFound.

Examples:

Hiding cache miss (considering "miss" key is not stored)

connection.quiet = true
connection.get("miss")     #=> nil

Raising errors on miss (considering "miss" key is not stored)

connection.quiet = false
connection.get("miss")     #=> will raise Couchbase::Error::NotFound

Returns:

  • (Boolean)


1468
1469
1470
1471
1472
1473
# File 'ext/couchbase_ext/couchbase_ext.c', line 1468

static VALUE
cb_bucket_quiet_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return bucket->quiet ? Qtrue : Qfalse;
}

- (Object) seqno (readonly)

The number of scheduled commands



998
999
1000
1001
1002
1003
1004
# File 'ext/couchbase_ext/couchbase_ext.c', line 998

static VALUE
cb_bucket_seqno(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);

    return LONG2FIX(bucket->seqno);
}

- (Fixnum) timeout

The timeout for the operations. The client will raise Error::Timeout exception for all commands which weren’t completed in given timeslot.

Returns:

  • (Fixnum)

    The timeout for the operations. The client will raise Error::Timeout exception for all commands which weren’t completed in given timeslot.



1562
1563
1564
1565
1566
1567
# File 'ext/couchbase_ext/couchbase_ext.c', line 1562

static VALUE
cb_bucket_timeout_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return ULONG2NUM(bucket->timeout);
}

- (String) url (readonly)

The address of the cluster management interface

Returns:

  • (String)

    the address of the cluster management interface



1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
# File 'ext/couchbase_ext/couchbase_ext.c', line 1679

static VALUE
cb_bucket_url_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    VALUE str;

    (void)cb_bucket_authority_get(self);
    str = rb_str_buf_new2("http://");
    rb_str_buf_cat2(str, bucket->authority);
    rb_str_buf_cat2(str, "/pools/");
    rb_str_buf_cat2(str, bucket->pool);
    rb_str_buf_cat2(str, "/buckets/");
    rb_str_buf_cat2(str, bucket->bucket);
    rb_str_buf_cat2(str, "/");
    return str;
}

- (String) username (readonly)

The username for protected buckets (usually matches the bucket name)

Returns:

  • (String)

    the username for protected buckets (usually matches the bucket name)



1659
1660
1661
1662
1663
1664
# File 'ext/couchbase_ext/couchbase_ext.c', line 1659

static VALUE
cb_bucket_username_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return STR_NEW_CSTR(bucket->username);
}

Instance Method Details

- (Fixnum) add(key, value, options = {}) {|ret| ... }

Add the item to the database, but fail if the object exists already

The CAS value of the object.

Examples:

Add the same key twice

c.add("foo", "bar")  #=> stored successully
c.add("foo", "baz")  #=> will raise Couchbase::Error::KeyExists: failed to store value (key="foo", error=0x0c)

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • value (Object)

    Value to be stored

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :ttl (Fixnum) — default: self.default_ttl

    Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch).

  • :flags (Fixnum) — default: self.default_flags

    Flags for storage options. Flags are ignored by the server but preserved for use by the client. For more info see #default_flags.

  • :format (Symbol) — default: self.default_format

    The representation for storing the value in the bucket. For more info see #default_format.

  • :cas (Fixnum)

    The CAS value for an object. This value created on the server and is guaranteed to be unique for each value of a given key. This value is used to provide simple optimistic concurrency control when multiple clients or threads try to update an item simultaneously.

Yield Parameters:

  • ret (Result)

    the result of operation in asynchronous mode (valid attributes: error, operation, key).

Returns:

  • (Fixnum)

    The CAS value of the object.

Raises:



2959
2960
2961
2962
2963
# File 'ext/couchbase_ext/couchbase_ext.c', line 2959

static VALUE
cb_bucket_add(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_store(LIBCOUCHBASE_ADD, argc, argv, self);
}

- (Fixnum) append(key, value, options = {})

Note:

This operation is kind of data-aware from server point of view. This mean that the server treats value as binary stream and just perform concatenation, therefore it won’t work with :marshal and :document formats, because of lack of knowledge how to merge values in these formats. See Bucket#cas for workaround.

Append this object to the existing object

The CAS value of the object.

Examples:

Simple append

c.set("foo", "aaa")
c.append("foo", "bbb")
c.get("foo")           #=> "aaabbb"

Implementing sets using append

def set_add(key, *values)
  encoded = values.flatten.map{|v| "+#{v} "}.join
  append(key, encoded)
end

def set_remove(key, *values)
  encoded = values.flatten.map{|v| "-#{v} "}.join
  append(key, encoded)
end

def set_get(key)
  encoded = get(key)
  ret = Set.new
  encoded.split(' ').each do |v|
    op, val = v[0], v[1..-1]
    case op
    when "-"
      ret.delete(val)
    when "+"
      ret.add(val)
    end
  end
  ret
end

Using optimistic locking. The operation will fail on CAS mismatch

ver = c.set("foo", "aaa")
c.append("foo", "bbb", :cas => ver)

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • value (Object)

    Value to be stored

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :cas (Fixnum)

    The CAS value for an object. This value created on the server and is guaranteed to be unique for each value of a given key. This value is used to provide simple optimistic concurrency control when multiple clients or threads try to update an item simultaneously.

  • :format (Symbol) — default: self.default_format

    The representation for storing the value in the bucket. For more info see #default_format.

Returns:

  • (Fixnum)

    The CAS value of the object.

Raises:



3062
3063
3064
3065
3066
# File 'ext/couchbase_ext/couchbase_ext.c', line 3062

static VALUE
cb_bucket_append(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_store(LIBCOUCHBASE_APPEND, argc, argv, self);
}

- (Boolean) async?

Check whether the connection asynchronous.

By default all operations are synchronous and block waiting for results, but you can make them asynchronous and run event loop explicitly. (see #run)

Examples:

Return value of #get operation depending on async flag

connection = Connection.new
connection.async?      #=> false

connection.run do |conn|
  conn.async?          #=> true
end

Returns:

  • (Boolean)

    true if the connection if asynchronous

  • (Boolean)

See Also:



1461
1462
1463
1464
1465
1466
# File 'ext/couchbase_ext/couchbase_ext.c', line 1461

static VALUE
cb_bucket_async_p(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return bucket->async ? Qtrue : Qfalse;
}

- (Fixnum) cas(key, options = {}) {|value| ... } Also known as: compare_and_swap

Reads a key’s value from the server and yields it to a block. Replaces the key’s value with the result of the block as long as the key hasn’t been updated in the meantime, otherwise raises Error::KeyExists. CAS stands for "compare and swap", and avoids the need for manual key mutexing. Read more info here:


  http://docs.couchbase.org/memcached-api/memcached-api-protocol-text_cas.html

Examples:

Implement append to JSON encoded value

c.default_format = :document
c.set("foo", {"bar" => 1})
c.cas("foo") do |val|
  val["baz"] = 2
  val
end
c.get("foo")      #=> {"bar" => 1, "baz" => 2}

Parameters:

  • key (String, Symbol)
  • options (Hash) (defaults to: {})

    the options for operation

Options Hash (options):

  • :ttl (String) — default: self.default_ttl

    the time to live of this key

  • :format (Symbol) — default: self.default_format

    format of the value

  • :flags (Fixnum) — default: self.default_flags

    flags for this key

Yield Parameters:

  • value (Object, Result)

    old value in synchronous mode and Result object in asynchronous mode.

Yield Returns:

  • (Object)

    new value.

Returns:

  • (Fixnum)

    the CAS of new value

Raises:

  • (Couchbase::Error::KeyExists)

    if the key was updated before the the code in block has been completed (the CAS value has been changed).



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/couchbase/bucket.rb', line 55

def cas(key, options = {})
  options = options.merge(:extended => true)
  if async?
    get(key, options) do |ret|
      val = yield(ret) # get new value from caller
      set(ret.key, val, :cas => ret.cas, :flags => ret.flags)
    end
  else
    val, flags, ver = get(key, options)
    val = yield(val) # get new value from caller
    set(key, val, :cas => ver, :flags => flags)
  end
end

- (Boolean) connected?

Check whether the instance connected to the cluster.

Returns:

  • (Boolean)

    true if the instance connected to the cluster

  • (Boolean)


1435
1436
1437
1438
1439
1440
# File 'ext/couchbase_ext/couchbase_ext.c', line 1435

static VALUE
cb_bucket_connected_p(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    return bucket->handle ? Qtrue : Qfalse;
}

- (Fixnum) decr(key, delta = 1, options = {}) {|ret| ... } Also known as: decrement

Note:

that server values stored and transmitted as unsigned numbers, therefore if you try to decrement negative or zero key, you will always get zero.

Decrement the value of an existing numeric key

The decrement methods reduce the value of a given key if the corresponding value can be parsed to an integer value. These operations are provided at a protocol level to eliminate the need to get, update, and reset a simple integer value in the database. It supports the use of an explicit offset value that will be used to reduce the stored value in the database.

The actual value of the key.

Examples:

Decrement key by one

c.decr("foo")

Decrement key by 50

c.decr("foo", 50)

Decrement key by one OR initialize with zero

c.decr("foo", :create => true)   #=> will return old-1 or 0

Decrement key by one OR initialize with three

c.decr("foo", 50, :initial => 3) #=> will return old-50 or 3

Decrement key and get its CAS value

val, cas = c.decr("foo", :extended => true)

Decrementing zero

c.set("foo", 0)
c.decrement("foo", 100500)   #=> 0

Decrementing negative value

c.set("foo", -100)
c.decrement("foo", 100500)   #=> 0

Asynchronous invocation

c.run do
  c.decr("foo") do |ret|
    ret.operation   #=> :decrement
    ret.success?    #=> true
    ret.key         #=> "foo"
    ret.value
    ret.cas
  end
end

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • delta (Fixnum)

    Integer (up to 64 bits) value to decrement

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :create (Boolean) — default: false

    If set to true, it will initialize the key with zero value and zero flags (use :initial option to set another initial value). Note: it won’t decrement the missing value.

  • :initial (Fixnum) — default: 0

    Integer (up to 64 bits) value for missing key initialization. This option imply :create option is true.

  • :ttl (Fixnum) — default: self.default_ttl

    Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). This option ignored for existent keys.

  • :extended (Boolean) — default: false

    If set to true, the operation will return tuple [value, cas], otherwise (by default) it returns just value.

Yield Parameters:

  • ret (Result)

    the result of operation in asynchronous mode (valid attributes: error, operation, key, value, cas).

Returns:

  • (Fixnum)

    the actual value of the key.

Raises:



2185
2186
2187
2188
2189
# File 'ext/couchbase_ext/couchbase_ext.c', line 2185

static VALUE
cb_bucket_decr(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_arithmetic(-1, argc, argv, self);
}

- (Object) delete(key, options = {})

Delete the specified key

Examples:

Delete the key in quiet mode (default)

c.set("foo", "bar")
c.delete("foo")        #=> true
c.delete("foo")        #=> false

Delete the key verbosely

c.set("foo", "bar")
c.delete("foo", :quiet => false)   #=> true
c.delete("foo", :quiet => false)   #=> will raise Couchbase::Error::NotFound

Delete the key with version check

ver = c.set("foo", "bar")          #=> 5992859822302167040
c.delete("foo", :cas => 123456)    #=> will raise Couchbase::Error::KeyExists
c.delete("foo", :cas => ver)       #=> true

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :quiet (Boolean) — default: self.quiet

    If set to true, the operation won’t raise error for missing key, it will return nil. Otherwise it will raise error in synchronous mode. In asynchronous mode this option ignored.

  • :cas (Fixnum)

    The CAS value for an object. This value created on the server and is guaranteed to be unique for each value of a given key. This value is used to provide simple optimistic concurrency control when multiple clients or threads try to update/delete an item simultaneously.

Raises:



1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
# File 'ext/couchbase_ext/couchbase_ext.c', line 1768

static VALUE
cb_bucket_delete(int argc, VALUE *argv, VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    context_t *ctx;
    VALUE k, c, rv, proc, exc, opts;
    char *key;
    size_t nkey;
    libcouchbase_cas_t cas = 0;
    libcouchbase_error_t err;
    long seqno;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    rb_scan_args(argc, argv, "11&", &k, &opts, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    k = unify_key(k);
    key = RSTRING_PTR(k);
    nkey = RSTRING_LEN(k);
    ctx = xcalloc(1, sizeof(context_t));
    ctx->quiet = bucket->quiet;
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    if (opts != Qnil) {
        if (TYPE(opts) == T_BIGNUM || TYPE(opts) == T_FIXNUM) {
            cas = NUM2ULL(opts);
        } else {
            Check_Type(opts, T_HASH);
            if ((c = rb_hash_aref(opts, sym_cas)) != Qnil) {
                cas = NUM2ULL(c);
            }
            if (RTEST(rb_funcall(opts, id_has_key_p, 1, sym_quiet))) {
                ctx->quiet = RTEST(rb_hash_aref(opts, sym_quiet));
            }
        }
    }
    ctx->proc = proc;
    cb_gc_protect(bucket, ctx->proc);
    rv = rb_ary_new();
    ctx->rv = &rv;
    ctx->bucket = bucket;
    ctx->exception = Qnil;
    seqno = bucket->seqno;
    bucket->seqno++;
    err = libcouchbase_remove(bucket->handle, (const void *)ctx,
            (const void *)key, nkey, cas);
    exc = cb_check_error(err, "failed to schedule delete request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    if (bucket->async) {
        return Qnil;
    } else {
        if (bucket->seqno - seqno > 0) {
            /* we have some operations pending */
            bucket->io->run_event_loop(bucket->io);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        return rv;
    }
}

- (true) disconnect

Close the connection to the cluster

Returns:

  • (true)

Raises:



3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
# File 'ext/couchbase_ext/couchbase_ext.c', line 3138

static VALUE
cb_bucket_disconnect(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);

    if (bucket->handle) {
        libcouchbase_destroy(bucket->handle);
        bucket->handle = NULL;
        bucket->io = NULL;
        return Qtrue;
    } else {
        rb_raise(eConnectError, "closed connection");
    }
}

- (Boolean) flush {|ret| ... }

Deletes all values from a server

true on success

Examples:

Simple flush the bucket

c.flush    #=> true

Asynchronous flush

c.run do
  c.flush do |ret|
    ret.operation   #=> :flush
    ret.success?    #=> true
    ret.node        #=> "localhost:11211"
  end
end

Yield Parameters:

  • ret (Result)

    the object with error, node and operation attributes.

Returns:

  • (Boolean)

    true on success

Raises:



2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
# File 'ext/couchbase_ext/couchbase_ext.c', line 2522

static VALUE
cb_bucket_flush(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    context_t *ctx;
    VALUE rv, exc;
    libcouchbase_error_t err;
    long seqno;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    if (!bucket->async && rb_block_given_p()) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    ctx = xcalloc(1, sizeof(context_t));
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    rv = Qtrue; /* optimistic by default */
    ctx->rv = &rv;
    ctx->bucket = bucket;
    ctx->exception = Qnil;
    if (rb_block_given_p()) {
        ctx->proc = rb_block_proc();
    } else {
        ctx->proc = Qnil;
    }
    cb_gc_protect(bucket, ctx->proc);
    seqno = bucket->seqno;
    bucket->seqno++;
    err = libcouchbase_flush(bucket->handle, (const void *)ctx);
    exc = cb_check_error(err, "failed to schedule flush request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    if (bucket->async) {
        return Qnil;
    } else {
        if (bucket->seqno - seqno > 0) {
            /* we have some operations pending */
            bucket->io->run_event_loop(bucket->io);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        return rv;
    }
}

- (Object, ...) get(*keys, options = {}) {|ret| ... } - (Hash) get(keys, options = {}) Also known as: []

Obtain an object stored in Couchbase by given key.

Overloads:

  • - (Object, ...) get(*keys, options = {}) {|ret| ... }

    The value(s) (or tuples in extended mode) assiciated with the key.

    Examples:

    Get single value in quite mode (the default)

    c.get("foo")     #=> the associated value or nil
    

    Use alternative hash-like syntax

    c["foo"]         #=> the associated value or nil
    

    Get single value in verbose mode

    c.get("missing-foo", :quiet => false)  #=> raises Couchbase::NotFound
    

    Get and touch single value. The key won’t be accessible after 10 seconds

    c.get("foo", :ttl => 10)
    

    Extended get

    val, flags, cas = c.get("foo", :extended => true)
    

    Get multiple keys

    c.get("foo", "bar", "baz")   #=> [val1, val2, val3]
    

    Extended get multiple keys

    c.get("foo", "bar", :extended => true)
    #=> {"foo" => [val1, flags1, cas1], "bar" => [val2, flags2, cas2]}
    

    Asynchronous get

    c.run do
      c.get("foo", "bar", "baz") do |res|
        ret.operation   #=> :get
        ret.success?    #=> true
        ret.key         #=> "foo", "bar" or "baz" in separate calls
        ret.value
        ret.flags
        ret.cas
      end
    end
    

    Parameters:

    • keys (String, Symbol, Array)

      One or several keys to fetch

    • options (Hash)

      Options for operation.

    Options Hash (options):

    • :extended (Boolean) — default: false

      If set to true, the operation will return tuple +[value, flags, cas]+, otherwise (by default) it returns just value.

    • :ttl (Fixnum) — default: self.default_ttl

      Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch).

    • :quiet (Boolean) — default: self.quiet

      If set to true, the operation won’t raise error for missing key, it will return nil. Otherwise it will raise error in synchronous mode. In asynchronous mode this option ignored.

    • :format (Symbol) — default: nil

      Explicitly choose the decoder for this key (+:plain+, :document, :marshal). See #default_format.

    Yield Parameters:

    • ret (Result)

      the result of operation in asynchronous mode (valid attributes: error, operation, key, value, flags, cas).

    Returns:

    • (Object, Array, Hash)

      the value(s) (or tuples in extended mode) assiciated with the key.

    Raises:

  • - (Hash) get(keys, options = {})

    When the method receive hash map, it will behave like it receive list of keys (+keys.keys+), but also touch each key setting expiry time to the corresponding value. But unlike usual get this command always return hash map {key => value} or {key => [value, flags, cas]}.

    Examples:

    Get and touch multiple keys

    c.get("foo" => 10, "bar" => 20)   #=> {"foo" => val1, "bar" => val2}
    

    Extended get and touch multiple keys

    c.get({"foo" => 10, "bar" => 20}, :extended => true)
    #=> {"foo" => [val1, flags1, cas1], "bar" => [val2, flags2, cas2]}
    

    Parameters:

    • keys (Hash)

      Map key-ttl

    • options (Hash)

      Options for operation. (see options definition above)

    Returns:

    • (Hash)

      the values (or tuples in extended mode) assiciated with the keys.



2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
# File 'ext/couchbase_ext/couchbase_ext.c', line 2279

static VALUE
cb_bucket_get(int argc, VALUE *argv, VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    context_t *ctx;
    VALUE args, rv, proc, exc, keys;
    long nn;
    libcouchbase_error_t err;
    struct key_traits *traits;
    int extended, mgat;
    long seqno;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    rb_scan_args(argc, argv, "0*&", &args, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    rb_funcall(args, id_flatten_bang, 0);
    traits = xcalloc(1, sizeof(struct key_traits));
    nn = cb_args_scan_keys(RARRAY_LEN(args), args, bucket, traits);
    ctx = xcalloc(1, sizeof(context_t));
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    mgat = traits->mgat;
    keys = traits->keys_ary;
    ctx->proc = proc;
    cb_gc_protect(bucket, ctx->proc);
    ctx->bucket = bucket;
    ctx->extended = traits->extended;
    ctx->quiet = traits->quiet;
    ctx->force_format = traits->force_format;
    rv = rb_hash_new();
    ctx->rv = &rv;
    ctx->exception = Qnil;
    seqno = bucket->seqno;
    bucket->seqno += nn;
    err = libcouchbase_mget(bucket->handle, (const void *)ctx,
            traits->nkeys, (const void * const *)traits->keys,
            traits->lens, (traits->explicit_ttl) ? traits->ttls : NULL);
    xfree(traits->keys);
    xfree(traits->lens);
    xfree(traits->ttls);
    xfree(traits);
    exc = cb_check_error(err, "failed to schedule get request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    if (bucket->async) {
        return Qnil;
    } else {
        if (bucket->seqno - seqno > 0) {
            /* we have some operations pending */
            bucket->io->run_event_loop(bucket->io);
        }
        exc = ctx->exception;
        extended = ctx->extended;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        if (bucket->exception != Qnil) {
            rb_exc_raise(bucket->exception);
        }
        if (mgat || (extended && nn > 1)) {
            return rv;  /* return as a hash {key => [value, flags, cas], ...} */
        }
        if (nn > 1) {
            long ii;
            VALUE *keys_ptr, ret;
            ret = rb_ary_new();
            keys_ptr = RARRAY_PTR(keys);
            for (ii = 0; ii < nn; ii++) {
                rb_ary_push(ret, rb_hash_aref(rv, keys_ptr[ii]));
            }
            return ret;  /* return as an array [value1, value2, ...] */
        } else {
            VALUE vv = Qnil;
            rb_hash_foreach(rv, cb_first_value_i, (VALUE)&vv);
            return vv;
        }
    }
}

- (Fixnum) incr(key, delta = 1, options = {}) {|ret| ... } Also known as: increment

Note:

that server values stored and transmitted as unsigned numbers, therefore if you try to store negative number and then increment or decrement it will cause overflow. (see "Integer overflow" example below)

Increment the value of an existing numeric key

The increment methods enable you to increase a given stored integer value. These are the incremental equivalent of the decrement operations and work on the same basis; updating the value of a key if it can be parsed to an integer. The update operation occurs on the server and is provided at the protocol level. This simplifies what would otherwise be a two-stage get and set operation.

The actual value of the key.

Examples:

Increment key by one

c.incr("foo")

Increment key by 50

c.incr("foo", 50)

Increment key by one OR initialize with zero

c.incr("foo", :create => true)   #=> will return old+1 or 0

Increment key by one OR initialize with three

c.incr("foo", 50, :initial => 3) #=> will return old+50 or 3

Increment key and get its CAS value

val, cas = c.incr("foo", :extended => true)

Integer overflow

c.set("foo", -100)
c.get("foo")           #=> -100
c.incr("foo")          #=> 18446744073709551517

Asynchronous invocation

c.run do
  c.incr("foo") do |ret|
    ret.operation   #=> :increment
    ret.success?    #=> true
    ret.key         #=> "foo"
    ret.value
    ret.cas
  end
end

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • delta (Fixnum)

    Integer (up to 64 bits) value to increment

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :create (Boolean) — default: false

    If set to true, it will initialize the key with zero value and zero flags (use :initial option to set another initial value). Note: it won’t increment the missing value.

  • :initial (Fixnum) — default: 0

    Integer (up to 64 bits) value for missing key initialization. This option imply :create option is true.

  • :ttl (Fixnum) — default: self.default_ttl

    Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). This option ignored for existent keys.

  • :extended (Boolean) — default: false

    If set to true, the operation will return tuple [value, cas], otherwise (by default) it returns just value.

Yield Parameters:

  • ret (Result)

    the result of operation in asynchronous mode (valid attributes: error, operation, key, value, cas).

Returns:

  • (Fixnum)

    the actual value of the key.

Raises:



2096
2097
2098
2099
2100
# File 'ext/couchbase_ext/couchbase_ext.c', line 2096

static VALUE
cb_bucket_incr(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_arithmetic(+1, argc, argv, self);
}

- (Couchbase::Bucket) initialize_copy

Initialize copy

Initializes copy of the object, used by #dup

Parameters:

Returns:



1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
# File 'ext/couchbase_ext/couchbase_ext.c', line 1356

static VALUE
cb_bucket_init_copy(VALUE copy, VALUE orig)
{
    bucket_t *copy_b;
    bucket_t *orig_b;

    if (copy == orig)
        return copy;

    if (TYPE(orig) != T_DATA || TYPE(copy) != T_DATA ||
            RDATA(orig)->dfree != (RUBY_DATA_FUNC)cb_bucket_free) {
        rb_raise(rb_eTypeError, "wrong argument type");
    }

    copy_b = DATA_PTR(copy);
    orig_b = DATA_PTR(orig);

    copy_b->port = orig_b->port;
    copy_b->authority = strdup(orig_b->authority);
    copy_b->hostname = strdup(orig_b->hostname);
    copy_b->pool = strdup(orig_b->pool);
    copy_b->bucket = strdup(orig_b->bucket);
    if (orig_b->username) {
        copy_b->username = strdup(orig_b->username);
    }
    if (orig_b->password) {
        copy_b->password = strdup(orig_b->password);
    }
    copy_b->async = orig_b->async;
    copy_b->quiet = orig_b->quiet;
    copy_b->seqno = orig_b->seqno;
    copy_b->default_format = orig_b->default_format;
    copy_b->default_flags = orig_b->default_flags;
    copy_b->default_ttl = orig_b->default_ttl;
    copy_b->timeout = orig_b->timeout;
    copy_b->exception = Qnil;
    if (orig_b->on_error_proc != Qnil) {
        copy_b->on_error_proc = rb_funcall(orig_b->on_error_proc, id_dup, 0);
    }

    do_connect(copy_b);

    return copy;
}

- (String) inspect

Returns a string containing a human-readable representation of the Bucket.

Returns:

  • (String)


1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
# File 'ext/couchbase_ext/couchbase_ext.c', line 1702

static VALUE
cb_bucket_inspect(VALUE self)
{
    VALUE str;
    bucket_t *bucket = DATA_PTR(self);
    char buf[200];

    str = rb_str_buf_new2("#<");
    rb_str_buf_cat2(str, rb_obj_classname(self));
    snprintf(buf, 25, ":%p \"", (void *)self);
    (void)cb_bucket_authority_get(self);
    rb_str_buf_cat2(str, buf);
    rb_str_buf_cat2(str, "http://");
    rb_str_buf_cat2(str, bucket->authority);
    rb_str_buf_cat2(str, "/pools/");
    rb_str_buf_cat2(str, bucket->pool);
    rb_str_buf_cat2(str, "/buckets/");
    rb_str_buf_cat2(str, bucket->bucket);
    rb_str_buf_cat2(str, "/");
    snprintf(buf, 150, "\" default_format=:%s, default_flags=0x%x, quiet=%s, connected=%s, timeout=%u>",
            rb_id2name(SYM2ID(bucket->default_format)),
            bucket->default_flags,
            bucket->quiet ? "true" : "false",
            bucket->handle ? "true" : "false",
            bucket->timeout);
    rb_str_buf_cat2(str, buf);

    return str;
}

- (Object) prepend(key, value, options = {})

Note:

This operation is kind of data-aware from server point of view. This mean that the server treats value as binary stream and just perform concatenation, therefore it won’t work with :marshal and :document formats, because of lack of knowledge how to merge values in these formats. See Bucket#cas for workaround.

Prepend this object to the existing object

Examples:

Simple prepend example

c.set("foo", "aaa")
c.prepend("foo", "bbb")
c.get("foo")           #=> "bbbaaa"

Using explicit format option

c.default_format       #=> :document
c.set("foo", {"y" => "z"})
c.prepend("foo", '[', :format => :plain)
c.append("foo", ', {"z": "y"}]', :format => :plain)
c.get("foo")           #=> [{"y"=>"z"}, {"z"=>"y"}]

Using optimistic locking. The operation will fail on CAS mismatch

ver = c.set("foo", "aaa")
c.prepend("foo", "bbb", :cas => ver)

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • value (Object)

    Value to be stored

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :cas (Fixnum)

    The CAS value for an object. This value created on the server and is guaranteed to be unique for each value of a given key. This value is used to provide simple optimistic concurrency control when multiple clients or threads try to update an item simultaneously.

  • :format (Symbol) — default: self.default_format

    The representation for storing the value in the bucket. For more info see #default_format.

Raises:



3111
3112
3113
3114
3115
# File 'ext/couchbase_ext/couchbase_ext.c', line 3111

static VALUE
cb_bucket_prepend(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_store(LIBCOUCHBASE_PREPEND, argc, argv, self);
}

- (Object) reconnect(url, options = {}) - (Object) reconnect(options = {})

Reconnect the bucket

Reconnect the bucket using initial configuration with optional redefinition.

Overloads:



1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
# File 'ext/couchbase_ext/couchbase_ext.c', line 1419

static VALUE
cb_bucket_reconnect(int argc, VALUE *argv, VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);

    do_scan_connection_options(bucket, argc, argv);
    do_connect(bucket);

    return self;
}

- (Fixnum) replace(key, value, options = {})

Replace the existing object in the database

The CAS value of the object.

Examples:

Replacing missing key

c.replace("foo", "baz")  #=> will raise Couchbase::Error::NotFound: failed to store value (key="foo", error=0x0d)

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • value (Object)

    Value to be stored

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :ttl (Fixnum) — default: self.default_ttl

    Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch).

  • :flags (Fixnum) — default: self.default_flags

    Flags for storage options. Flags are ignored by the server but preserved for use by the client. For more info see #default_flags.

  • :format (Symbol) — default: self.default_format

    The representation for storing the value in the bucket. For more info see #default_format.

Returns:

  • (Fixnum)

    The CAS value of the object.

Raises:



2992
2993
2994
2995
2996
# File 'ext/couchbase_ext/couchbase_ext.c', line 2992

static VALUE
cb_bucket_replace(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_store(LIBCOUCHBASE_REPLACE, argc, argv, self);
}

- (nil) run {|bucket| ... }

Run the event loop.

Examples:

Use block to run the loop

c = Couchbase.new
c.run do
  c.get("foo") {|ret| puts ret.value}
end

Use lambda to run the loop

c = Couchbase.new
operations = lambda do |c|
  c.get("foo") {|ret| puts ret.value}
end
c.run(&operations)

Yield Parameters:

  • bucket (Bucket)

    the bucket instance

Returns:

  • (nil)

Raises:



2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
# File 'ext/couchbase_ext/couchbase_ext.c', line 2834

static VALUE
cb_bucket_run(VALUE self)
{
    VALUE args[2];

    rb_need_block();
    args[0] = self;
    args[1] = rb_block_proc();
    rb_ensure(do_run, (VALUE)args, ensure_run, (VALUE)args);
    return Qnil;
}

- (Fixnum) set(key, value, options = {}) {|ret| ... } Also known as: []=

Unconditionally store the object in the Couchbase

The CAS value of the object.

Examples:

Store the key which will be expired in 2 seconds using relative TTL.

c.set("foo", "bar", :ttl => 2)

Store the key which will be expired in 2 seconds using absolute TTL.

c.set("foo", "bar", :ttl => Time.now.to_i + 2)

Force JSON document format for value

c.set("foo", {"bar" => "baz}, :format => :document)

Use hash-like syntax to store the value

c.set["foo"] = {"bar" => "baz}

Use extended hash-like syntax

c["foo", {:flags => 0x1000, :format => :plain}] = "bar"
c["foo", :flags => 0x1000] = "bar"  # for ruby 1.9.x only

Set application specific flags (note that it will be OR-ed with format flags)

c.set("foo", "bar", :flags => 0x1000)

Perform optimistic locking by specifying last known CAS version

c.set("foo", "bar", :cas => 8835713818674332672)

Perform asynchronous call

c.run do
  c.set("foo", "bar") do |ret|
    ret.operation   #=> :set
    ret.success?    #=> true
    ret.key         #=> "foo"
    ret.cas
  end
end

Parameters:

  • key (String, Symbol)

    Key used to reference the value.

  • value (Object)

    Value to be stored

  • options (Hash)

    Options for operation.

Options Hash (options):

  • :ttl (Fixnum) — default: self.default_ttl

    Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch).

  • :flags (Fixnum) — default: self.default_flags

    Flags for storage options. Flags are ignored by the server but preserved for use by the client. For more info see #default_flags.

  • :format (Symbol) — default: self.default_format

    The representation for storing the value in the bucket. For more info see #default_format.

  • :cas (Fixnum)

    The CAS value for an object. This value created on the server and is guaranteed to be unique for each value of a given key. This value is used to provide simple optimistic concurrency control when multiple clients or threads try to update an item simultaneously.

Yield Parameters:

  • ret (Result)

    the result of operation in asynchronous mode (valid attributes: error, operation, key).

Returns:

  • (Fixnum)

    The CAS value of the object.

Raises:



2914
2915
2916
2917
2918
# File 'ext/couchbase_ext/couchbase_ext.c', line 2914

static VALUE
cb_bucket_set(int argc, VALUE *argv, VALUE self)
{
    return cb_bucket_store(LIBCOUCHBASE_SET, argc, argv, self);
}

- (Hash) stats(arg = nil) {|ret| ... }

Request server statistics.

Fetches stats from each node in cluster. Without a key specified the server will respond with a "default" set of statistical information. In asynchronous mode each statistic is returned in separate call where the Result object yielded (+#key+ contains the name of the statistical item and the #value contains the value, the #node will indicate the server address). In synchronous mode it returns the hash of stats keys and node-value pairs as a value.

Where keys are stat keys, values are host-value pairs

Examples:

Found how many items in the bucket

total = 0
c.stats["total_items"].each do |key, value|
  total += value.to_i
end

Found total items number asynchronously

total = 0
c.run do
  c.stats do |ret|
    if ret.key == "total_items"
      total += ret.value.to_i
    end
  end
end

Get memory stats (works on couchbase buckets)

c.stats(:memory)   #=> {"mem_used"=>{...}, ...}

Parameters:

  • arg (String)

    argument to STATS query

Yield Parameters:

  • ret (Result)

    the object with node, key and value attributes.

Returns:

  • (Hash)

    where keys are stat keys, values are host-value pairs

Raises:



2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
# File 'ext/couchbase_ext/couchbase_ext.c', line 2695

static VALUE
cb_bucket_stats(int argc, VALUE *argv, VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    context_t *ctx;
    VALUE rv, exc, arg, proc;
    char *key;
    size_t nkey;
    libcouchbase_error_t err;
    long seqno;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    rb_scan_args(argc, argv, "01&", &arg, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }

    ctx = xcalloc(1, sizeof(context_t));
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    rv = rb_hash_new();
    ctx->rv = &rv;
    ctx->bucket = bucket;
    ctx->proc = proc;
    cb_gc_protect(bucket, ctx->proc);
    ctx->exception = Qnil;
    if (arg != Qnil) {
        arg = unify_key(arg);
        key = RSTRING_PTR(arg);
        nkey = RSTRING_LEN(arg);
    } else {
        key = NULL;
        nkey = 0;
    }
    seqno = bucket->seqno;
    bucket->seqno++;
    err = libcouchbase_server_stats(bucket->handle, (const void *)ctx,
            key, nkey);
    exc = cb_check_error(err, "failed to schedule stat request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    if (bucket->async) {
        return Qnil;
    } else {
        if (bucket->seqno - seqno > 0) {
            /* we have some operations pending */
            bucket->io->run_event_loop(bucket->io);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        if (bucket->exception != Qnil) {
            rb_exc_raise(bucket->exception);
        }
        return rv;
    }

    return Qnil;
}

- (Boolean) touch(key, options = {}) {|ret| ... } - (Hash) touch(keys) {|ret| ... }

Update the expiry time of an item

The touch method allow you to update the expiration time on a given key. This can be useful for situations where you want to prevent an item from expiring without resetting the associated value. For example, for a session database you might want to keep the session alive in the database each time the user accesses a web page without explicitly updating the session value, keeping the user’s session active and available.

Overloads:

  • - (Boolean) touch(key, options = {}) {|ret| ... }

    true if the operation was successful and false otherwise.

    Examples:

    Touch value using default_ttl

    c.touch("foo")
    

    Touch value using custom TTL (10 seconds)

    c.touch("foo", :ttl => 10)
    

    Parameters:

    • key (String, Symbol)

      Key used to reference the value.

    • options (Hash)

      Options for operation.

    Options Hash (options):

    • :ttl (Fixnum) — default: self.default_ttl

      Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch).

    Yield Parameters:

    • ret (Result)

      the result of operation in asynchronous mode (valid attributes: error, operation, key).

    Returns:

    • (Boolean)

      true if the operation was successful and false otherwise.

    Raises:

  • - (Hash) touch(keys) {|ret| ... }

    Mapping keys to result of touch operation (true if the operation was successful and false otherwise)

    Examples:

    Touch several values

    c.touch("foo" => 10, :bar => 20) #=> {"foo" => true, "bar" => true}
    

    Touch several values in async mode

    c.run do
      c.touch("foo" => 10, :bar => 20) do |ret|
         ret.operation   #=> :touch
         ret.success?    #=> true
         ret.key         #=> "foo" and "bar" in separate calls
      end
    end
    

    Touch single value

    c.touch("foo" => 10)             #=> true
    

    Parameters:

    • keys (Hash)

      The Hash where keys represent the keys in the database, values — the expiry times for corresponding key. See description of :ttl argument above for more information about TTL values.

    Yield Parameters:

    • ret (Result)

      the result of operation for each key in asynchronous mode (valid attributes: error, operation, key).

    Returns:

    • (Hash)

      Mapping keys to result of touch operation (true if the operation was successful and false otherwise)



2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
# File 'ext/couchbase_ext/couchbase_ext.c', line 2428

static VALUE
cb_bucket_touch(int argc, VALUE *argv, VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    context_t *ctx;
    VALUE args, rv, proc, exc;
    size_t nn;
    libcouchbase_error_t err;
    struct key_traits *traits;
    long seqno;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    rb_scan_args(argc, argv, "0*&", &args, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    rb_funcall(args, id_flatten_bang, 0);
    traits = xcalloc(1, sizeof(struct key_traits));
    nn = cb_args_scan_keys(RARRAY_LEN(args), args, bucket, traits);
    ctx = xcalloc(1, sizeof(context_t));
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    ctx->proc = proc;
    cb_gc_protect(bucket, ctx->proc);
    ctx->bucket = bucket;
    rv = rb_hash_new();
    ctx->rv = &rv;
    ctx->exception = Qnil;
    seqno = bucket->seqno;
    bucket->seqno += nn;
    err = libcouchbase_mtouch(bucket->handle, (const void *)ctx,
            traits->nkeys, (const void * const *)traits->keys,
            traits->lens, traits->ttls);
    xfree(traits->keys);
    xfree(traits->lens);
    xfree(traits);
    exc = cb_check_error(err, "failed to schedule touch request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    if (bucket->async) {
        return Qnil;
    } else {
        if (bucket->seqno - seqno > 0) {
            /* we have some operations pending */
            bucket->io->run_event_loop(bucket->io);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        if (bucket->exception != Qnil) {
            rb_exc_raise(bucket->exception);
        }
        if (nn > 1) {
            return rv;  /* return as a hash {key => true, ...} */
        } else {
            VALUE vv = Qnil;
            rb_hash_foreach(rv, cb_first_value_i, (VALUE)&vv);
            return vv;
        }
    }
}

- (Hash) version {|ret| ... }

Returns versions of the server for each node in the cluster

Node-version pairs

Examples:

Synchronous version request

c.version            #=> will render version

Asynchronous version request

c.run do
  c.version do |ret|
    ret.operation    #=> :version
    ret.success?     #=> true
    ret.node         #=> "localhost:11211"
    ret.value        #=> will render version
  end
end

Yield Parameters:

  • ret (Result)

    the object with error, node, operation and value attributes.

Returns:

  • (Hash)

    node-version pairs

Raises:



2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
# File 'ext/couchbase_ext/couchbase_ext.c', line 2601

static VALUE
cb_bucket_version(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    context_t *ctx;
    VALUE rv, exc;
    libcouchbase_error_t err;
    long seqno;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    if (!bucket->async && rb_block_given_p()) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    ctx = xcalloc(1, sizeof(context_t));
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    rv = rb_hash_new();
    ctx->rv = &rv;
    ctx->bucket = bucket;
    ctx->exception = Qnil;
    if (rb_block_given_p()) {
        ctx->proc = rb_block_proc();
    } else {
        ctx->proc = Qnil;
    }
    cb_gc_protect(bucket, ctx->proc);
    seqno = bucket->seqno;
    bucket->seqno++;
    err = libcouchbase_server_versions(bucket->handle, (const void *)ctx);
    exc = cb_check_error(err, "failed to schedule version request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    if (bucket->async) {
        return Qnil;
    } else {
        if (bucket->seqno - seqno > 0) {
            /* we have some operations pending */
            bucket->io->run_event_loop(bucket->io);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        return rv;
    }
}