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 collapse

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: dustin.github.com/2011/02/17/memcached-set.html

0x02

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, options = {}) ⇒ Bucket #initialize(options = {}) ⇒ Bucket

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')

Overloads:

  • #initialize(url, options = {}) ⇒ Bucket

    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) (defaults to: {})

      The options for connection. See options definition below.

  • #initialize(options = {}) ⇒ Bucket

    Initialize bucket using options only.

    Parameters:

    • options (Hash) (defaults to: {})

      The options for operation for connection

    Options Hash (options):

    • :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).



1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
# File 'ext/couchbase_ext/couchbase_ext.c', line 1281

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;

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

    return self;
}

Instance Attribute Details

#authorityString (readonly)

Returns host with port.

Returns:

  • (String)

    host with port



1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
# File 'ext/couchbase_ext/couchbase_ext.c', line 1522

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 = calloc(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 rb_str_new2(bucket->authority);
}

#bucketString (readonly) Also known as: name

Returns the bucket name.

Returns:

  • (String)

    the bucket name



1542
1543
1544
1545
1546
1547
# File 'ext/couchbase_ext/couchbase_ext.c', line 1542

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

#default_flagsFixnum

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



1390
1391
1392
1393
1394
1395
# File 'ext/couchbase_ext/couchbase_ext.c', line 1390

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

#default_formatSymbol

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: 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



1407
1408
1409
1410
1411
1412
# File 'ext/couchbase_ext/couchbase_ext.c', line 1407

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

#hostnameString (readonly)

Returns the host name of the management interface (default: “localhost”).

Returns:

  • (String)

    the host name of the management interface (default: “localhost”)



1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
# File 'ext/couchbase_ext/couchbase_ext.c', line 1489

static VALUE
cb_bucket_hostname_get(VALUE self)
{
    bucket_t *bucket = DATA_PTR(self);
    if (bucket->handle) {
        if (bucket->hostname) {
            free(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 rb_str_new2(bucket->hostname);
}

#on_error {|op, key, exc| ... } ⇒ Proc

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



1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
# File 'ext/couchbase_ext/couchbase_ext.c', line 1454

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;
    }
}

#passwordString (readonly)

Returns the password for protected buckets.

Returns:

  • (String)

    the password for protected buckets



1573
1574
1575
1576
1577
1578
# File 'ext/couchbase_ext/couchbase_ext.c', line 1573

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

#poolString (readonly)

Returns the pool name (usually “default”).

Returns:

  • (String)

    the pool name (usually “default”)



1552
1553
1554
1555
1556
1557
# File 'ext/couchbase_ext/couchbase_ext.c', line 1552

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

#portFixnum (readonly)

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

Returns:

  • (Fixnum)

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



1509
1510
1511
1512
1513
1514
1515
1516
1517
# File 'ext/couchbase_ext/couchbase_ext.c', line 1509

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);
}

#quietBoolean 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)


1372
1373
1374
1375
1376
1377
# File 'ext/couchbase_ext/couchbase_ext.c', line 1372

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

#seqnoObject (readonly)

The number of scheduled commands



966
967
968
969
970
971
972
# File 'ext/couchbase_ext/couchbase_ext.c', line 966

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

    return LONG2FIX(bucket->seqno);
}

#timeoutFixnum

Returns 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.



1466
1467
1468
1469
1470
1471
# File 'ext/couchbase_ext/couchbase_ext.c', line 1466

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

#urlString (readonly)

Returns the address of the cluster management interface.

Returns:

  • (String)

    the address of the cluster management interface



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

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;
}

#usernameString (readonly)

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

Returns:

  • (String)

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



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

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

Class Method Details

.new(*args) ⇒ Bucket

Create and initialize new Bucket.

Returns:

See Also:



1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
# File 'ext/couchbase_ext/couchbase_ext.c', line 1218

static VALUE
cb_bucket_new(int argc, VALUE *argv, VALUE klass)
{
    VALUE obj;
    bucket_t *bucket;

    /* allocate new bucket struct and set it to zero */
    obj = Data_Make_Struct(klass, bucket_t, cb_bucket_mark, cb_bucket_free,
            bucket);
    rb_obj_call_init(obj, argc, argv);
    return obj;
}

Instance Method Details

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

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

Returns 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) (defaults to: {})

    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:



2855
2856
2857
2858
2859
# File 'ext/couchbase_ext/couchbase_ext.c', line 2855

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

#append(key, value, options = {}) ⇒ Fixnum

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

Returns 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) (defaults to: {})

    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:



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

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

#async?Boolean

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

See Also:



1365
1366
1367
1368
1369
1370
# File 'ext/couchbase_ext/couchbase_ext.c', line 1365

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

#cas(key, options = {}) {|value| ... } ⇒ Fixnum 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)
    end
  else
    val, flags, ver = get(key, options)
    val = yield(val) # get new value from caller
    set(key, val, :cas => ver)
  end
end

#connected?Boolean

Check whether the instance connected to the cluster.

Returns:

  • (Boolean)

    true if the instance connected to the cluster



1339
1340
1341
1342
1343
1344
# File 'ext/couchbase_ext/couchbase_ext.c', line 1339

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

#decr(key, delta = 1, options = {}) {|ret| ... } ⇒ Fixnum 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.

Returns 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) (defaults to: 1)

    Integer (up to 64 bits) value to decrement

  • options (Hash) (defaults to: {})

    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:



2086
2087
2088
2089
2090
# File 'ext/couchbase_ext/couchbase_ext.c', line 2086

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

#delete(key, options = {}) ⇒ Object

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) (defaults to: {})

    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:



1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
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
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
# File 'ext/couchbase_ext/couchbase_ext.c', line 1672

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 = calloc(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;
    rb_hash_aset(object_space, ctx->proc|1, 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) {
        free(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;
        free(ctx);
        if (exc != Qnil) {
            rb_exc_raise(exc);
        }
        return rv;
    }
}

#disconnecttrue

Close the connection to the cluster

Returns:

  • (true)

Raises:



3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
# File 'ext/couchbase_ext/couchbase_ext.c', line 3034

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");
    }
}

#flush {|ret| ... } ⇒ Boolean

Deletes all values from a server

Returns 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:



2421
2422
2423
2424
2425
2426
2427
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
# File 'ext/couchbase_ext/couchbase_ext.c', line 2421

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 = calloc(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;
    }
    rb_hash_aset(object_space, ctx->proc|1, 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) {
        free(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;
        free(ctx);
        if (exc != Qnil) {
            rb_exc_raise(exc);
        }
        return rv;
    }
}

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

Obtain an object stored in Couchbase by given key.

Overloads:

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

    Returns 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) (defaults to: {})

      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:

  • #get(keys, options = {}) ⇒ Hash

    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) (defaults to: {})

      Options for operation. (see options definition above)

    Returns:

    • (Hash)

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



2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
# File 'ext/couchbase_ext/couchbase_ext.c', line 2180

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 = calloc(1, sizeof(struct key_traits));
    nn = cb_args_scan_keys(RARRAY_LEN(args), args, bucket, traits);
    ctx = calloc(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;
    rb_hash_aset(object_space, ctx->proc|1, 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);
    free(traits->keys);
    free(traits->lens);
    free(traits->ttls);
    free(traits);
    exc = cb_check_error(err, "failed to schedule get request", Qnil);
    if (exc != Qnil) {
        free(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;
        free(ctx);
        if (exc != Qnil) {
            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;
        }
    }
}

#incr(key, delta = 1, options = {}) {|ret| ... } ⇒ Fixnum 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.

Returns 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) (defaults to: 1)

    Integer (up to 64 bits) value to increment

  • options (Hash) (defaults to: {})

    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:



1997
1998
1999
2000
2001
# File 'ext/couchbase_ext/couchbase_ext.c', line 1997

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

#inspectString

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

Returns:

  • (String)


1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
# File 'ext/couchbase_ext/couchbase_ext.c', line 1606

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;
}

#prepend(key, value, options = {}) ⇒ Object

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) (defaults to: {})

    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:



3007
3008
3009
3010
3011
# File 'ext/couchbase_ext/couchbase_ext.c', line 3007

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

#reconnect(url, options = {}) ⇒ Object #reconnect(options = {}) ⇒ Object

Reconnect the bucket

Reconnect the bucket using initial configuration with optional redefinition.

Overloads:



1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
# File 'ext/couchbase_ext/couchbase_ext.c', line 1323

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;
}

#replace(key, value, options = {}) ⇒ Fixnum

Replace the existing object in the database

Returns 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) (defaults to: {})

    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:



2888
2889
2890
2891
2892
# File 'ext/couchbase_ext/couchbase_ext.c', line 2888

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

#run {|bucket| ... } ⇒ nil

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:



2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
# File 'ext/couchbase_ext/couchbase_ext.c', line 2730

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;
}

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

Unconditionally store the object in the Couchbase

Returns 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) (defaults to: {})

    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:



2810
2811
2812
2813
2814
# File 'ext/couchbase_ext/couchbase_ext.c', line 2810

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

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

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.

Returns 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) (defaults to: nil)

    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:



2592
2593
2594
2595
2596
2597
2598
2599
2600
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
2654
2655
2656
2657
# File 'ext/couchbase_ext/couchbase_ext.c', line 2592

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 = calloc(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;
    rb_hash_aset(object_space, ctx->proc|1, 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) {
        free(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;
        free(ctx);
        if (exc != Qnil) {
            rb_exc_raise(exc);
        }
        if (bucket->exception != Qnil) {
            rb_exc_raise(bucket->exception);
        }
        return rv;
    }

    return Qnil;
}

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

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:

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

    Returns 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) (defaults to: {})

      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:

  • #touch(keys) {|ret| ... } ⇒ Hash

    Returns 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)



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
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
# File 'ext/couchbase_ext/couchbase_ext.c', line 2328

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 = calloc(1, sizeof(struct key_traits));
    nn = cb_args_scan_keys(RARRAY_LEN(args), args, bucket, traits);
    ctx = calloc(1, sizeof(context_t));
    if (ctx == NULL) {
        rb_raise(eNoMemoryError, "failed to allocate memory for context");
    }
    ctx->proc = proc;
    rb_hash_aset(object_space, ctx->proc|1, 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);
    free(traits->keys);
    free(traits->lens);
    free(traits);
    exc = cb_check_error(err, "failed to schedule touch request", Qnil);
    if (exc != Qnil) {
        free(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;
        free(ctx);
        if (exc != Qnil) {
            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;
        }
    }
}

#version {|ret| ... } ⇒ Hash

Returns versions of the server for each node in the cluster

Returns 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:



2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
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
# File 'ext/couchbase_ext/couchbase_ext.c', line 2499

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 = calloc(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;
    }
    rb_hash_aset(object_space, ctx->proc|1, 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) {
        free(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;
        free(ctx);
        if (exc != Qnil) {
            rb_exc_raise(exc);
        }
        return rv;
    }
}