couchbase 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +11 -0
- data/HISTORY.markdown +17 -0
- data/README.markdown +99 -59
- data/couchbase.gemspec +1 -0
- data/ext/couchbase_ext/couchbase_ext.c +1557 -425
- data/ext/couchbase_ext/extconf.rb +60 -49
- data/lib/couchbase.rb +41 -7
- data/lib/couchbase/bucket.rb +5 -3
- data/lib/couchbase/version.rb +1 -1
- data/tasks/compile.rake +72 -0
- data/tasks/test.rake +2 -2
- data/test/setup.rb +52 -2
- data/test/test_arithmetic.rb +37 -26
- data/test/test_async.rb +68 -44
- data/test/test_bucket.rb +130 -45
- data/test/test_cas.rb +8 -8
- data/test/test_couchbase.rb +1 -1
- data/test/test_delete.rb +15 -15
- data/test/test_errors.rb +6 -6
- data/test/test_flush.rb +3 -3
- data/test/test_format.rb +14 -14
- data/test/test_get.rb +144 -69
- data/test/test_stats.rb +18 -14
- data/test/test_store.rb +40 -40
- data/test/test_touch.rb +26 -14
- data/test/test_version.rb +30 -2
- metadata +34 -17
@@ -20,62 +20,70 @@ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
|
|
20
20
|
|
21
21
|
require 'mkmf'
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
HEADER_DIRS = [
|
27
|
-
# First search /opt/local for macports
|
28
|
-
'/opt/local/include',
|
29
|
-
# Then search /usr/local for people that installed from source
|
30
|
-
'/usr/local/include',
|
31
|
-
# Check the ruby install locations
|
32
|
-
INCLUDEDIR,
|
33
|
-
# Finally fall back to /usr
|
34
|
-
'/usr/include'
|
35
|
-
]
|
23
|
+
def define(macro, value = nil)
|
24
|
+
$defs.push("-D #{[macro.upcase, value].compact.join('=')}")
|
25
|
+
end
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# Then search /usr/local for people that installed from source
|
41
|
-
'/usr/local/lib',
|
42
|
-
# Check the ruby install locations
|
43
|
-
LIBDIR,
|
44
|
-
# Finally fall back to /usr
|
45
|
-
'/usr/lib'
|
46
|
-
]
|
27
|
+
$CFLAGS << " #{ENV["CFLAGS"]}"
|
28
|
+
$LDFLAGS << " #{ENV["LDFLAGS"]}"
|
29
|
+
$LIBS << " #{ENV["LIBS"]}"
|
47
30
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
LIB_DIRS.unshift File.join(brew_prefix, 'lib')
|
52
|
-
HEADER_DIRS.unshift File.join(brew_prefix, 'include')
|
31
|
+
$CFLAGS << ' -std=c99 -Wall -Wextra '
|
32
|
+
if ENV['DEBUG']
|
33
|
+
$CFLAGS << ' -O0 -ggdb3 -pedantic '
|
53
34
|
end
|
54
35
|
|
55
|
-
|
56
|
-
|
36
|
+
if RbConfig::CONFIG['target_os'] =~ /mingw32/
|
37
|
+
dir_config("libcouchbase")
|
38
|
+
else
|
39
|
+
LIBDIR = RbConfig::CONFIG['libdir']
|
40
|
+
INCLUDEDIR = RbConfig::CONFIG['includedir']
|
57
41
|
|
58
|
-
|
59
|
-
|
60
|
-
|
42
|
+
HEADER_DIRS = [
|
43
|
+
# First search /opt/local for macports
|
44
|
+
'/opt/local/include',
|
45
|
+
# Then search /usr/local for people that installed from source
|
46
|
+
'/usr/local/include',
|
47
|
+
# Check the ruby install locations
|
48
|
+
INCLUDEDIR,
|
49
|
+
# Finally fall back to /usr
|
50
|
+
'/usr/include'
|
51
|
+
]
|
61
52
|
|
62
|
-
|
63
|
-
#
|
64
|
-
|
65
|
-
#
|
66
|
-
|
67
|
-
#
|
68
|
-
|
69
|
-
#
|
70
|
-
|
53
|
+
LIB_DIRS = [
|
54
|
+
# First search /opt/local for macports
|
55
|
+
'/opt/local/lib',
|
56
|
+
# Then search /usr/local for people that installed from source
|
57
|
+
'/usr/local/lib',
|
58
|
+
# Check the ruby install locations
|
59
|
+
LIBDIR,
|
60
|
+
# Finally fall back to /usr
|
61
|
+
'/usr/lib'
|
62
|
+
]
|
71
63
|
|
72
|
-
|
73
|
-
|
64
|
+
# For people using homebrew
|
65
|
+
brew_prefix = `brew --prefix libevent 2> /dev/null`.chomp
|
66
|
+
unless brew_prefix.empty?
|
67
|
+
LIB_DIRS.unshift File.join(brew_prefix, 'lib')
|
68
|
+
HEADER_DIRS.unshift File.join(brew_prefix, 'include')
|
69
|
+
end
|
70
|
+
|
71
|
+
HEADER_DIRS.delete_if{|d| !File.exists?(d)}
|
72
|
+
LIB_DIRS.delete_if{|d| !File.exists?(d)}
|
73
|
+
|
74
|
+
# it will find the libcouchbase likely. you can specify its path otherwise
|
75
|
+
#
|
76
|
+
# ruby extconf.rb [--with-libcouchbase-include=<dir>] [--with-libcouchbase-lib=<dir>]
|
77
|
+
#
|
78
|
+
# or
|
79
|
+
#
|
80
|
+
# ruby extconf.rb [--with-libcouchbase-dir=<dir>]
|
81
|
+
#
|
82
|
+
dir_config("libcouchbase", HEADER_DIRS, LIB_DIRS)
|
74
83
|
end
|
75
84
|
|
76
|
-
|
77
|
-
|
78
|
-
$CFLAGS << ' -O0 -ggdb3 -pedantic'
|
85
|
+
if COMMON_HEADERS !~ /"ruby\.h"/
|
86
|
+
COMMON_HEADERS << %(\n#include "ruby.h"\n)
|
79
87
|
end
|
80
88
|
|
81
89
|
if try_compile(<<-SRC)
|
@@ -96,7 +104,10 @@ if try_compile(<<-SRC)
|
|
96
104
|
define("HAVE_STDARG_PROTOTYPES")
|
97
105
|
end
|
98
106
|
|
99
|
-
|
100
|
-
|
107
|
+
|
108
|
+
if RbConfig::CONFIG['target_os'] =~ /mingw32/
|
109
|
+
have_library("vbucket", "vbucket_config_create", "libvbucket/vbucket.h") or abort "You should install libvbucket >= 1.8.0.2"
|
110
|
+
end
|
111
|
+
have_library("couchbase", "libcouchbase_server_versions", "libcouchbase/couchbase.h") or abort "You should install libcouchbase >= 1.0.2"
|
101
112
|
create_header("couchbase_config.h")
|
102
113
|
create_makefile("couchbase_ext")
|
data/lib/couchbase.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
require 'couchbase/version'
|
19
19
|
require 'yajl/json_gem'
|
20
|
+
require 'uri'
|
20
21
|
require 'couchbase_ext'
|
21
22
|
require 'couchbase/bucket'
|
22
23
|
|
@@ -24,24 +25,57 @@ require 'couchbase/bucket'
|
|
24
25
|
module Couchbase
|
25
26
|
|
26
27
|
class << self
|
27
|
-
# The method +
|
28
|
+
# The method +connect+ initializes new Bucket instance with all arguments passed.
|
28
29
|
#
|
29
30
|
# @example Use default values for all options
|
30
|
-
# Couchbase.
|
31
|
+
# Couchbase.connect
|
31
32
|
#
|
32
33
|
# @example Establish connection with couchbase default pool and default bucket
|
33
|
-
# Couchbase.
|
34
|
+
# Couchbase.connect("http://localhost:8091/pools/default")
|
34
35
|
#
|
35
36
|
# @example Select custom bucket
|
36
|
-
# Couchbase.
|
37
|
+
# Couchbase.connect("http://localhost:8091/pools/default", :bucket => 'blog')
|
37
38
|
#
|
38
39
|
# @example Specify bucket credentials
|
39
|
-
# Couchbase.
|
40
|
+
# Couchbase.connect("http://localhost:8091/pools/default", :bucket => 'blog', :username => 'bucket', :password => 'secret')
|
40
41
|
#
|
41
42
|
# @return [Bucket] connection instance
|
42
|
-
def
|
43
|
-
Bucket.new(*
|
43
|
+
def connect(*options)
|
44
|
+
Bucket.new(*options)
|
44
45
|
end
|
46
|
+
alias :new :connect
|
47
|
+
|
48
|
+
# Default connection options
|
49
|
+
#
|
50
|
+
# @example Using {Couchbase#connection_options} to change the bucket
|
51
|
+
# Couchbase.connection_options = {:bucket => 'blog'}
|
52
|
+
# Couchbase.bucket.name #=> "blog"
|
53
|
+
#
|
54
|
+
# @return [Hash, String]
|
55
|
+
attr_accessor :connection_options
|
56
|
+
|
57
|
+
# @private the thread local storage
|
58
|
+
def thread_storage
|
59
|
+
Thread.current[:couchbase] ||= {}
|
60
|
+
end
|
61
|
+
|
62
|
+
# The connection instance for current thread
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# Couchbase.bucket.set("foo", "bar")
|
66
|
+
#
|
67
|
+
# @return [Bucket]
|
68
|
+
def bucket
|
69
|
+
thread_storage[:bucket] ||= connect(*connection_options)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set a connection instance for current thread
|
73
|
+
#
|
74
|
+
# @return [Bucket]
|
75
|
+
def bucket=(connection)
|
76
|
+
thread_storage[:bucket] = connection
|
77
|
+
end
|
78
|
+
|
45
79
|
end
|
46
80
|
|
47
81
|
end
|
data/lib/couchbase/bucket.rb
CHANGED
@@ -16,17 +16,18 @@
|
|
16
16
|
#
|
17
17
|
|
18
18
|
module Couchbase
|
19
|
+
|
19
20
|
class Bucket
|
20
21
|
|
21
22
|
# Reads a key's value from the server and yields it to a block. Replaces
|
22
23
|
# the key's value with the result of the block as long as the key hasn't
|
23
24
|
# been updated in the meantime, otherwise raises
|
24
|
-
# Couchbase::Error::KeyExists. CAS stands for "compare and swap", and
|
25
|
+
# {Couchbase::Error::KeyExists}. CAS stands for "compare and swap", and
|
25
26
|
# avoids the need for manual key mutexing. Read more info here:
|
26
27
|
#
|
27
28
|
# http://docs.couchbase.org/memcached-api/memcached-api-protocol-text_cas.html
|
28
29
|
#
|
29
|
-
# @param [String] key
|
30
|
+
# @param [String, Symbol] key
|
30
31
|
#
|
31
32
|
# @param [Hash] options the options for operation
|
32
33
|
# @option options [String] :ttl (self.default_ttl) the time to live of this key
|
@@ -37,7 +38,7 @@ module Couchbase
|
|
37
38
|
# +Result+ object in asynchronous mode.
|
38
39
|
# @yieldreturn [Object] new value.
|
39
40
|
#
|
40
|
-
# @raise [Couchbase::
|
41
|
+
# @raise [Couchbase::Error::KeyExists] if the key was updated before the the
|
41
42
|
# code in block has been completed (the CAS value has been changed).
|
42
43
|
#
|
43
44
|
# @example Implement append to JSON encoded value
|
@@ -67,4 +68,5 @@ module Couchbase
|
|
67
68
|
alias :compare_and_swap :cas
|
68
69
|
|
69
70
|
end
|
71
|
+
|
70
72
|
end
|
data/lib/couchbase/version.rb
CHANGED
data/tasks/compile.rake
CHANGED
@@ -32,6 +32,16 @@ end
|
|
32
32
|
# rake compile with_libcouchbase_dir=/opt/couchbase
|
33
33
|
#
|
34
34
|
Rake::ExtensionTask.new("couchbase_ext", gemspec) do |ext|
|
35
|
+
ext.cross_compile = true
|
36
|
+
ext.cross_platform = [ENV['HOST'] || "i386-mingw32"]
|
37
|
+
if ENV['RUBY_CC_VERSION']
|
38
|
+
ext.lib_dir = "lib/couchbase"
|
39
|
+
end
|
40
|
+
ext.cross_compiling do |spec|
|
41
|
+
spec.files.delete("lib/couchbase/couchbase_ext.so")
|
42
|
+
spec.files.push("lib/couchbase_ext.rb", Dir["lib/couchbase/1.{8,9}/couchbase_ext.so"])
|
43
|
+
end
|
44
|
+
|
35
45
|
CLEAN.include "#{ext.lib_dir}/*.#{RbConfig::CONFIG['DLEXT']}"
|
36
46
|
|
37
47
|
ENV.each do |key, val|
|
@@ -50,3 +60,65 @@ Gem::PackageTask.new(gemspec) do |pkg|
|
|
50
60
|
pkg.need_zip = true
|
51
61
|
pkg.need_tar = true
|
52
62
|
end
|
63
|
+
|
64
|
+
require 'mini_portile'
|
65
|
+
require 'rake/extensioncompiler'
|
66
|
+
|
67
|
+
class MiniPortile
|
68
|
+
alias :initialize_with_default_host :initialize
|
69
|
+
def initialize(name, version)
|
70
|
+
initialize_with_default_host(name, version)
|
71
|
+
@host = ENV['HOST'] || Rake::ExtensionCompiler.mingw_host
|
72
|
+
end
|
73
|
+
|
74
|
+
alias :cook_without_checkpoint :cook
|
75
|
+
def cook
|
76
|
+
checkpoint = "ports/.#{name}-#{version}-#{host}.installed"
|
77
|
+
unless File.exist?(checkpoint)
|
78
|
+
cook_without_checkpoint
|
79
|
+
FileUtils.touch(checkpoint)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
namespace :ports do
|
85
|
+
directory "ports"
|
86
|
+
|
87
|
+
task :libvbucket => ["ports"] do
|
88
|
+
recipe = MiniPortile.new "libvbucket", "1.8.0.3"
|
89
|
+
recipe.files << "http://packages.couchbase.com/clients/c/#{recipe.name}-#{recipe.version}.tar.gz"
|
90
|
+
recipe.configure_options.push("--disable-debug",
|
91
|
+
"--without-docs",
|
92
|
+
"--disable-dependency-tracking")
|
93
|
+
recipe.cook
|
94
|
+
recipe.activate
|
95
|
+
end
|
96
|
+
|
97
|
+
task :libcouchbase => [:libvbucket] do
|
98
|
+
recipe = MiniPortile.new "libcouchbase", "1.0.2"
|
99
|
+
recipe.files << "http://packages.couchbase.com/clients/c/#{recipe.name}-#{recipe.version}.tar.gz"
|
100
|
+
recipe.configure_options.push("--disable-debug",
|
101
|
+
"--disable-dependency-tracking",
|
102
|
+
"--disable-couchbasemock",
|
103
|
+
"--disable-tools")
|
104
|
+
recipe.cook
|
105
|
+
recipe.activate
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
file "lib/couchbase_ext.rb" do
|
110
|
+
File.open("lib/couchbase_ext.rb", 'wb') do |f|
|
111
|
+
f.write <<-RUBY
|
112
|
+
require "couchbase/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/couchbase_ext"
|
113
|
+
RUBY
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
task :cross => ["lib/couchbase_ext.rb", "ports:libcouchbase"]
|
118
|
+
|
119
|
+
desc "Package gem for windows"
|
120
|
+
task "package:windows" => :package do
|
121
|
+
sh("env RUBY_CC_VERSION=1.8.7 rvm 1.8.7 do bundle exec rake cross compile")
|
122
|
+
sh("env RUBY_CC_VERSION=1.9.2 rvm 1.9.2 do bundle exec rake cross compile")
|
123
|
+
sh("env RUBY_CC_VERSION=1.8.7:1.9.2 rvm 1.9.2 do bundle exec rake cross native gem")
|
124
|
+
end
|
data/tasks/test.rake
CHANGED
@@ -19,8 +19,8 @@ require 'rake/testtask'
|
|
19
19
|
require 'rake/clean'
|
20
20
|
|
21
21
|
rule 'test/CouchbaseMock.jar' do |task|
|
22
|
-
|
23
|
-
sh %{wget -q -O test/CouchbaseMock.jar
|
22
|
+
jar_path = "0.5-SNAPSHOT/CouchbaseMock-0.5-20120222.060643-15.jar"
|
23
|
+
sh %{wget -q -O test/CouchbaseMock.jar http://files.couchbase.com/maven2/org/couchbase/mock/CouchbaseMock/#{jar_path}}
|
24
24
|
end
|
25
25
|
|
26
26
|
CLOBBER << 'test/CouchbaseMock.jar'
|
data/test/setup.rb
CHANGED
@@ -19,12 +19,52 @@ require 'minitest/autorun'
|
|
19
19
|
require 'couchbase'
|
20
20
|
|
21
21
|
require 'socket'
|
22
|
+
require 'open-uri'
|
23
|
+
|
24
|
+
class CouchbaseServer
|
25
|
+
attr_accessor :host, :port, :num_nodes, :buckets_spec
|
26
|
+
|
27
|
+
def real?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(params = {})
|
32
|
+
@host, @port = ENV['COUCHBASE_SERVER'].split(':')
|
33
|
+
@port = @port.to_i
|
34
|
+
|
35
|
+
if @host.nil? || @host.empty? || @port == 0
|
36
|
+
raise ArgumentError, "Check COUCHBASE_SERVER variable. It should be hostname:port"
|
37
|
+
end
|
38
|
+
|
39
|
+
@config = Yajl::Parser.parse(open("http://#{@host}:#{@port}/pools/default"))
|
40
|
+
@num_nodes = @config["nodes"].size
|
41
|
+
@buckets_spec = params[:buckets_spec] || "default:" # "default:,protected:secret,cache::memcache"
|
42
|
+
end
|
43
|
+
|
44
|
+
def start
|
45
|
+
# flush all buckets
|
46
|
+
@buckets_spec.split(',') do |bucket|
|
47
|
+
name, password, _ = bucket.split(':')
|
48
|
+
connection = Couchbase.new(:hostname => @host,
|
49
|
+
:port => @port,
|
50
|
+
:username => name,
|
51
|
+
:bucket => name,
|
52
|
+
:password => password)
|
53
|
+
connection.flush
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def stop; end
|
57
|
+
end
|
22
58
|
|
23
59
|
class CouchbaseMock
|
24
60
|
Monitor = Struct.new(:pid, :client, :socket, :port)
|
25
61
|
|
26
62
|
attr_accessor :host, :port, :buckets_spec, :num_nodes, :num_vbuckets
|
27
63
|
|
64
|
+
def real?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
28
68
|
def initialize(params = {})
|
29
69
|
@host = "127.0.0.1"
|
30
70
|
@port = 0
|
@@ -91,7 +131,17 @@ end
|
|
91
131
|
class MiniTest::Unit::TestCase
|
92
132
|
|
93
133
|
def start_mock(params = {})
|
94
|
-
mock =
|
134
|
+
mock = nil
|
135
|
+
if ENV['COUCHBASE_SERVER']
|
136
|
+
mock = CouchbaseServer.new(params)
|
137
|
+
if (params[:port] && mock.port != params[:port]) ||
|
138
|
+
(params[:host] && mock.host != params[:host]) ||
|
139
|
+
mock.buckets_spec != "default:"
|
140
|
+
skip("Unable to configure real cluster. Requested config is: #{params.inspect}")
|
141
|
+
end
|
142
|
+
else
|
143
|
+
mock = CouchbaseMock.new(params)
|
144
|
+
end
|
95
145
|
mock.start
|
96
146
|
mock
|
97
147
|
end
|
@@ -111,7 +161,7 @@ class MiniTest::Unit::TestCase
|
|
111
161
|
stop_mock(mock) if mock
|
112
162
|
end
|
113
163
|
|
114
|
-
def
|
164
|
+
def uniq_id(*suffixes)
|
115
165
|
[caller.first[/.*[` ](.*)'/, 1], suffixes].join("_")
|
116
166
|
end
|
117
167
|
end
|
data/test/test_arithmetic.rb
CHANGED
@@ -28,70 +28,81 @@ class TestArithmetic < MiniTest::Unit::TestCase
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_trivial_incr_decr
|
31
|
-
connection = Couchbase.new(:port => @mock.port)
|
31
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
32
32
|
|
33
|
-
connection.set(
|
34
|
-
val = connection.incr(
|
33
|
+
connection.set(uniq_id, 1)
|
34
|
+
val = connection.incr(uniq_id)
|
35
35
|
assert_equal 2, val
|
36
|
-
val = connection.get(
|
36
|
+
val = connection.get(uniq_id)
|
37
37
|
assert_equal 2, val
|
38
38
|
|
39
|
-
connection.set(
|
40
|
-
val = connection.decr(
|
39
|
+
connection.set(uniq_id, 7)
|
40
|
+
val = connection.decr(uniq_id)
|
41
41
|
assert_equal 6, val
|
42
|
-
val = connection.get(
|
42
|
+
val = connection.get(uniq_id)
|
43
43
|
assert_equal 6, val
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_it_fails_to_incr_decr_missing_key
|
47
|
-
connection = Couchbase.new(:port => @mock.port)
|
47
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
48
48
|
|
49
49
|
assert_raises(Couchbase::Error::NotFound) do
|
50
|
-
connection.incr(
|
50
|
+
connection.incr(uniq_id(:missing))
|
51
51
|
end
|
52
52
|
assert_raises(Couchbase::Error::NotFound) do
|
53
|
-
connection.decr(
|
53
|
+
connection.decr(uniq_id(:missing))
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
def test_it_creates_missing_key_when_initial_value_specified
|
58
|
-
connection = Couchbase.new(:port => @mock.port)
|
58
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
59
59
|
|
60
|
-
val = connection.incr(
|
60
|
+
val = connection.incr(uniq_id(:missing), :initial => 5)
|
61
61
|
assert_equal 5, val
|
62
|
-
val = connection.incr(
|
62
|
+
val = connection.incr(uniq_id(:missing), :initial => 5)
|
63
63
|
assert_equal 6, val
|
64
|
-
val = connection.get(
|
64
|
+
val = connection.get(uniq_id(:missing))
|
65
65
|
assert_equal 6, val
|
66
66
|
end
|
67
67
|
|
68
68
|
def test_it_uses_zero_as_default_value_for_missing_keys
|
69
|
-
connection = Couchbase.new(:port => @mock.port)
|
69
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
70
70
|
|
71
|
-
val = connection.incr(
|
71
|
+
val = connection.incr(uniq_id(:missing), :create => true)
|
72
72
|
assert_equal 0, val
|
73
|
-
val = connection.incr(
|
73
|
+
val = connection.incr(uniq_id(:missing), :create => true)
|
74
74
|
assert_equal 1, val
|
75
|
-
val = connection.get(
|
75
|
+
val = connection.get(uniq_id(:missing))
|
76
76
|
assert_equal 1, val
|
77
77
|
end
|
78
78
|
|
79
79
|
def test_it_allows_custom_ttl
|
80
|
-
connection = Couchbase.new(:port => @mock.port)
|
80
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
81
81
|
|
82
|
-
val = connection.incr(
|
82
|
+
val = connection.incr(uniq_id(:missing), :create => true, :ttl => 1)
|
83
83
|
assert_equal 0, val
|
84
|
-
val = connection.incr(
|
84
|
+
val = connection.incr(uniq_id(:missing), :create => true)
|
85
85
|
assert_equal 1, val
|
86
|
-
sleep(
|
87
|
-
refute connection.get(
|
86
|
+
sleep(2)
|
87
|
+
refute connection.get(uniq_id(:missing))
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_decrement_with_absolute_ttl
|
91
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
92
|
+
# absolute TTL: one second from now
|
93
|
+
exp = Time.now.to_i + 1
|
94
|
+
val = connection.decr(uniq_id, 12, :initial => 0, :ttl => exp)
|
95
|
+
assert_equal 0, val
|
96
|
+
assert_equal 0, connection.get(uniq_id)
|
97
|
+
sleep(2)
|
98
|
+
refute connection.get(uniq_id)
|
88
99
|
end
|
89
100
|
|
90
101
|
def test_it_allows_custom_delta
|
91
|
-
connection = Couchbase.new(:port => @mock.port)
|
102
|
+
connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
|
92
103
|
|
93
|
-
connection.set(
|
94
|
-
val = connection.incr(
|
104
|
+
connection.set(uniq_id, 12)
|
105
|
+
val = connection.incr(uniq_id, 10)
|
95
106
|
assert_equal 22, val
|
96
107
|
end
|
97
108
|
|