libcouchbase-mapo 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +38 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +24 -0
  8. data/README.md +445 -0
  9. data/Rakefile +76 -0
  10. data/ext/README.md +6 -0
  11. data/ext/Rakefile +19 -0
  12. data/lib/libcouchbase.rb +40 -0
  13. data/lib/libcouchbase/bucket.rb +825 -0
  14. data/lib/libcouchbase/callbacks.rb +69 -0
  15. data/lib/libcouchbase/connection.rb +886 -0
  16. data/lib/libcouchbase/design_docs.rb +92 -0
  17. data/lib/libcouchbase/error.rb +68 -0
  18. data/lib/libcouchbase/ext/libcouchbase.rb +1175 -0
  19. data/lib/libcouchbase/ext/libcouchbase/cmdbase.rb +23 -0
  20. data/lib/libcouchbase/ext/libcouchbase/cmdcounter.rb +36 -0
  21. data/lib/libcouchbase/ext/libcouchbase/cmdendure.rb +26 -0
  22. data/lib/libcouchbase/ext/libcouchbase/cmdfts.rb +24 -0
  23. data/lib/libcouchbase/ext/libcouchbase/cmdget.rb +30 -0
  24. data/lib/libcouchbase/ext/libcouchbase/cmdgetreplica.rb +49 -0
  25. data/lib/libcouchbase/ext/libcouchbase/cmdhttp.rb +58 -0
  26. data/lib/libcouchbase/ext/libcouchbase/cmdn1ql.rb +40 -0
  27. data/lib/libcouchbase/ext/libcouchbase/cmdobseqno.rb +33 -0
  28. data/lib/libcouchbase/ext/libcouchbase/cmdobserve.rb +30 -0
  29. data/lib/libcouchbase/ext/libcouchbase/cmdstore.rb +40 -0
  30. data/lib/libcouchbase/ext/libcouchbase/cmdstoredur.rb +45 -0
  31. data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +61 -0
  32. data/lib/libcouchbase/ext/libcouchbase/cmdverbosity.rb +29 -0
  33. data/lib/libcouchbase/ext/libcouchbase/cmdviewquery.rb +61 -0
  34. data/lib/libcouchbase/ext/libcouchbase/contigbuf.rb +14 -0
  35. data/lib/libcouchbase/ext/libcouchbase/create_st.rb +15 -0
  36. data/lib/libcouchbase/ext/libcouchbase/create_st0.rb +23 -0
  37. data/lib/libcouchbase/ext/libcouchbase/create_st1.rb +26 -0
  38. data/lib/libcouchbase/ext/libcouchbase/create_st2.rb +32 -0
  39. data/lib/libcouchbase/ext/libcouchbase/create_st3.rb +26 -0
  40. data/lib/libcouchbase/ext/libcouchbase/crst_u.rb +20 -0
  41. data/lib/libcouchbase/ext/libcouchbase/durability_opts_st_v.rb +11 -0
  42. data/lib/libcouchbase/ext/libcouchbase/durability_opts_t.rb +14 -0
  43. data/lib/libcouchbase/ext/libcouchbase/durabilityopt_sv0.rb +63 -0
  44. data/lib/libcouchbase/ext/libcouchbase/enums.rb +1007 -0
  45. data/lib/libcouchbase/ext/libcouchbase/fragbuf.rb +18 -0
  46. data/lib/libcouchbase/ext/libcouchbase/ftshandle.rb +7 -0
  47. data/lib/libcouchbase/ext/libcouchbase/histogram.rb +34 -0
  48. data/lib/libcouchbase/ext/libcouchbase/http_request_t.rb +7 -0
  49. data/lib/libcouchbase/ext/libcouchbase/keybuf.rb +20 -0
  50. data/lib/libcouchbase/ext/libcouchbase/multicmd_ctx.rb +30 -0
  51. data/lib/libcouchbase/ext/libcouchbase/mutation_token.rb +17 -0
  52. data/lib/libcouchbase/ext/libcouchbase/n1qlhandle.rb +7 -0
  53. data/lib/libcouchbase/ext/libcouchbase/n1qlparams.rb +7 -0
  54. data/lib/libcouchbase/ext/libcouchbase/respbase.rb +29 -0
  55. data/lib/libcouchbase/ext/libcouchbase/respcounter.rb +32 -0
  56. data/lib/libcouchbase/ext/libcouchbase/respendure.rb +49 -0
  57. data/lib/libcouchbase/ext/libcouchbase/respfts.rb +40 -0
  58. data/lib/libcouchbase/ext/libcouchbase/respget.rb +44 -0
  59. data/lib/libcouchbase/ext/libcouchbase/resphttp.rb +48 -0
  60. data/lib/libcouchbase/ext/libcouchbase/respmcversion.rb +38 -0
  61. data/lib/libcouchbase/ext/libcouchbase/respn1ql.rb +41 -0
  62. data/lib/libcouchbase/ext/libcouchbase/respobseqno.rb +52 -0
  63. data/lib/libcouchbase/ext/libcouchbase/respobserve.rb +41 -0
  64. data/lib/libcouchbase/ext/libcouchbase/respserverbase.rb +32 -0
  65. data/lib/libcouchbase/ext/libcouchbase/respstats.rb +38 -0
  66. data/lib/libcouchbase/ext/libcouchbase/respstore.rb +32 -0
  67. data/lib/libcouchbase/ext/libcouchbase/respstoredur.rb +38 -0
  68. data/lib/libcouchbase/ext/libcouchbase/respsubdoc.rb +35 -0
  69. data/lib/libcouchbase/ext/libcouchbase/respviewquery.rb +67 -0
  70. data/lib/libcouchbase/ext/libcouchbase/sdentry.rb +22 -0
  71. data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +31 -0
  72. data/lib/libcouchbase/ext/libcouchbase/t.rb +7 -0
  73. data/lib/libcouchbase/ext/libcouchbase/valbuf.rb +22 -0
  74. data/lib/libcouchbase/ext/libcouchbase/valbuf_u_buf.rb +14 -0
  75. data/lib/libcouchbase/ext/libcouchbase/viewhandle.rb +7 -0
  76. data/lib/libcouchbase/ext/libcouchbase_libuv.rb +22 -0
  77. data/lib/libcouchbase/ext/tasks.rb +39 -0
  78. data/lib/libcouchbase/n1ql.rb +78 -0
  79. data/lib/libcouchbase/query_full_text.rb +147 -0
  80. data/lib/libcouchbase/query_n1ql.rb +123 -0
  81. data/lib/libcouchbase/query_view.rb +135 -0
  82. data/lib/libcouchbase/results_fiber.rb +281 -0
  83. data/lib/libcouchbase/results_native.rb +220 -0
  84. data/lib/libcouchbase/subdoc_request.rb +139 -0
  85. data/lib/libcouchbase/version.rb +5 -0
  86. data/libcouchbase.gemspec +68 -0
  87. data/spec/bucket_spec.rb +290 -0
  88. data/spec/connection_spec.rb +257 -0
  89. data/spec/design_docs_spec.rb +31 -0
  90. data/spec/error_spec.rb +26 -0
  91. data/spec/fts_spec.rb +135 -0
  92. data/spec/n1ql_spec.rb +206 -0
  93. data/spec/results_libuv_spec.rb +244 -0
  94. data/spec/results_native_spec.rb +259 -0
  95. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/design.json +1 -0
  96. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/data-0000.cbb +0 -0
  97. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/failover.json +1 -0
  98. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/meta.json +1 -0
  99. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/seqno.json +1 -0
  100. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/snapshot_markers.json +1 -0
  101. data/spec/subdoc_spec.rb +192 -0
  102. data/spec/view_spec.rb +201 -0
  103. data/windows_build.md +36 -0
  104. metadata +265 -0
@@ -0,0 +1,22 @@
1
+ module Libcouchbase::Ext
2
+ # (Not documented)
3
+ #
4
+ # ## Fields:
5
+ # :vtype ::
6
+ # (KVBUFTYPE) Value request type. This may be one of:
7
+ # - LCB_KV_COPY: Copy over the value into LCB's own buffers
8
+ # Use the 'contig' field to supply the information.
9
+ #
10
+ # - LCB_KV_CONTIG: The buffer is a contiguous chunk of value data.
11
+ # Use the 'contig' field to supply the information.
12
+ #
13
+ # - LCB_KV_IOV: The buffer is a series of IOV elements. Use the 'multi'
14
+ # field to supply the information.
15
+ # :u_buf ::
16
+ # (VALBUFUBuf)
17
+ class VALBUF < FFI::Struct
18
+ layout :vtype, KVBUFTYPE,
19
+ :u_buf, VALBUFUBuf.by_value
20
+ end
21
+
22
+ end
@@ -0,0 +1,14 @@
1
+ module Libcouchbase::Ext
2
+ # (Not documented)
3
+ #
4
+ # ## Fields:
5
+ # :contig ::
6
+ # (CONTIGBUF)
7
+ # :multi ::
8
+ # (FRAGBUF)
9
+ class VALBUFUBuf < FFI::Union
10
+ layout :contig, CONTIGBUF.by_value,
11
+ :multi, FRAGBUF.by_value
12
+ end
13
+
14
+ end
@@ -0,0 +1,7 @@
1
+ module Libcouchbase::Ext
2
+ # (Not documented)
3
+ class VIEWHANDLE < FFI::Struct
4
+ layout :dummy, :char
5
+ end
6
+
7
+ end
@@ -0,0 +1,22 @@
1
+
2
+ # This file contains all the structures required to configure libcouchbase to use
3
+ # Libuv as the primary event loop
4
+
5
+ module Libcouchbase::Ext::Libuv
6
+ extend FFI::Library
7
+ if FFI::Platform.windows?
8
+ ffi_lib ::File.expand_path("../../../../ext/libcouchbase_libuv.dll", __FILE__)
9
+ else
10
+ ffi_lib ::File.expand_path("../../../../ext/libcouchbase/build/lib/libcouchbase_libuv.#{FFI::Platform::LIBSUFFIX}", __FILE__)
11
+ end
12
+
13
+ # ref: http://docs.couchbase.com/sdk-api/couchbase-c-client-2.4.8/group__lcb-libuv.html
14
+ class UVOptions < FFI::Struct
15
+ layout :version, :int,
16
+ :loop, :pointer,
17
+ :start_stop_noop,:int
18
+ end
19
+
20
+ # pointer param returns IO opts structure
21
+ attach_function :create_libuv_io_opts, :lcb_create_libuv_io_opts, [:int, :pointer, UVOptions.by_ref], ::Libcouchbase::Ext::ErrorT
22
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true, encoding: ASCII-8BIT
2
+
3
+ require 'fileutils'
4
+ require 'libuv'
5
+
6
+ module FFI::Platform
7
+ def self.ia32?
8
+ ARCH == "i386"
9
+ end
10
+
11
+ def self.x64?
12
+ ARCH == "x86_64"
13
+ end
14
+ end
15
+
16
+ # Ensure the submodule is cloned
17
+ file 'ext/libcouchbase/include' do
18
+ system 'git', 'submodule', 'update', '--init'
19
+ end
20
+
21
+ file 'ext/libcouchbase/build' => 'ext/libcouchbase/include' do
22
+ FileUtils.mkdir('ext/libcouchbase/build')
23
+ end
24
+
25
+ file 'ext/libcouchbase/build/makefile' => 'ext/libcouchbase/build' do
26
+ result = nil
27
+ Dir.chdir("ext/libcouchbase") do |path|
28
+ result = system './cmake/configure', '-disable-couchbasemock', '-with-libuv', ::File.expand_path('../../', ::Libuv::Ext.path_to_internal_libuv)
29
+ end
30
+ raise 'could not find cmake on path' unless result
31
+ end
32
+
33
+ file "ext/libcouchbase/build/lib/libcouchbase_libuv.#{FFI::Platform::LIBSUFFIX}" => 'ext/libcouchbase/build/makefile' do
34
+ result = nil
35
+ Dir.chdir('ext/libcouchbase/build') do |path|
36
+ result = system 'make'
37
+ end
38
+ raise 'make failed' unless result
39
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true, encoding: ASCII-8BIT
2
+
3
+ module Libcouchbase
4
+ class N1QL
5
+ Ordering = [
6
+ :build_index, :create_index, :drop_index, :create_primary_index,
7
+ :drop_primary_index, :grant, :on, :to, :infer, :select, :insert_into,
8
+ :delete_from, :update, :from, :with, :use_keys, :unnest, :join, :where,
9
+ :group_by, :order_by, :limit, :offset, :upsert_into, :merge_into
10
+ ]
11
+
12
+ def initialize(bucket, explain: false, **options)
13
+ @bucket = bucket
14
+ @connection = bucket.connection
15
+ @explain = !!explain
16
+ options.each do |key, value|
17
+ if self.respond_to? key
18
+ self.public_send key, value
19
+ end
20
+ end
21
+ end
22
+
23
+ attr_accessor *Ordering
24
+ attr_accessor :explain
25
+ attr_reader :bucket, :connection
26
+
27
+ def explain(val = nil)
28
+ return @explain if val.nil?
29
+ @explain = !!val
30
+ self
31
+ end
32
+
33
+ Ordering.each do |helper|
34
+ define_method helper do |*args|
35
+ return instance_variable_get :"@#{helper}" if args.empty?
36
+ if args.length == 1
37
+ instance_variable_set :"@#{helper}", args[0]
38
+ else
39
+ instance_variable_set :"@#{helper}", args
40
+ end
41
+ self
42
+ end
43
+ end
44
+
45
+ def to_s
46
+ res = String.new
47
+ res << "EXPLAIN\n" if @explain
48
+ Ordering.each do |statement|
49
+ val = public_send statement
50
+ unless val.nil?
51
+ res << "#{statement.to_s.gsub('_', ' ').upcase} "
52
+
53
+ if val.is_a? Array
54
+ res << val.collect { |obj| obj.to_s }.join(', ')
55
+ else
56
+ res << val.to_s
57
+ end
58
+
59
+ res << "\n"
60
+ end
61
+ end
62
+ res
63
+ end
64
+
65
+ def results(&row_modifier)
66
+ n1ql_view = @connection.n1ql_query(self)
67
+
68
+ current = ::Libuv::Reactor.current
69
+ if current && current.running?
70
+ ResultsLibuv.new(n1ql_view, current, &row_modifier)
71
+ elsif Object.const_defined?(:EventMachine) && EM.reactor_thread?
72
+ ResultsEM.new(n1ql_view, &row_modifier)
73
+ else
74
+ ResultsNative.new(n1ql_view, &row_modifier)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true, encoding: ASCII-8BIT
2
+
3
+ module Libcouchbase
4
+ class QueryFullText
5
+ def initialize(connection, reactor, include_docs: true, **opts)
6
+ @connection = connection
7
+ @reactor = reactor
8
+
9
+ @options = opts
10
+ @include_docs = include_docs
11
+ @request_handle = FFI::MemoryPointer.new :pointer, 1
12
+ end
13
+
14
+ attr_reader :options, :connection
15
+ attr_accessor :include_docs
16
+
17
+ def index
18
+ @options[:indexName]
19
+ end
20
+
21
+ def get_count(metadata)
22
+ metadata[:total_hits]
23
+ end
24
+
25
+ def perform(limit: nil, **options, &blk)
26
+ raise 'not connected' unless @connection.handle
27
+ raise 'query already in progress' if @query_cstr
28
+ raise 'callback required' unless block_given?
29
+
30
+ # customise the size based on the request being made
31
+ orig_size = @options[:size] || 10 # 10 is the couchbase default
32
+ new_size = limit || orig_size
33
+ begin
34
+ @options[:size] = new_size if orig_size > new_size
35
+ @query_text = JSON.generate(@options)
36
+ @query_cstr = FFI::MemoryPointer.from_string(@query_text)
37
+ rescue
38
+ @query_cstr = nil
39
+ @query_text = nil
40
+ raise
41
+ ensure
42
+ @options[:size] = orig_size
43
+ end
44
+
45
+ @reactor.schedule {
46
+ @error = nil
47
+ @doc_count = 0
48
+ @callback = blk
49
+
50
+ @cmd = Ext::CMDFTS.new
51
+ @cmd[:query] = @query_cstr
52
+ @cmd[:nquery] = @query_text.bytesize
53
+ @cmd[:callback] = @connection.get_callback(:fts_callback)
54
+ @cmd[:handle] = @request_handle
55
+
56
+ pointer = @cmd.to_ptr
57
+ @connection.requests[pointer.address] = self
58
+
59
+ err = Ext.fts_query(@connection.handle, pointer, @cmd)
60
+ if err != :success
61
+ error(Error.lookup(err).new('full text search not scheduled'))
62
+ end
63
+ }
64
+ end
65
+
66
+ # Example Row:
67
+ # {:index=>"default_3f230bec977a680e_b7ff6b68", :id=>"dep_1-18", :score=>1.3540229098345296,
68
+ # :locations=>{:class_name=>{:toshiba=>[{:pos=>1, :start=>2, :end=>9, :array_positions=>nil}]},
69
+ # :name=>{:toshiba=>[{:pos=>1, :start=>0, :end=>7, :array_positions=>nil}]}}}
70
+ def received(row)
71
+ return if @error
72
+
73
+ resp = Response.new(:fts_callback, row[:id])
74
+ resp.metadata = row
75
+
76
+ # TODO:: this could cause results to be returned out of order
77
+ if @include_docs
78
+ @doc_count += 1
79
+ doc = @connection.get(resp.key).value
80
+ resp.value = doc.value
81
+ resp.cas = doc.cas
82
+ resp.metadata.merge! doc.metadata
83
+ end
84
+
85
+ @callback.call(false, resp)
86
+ rescue => e
87
+ @error = e
88
+ cancel
89
+ ensure
90
+ if @include_docs
91
+ @doc_count -= 1
92
+ process_final if @metadata && @doc_count == 0
93
+ end
94
+ end
95
+
96
+ # Example metadata
97
+ # {:status=>{:total=>2, :failed=>0, :successful=>2}, :request=>{:query=>{:query=>"Toshiba", :boost=>1},
98
+ # :size=>10, :from=>0, :highlight=>nil, :fields=>nil, :facets=>nil, :explain=>false}, :hits=>[],
99
+ # :total_hits=>4, :max_score=>1.6405488681166451, :took=>10182765, :facets=>{}}
100
+ def received_final(metadata)
101
+ @metadata = metadata
102
+ process_final unless @doc_count > 0
103
+ end
104
+
105
+ def error(obj)
106
+ @error = obj
107
+ # This sets metadata to true, however it'll be ignored as error is set
108
+ # We set it to true as we may be fetching documents in parallel and need to wait
109
+ received_final(true)
110
+ end
111
+
112
+ def cancel
113
+ @error = :cancelled unless @error
114
+ @reactor.schedule {
115
+ if @connection.handle && @cmd
116
+ Ext.fts_cancel(@connection.handle, @handle_ptr.get_pointer(0))
117
+ received_final(true)
118
+ end
119
+ }
120
+ end
121
+
122
+
123
+ protected
124
+
125
+
126
+ def process_final
127
+ metadata = @metadata
128
+ @metadata = nil
129
+
130
+ @query_cstr = nil
131
+ @query_text = nil
132
+
133
+ @connection.requests.delete(@cmd.to_ptr.address)
134
+ @cmd = nil
135
+
136
+ if @error
137
+ if @error == :cancelled
138
+ @callback.call(:final, metadata)
139
+ else
140
+ @callback.call(:error, @error)
141
+ end
142
+ else
143
+ @callback.call(:final, metadata)
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true, encoding: ASCII-8BIT
2
+
3
+ module Libcouchbase
4
+ class QueryN1QL
5
+ N1P_QUERY_STATEMENT = 1
6
+ N1P_CONSISTENCY_REQUEST = 2
7
+
8
+ def initialize(connection, reactor, n1ql, **opts)
9
+ @connection = connection
10
+ @reactor = reactor
11
+
12
+ @n1ql = n1ql
13
+ @request_handle = FFI::MemoryPointer.new :pointer, 1
14
+ end
15
+
16
+ attr_reader :connection, :n1ql
17
+
18
+ def get_count(metadata)
19
+ metadata[:metrics][:resultCount]
20
+ end
21
+
22
+ def perform(limit: nil, **options, &blk)
23
+ raise 'not connected' unless @connection.handle
24
+ raise 'query already in progress' if @query_text
25
+ raise 'callback required' unless block_given?
26
+
27
+ # customise the size based on the request being made
28
+ orig_limit = @n1ql.limit
29
+ begin
30
+ if orig_limit && limit
31
+ @n1ql.limit = limit if orig_limit > limit
32
+ end
33
+ @query_text = @n1ql.to_s
34
+ rescue
35
+ @query_text = nil
36
+ raise
37
+ ensure
38
+ @n1ql.limit = orig_limit
39
+ end
40
+
41
+ @reactor.schedule {
42
+ @error = nil
43
+ @callback = blk
44
+
45
+ @cmd = Ext::CMDN1QL.new
46
+ @params = Ext.n1p_new
47
+ err = Ext.n1p_setconsistency(@params, N1P_CONSISTENCY_REQUEST)
48
+ if err == :success
49
+ err = Ext.n1p_setquery(@params, @query_text, @query_text.bytesize, N1P_QUERY_STATEMENT)
50
+ if err == :success
51
+
52
+ err = Ext.n1p_mkcmd(@params, @cmd)
53
+ if err == :success
54
+ pointer = @cmd.to_ptr
55
+ @connection.requests[pointer.address] = self
56
+
57
+ @cmd[:callback] = @connection.get_callback(:n1ql_callback)
58
+ @cmd[:handle] = @request_handle
59
+
60
+ err = Ext.n1ql_query(@connection.handle, pointer, @cmd)
61
+ if err != :success
62
+ error(Error.lookup(err).new('full text search not scheduled'))
63
+ end
64
+ else
65
+ error(Error.lookup(err).new('failed to build full text search command'))
66
+ end
67
+ else
68
+ error(Error.lookup(err).new('failed to build full text search query structure'))
69
+ end
70
+ else
71
+ error(Error.lookup(err).new('failed set consistency value'))
72
+ end
73
+ }
74
+ end
75
+
76
+ # Row is JSON value representing the result
77
+ def received(row)
78
+ return if @error
79
+ @callback.call(false, row)
80
+ rescue => e
81
+ @error = e
82
+ cancel
83
+ end
84
+
85
+ # Example metadata
86
+ # {:requestID=>"36162fce-ef39-4821-bf03-449e4073185d", :signature=>{:*=>"*"}, :results=>[], :status=>"success",
87
+ # :metrics=>{:elapsedTime=>"15.298243ms", :executionTime=>"15.256975ms", :resultCount=>12, :resultSize=>8964}}
88
+ def received_final(metadata)
89
+ @query_text = nil
90
+
91
+ @connection.requests.delete(@cmd.to_ptr.address)
92
+ @cmd = nil
93
+
94
+ Ext.n1p_free(@params)
95
+ @params = nil
96
+
97
+ if @error
98
+ if @error == :cancelled
99
+ @callback.call(:final, metadata)
100
+ else
101
+ @callback.call(:error, @error)
102
+ end
103
+ else
104
+ @callback.call(:final, metadata)
105
+ end
106
+ end
107
+
108
+ def error(obj)
109
+ @error = obj
110
+ received_final(nil)
111
+ end
112
+
113
+ def cancel
114
+ @error = :cancelled unless @error
115
+ @reactor.schedule {
116
+ if @connection.handle && @cmd
117
+ Ext.n1ql_cancel(@connection.handle, @handle_ptr.get_pointer(0))
118
+ received_final(nil)
119
+ end
120
+ }
121
+ end
122
+ end
123
+ end