couchbase 1.3.3-x86-mingw32 → 1.3.4-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64c92cbfdb47cf90b52c5a3ddf6817b0b2f47824
4
- data.tar.gz: 52b91ab4cad3bd75ca351b24f34a7cf3b68b7344
3
+ metadata.gz: 221f1d443a518cad70e8ead8d41d7c608dbb908e
4
+ data.tar.gz: 86524a93db4d704a9a63b7ef242dbb5f904901b3
5
5
  SHA512:
6
- metadata.gz: 1cc2d6eaf5fff25fa40b9d0ac9e389bd2cbc3561c6e98355d138c746db7004614d01e3e47ef5c1f2990657cfb68571bba12a19182c091c8c70f045320232fb66
7
- data.tar.gz: db81527b9c87d8522e5b4e0c9712fbef06b53628d388757e0f5c60d12e9403afd71b10b4c8311073fbf178f79397b6c86775da28e02c6fb1f961e26dbaf3bfb6
6
+ metadata.gz: 04ba277b1f42d6f2fade8012c4d855ba8c4846d33087849e93748066d4adf10dd7403a6983f253cc848069c86b51ffba8a598004d8be6916cd4e31687b53472f
7
+ data.tar.gz: 019154be57677cf09f9ff39a30a1eba41a59757005c1850ec6e1fad91bb347cdd199e7b8a5368b47d13745d41775a62d58f0bef4a61004f9b6ff152603a604da
@@ -8,10 +8,11 @@ are related libraries available:
8
8
 
9
9
  ## SUPPORT
10
10
 
11
- If you found an issue, please file it in our [JIRA][1]. Also you are
12
- always welcome on `#libcouchbase` channel at [freenode.net IRC servers][2].
11
+ If you find an issue, please file it in our [JIRA][1]. Also you are
12
+ always welcome on the `#libcouchbase` channel at [freenode.net IRC servers][2].
13
13
 
14
- Documentation: [http://rdoc.info/gems/couchbase](http://rdoc.info/gems/couchbase)
14
+ Documentation: [http://docs.couchbase.com/couchbase-sdk-ruby-1.3/](http://docs.couchbase.com/couchbase-sdk-ruby-1.3/)
15
+ API Documentation: [http://www.couchbase.com/autodocs/](http://www.couchbase.com/autodocs/)
15
16
 
16
17
  ## INSTALL
17
18
 
@@ -39,7 +40,7 @@ your OS release:
39
40
  # Ubuntu 10.04 Lucid Lynx (Debian stable or testing)
40
41
  deb http://packages.couchbase.com/ubuntu lucid lucid/main
41
42
 
42
- Import Couchbase PGP key:
43
+ Import the Couchbase PGP key:
43
44
 
44
45
  wget -O- http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -
45
46
 
@@ -47,7 +48,7 @@ Then install them
47
48
 
48
49
  $ sudo apt-get update && sudo apt-get install libcouchbase-dev
49
50
 
50
- Again, if you need preview versions, just use another repositories in
51
+ Again, if you need a preview of a future version, just use another repository in
51
52
  your `couchbase.list`
52
53
 
53
54
  # Ubuntu 11.10 Oneiric Ocelot (Debian unstable)
@@ -72,8 +73,8 @@ Then to install libcouchbase itself, run:
72
73
 
73
74
  $ sudo yum update && sudo yum install libcouchbase-devel
74
75
 
75
- We have preview repositories for RPMs too, use them if you need to try
76
- fresh version of couchbase gem:
76
+ We have preview repositories for RPMs too, use them if you want to try
77
+ the latest version of libcouchbase:
77
78
 
78
79
  [couchbase]
79
80
  name = Couchbase package repository
@@ -85,8 +86,8 @@ fresh version of couchbase gem:
85
86
 
86
87
  ### Windows
87
88
 
88
- There no additional dependencies for Windows systems. The gem carry
89
- prebuilt binary for it.
89
+ There are no additional dependencies for Windows systems. The gem carries
90
+ a prebuilt binary for it.
90
91
 
91
92
  ### Couchbase gem
92
93
 
@@ -96,12 +97,12 @@ Now install the couchbase gem itself
96
97
 
97
98
  ## USAGE
98
99
 
99
- First of all you need to load library:
100
+ First, you need to load the library:
100
101
 
101
102
  require 'couchbase'
102
103
 
103
- There are several ways to establish new connection to Couchbase Server.
104
- By default it uses the `http://localhost:8091/pools/default/buckets/default`
104
+ There are several ways to establish a new connection to Couchbase Server.
105
+ By default it uses `http://localhost:8091/pools/default/buckets/default`
105
106
  as the endpoint. The client will automatically adjust configuration when
106
107
  the cluster will rebalance its nodes when nodes are added or deleted
107
108
  therefore this client is "smart".
@@ -122,13 +123,13 @@ The hash parameters take precedence on string URL.
122
123
  If you worry about state of your nodes or not sure what node is alive,
123
124
  you can pass the list of nodes and the library will iterate over it
124
125
  until finds the working one. From that moment it won't use **your**
125
- list, because node list from cluster config is more actual.
126
+ list, because node list from cluster config carries more detail.
126
127
 
127
128
  c = Couchbase.connect(:bucket => "mybucket",
128
129
  :node_list => ['example.com:8091', example.net'])
129
130
 
130
- There is also handy method `Couchbase.bucket` which uses thread local
131
- storage to keep the reference to default connection. You can set the
131
+ There is also a handy method `Couchbase.bucket` which uses thread local
132
+ storage to keep a reference to a connection. You can set the
132
133
  connection options via `Couchbase.connection_options`:
133
134
 
134
135
  Couchbase.connection_options = {:bucket => 'blog'}
@@ -137,9 +138,9 @@ connection options via `Couchbase.connection_options`:
137
138
 
138
139
  The library supports both synchronous and asynchronous mode. In
139
140
  asynchronous mode all operations will return control to caller
140
- without blocking current thread. You can pass the block to method and it
141
+ without blocking current thread. You can pass a block to the method and it
141
142
  will be called with result when the operation will be completed. You
142
- need to run event loop when you scheduled your operations:
143
+ need to run the event loop once you've scheduled your operations:
143
144
 
144
145
  c = Couchbase.connect
145
146
  c.run do |conn|
@@ -155,7 +156,7 @@ The handlers could be nested
155
156
  end
156
157
  end
157
158
 
158
- The asynchronous callback receives instance of `Couchbase::Result` which
159
+ The asynchronous callback receives an instance of `Couchbase::Result` which
159
160
  responds to several methods to figure out what was happened:
160
161
 
161
162
  * `success?`. Returns `true` if operation succed.
@@ -171,7 +172,7 @@ responds to several methods to figure out what was happened:
171
172
 
172
173
  * `cas`. The CAS version tag.
173
174
 
174
- * `node`. Node address. It is used in flush and stats commands.
175
+ * `node`. Node address. This is used in the flush and stats commands.
175
176
 
176
177
  * `operation`. The symbol, representing an operation.
177
178
 
@@ -186,14 +187,14 @@ used. It can be set in following fashions:
186
187
  handler = lambda {|opcode, key, exc| }
187
188
  c.on_error = handler
188
189
 
189
- By default connection uses `:quiet` mode. This mean it won't raise
190
- exceptions when the given key is not exists:
190
+ By default connections use `:quiet` mode. This mean it won't raise
191
+ exceptions when the given key does not exist:
191
192
 
192
193
  c.get("missing-key") #=> nil
193
194
 
194
195
  It could be useful when you are trying to make you code a bit efficient
195
196
  by avoiding exception handling. (See `#add` and `#replace` operations).
196
- You can turn on these exception by passing `:quiet => false` when you
197
+ You can turn on these exceptions by passing `:quiet => false` when you
197
198
  are instantiating the connection or change corresponding attribute:
198
199
 
199
200
  c.quiet = false
@@ -278,7 +279,7 @@ Hash-like syntax
278
279
 
279
280
  ### Add
280
281
 
281
- Add command will fail if the key already exists. It accepts the same
282
+ The add command will fail if the key already exists. It accepts the same
282
283
  options as set command above.
283
284
 
284
285
  c.add("foo", "bar")
@@ -338,8 +339,10 @@ Couchbase::Error::DeltaBadval if the delta or value is not a number.
338
339
  c.incr("missing2", :create => true) #=> 0
339
340
  c.incr("missing2", :create => true) #=> 1
340
341
 
341
- Note that it isn't the same as increment/decrement in ruby, which is
342
- performed on client side with following `set` operation:
342
+ Note that it isn't the same as increment/decrement in ruby. A
343
+ Couchbase increment is atomic on a distributed system. The
344
+ Ruby incement could ovewrite intermediate values with multiple
345
+ clients, as shown with following `set` operation:
343
346
 
344
347
  c["foo"] = 10
345
348
  c["foo"] -= 20 #=> -10
@@ -469,9 +472,9 @@ To execute view you need to fetch it from design document `_design/blog`:
469
472
  blog.views #=> ["recent_posts"]
470
473
  blog.recent_posts #=> [#<Couchbase::ViewRow:9855800 @id="hello-world" @key="2009/01/15 15:52:20" @value="Hello World" @doc=nil @meta={} @views=[]>, ...]
471
474
 
472
- Gem uses streaming parser to access view results so you can iterate them
473
- easily and if your code won't keep links to the documents GC might free
474
- them as soon as it decide they are unreachable, because parser doesn't
475
+ The gem uses a streaming parser to access view results so you can iterate them
476
+ easily. If your code doesn't keep links to the documents the GC might free
477
+ them as soon as it decides they are unreachable, because the parser doesn't
475
478
  store global JSON tree.
476
479
 
477
480
  blog.recent_posts.each do |doc|
@@ -499,7 +502,7 @@ You can also use Enumerator to iterate view results
499
502
  acc
500
503
  end
501
504
 
502
- The Couchbase server could generate errors during view execution with
505
+ Couchbase Server could generate errors during view execution with
503
506
  `200 OK` and partial results. By default the library raises exception as
504
507
  soon as errors detected in the result stream, but you can define the
505
508
  callback `on_error` to intercept these errors and do something more
@@ -569,6 +572,69 @@ choose from several asynchronous IO options:
569
572
  end
570
573
  end
571
574
 
575
+ ## HACKING
576
+
577
+ Clone the repository. For starters, you can use github mirror, but
578
+ make sure you have read and understand [CONTRIBUTING.markdown][10] if
579
+ you are going to send us patches.
580
+
581
+ $ git clone git://github.com/couchbase/couchbase-ruby-client.git
582
+ $ cd couchbase-ruby-client
583
+
584
+ Install all development dependencies. You can use any ruby version
585
+ since 1.8.7, but make sure your changes work at least on major
586
+ releases (1.8.7, 1.9.3, 2.0.0 and 2.1.0 at the moment):
587
+
588
+ $ gem install bundler
589
+ $ bundle install
590
+
591
+ Don't forget to write the tests. You can find examples in the `tests/`
592
+ directory. To run tests with a mock just compile extension and run the
593
+ `test` task, it will download a test mock of couchbase cluster as a
594
+ part of the process (the mock is generally slower, but easier to
595
+ setup):
596
+
597
+ $ rake compile test
598
+
599
+ If you have real Couchbase server installed somewhere, you can pass
600
+ its address using environment variable `COUCHBASE_SERVER` like this:
601
+
602
+ $ COUCHBASE_SERVER=localhost:8091 rake compile test
603
+
604
+ And finally, you can package the gem with your awesome changes. For
605
+ UNIX-like systems a regular source-based package will be enough, so the
606
+ command below will produce `pkg/couchbase-VERSION.gem`, where
607
+ `VERSION` is the current version from file `lib/couchbase/version.rb`:
608
+
609
+ $ rake package
610
+
611
+ The Windows operating system usually doesn't have a build environment
612
+ installed. This is why we are cross-compiling blobs for Windows from
613
+ UNIX-like boxes. To do it you need to install mingw and the
614
+ [rake-compiler][11] and then build a variety of ruby versions currently
615
+ supported on Windows. An example config looks like this:
616
+
617
+ $ rake-compiler update-config
618
+ Updating /home/avsej/.rake-compiler/config.yml
619
+ Found Ruby version 1.8.7 for platform i386-mingw32 (/home/avsej/.rake-compiler/ruby/i686-w64-mingw32/ruby-1.8.7-p374/lib/ruby/1.8/i386-mingw32/rbconfig.rb)
620
+ Found Ruby version 1.9.3 for platform i386-mingw32 (/home/avsej/.rake-compiler/ruby/i686-w64-mingw32/ruby-1.9.3-p448/lib/ruby/1.9.1/i386-mingw32/rbconfig.rb)
621
+ Found Ruby version 2.0.0 for platform i386-mingw32 (/home/avsej/.rake-compiler/ruby/i686-w64-mingw32/ruby-2.0.0-p247/lib/ruby/2.0.0/i386-mingw32/rbconfig.rb)
622
+ Found Ruby version 2.1.0 for platform i386-mingw32 (/home/avsej/.rake-compiler/ruby/i686-w64-mingw32/ruby-2.1.0/lib/ruby/2.1.0/i386-mingw32/rbconfig.rb)
623
+ Found Ruby version 1.9.3 for platform x64-mingw32 (/home/avsej/.rake-compiler/ruby/x86_64-w64-mingw32/ruby-1.9.3-p448/lib/ruby/1.9.1/x64-mingw32/rbconfig.rb)
624
+ Found Ruby version 2.0.0 for platform x64-mingw32 (/home/avsej/.rake-compiler/ruby/x86_64-w64-mingw32/ruby-2.0.0-p247/lib/ruby/2.0.0/x64-mingw32/rbconfig.rb)
625
+ Found Ruby version 2.1.0 for platform x64-mingw32 (/home/avsej/.rake-compiler/ruby/x86_64-w64-mingw32/ruby-2.1.0/lib/ruby/2.1.0/x64-mingw32/rbconfig.rb)
626
+
627
+ Before you build, check relevant ruby and libcouchbase versions in
628
+ `tasks/compile.rake`. After that you can run the `package:windows`
629
+ task and you will find all artifacts in `pkg/` directory:
630
+
631
+ $ rake package:windows
632
+ $ ls -1 pkg/*.gem
633
+ pkg/couchbase-1.3.4.gem
634
+ pkg/couchbase-1.3.4-x64-mingw32.gem
635
+ pkg/couchbase-1.3.4-x86-mingw32.gem
636
+
637
+
572
638
  [1]: http://couchbase.com/issues/browse/RCBC
573
639
  [2]: http://freenode.net/irc_servers.shtml
574
640
  [3]: http://www.couchbase.com/develop/c/current
@@ -578,4 +644,6 @@ choose from several asynchronous IO options:
578
644
  [7]: https://github.com/couchbase/couchbase-ruby-model
579
645
  [8]: http://www.couchbase.com/develop/c/current
580
646
  [9]: http://rubygems.org/gems/eventmachine
647
+ [10]: https://github.com/couchbase/couchbase-ruby-client/blob/master/CONTRIBUTING.markdown
648
+ [11]: https://github.com/luislavena/rake-compiler
581
649
 
@@ -3,6 +3,32 @@
3
3
  This document is a list of user visible feature changes and important
4
4
  bugfixes. Do not forget to update this doc in every important patch.
5
5
 
6
+ ## 1.3.4 (2014-01-08)
7
+
8
+ * [major] Build 64-bit versions of the extensions for Windows
9
+ platform. Also support ruby 2.0 and 2.1.
10
+
11
+ * [minor] Update hacking section in README
12
+
13
+ * [minor] Fix gemspec warnings regarding versions of the dependencies.
14
+ Now it honours semantic versioning and doesn't use strict versions.
15
+
16
+ * [major] RCBC-151 Return CAS in extended mode for incr/decr
17
+
18
+ * [minor] RCBC-150 Update list of options on `Cluster.create_bucket`.
19
+ Added new options: `:replica_index`, `:flush_enabled`,
20
+ `:parallel_db_and_view_compaction`.
21
+
22
+ * [major] Allow retries on Couchbase::Bucket#cas collisions. Now it
23
+ takes a `:retry` Fixnum option that specifies the maximum number of
24
+ times the method should retry the entire get/update/set operation
25
+ when a `Couchbase::Error::KeyExists` error is encountered due to a
26
+ concurrent update from another writer between its `#get` and `#set`
27
+ calls.
28
+
29
+ * [major] MD5 and truncate ActiveSupport::Cache keys that are longer
30
+ than 250 characters.
31
+
6
32
  ## 1.3.3 (2013-09-12)
7
33
 
8
34
  * [major] RCBC-134 Allow application to use several connections with
data/Rakefile CHANGED
@@ -15,8 +15,6 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- require 'bundler/gem_tasks'
19
-
20
18
  Dir['tasks/*.rake'].sort.each { |f| load f }
21
19
 
22
20
  task :default => [:clobber, :compile, :test]
@@ -35,15 +35,15 @@ Gem::Specification.new do |s|
35
35
  s.extensions = `git ls-files -- ext/**/extconf.rb`.split("\n")
36
36
  s.require_paths = ['lib']
37
37
 
38
- s.add_runtime_dependency 'yaji', '~> 0.3.2'
38
+ s.add_runtime_dependency 'yaji', '~> 0.3', '>= 0.3.2'
39
39
  s.add_runtime_dependency 'multi_json', '~> 1.0'
40
- s.add_runtime_dependency 'connection_pool', '~> 1.0.0'
40
+ s.add_runtime_dependency 'connection_pool', '~> 1.0', '>= 1.0.0'
41
41
 
42
42
  s.add_development_dependency 'rake'
43
- s.add_development_dependency 'minitest', '~> 5.0.4'
44
- s.add_development_dependency 'rake-compiler', '>= 0.7.5'
45
- s.add_development_dependency 'mini_portile'
46
- s.add_development_dependency 'yajl-ruby', '~> 1.1.0'
43
+ s.add_development_dependency 'minitest', '~> 5.0', '>= 5.0.4'
44
+ s.add_development_dependency 'rake-compiler', '~> 0.7', '>= 0.7.5'
45
+ s.add_development_dependency 'mini_portile', '~> 0.5', '>= 0.5.2'
46
+ s.add_development_dependency 'yajl-ruby', '~> 1.1', '>= 1.1.0'
47
47
  s.add_development_dependency 'active_support'
48
48
  s.add_development_dependency 'eventmachine'
49
49
  end
@@ -89,6 +89,7 @@ cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
89
89
  params.cmd.arith.sign = sign;
90
90
  cb_params_build(&params);
91
91
  ctx = cb_context_alloc_common(bucket, proc, params.cmd.arith.num);
92
+ ctx->extended = params.cmd.arith.extended;
92
93
  err = lcb_arithmetic(bucket->handle, (const void *)ctx,
93
94
  params.cmd.arith.num, params.cmd.arith.ptr);
94
95
  cb_params_destroy(&params);
@@ -46,8 +46,12 @@ end
46
46
  $CFLAGS << ' -std=c99 -Wall -Wextra '
47
47
  if ENV['DEBUG']
48
48
  $CFLAGS << ' -O0 -ggdb3 -pedantic '
49
+ else
50
+ $CFLAGS << ' -O2'
51
+ $LDFLAGS << ' -Wl,--strip-debug' if RbConfig::CONFIG['target_os'] =~ /mingw32/
49
52
  end
50
53
 
54
+
51
55
  if RbConfig::CONFIG['target_os'] =~ /mingw32/
52
56
  dir_config("libcouchbase")
53
57
  else
@@ -97,6 +101,7 @@ else
97
101
  dir_config("libcouchbase", HEADER_DIRS, LIB_DIRS)
98
102
  end
99
103
 
104
+
100
105
  if COMMON_HEADERS !~ /"ruby\.h"/
101
106
  (COMMON_HEADERS ||= "") << %(\n#include "ruby.h"\n)
102
107
  end
@@ -126,6 +131,8 @@ def die(message)
126
131
  abort
127
132
  end
128
133
 
134
+ install_notice = "You must install libcouchbase >= 2.1.3\nSee http://www.couchbase.com/communities/c/ for more details"
135
+
129
136
  unless try_compile(<<-SRC)
130
137
  #include <libcouchbase/couchbase.h>
131
138
  #include <stdio.h>
@@ -135,10 +142,11 @@ unless try_compile(<<-SRC)
135
142
  return 0;
136
143
  }
137
144
  SRC
138
- die("You must install libcouchbase >= 2.1.3\nSee http://www.couchbase.com/communities/c/ for more details")
145
+ die(install_notice)
139
146
  end
140
147
 
141
- have_library("couchbase", "lcb_verify_compiler_setup", "libcouchbase/couchbase.h") # just to add -lcouchbase properly
148
+ # just to add -lcouchbase properly
149
+ have_library("couchbase", "lcb_verify_compiler_setup", "libcouchbase/couchbase.h") or die(install_notice)
142
150
  have_header("mach/mach_time.h")
143
151
  have_header("stdint.h") or die("Failed to locate stdint.h")
144
152
  have_header("sys/time.h")
@@ -550,7 +550,7 @@ typedef fd_set rb_fdset_t;
550
550
 
551
551
  typedef struct loop_select_arg {
552
552
  rb_mt_loop *loop;
553
- rb_fdset_t in, out;
553
+ rb_fdset_t in, out, exc;
554
554
  } ls_arg;
555
555
 
556
556
  static void
@@ -574,7 +574,7 @@ loop_run_select(VALUE argp)
574
574
  {
575
575
  ls_arg *args = (ls_arg*) argp;
576
576
  rb_mt_loop *loop = args->loop;
577
- rb_fdset_t *in = NULL, *out = NULL;
577
+ rb_fdset_t *in = NULL, *out = NULL, *exc = NULL;
578
578
  struct timeval timeout;
579
579
  struct timeval *timeoutp = NULL;
580
580
  int result, max = 0;
@@ -598,21 +598,26 @@ loop_run_select(VALUE argp)
598
598
  uint32_t i;
599
599
  rb_fd_init(&args->in);
600
600
  rb_fd_init(&args->out);
601
+ rb_fd_init(&args->exc);
601
602
  for(i = 0; i < loop->events.count; i++) {
602
603
  rb_mt_socket_list *list = &loop->events.sockets[i];
603
- if (list->flags & LCB_READ_EVENT) {
604
- in = &args->in;
605
- rb_fd_set(list->socket, in);
606
- }
607
- if (list->flags & LCB_WRITE_EVENT) {
608
- out = &args->out;
609
- rb_fd_set(list->socket, out);
604
+ if (list->flags != 0) {
605
+ if (list->flags & LCB_READ_EVENT) {
606
+ in = &args->in;
607
+ rb_fd_set(list->socket, in);
608
+ }
609
+ if (list->flags & LCB_WRITE_EVENT) {
610
+ out = &args->out;
611
+ rb_fd_set(list->socket, out);
612
+ }
613
+ exc = &args->exc;
614
+ rb_fd_set(list->socket, exc);
610
615
  }
611
616
  }
612
617
  max = events_max_fd(&loop->events) + 1;
613
618
  }
614
619
 
615
- result = rb_thread_fd_select(max, in, out, NULL, timeoutp);
620
+ result = rb_thread_fd_select(max, in, out, exc, timeoutp);
616
621
 
617
622
  if (result < 0) {
618
623
  rb_sys_fail("rb_thread_fd_select");
@@ -636,6 +641,10 @@ loop_run_select(VALUE argp)
636
641
  flags |= LCB_WRITE_EVENT;
637
642
  result--;
638
643
  }
644
+ if (exc && rb_fd_isset(list->socket, exc)) {
645
+ flags = LCB_ERROR_EVENT | LCB_WRITE_EVENT;
646
+ result--;
647
+ }
639
648
  if (flags) {
640
649
  loop_enque_events(&loop->callbacks, sock, flags);
641
650
  }
@@ -55,6 +55,7 @@ module ActiveSupport
55
55
  options[:default_ttl] ||= options.delete(:expires_in)
56
56
  options[:default_format] ||= :marshal
57
57
  options[:key_prefix] ||= options.delete(:namespace)
58
+ @key_prefix = options[:key_prefix]
58
59
  options[:connection_pool] ||= options.delete(:connection_pool)
59
60
  args.push(options)
60
61
 
@@ -348,7 +349,7 @@ module ActiveSupport
348
349
  # object responds to +cache_key+. Otherwise, to_param method will be
349
350
  # called. If the key is a Hash, then keys will be sorted alphabetically.
350
351
  def expanded_key(key) # :nodoc:
351
- return key.cache_key.to_s if key.respond_to?(:cache_key)
352
+ return validate_key(key.cache_key.to_s) if key.respond_to?(:cache_key)
352
353
 
353
354
  case key
354
355
  when Array
@@ -361,7 +362,22 @@ module ActiveSupport
361
362
  key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
362
363
  end
363
364
 
364
- key.respond_to?(:to_param) ? key.to_param : key
365
+ validate_key(key.respond_to?(:to_param) ? key.to_param : key)
366
+ end
367
+
368
+ def validate_key(key)
369
+ if key_with_prefix(key).length > 250
370
+ key = "#{key[0, max_length_before_prefix]}:md5:#{Digest::MD5.hexdigest(key)}"
371
+ end
372
+ return key
373
+ end
374
+
375
+ def key_with_prefix(key)
376
+ (ns = @key_prefix) ? "#{ns}#{key}" : key
377
+ end
378
+
379
+ def max_length_before_prefix
380
+ @max_length_before_prefix ||= 212 - (@key_prefix || '').size
365
381
  end
366
382
 
367
383
  module Threadsafe
@@ -35,12 +35,23 @@ module Couchbase
35
35
  #
36
36
  # @see http://couchbase.com/docs/memcached-api/memcached-api-protocol-text_cas.html
37
37
  #
38
+ # Setting the +:retry+ option to a positive number will cause this method
39
+ # to rescue the {Couchbase::Error::KeyExists} error that happens when
40
+ # an update collision is detected, and automatically get a fresh copy
41
+ # of the value and retry the block. This will repeat as long as there
42
+ # continues to be conflicts, up to the maximum number of retries specified.
43
+ # For asynchronous mode, this means the block will be yielded once for
44
+ # the initial {Bucket#get}, once for the final {Bucket#set} (successful
45
+ # or last failure), and zero or more additional {Bucket#get} retries
46
+ # in between, up to the maximum allowed by the +:retry+ option.
47
+ #
38
48
  # @param [String, Symbol] key
39
49
  #
40
50
  # @param [Hash] options the options for "swap" part
41
51
  # @option options [Fixnum] :ttl (self.default_ttl) the time to live of this key
42
52
  # @option options [Symbol] :format (self.default_format) format of the value
43
53
  # @option options [Fixnum] :flags (self.default_flags) flags for this key
54
+ # @option options [Fixnum] :retry (0) maximum number of times to autmatically retry upon update collision
44
55
  #
45
56
  # @yieldparam [Object, Result] value old value in synchronous mode and
46
57
  # +Result+ object in asynchronous mode.
@@ -80,16 +91,32 @@ module Couchbase
80
91
  #
81
92
  # @return [Fixnum] the CAS of new value
82
93
  def cas(key, options = {})
94
+ retries_remaining = options.delete(:retry) || 0
83
95
  if async?
84
96
  block = Proc.new
85
97
  get(key) do |ret|
86
98
  val = block.call(ret) # get new value from caller
87
- set(ret.key, val, options.merge(:cas => ret.cas, :flags => ret.flags), &block)
99
+ set(ret.key, val, options.merge(:cas => ret.cas, :flags => ret.flags)) do |set_ret|
100
+ if set_ret.error.is_a?(Couchbase::Error::KeyExists) && (retries_remaining > 0)
101
+ cas(key, options.merge(:retry => retries_remaining - 1), &block)
102
+ else
103
+ block.call(set_ret)
104
+ end
105
+ end
88
106
  end
89
107
  else
90
- val, flags, ver = get(key, :extended => true)
91
- val = yield(val) # get new value from caller
92
- set(key, val, options.merge(:cas => ver, :flags => flags))
108
+ begin
109
+ val, flags, ver = get(key, :extended => true)
110
+ val = yield(val) # get new value from caller
111
+ set(key, val, options.merge(:cas => ver, :flags => flags))
112
+ rescue Couchbase::Error::KeyExists
113
+ if retries_remaining > 0
114
+ retries_remaining -= 1
115
+ retry
116
+ else
117
+ raise
118
+ end
119
+ end
93
120
  end
94
121
  end
95
122
  alias :compare_and_swap :cas
@@ -42,11 +42,19 @@ module Couchbase
42
42
  # bucket. Possible values are "memcached" and "couchbase".
43
43
  # @option options [Fixnum] :ram_quota (100) The RAM quota in megabytes.
44
44
  # @option options [Fixnum] :replica_number (1) The number of replicas of
45
- # each document
45
+ # each document. Minimum 0, maximum 3.
46
46
  # @option options [String] :auth_type ("sasl") The authentication type.
47
47
  # Possible values are "sasl" and "none". Note you should specify free
48
48
  # port for "none"
49
49
  # @option options [Fixnum] :proxy_port The port for moxi
50
+ # @option options [true, false] :replica_index (true) Disable or
51
+ # enable indexes for bucket replicas
52
+ # @option options [true, false] :flush_enabled (false) Enables the
53
+ # 'flush all' functionality on the specified bucket.
54
+ # @option options [true, false] :parallel_db_and_view_compaction (false)
55
+ # Indicates whether database and view files on disk can be
56
+ # compacted simultaneously
57
+ #
50
58
  def create_bucket(name, options = {})
51
59
  defaults = {
52
60
  :type => "couchbase",
@@ -54,7 +62,10 @@ module Couchbase
54
62
  :replica_number => 1,
55
63
  :auth_type => "sasl",
56
64
  :sasl_password => "",
57
- :proxy_port => nil
65
+ :proxy_port => nil,
66
+ :flush_enabled => false,
67
+ :replica_index => true,
68
+ :parallel_db_and_view_compaction => false
58
69
  }
59
70
  options = defaults.merge(options)
60
71
  params = {"name" => name}
@@ -64,6 +75,9 @@ module Couchbase
64
75
  params["authType"] = options[:auth_type]
65
76
  params["saslPassword"] = options[:sasl_password]
66
77
  params["proxyPort"] = options[:proxy_port]
78
+ params["flushEnabled"] = !!options[:flush_enabled]
79
+ params["replicaIndex"] = !!options[:replica_index]
80
+ params["parallelDBAndViewCompaction"] = !!options[:parallel_db_and_view_compaction]
67
81
  payload = Utils.encode_params(params.reject!{|k, v| v.nil?})
68
82
  request = @connection.make_http_request("/pools/default/buckets",
69
83
  :content_type => "application/x-www-form-urlencoded",
@@ -17,5 +17,5 @@
17
17
 
18
18
  # Couchbase ruby client
19
19
  module Couchbase
20
- VERSION = "1.3.3"
20
+ VERSION = "1.3.4"
21
21
  end
@@ -30,6 +30,36 @@ version_router = lambda do |t|
30
30
  end
31
31
  end
32
32
 
33
+ class Platform
34
+ attr_reader :name, :host, :versions
35
+
36
+ def initialize(params)
37
+ @name = params[:name]
38
+ @host = params[:host]
39
+ @versions = params[:versions]
40
+ end
41
+
42
+ def each_version
43
+ @versions.each do |v|
44
+ yield(v, v[/\d\.\d\.\d/])
45
+ end
46
+ end
47
+
48
+ def short_versions
49
+ res = []
50
+ each_version do |long, short|
51
+ res << short
52
+ end
53
+ res
54
+ end
55
+ end
56
+
57
+ recent = "2.0.0-p353"
58
+ CROSS_PLATFORMS = [
59
+ Platform.new(:name => 'x64-mingw32', :host => 'x86_64-w64-mingw32', :versions => %w(1.9.3-p484 2.0.0-p353 2.1.0)),
60
+ Platform.new(:name => 'x86-mingw32', :host => 'i686-w64-mingw32', :versions => %w(1.8.7-p374 1.9.3-p484 2.0.0-p353 2.1.0)),
61
+ ]
62
+
33
63
  # Setup compile tasks. Configuration can be passed via ENV.
34
64
  # Example:
35
65
  # rake compile with_libcouchbase_include=/opt/couchbase/include
@@ -41,13 +71,14 @@ end
41
71
  #
42
72
  Rake::ExtensionTask.new("couchbase_ext", gemspec) do |ext|
43
73
  ext.cross_compile = true
44
- ext.cross_platform = ENV['HOST'] || "i386-mingw32"
74
+ ext.cross_platform = ENV['TARGET']
45
75
  if ENV['RUBY_CC_VERSION']
46
76
  ext.lib_dir = "lib/couchbase"
47
77
  end
48
78
  ext.cross_compiling do |spec|
49
79
  spec.files.delete("lib/couchbase/couchbase_ext.so")
50
- spec.files.push("lib/couchbase_ext.rb", Dir["lib/couchbase/1.{8,9}/couchbase_ext.so"])
80
+ spec.files.push("lib/couchbase_ext.rb", Dir["lib/couchbase/*/couchbase_ext.so"])
81
+ spec.files.push(Dir["lib/couchbase/*/couchbase_ext.so"])
51
82
  file "#{ext.tmp_dir}/#{ext.cross_platform}/stage/lib/couchbase_ext.rb", &version_router
52
83
  end
53
84
 
@@ -66,19 +97,13 @@ end
66
97
 
67
98
  require 'rubygems/package_task'
68
99
  Gem::PackageTask.new(gemspec) do |pkg|
69
- pkg.need_tar = true
100
+ pkg.need_tar = pkg.need_zip = false
70
101
  end
71
102
 
72
103
  require 'mini_portile'
73
104
  require 'rake/extensioncompiler'
74
105
 
75
106
  class MiniPortile
76
- alias :initialize_with_default_host :initialize
77
- def initialize(name, version)
78
- initialize_with_default_host(name, version)
79
- @host = ENV['HOST'] || Rake::ExtensionCompiler.mingw_host
80
- end
81
-
82
107
  alias :cook_without_checkpoint :cook
83
108
  def cook
84
109
  checkpoint = "ports/.#{name}-#{version}-#{host}.installed"
@@ -89,13 +114,30 @@ class MiniPortile
89
114
  end
90
115
  end
91
116
 
92
- namespace :ports do
93
- directory "ports"
117
+ file "lib/couchbase_ext.rb", &version_router
94
118
 
95
- task :libcouchbase => ["ports"] do
96
- recipe = MiniPortile.new "libcouchbase", "2.1.3"
119
+ desc "Package gem for windows"
120
+ task "package:windows" => ["package", "lib/couchbase_ext.rb"] do
121
+ vars = [
122
+ 'CC',
123
+ 'CFLAGS',
124
+ 'CPATH',
125
+ 'CPP',
126
+ 'CPPFLAGS',
127
+ 'LDFLAGS',
128
+ 'LIBRARY_PATH',
129
+ 'PATH'
130
+ ].reduce({}) do |h, v|
131
+ h[v] = ENV[v]
132
+ h
133
+ end
134
+ CROSS_PLATFORMS.each do |platform|
135
+ ENV['TARGET'] = platform.name
136
+ rm_rf("tmp/ ports/")
137
+ mkdir_p("ports")
138
+ recipe = MiniPortile.new("libcouchbase", "2.2.0_30_gc87bec4")
139
+ recipe.host = platform.host
97
140
  recipe.files << "http://packages.couchbase.com/clients/c/libcouchbase-#{recipe.version}.tar.gz"
98
-
99
141
  recipe.configure_options.push("--disable-debug",
100
142
  "--disable-dependency-tracking",
101
143
  "--disable-couchbasemock",
@@ -105,16 +147,12 @@ namespace :ports do
105
147
  "--disable-tools")
106
148
  recipe.cook
107
149
  recipe.activate
150
+ platform.each_version do |long, short|
151
+ sh("env RUBY_CC_VERSION=#{short} RBENV_VERSION=#{long} rbenv exec rake cross compile")
152
+ end
153
+ vars.each do |k, v|
154
+ ENV[k] = v
155
+ end
156
+ sh("env RUBY_CC_VERSION=#{platform.short_versions.join(":")} RBENV_VERSION=#{recent} rbenv exec rake cross native gem")
108
157
  end
109
158
  end
110
-
111
- file "lib/couchbase_ext.rb", &version_router
112
- task :cross => ["lib/couchbase_ext.rb", "ports:libcouchbase"]
113
-
114
- desc "Package gem for windows"
115
- task "package:windows" => :package do
116
- sh("env RUBY_CC_VERSION=1.8.7 RBENV_VERSION=1.8.7-p370 rbenv exec bundle exec rake cross compile")
117
- sh("env RUBY_CC_VERSION=1.9.2 RBENV_VERSION=1.9.2-p320 rbenv exec bundle exec rake cross compile")
118
- sh("env RUBY_CC_VERSION=2.0.0 RBENV_VERSION=2.0.0-p247 rbenv exec bundle exec rake cross compile")
119
- sh("env RUBY_CC_VERSION=1.8.7:1.9.2:2.0.0 RBENV_VERSION=1.9.2-p320 rbenv exec bundle exec rake cross native gem")
120
- end
@@ -173,4 +173,13 @@ class TestArithmetic < MiniTest::Test
173
173
  assert_equal [2, 2], connection.decr(uniq_id(:foo), uniq_id(:bar), :delta => 10).values.sort
174
174
  assert_equal [1, 1], connection.decr(uniq_id(:foo), uniq_id(:bar)).values.sort
175
175
  end
176
+
177
+ def test_it_returns_cas_value_in_extended_mode
178
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
179
+ orig_cas = connection.set(uniq_id(:foo), 1)
180
+ val, cas = connection.incr(uniq_id(:foo), :extended => true)
181
+ assert_equal 2, val
182
+ assert cas.is_a?(Numeric), "CAS should be numeric value: #{cas.inspect}"
183
+ refute_equal orig_cas, cas
184
+ end
176
185
  end
@@ -40,6 +40,69 @@ class TestCas < MiniTest::Test
40
40
  assert_equal expected, val
41
41
  end
42
42
 
43
+ def test_compare_and_swap_collision
44
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
45
+ :default_format => :document)
46
+ connection.set(uniq_id, {"bar" => 1})
47
+ assert_raises(Couchbase::Error::KeyExists) do
48
+ connection.cas(uniq_id) do |val|
49
+ # Simulate collision with a separate writer. This will
50
+ # change the CAS value to be different than what #cas just loaded.
51
+ connection.set(uniq_id, {"bar" => 2})
52
+
53
+ # Complete the modification we desire, which should fail when set.
54
+ val["baz"] = 3
55
+ val
56
+ end
57
+ end
58
+ end
59
+
60
+ def test_compare_and_swap_retry
61
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
62
+ :default_format => :document)
63
+ connection.set(uniq_id, {"bar" => 1})
64
+ calls = 0
65
+ connection.cas(uniq_id, :retry => 1) do |val|
66
+ calls += 1
67
+ if calls == 1
68
+ # Simulate collision with a separate writer. This will
69
+ # change the CAS value to be different than what #cas just loaded.
70
+ # Only do this the first time this block is executed.
71
+ connection.set(uniq_id, {"bar" => 2})
72
+ end
73
+
74
+ # Complete the modification we desire, which should fail when set.
75
+ val["baz"] = 3
76
+ val
77
+ end
78
+ assert_equal 2, calls
79
+ val = connection.get(uniq_id)
80
+ expected = {"bar" => 2, "baz" => 3}
81
+ assert_equal expected, val
82
+ end
83
+
84
+ def test_compare_and_swap_too_many_retries
85
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
86
+ :default_format => :document)
87
+ connection.set(uniq_id, {"bar" => 0})
88
+ calls = 0
89
+ assert_raises(Couchbase::Error::KeyExists) do
90
+ connection.cas(uniq_id, :retry => 10) do |val|
91
+ calls += 1
92
+
93
+ # Simulate collision with a separate writer. This will
94
+ # change the CAS value to be different than what #cas just loaded.
95
+ # Do it every time so we just keep retrying and failing.
96
+ connection.set(uniq_id, {"bar" => calls})
97
+
98
+ # Complete the modification we desire, which should fail when set.
99
+ val["baz"] = 3
100
+ val
101
+ end
102
+ end
103
+ assert_equal 11, calls
104
+ end
105
+
43
106
  def test_compare_and_swap_async
44
107
  connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
45
108
  :default_format => :document)
@@ -66,6 +129,101 @@ class TestCas < MiniTest::Test
66
129
  assert_equal expected, val
67
130
  end
68
131
 
132
+ def test_compare_and_swap_async_collision
133
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
134
+ :default_format => :document)
135
+ connection.set(uniq_id, {"bar" => 1})
136
+ calls = 0
137
+ connection.run do |conn|
138
+ conn.cas(uniq_id) do |ret|
139
+ calls += 1
140
+ case ret.operation
141
+ when :get
142
+ new_val = ret.value
143
+
144
+ # Simulate collision with a separate writer. This will
145
+ # change the CAS value to be different than what #cas just loaded.
146
+ connection.set(uniq_id, {"bar" => 2})
147
+
148
+
149
+ # Complete the modification we desire, which should fail when set.
150
+ new_val["baz"] = 3
151
+ new_val
152
+ when :set
153
+ assert ret.error.is_a? Couchbase::Error::KeyExists
154
+ else
155
+ flunk "Unexpected operation: #{ret.operation.inspect}"
156
+ end
157
+ end
158
+ end
159
+ assert_equal 2, calls
160
+ end
161
+
162
+ def test_compare_and_swap_async_retry
163
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
164
+ :default_format => :document)
165
+ connection.set(uniq_id, {"bar" => 1})
166
+ calls = 0
167
+ connection.run do |conn|
168
+ conn.cas(uniq_id, :retry => 1) do |ret|
169
+ calls += 1
170
+ case ret.operation
171
+ when :get
172
+ new_val = ret.value
173
+
174
+ if calls == 1
175
+ # Simulate collision with a separate writer. This will
176
+ # change the CAS value to be different than what #cas just loaded.
177
+ # Only do this the first time this block is executed.
178
+ connection.set(uniq_id, {"bar" => 2})
179
+ end
180
+
181
+ # Complete the modification we desire, which should fail when set.
182
+ new_val["baz"] = 3
183
+ new_val
184
+ when :set
185
+ assert ret.success?
186
+ else
187
+ flunk "Unexpected operation: #{ret.operation.inspect}"
188
+ end
189
+ end
190
+ end
191
+ assert_equal 3, calls
192
+ val = connection.get(uniq_id)
193
+ expected = {"bar" => 2, "baz" => 3}
194
+ assert_equal expected, val
195
+ end
196
+
197
+ def test_compare_and_swap_async_too_many_retries
198
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
199
+ :default_format => :document)
200
+ connection.set(uniq_id, {"bar" => 0})
201
+ calls = 0
202
+ connection.run do |conn|
203
+ conn.cas(uniq_id, :retry => 10) do |ret|
204
+ calls += 1
205
+ case ret.operation
206
+ when :get
207
+ new_val = ret.value
208
+
209
+ # Simulate collision with a separate writer. This will
210
+ # change the CAS value to be different than what #cas just loaded.
211
+ # Do it every time so we just keep retrying and failing.
212
+ connection.set(uniq_id, {"bar" => calls})
213
+
214
+ # Complete the modification we desire, which should fail when set.
215
+ new_val["baz"] = 3
216
+ new_val
217
+ when :set
218
+ assert ret.error.is_a? Couchbase::Error::KeyExists
219
+ else
220
+ flunk "Unexpected operation: #{ret.operation.inspect}"
221
+ end
222
+ end
223
+ end
224
+ assert_equal 12, calls
225
+ end
226
+
69
227
  def test_flags_replication
70
228
  connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port,
71
229
  :default_format => :document)
@@ -43,6 +43,12 @@ class TestCouchbaseRailsCacheStore < MiniTest::Test
43
43
  :connection_pool => 5)
44
44
  end
45
45
 
46
+ def prefixed_store
47
+ @prefixed_store ||= ActiveSupport::Cache::CouchbaseStore.new(:hostname => @mock.host,
48
+ :port => @mock.port,
49
+ :namespace => 'v1')
50
+ end
51
+
46
52
  def test_it_supported_methods
47
53
  supported_methods = store.public_methods(false).map(&:to_sym)
48
54
  assert supported_methods.include?(:fetch)
@@ -327,6 +333,20 @@ class TestCouchbaseRailsCacheStore < MiniTest::Test
327
333
  workers.each { |w| w.join }
328
334
  end
329
335
 
336
+ # These tests are only relevant against a real server,
337
+ # CouchbaseMock seems to accept long keys.
338
+ def test_it_can_handle_keys_longer_than_250_characters
339
+ long_key = 'a' * 260
340
+ assert store.write(long_key, 123)
341
+ assert_equal 123, store.read(long_key)
342
+ end
343
+
344
+ def test_it_can_handle_keys_longer_than_250_characters_with_a_prefix
345
+ long_key = 'a' * 249
346
+ assert prefixed_store.write(long_key, 123)
347
+ assert_equal 123, prefixed_store.read(long_key)
348
+ end
349
+
330
350
  private
331
351
 
332
352
  def collect_notifications
@@ -153,7 +153,12 @@ class TestFormat < MiniTest::Test
153
153
  assert_equal(ZlibTranscoder::FMT_ZLIB|Couchbase::Bucket::FMT_DOCUMENT, flags)
154
154
  connection.transcoder = nil
155
155
  doc = connection.get(uniq_id)
156
- assert_equal "x\x01\xABVJ\xCB\xCFW\xB2RJJ,R\xAA\x05\0\x1Dz\x044", doc
156
+ case RUBY_VERSION
157
+ when /^1\.8/
158
+ assert_equal "x\x01\xABVJ\xCB\xCFW\xB2RJJ,R\xAA\x05\0\x1Dz\x044", doc
159
+ else
160
+ assert_equal "x\u0001\xABVJ\xCB\xCFW\xB2RJJ,R\xAA\u0005\u0000\u001Dz\u00044", doc
161
+ end
157
162
  end
158
163
 
159
164
  end
metadata CHANGED
@@ -1,20 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couchbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.4
5
5
  platform: x86-mingw32
6
6
  authors:
7
7
  - Couchbase
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-17 00:00:00.000000000 Z
11
+ date: 2014-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yaji
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ - - '>='
18
21
  - !ruby/object:Gem::Version
19
22
  version: 0.3.2
20
23
  type: :runtime
@@ -22,6 +25,9 @@ dependencies:
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '0.3'
30
+ - - '>='
25
31
  - !ruby/object:Gem::Version
26
32
  version: 0.3.2
27
33
  - !ruby/object:Gem::Dependency
@@ -43,6 +49,9 @@ dependencies:
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ - - '>='
46
55
  - !ruby/object:Gem::Version
47
56
  version: 1.0.0
48
57
  type: :runtime
@@ -50,20 +59,23 @@ dependencies:
50
59
  version_requirements: !ruby/object:Gem::Requirement
51
60
  requirements:
52
61
  - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '1.0'
64
+ - - '>='
53
65
  - !ruby/object:Gem::Version
54
66
  version: 1.0.0
55
67
  - !ruby/object:Gem::Dependency
56
68
  name: rake
57
69
  requirement: !ruby/object:Gem::Requirement
58
70
  requirements:
59
- - - ! '>='
71
+ - - '>='
60
72
  - !ruby/object:Gem::Version
61
73
  version: '0'
62
74
  type: :development
63
75
  prerelease: false
64
76
  version_requirements: !ruby/object:Gem::Requirement
65
77
  requirements:
66
- - - ! '>='
78
+ - - '>='
67
79
  - !ruby/object:Gem::Version
68
80
  version: '0'
69
81
  - !ruby/object:Gem::Dependency
@@ -71,6 +83,9 @@ dependencies:
71
83
  requirement: !ruby/object:Gem::Requirement
72
84
  requirements:
73
85
  - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '5.0'
88
+ - - '>='
74
89
  - !ruby/object:Gem::Version
75
90
  version: 5.0.4
76
91
  type: :development
@@ -78,41 +93,59 @@ dependencies:
78
93
  version_requirements: !ruby/object:Gem::Requirement
79
94
  requirements:
80
95
  - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: '5.0'
98
+ - - '>='
81
99
  - !ruby/object:Gem::Version
82
100
  version: 5.0.4
83
101
  - !ruby/object:Gem::Dependency
84
102
  name: rake-compiler
85
103
  requirement: !ruby/object:Gem::Requirement
86
104
  requirements:
87
- - - ! '>='
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ version: '0.7'
108
+ - - '>='
88
109
  - !ruby/object:Gem::Version
89
110
  version: 0.7.5
90
111
  type: :development
91
112
  prerelease: false
92
113
  version_requirements: !ruby/object:Gem::Requirement
93
114
  requirements:
94
- - - ! '>='
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '0.7'
118
+ - - '>='
95
119
  - !ruby/object:Gem::Version
96
120
  version: 0.7.5
97
121
  - !ruby/object:Gem::Dependency
98
122
  name: mini_portile
99
123
  requirement: !ruby/object:Gem::Requirement
100
124
  requirements:
101
- - - ! '>='
125
+ - - ~>
102
126
  - !ruby/object:Gem::Version
103
- version: '0'
127
+ version: '0.5'
128
+ - - '>='
129
+ - !ruby/object:Gem::Version
130
+ version: 0.5.2
104
131
  type: :development
105
132
  prerelease: false
106
133
  version_requirements: !ruby/object:Gem::Requirement
107
134
  requirements:
108
- - - ! '>='
135
+ - - ~>
109
136
  - !ruby/object:Gem::Version
110
- version: '0'
137
+ version: '0.5'
138
+ - - '>='
139
+ - !ruby/object:Gem::Version
140
+ version: 0.5.2
111
141
  - !ruby/object:Gem::Dependency
112
142
  name: yajl-ruby
113
143
  requirement: !ruby/object:Gem::Requirement
114
144
  requirements:
115
145
  - - ~>
146
+ - !ruby/object:Gem::Version
147
+ version: '1.1'
148
+ - - '>='
116
149
  - !ruby/object:Gem::Version
117
150
  version: 1.1.0
118
151
  type: :development
@@ -120,34 +153,37 @@ dependencies:
120
153
  version_requirements: !ruby/object:Gem::Requirement
121
154
  requirements:
122
155
  - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '1.1'
158
+ - - '>='
123
159
  - !ruby/object:Gem::Version
124
160
  version: 1.1.0
125
161
  - !ruby/object:Gem::Dependency
126
162
  name: active_support
127
163
  requirement: !ruby/object:Gem::Requirement
128
164
  requirements:
129
- - - ! '>='
165
+ - - '>='
130
166
  - !ruby/object:Gem::Version
131
167
  version: '0'
132
168
  type: :development
133
169
  prerelease: false
134
170
  version_requirements: !ruby/object:Gem::Requirement
135
171
  requirements:
136
- - - ! '>='
172
+ - - '>='
137
173
  - !ruby/object:Gem::Version
138
174
  version: '0'
139
175
  - !ruby/object:Gem::Dependency
140
176
  name: eventmachine
141
177
  requirement: !ruby/object:Gem::Requirement
142
178
  requirements:
143
- - - ! '>='
179
+ - - '>='
144
180
  - !ruby/object:Gem::Version
145
181
  version: '0'
146
182
  type: :development
147
183
  prerelease: false
148
184
  version_requirements: !ruby/object:Gem::Requirement
149
185
  requirements:
150
- - - ! '>='
186
+ - - '>='
151
187
  - !ruby/object:Gem::Version
152
188
  version: '0'
153
189
  description: The official client library for use with Couchbase Server.
@@ -249,6 +285,7 @@ files:
249
285
  - lib/couchbase/1.8/couchbase_ext.so
250
286
  - lib/couchbase/1.9/couchbase_ext.so
251
287
  - lib/couchbase/2.0/couchbase_ext.so
288
+ - lib/couchbase/2.1/couchbase_ext.so
252
289
  - lib/couchbase_ext.rb
253
290
  homepage: http://couchbase.org
254
291
  licenses:
@@ -260,18 +297,41 @@ require_paths:
260
297
  - lib
261
298
  required_ruby_version: !ruby/object:Gem::Requirement
262
299
  requirements:
263
- - - ! '>='
300
+ - - '>='
264
301
  - !ruby/object:Gem::Version
265
302
  version: '0'
266
303
  required_rubygems_version: !ruby/object:Gem::Requirement
267
304
  requirements:
268
- - - ! '>='
305
+ - - '>='
269
306
  - !ruby/object:Gem::Version
270
307
  version: '0'
271
308
  requirements: []
272
309
  rubyforge_project:
273
- rubygems_version: 2.0.7
310
+ rubygems_version: 2.0.14
274
311
  signing_key:
275
312
  specification_version: 4
276
313
  summary: Couchbase ruby driver
277
- test_files: []
314
+ test_files:
315
+ - test/profile/.gitignore
316
+ - test/profile/Gemfile
317
+ - test/profile/benchmark.rb
318
+ - test/setup.rb
319
+ - test/test_arithmetic.rb
320
+ - test/test_async.rb
321
+ - test/test_bucket.rb
322
+ - test/test_cas.rb
323
+ - test/test_couchbase.rb
324
+ - test/test_couchbase_connection_pool.rb
325
+ - test/test_couchbase_rails_cache_store.rb
326
+ - test/test_delete.rb
327
+ - test/test_errors.rb
328
+ - test/test_eventmachine.rb
329
+ - test/test_format.rb
330
+ - test/test_get.rb
331
+ - test/test_stats.rb
332
+ - test/test_store.rb
333
+ - test/test_timer.rb
334
+ - test/test_touch.rb
335
+ - test/test_unlock.rb
336
+ - test/test_utils.rb
337
+ - test/test_version.rb