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(*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
195 196 197 |
# File 'lib/libcouchbase/bucket.rb', line 195 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
340 341 342 |
# File 'lib/libcouchbase/bucket.rb', line 340 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.
669 670 671 672 673 674 675 676 677 678 679 680 681 682 |
# File 'lib/libcouchbase/bucket.rb', line 669 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
451 452 453 |
# File 'lib/libcouchbase/bucket.rb', line 451 def decr(key, by = 1, **opts) incr(key, -by, **opts) end |
#delete(key, async: false, quiet: @quiet, **opts) ⇒ true, false
Delete the specified key
491 492 493 494 495 496 497 498 499 500 501 502 503 |
# File 'lib/libcouchbase/bucket.rb', line 491 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.
628 629 630 631 632 |
# File 'lib/libcouchbase/bucket.rb', line 628 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
528 529 530 |
# File 'lib/libcouchbase/bucket.rb', line 528 def design_docs(**opts) DesignDocs.new(self, @connection, method(:result), **opts) end |
#flush(async: false) ⇒ Libcouchbase::Response
Delete contents of the bucket
516 517 518 |
# File 'lib/libcouchbase/bucket.rb', line 516 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
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 |
# File 'lib/libcouchbase/bucket.rb', line 562 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(*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 |
# File 'lib/libcouchbase/bucket.rb', line 87 def get(*keys, extended: false, async: false, quiet: @quiet, assemble_hash: false, **opts) keys = keys.flatten 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 }) 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 not extended # Check if resp nil as might have been a quiet request 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
693 694 695 |
# File 'lib/libcouchbase/bucket.rb', line 693 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
687 688 689 |
# File 'lib/libcouchbase/bucket.rb', line 687 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.
438 439 440 441 442 443 444 445 446 |
# File 'lib/libcouchbase/bucket.rb', line 438 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.
589 590 591 |
# File 'lib/libcouchbase/bucket.rb', line 589 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
385 386 387 |
# File 'lib/libcouchbase/bucket.rb', line 385 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
295 296 297 |
# File 'lib/libcouchbase/bucket.rb', line 295 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
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 |
# File 'lib/libcouchbase/bucket.rb', line 599 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
247 248 249 250 |
# File 'lib/libcouchbase/bucket.rb', line 247 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
521 522 523 |
# File 'lib/libcouchbase/bucket.rb', line 521 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
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 |
# File 'lib/libcouchbase/bucket.rb', line 537 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
700 701 702 |
# File 'lib/libcouchbase/bucket.rb', line 700 def wait_results(*results) result ::Libuv::Q.all(@reactor, *results.flatten) end |