Class: Libcouchbase::Bucket
- Inherits:
-
Object
- Object
- Libcouchbase::Bucket
- Extended by:
- Forwardable
- Defined in:
- lib/libcouchbase/bucket.rb
Constant Summary collapse
- AddDefaults =
{operation: :add}.freeze
- ReplaceDefaults =
{operation: :replace}.freeze
- AppendDefaults =
{operation: :append}.freeze
- PrependDefaults =
{operation: :prepend}.freeze
- ViewDefaults =
{ on_error: :stop, stale: false }
- FtsDefaults =
{ include_docs: true, size: 10000, # Max result size from: 0, explain: false }
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#quiet ⇒ Object
Returns the value of attribute quiet.
Class Method Summary collapse
-
.finalize(connection) ⇒ Object
Finalizer done right http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/.
Instance Method Summary collapse
-
#add(key, value, async: false, **opts) ⇒ Libcouchbase::Result
Add the item to the database, but fail if the object exists already.
-
#append(key, value, async: false, **opts) ⇒ Libcouchbase::Result
Append this object to the existing object.
-
#compare_and_swap(key, **opts) {|value| ... } ⇒ Libcouchbase::Response
(also: #cas)
Compare and swap value.
-
#decr(key, by = 1, **opts) ⇒ Object
Decrement the value of an existing numeric key.
-
#delete(key, async: false, quiet: @quiet, **opts) ⇒ true, false
Delete the specified key.
-
#delete_design_doc(id, rev = nil, async: false) ⇒ Object
Delete design doc with given id and optional revision.
-
#design_docs(**opts) ⇒ Libcouchbase::DesignDocs
Fetch design docs stored in current bucket.
-
#flush(async: false) ⇒ Libcouchbase::Response
Delete contents of the bucket.
-
#full_text_search(index, query, **opts, &row_modifier) ⇒ Libcouchbase::Results
Returns an enumerable for the results in a full text search.
-
#get(key, *keys, extended: false, async: false, quiet: @quiet, assemble_hash: false, **opts) ⇒ Object, ...
(also: #[])
Obtain an object stored in Couchbase by given key.
-
#get_num_nodes ⇒ Integer
The numbers of nodes in the cluster.
-
#get_num_replicas ⇒ Integer
The numbers of the replicas for each node in the cluster.
-
#incr(key, by = 1, create: false, extended: false, async: false, **opts) ⇒ Integer
Increment the value of an existing numeric key.
-
#initialize(**options) ⇒ Bucket
constructor
A new instance of Bucket.
-
#n1ql(**options) ⇒ Libcouchbase::N1QL
Returns an n1ql query builder.
-
#prepend(key, value, async: false, **opts) ⇒ Libcouchbase::Result
Prepend this object to the existing object.
-
#replace(key, value, async: false, **opts) ⇒ Libcouchbase::Result
Replace the existing object in the database.
-
#save_design_doc(data, id = nil, async: false) ⇒ Object
Update or create design doc with supplied views.
-
#set(key, value, async: false, **opts) ⇒ Libcouchbase::Result
(also: #[]=)
Unconditionally store the object in the Couchbase.
-
#touch(async: false, **opts) ⇒ Object
Touch a key, changing its CAS and optionally setting a timeout.
-
#view(design, view, include_docs: true, is_spatial: false, **opts, &row_modifier) ⇒ Libcouchbase::Results
Returns an enumerable for the results in a view.
-
#wait_results(*results) ⇒ Array
Waits for all the async operations to complete and returns the results.
Constructor Details
#initialize(**options) ⇒ Bucket
Returns a new instance of Bucket.
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/libcouchbase/bucket.rb', line 20 def initialize(**) @connection_options = @connection = Connection.new(**) connect # This obtains the connections reactor @reactor = reactor @quiet = true # clean up the connection once this object is garbage collected ObjectSpace.define_finalizer( self, self.class.finalize(@connection) ) end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
34 35 36 |
# File 'lib/libcouchbase/bucket.rb', line 34 def connection @connection end |
#quiet ⇒ Object
Returns the value of attribute quiet.
35 36 37 |
# File 'lib/libcouchbase/bucket.rb', line 35 def quiet @quiet end |
Class Method Details
.finalize(connection) ⇒ Object
Finalizer done right http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
13 14 15 16 17 18 |
# File 'lib/libcouchbase/bucket.rb', line 13 def self.finalize(connection) proc { connection.reactor.unref connection.destroy } end |
Instance Method Details
#add(key, value, async: false, **opts) ⇒ Libcouchbase::Result
Add the item to the database, but fail if the object exists already
202 203 204 |
# File 'lib/libcouchbase/bucket.rb', line 202 def add(key, value, async: false, **opts) result @connection.store(key, value, **AddDefaults.merge(opts)), async end |
#append(key, value, async: false, **opts) ⇒ Libcouchbase::Result
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.
Append this object to the existing object
347 348 349 |
# File 'lib/libcouchbase/bucket.rb', line 347 def append(key, value, async: false, **opts) result @connection.store(key, value, **AppendDefaults.merge(opts)), async end |
#compare_and_swap(key, **opts) {|value| ... } ⇒ Libcouchbase::Response Also known as: cas
Compare and swap value.
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.
Setting the :retry option to a positive number will cause this method
to rescue the Error::KeyExists error that happens when
an update collision is detected, and automatically get a fresh copy
of the value and retry the block. This will repeat as long as there
continues to be conflicts, up to the maximum number of retries specified.
676 677 678 679 680 681 682 683 684 685 686 687 688 689 |
# File 'lib/libcouchbase/bucket.rb', line 676 def compare_and_swap(key, **opts) retries = opts.delete(:retry) || 0 begin current = result(@connection.get(key)) new_value = yield current.value, opts opts[:cas] = current.cas set(key, new_value, **opts) rescue Libcouchbase::Error::KeyExists retries -= 1 retry if retries >= 0 raise end end |
#decr(key, by = 1, **opts) ⇒ Object
Decrement the value of an existing numeric key
Helper method, see incr
458 459 460 |
# File 'lib/libcouchbase/bucket.rb', line 458 def decr(key, by = 1, **opts) incr(key, -by, **opts) end |
#delete(key, async: false, quiet: @quiet, **opts) ⇒ true, false
Delete the specified key
498 499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/libcouchbase/bucket.rb', line 498 def delete(key, async: false, quiet: @quiet, **opts) promise = @connection.remove(key, **opts).then { true } if quiet promise = promise.catch { |error| if error.is_a? Libcouchbase::Error::KeyNotFound false else ::Libuv::Q.reject(@reactor, error) end } end result promise, async end |
#delete_design_doc(id, rev = nil, async: false) ⇒ Object
Delete design doc with given id and optional revision.
635 636 637 638 639 |
# File 'lib/libcouchbase/bucket.rb', line 635 def delete_design_doc(id, rev = nil, async: false) id = id.to_s.sub(/^_design\//, '') rev = "?rev=#{rev}" if rev result @connection.http("/_design/#{id}#{rev}", method: :delete, type: :view), async end |
#design_docs(**opts) ⇒ Libcouchbase::DesignDocs
Fetch design docs stored in current bucket
535 536 537 |
# File 'lib/libcouchbase/bucket.rb', line 535 def design_docs(**opts) DesignDocs.new(self, @connection, method(:result), **opts) end |
#flush(async: false) ⇒ Libcouchbase::Response
Delete contents of the bucket
523 524 525 |
# File 'lib/libcouchbase/bucket.rb', line 523 def flush(async: false) result @connection.flush, async end |
#full_text_search(index, query, **opts, &row_modifier) ⇒ Libcouchbase::Results
Returns an enumerable for the results in a full text search.
Results are lazily loaded when an operation is performed on the enum
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/libcouchbase/bucket.rb', line 569 def full_text_search(index, query, **opts, &row_modifier) if query.is_a? Hash opts[:query] = query else opts[:query] = {query: query} end fts = @connection.full_text_search(index, **FtsDefaults.merge(opts)) current = ::Libuv::Reactor.current if current && current.running? ResultsLibuv.new(fts, current, &row_modifier) elsif Object.const_defined?(:EventMachine) && EM.reactor_thread? ResultsEM.new(fts, &row_modifier) else ResultsNative.new(fts, &row_modifier) end end |
#get(key, *keys, extended: false, async: false, quiet: @quiet, assemble_hash: false, **opts) ⇒ Object, ... Also known as: []
Obtain an object stored in Couchbase by given key.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/libcouchbase/bucket.rb', line 87 def get(key, *keys, extended: false, async: false, quiet: @quiet, assemble_hash: false, **opts) was_array = key.respond_to?(:to_a) || keys.length > 0 keys.unshift Array(key) # Convert enumerables keys.flatten! # Ensure we're left with a list of keys if keys.length == 1 promise = @connection.get(keys[0], **opts) unless extended promise = promise.then(proc { |resp| resp.value }) end if quiet promise = promise.catch { |err| if err.is_a? Libcouchbase::Error::KeyNotFound nil else ::Libuv::Q.reject(@reactor, err) end } end if assemble_hash promise = promise.then(proc { |val| hash = defined?(::HashWithIndifferentAccess) ? ::HashWithIndifferentAccess.new : {} hash[keys[0]] = val hash }) elsif was_array promise = promise.then(proc { |val| Array(val) }) end result(promise, async) else promises = keys.collect { |key| @connection.get(key, **opts) } if quiet promises.map! { |prom| prom.catch { |err| if err.is_a? Libcouchbase::Error::KeyNotFound nil else ::Libuv::Q.reject(@reactor, err) end } } end result(@reactor.all(*promises).then(proc { |results| if extended results.compact! else results.collect! { |resp| resp.value if resp } end if assemble_hash hash = defined?(::HashWithIndifferentAccess) ? ::HashWithIndifferentAccess.new : {} keys.each_with_index do |key, index| hash[key] = results[index] end hash else results end }), async) end end |
#get_num_nodes ⇒ Integer
The numbers of nodes in the cluster
700 701 702 |
# File 'lib/libcouchbase/bucket.rb', line 700 def get_num_nodes result @connection.get_num_nodes end |
#get_num_replicas ⇒ Integer
The numbers of the replicas for each node in the cluster
694 695 696 |
# File 'lib/libcouchbase/bucket.rb', line 694 def get_num_replicas result @connection.get_num_replicas end |
#incr(key, by = 1, create: false, extended: false, async: false, **opts) ⇒ Integer
Increment the value of an existing numeric key
The increment method allow you to increase or decrease a given stored integer value. 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.
445 446 447 448 449 450 451 452 453 |
# File 'lib/libcouchbase/bucket.rb', line 445 def incr(key, by = 1, create: false, extended: false, async: false, **opts) opts[:delta] ||= by opts[:initial] = 0 if create promise = @connection.counter(key, **opts) if not extended promise = promise.then { |resp| resp.value } end result promise, async end |
#n1ql(**options) ⇒ Libcouchbase::N1QL
Returns an n1ql query builder.
596 597 598 |
# File 'lib/libcouchbase/bucket.rb', line 596 def n1ql(**) N1QL.new(self, **) end |
#prepend(key, value, async: false, **opts) ⇒ Libcouchbase::Result
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.
Prepend this object to the existing object
392 393 394 |
# File 'lib/libcouchbase/bucket.rb', line 392 def prepend(key, value, async: false, **opts) result @connection.store(key, value, **PrependDefaults.merge(opts)), async end |
#replace(key, value, async: false, **opts) ⇒ Libcouchbase::Result
Replace the existing object in the database
302 303 304 |
# File 'lib/libcouchbase/bucket.rb', line 302 def replace(key, value, async: false, **opts) result @connection.store(key, value, **ReplaceDefaults.merge(opts)), async end |
#save_design_doc(data, id = nil, async: false) ⇒ Object
Update or create design doc with supplied views
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
# File 'lib/libcouchbase/bucket.rb', line 606 def save_design_doc(data, id = nil, async: false) attrs = case data when String JSON.parse(data, Connection::DECODE_OPTIONS) when IO JSON.parse(data.read, Connection::DECODE_OPTIONS) when Hash data else raise ArgumentError, "Document should be Hash, String or IO instance" end attrs[:language] ||= :javascript id ||= attrs.delete(:_id) id = id.to_s.sub(/^_design\//, '') result @connection.http("/_design/#{id}", method: :put, body: attrs, type: :view ), async end |
#set(key, value, async: false, **opts) ⇒ Libcouchbase::Result Also known as: []=
Unconditionally store the object in the Couchbase
254 255 256 257 |
# File 'lib/libcouchbase/bucket.rb', line 254 def set(key, value, async: false, **opts) # default operation is set result @connection.store(key, value, **opts), async end |
#touch(async: false, **opts) ⇒ Object
Touch a key, changing its CAS and optionally setting a timeout
528 529 530 |
# File 'lib/libcouchbase/bucket.rb', line 528 def touch(async: false, **opts) result @connection.touch(**opts), async end |
#view(design, view, include_docs: true, is_spatial: false, **opts, &row_modifier) ⇒ Libcouchbase::Results
Returns an enumerable for the results in a view.
Results are lazily loaded when an operation is performed on the enum
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
# File 'lib/libcouchbase/bucket.rb', line 544 def view(design, view, include_docs: true, is_spatial: false, **opts, &row_modifier) view = @connection.query_view(design, view, **ViewDefaults.merge(opts)) view.include_docs = include_docs view.is_spatial = is_spatial current = ::Libuv::Reactor.current if current && current.running? ResultsLibuv.new(view, current, &row_modifier) elsif Object.const_defined?(:EventMachine) && EM.reactor_thread? ResultsEM.new(view, &row_modifier) else ResultsNative.new(view, &row_modifier) end end |
#wait_results(*results) ⇒ Array
Waits for all the async operations to complete and returns the results
707 708 709 |
# File 'lib/libcouchbase/bucket.rb', line 707 def wait_results(*results) result ::Libuv::Q.all(@reactor, *results.flatten) end |