jmoses-couchbase 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +15 -0
  2. data/.travis.yml +22 -0
  3. data/.yardopts +5 -0
  4. data/CONTRIBUTING.markdown +75 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +201 -0
  7. data/Makefile +3 -0
  8. data/README.markdown +665 -0
  9. data/RELEASE_NOTES.markdown +819 -0
  10. data/Rakefile +20 -0
  11. data/couchbase.gemspec +49 -0
  12. data/examples/chat-em/Gemfile +7 -0
  13. data/examples/chat-em/README.markdown +45 -0
  14. data/examples/chat-em/server.rb +82 -0
  15. data/examples/chat-goliath-grape/Gemfile +5 -0
  16. data/examples/chat-goliath-grape/README.markdown +50 -0
  17. data/examples/chat-goliath-grape/app.rb +67 -0
  18. data/examples/chat-goliath-grape/config/app.rb +20 -0
  19. data/examples/transcoders/Gemfile +3 -0
  20. data/examples/transcoders/README.markdown +59 -0
  21. data/examples/transcoders/cb-zcat +40 -0
  22. data/examples/transcoders/cb-zcp +45 -0
  23. data/examples/transcoders/gzip_transcoder.rb +49 -0
  24. data/examples/transcoders/options.rb +54 -0
  25. data/ext/couchbase_ext/.gitignore +4 -0
  26. data/ext/couchbase_ext/arguments.c +956 -0
  27. data/ext/couchbase_ext/arithmetic.c +316 -0
  28. data/ext/couchbase_ext/bucket.c +1373 -0
  29. data/ext/couchbase_ext/context.c +65 -0
  30. data/ext/couchbase_ext/couchbase_ext.c +1364 -0
  31. data/ext/couchbase_ext/couchbase_ext.h +644 -0
  32. data/ext/couchbase_ext/delete.c +163 -0
  33. data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
  34. data/ext/couchbase_ext/extconf.rb +169 -0
  35. data/ext/couchbase_ext/get.c +316 -0
  36. data/ext/couchbase_ext/gethrtime.c +129 -0
  37. data/ext/couchbase_ext/http.c +432 -0
  38. data/ext/couchbase_ext/multithread_plugin.c +1090 -0
  39. data/ext/couchbase_ext/observe.c +171 -0
  40. data/ext/couchbase_ext/plugin_common.c +171 -0
  41. data/ext/couchbase_ext/result.c +129 -0
  42. data/ext/couchbase_ext/stats.c +163 -0
  43. data/ext/couchbase_ext/store.c +542 -0
  44. data/ext/couchbase_ext/timer.c +192 -0
  45. data/ext/couchbase_ext/touch.c +186 -0
  46. data/ext/couchbase_ext/unlock.c +176 -0
  47. data/ext/couchbase_ext/utils.c +551 -0
  48. data/ext/couchbase_ext/version.c +142 -0
  49. data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
  50. data/lib/active_support/cache/couchbase_store.rb +430 -0
  51. data/lib/couchbase.rb +155 -0
  52. data/lib/couchbase/bucket.rb +457 -0
  53. data/lib/couchbase/cluster.rb +119 -0
  54. data/lib/couchbase/connection_pool.rb +58 -0
  55. data/lib/couchbase/constants.rb +12 -0
  56. data/lib/couchbase/result.rb +26 -0
  57. data/lib/couchbase/transcoder.rb +120 -0
  58. data/lib/couchbase/utils.rb +62 -0
  59. data/lib/couchbase/version.rb +21 -0
  60. data/lib/couchbase/view.rb +506 -0
  61. data/lib/couchbase/view_row.rb +272 -0
  62. data/lib/ext/multi_json_fix.rb +56 -0
  63. data/lib/rack/session/couchbase.rb +108 -0
  64. data/tasks/benchmark.rake +6 -0
  65. data/tasks/compile.rake +160 -0
  66. data/tasks/test.rake +100 -0
  67. data/tasks/util.rake +21 -0
  68. data/test/profile/.gitignore +1 -0
  69. data/test/profile/Gemfile +6 -0
  70. data/test/profile/benchmark.rb +195 -0
  71. data/test/setup.rb +178 -0
  72. data/test/test_arithmetic.rb +185 -0
  73. data/test/test_async.rb +316 -0
  74. data/test/test_bucket.rb +276 -0
  75. data/test/test_cas.rb +235 -0
  76. data/test/test_couchbase.rb +77 -0
  77. data/test/test_couchbase_connection_pool.rb +77 -0
  78. data/test/test_couchbase_rails_cache_store.rb +361 -0
  79. data/test/test_delete.rb +120 -0
  80. data/test/test_errors.rb +82 -0
  81. data/test/test_eventmachine.rb +70 -0
  82. data/test/test_format.rb +164 -0
  83. data/test/test_get.rb +407 -0
  84. data/test/test_stats.rb +57 -0
  85. data/test/test_store.rb +216 -0
  86. data/test/test_timer.rb +42 -0
  87. data/test/test_touch.rb +97 -0
  88. data/test/test_unlock.rb +119 -0
  89. data/test/test_utils.rb +58 -0
  90. data/test/test_version.rb +52 -0
  91. metadata +353 -0
@@ -0,0 +1,20 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ Dir['tasks/*.rake'].sort.each { |f| load f }
19
+
20
+ task :default => [:clobber, :compile, :test]
@@ -0,0 +1,49 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # Author:: Couchbase <info@couchbase.com>
3
+ # Copyright:: 2011, 2012 Couchbase, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ $:.push File.expand_path('../lib', __FILE__)
20
+ require 'couchbase/version'
21
+
22
+ Gem::Specification.new do |s|
23
+ s.name = 'jmoses-couchbase'
24
+ s.version = Couchbase::VERSION
25
+ s.author = ['Couchbase', 'Jon Moses']
26
+ s.email = ['support@couchbase.com', 'jon@burningbush.us']
27
+ s.license = 'ASL-2'
28
+ s.homepage = 'http://couchbase.org'
29
+ s.summary = %q{Couchbase ruby driver (updated gemspec for connection-pool 2)}
30
+ s.description = %q{The official client library for use with Couchbase Server. This fork has been updated to require connection-pool 2.0, instead of 1.0}
31
+
32
+ s.files = `git ls-files`.split("\n")
33
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
34
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
35
+ s.extensions = `git ls-files -- ext/**/extconf.rb`.split("\n")
36
+ s.require_paths = ['lib']
37
+
38
+ s.add_runtime_dependency 'yaji', '~> 0.3', '>= 0.3.2'
39
+ s.add_runtime_dependency 'multi_json', '~> 1.0'
40
+ s.add_runtime_dependency 'connection_pool', '~> 2.0.0'
41
+
42
+ s.add_development_dependency 'rake'
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
+ s.add_development_dependency 'active_support'
48
+ s.add_development_dependency 'eventmachine'
49
+ end
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+
3
+ gem 'eventmachine'
4
+
5
+ # couchbase dependencies
6
+ gem 'yaji'
7
+ gem 'multi_json'
@@ -0,0 +1,45 @@
1
+ # Chat Demo
2
+
3
+ This is simple demo of the chat built on EventMachine, and using
4
+ Couchbase to store logs.
5
+
6
+ # Quick Start and Usage
7
+
8
+ Navigate to the example directory and install dependencies:
9
+
10
+ $ cd examples/chat-em
11
+ $ bundle install
12
+
13
+ Execute the server
14
+
15
+ $ ruby ./server.rb
16
+ Hi, this is simple chat server based on EventMachine.
17
+ To join, just use your telnet or netcat clients to connect to
18
+ port 9999 on this machine. Press Ctrl-C to stop it.
19
+
20
+ Use telnet to join the chat
21
+
22
+ $ telnet localhost 9999
23
+ Trying 127.0.0.1...
24
+ Connected to localhost.
25
+ Escape character is '^]'.
26
+ *** What is your name?
27
+ avsej
28
+ *** Hi, avsej!
29
+ Hi everyone in this chat
30
+
31
+ The server will broadcast all your messages and record any event to
32
+ the Couchbase server. If your server hosted not on the localhost or
33
+ using bucket different from "default" you might want to change the
34
+ connection options at the bottom of the `server.rb`, for example in
35
+ this case it will connect to the bucket "protected" with password
36
+ "secret".
37
+
38
+ Couchbase.connection_options = {
39
+ :async => true,
40
+ :engine => :eventmachine,
41
+ :bucket => "protected",
42
+ :password => "secret"
43
+ }
44
+
45
+ Happy hacking!
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+ ["/../../lib", "/.."].each do |path|
3
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + path))
4
+ end
5
+
6
+ require 'bundler'
7
+ Bundler.require
8
+
9
+ require 'couchbase'
10
+
11
+ class ChatServer < EM::Connection
12
+
13
+ @@clients = []
14
+
15
+ def log(message, author = nil)
16
+ Couchbase.bucket.incr("log:key", :initial => 1) do |res|
17
+ entry = {
18
+ 'time' => Time.now.utc,
19
+ 'author' => author || "[system]",
20
+ 'message' => message
21
+ }
22
+ Couchbase.bucket.set("log:#{res.value}", entry)
23
+ end
24
+ end
25
+
26
+ def post_init
27
+ @username = nil
28
+ send_data("*** What is your name?\n")
29
+ end
30
+
31
+ def receive_data(data)
32
+ if @username
33
+ broadcast(data.strip, @username)
34
+ else
35
+ name = data.gsub(/\s+|[\[\]]/, '').strip[0..20]
36
+ if name.empty?
37
+ send_data("*** What is your name?\n")
38
+ else
39
+ @username = name
40
+ @@clients.push(self)
41
+ broadcast("#{@username} has joined")
42
+ send_data("*** Hi, #{@username}!\n")
43
+ end
44
+ end
45
+ end
46
+
47
+ def unbind
48
+ @@clients.delete(self)
49
+ broadcast("#{@username} has left") if @username
50
+ end
51
+
52
+ def broadcast(message, author = nil)
53
+ prefix = author ? "<#{@username}>" : "***"
54
+ log(message, author)
55
+ @@clients.each do |client|
56
+ unless client == self
57
+ client.send_data("#{prefix} #{message}\n")
58
+ end
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ EventMachine.run do
65
+ # hit Control + C to stop
66
+ Signal.trap("INT") { EventMachine.stop }
67
+ Signal.trap("TERM") { EventMachine.stop }
68
+
69
+ Couchbase.connection_options = {:async => true, :engine => :eventmachine}
70
+ Couchbase.bucket.on_connect do |res|
71
+ if res.success?
72
+ puts(<<-MOTD.gsub(/^\s+/, ''))
73
+ Hi, this is simple chat server based on EventMachine.
74
+ To join, just use your telnet or netcat clients to connect to
75
+ port 9999 on this machine. Press Ctrl-C to stop it.
76
+ MOTD
77
+ EventMachine.start_server("0.0.0.0", 9999, ChatServer)
78
+ else
79
+ puts "Cannot connect to Couchbase Server: #{res.error}"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'couchbase'
4
+ gem 'goliath'
5
+ gem 'grape'
@@ -0,0 +1,50 @@
1
+ # Couchbase + Grape + Goliath = <3
2
+
3
+ This demo shows how to integrate these cool things to build
4
+ asynchronous REST service
5
+
6
+ # Usage
7
+
8
+ 1. Clone the repository. Navigate to `examples/chat-goliath-grape/`
9
+ directory
10
+
11
+ 2. Install libcouchbase (http://www.couchbase.com/develop/c/current).
12
+ For MacOS users it will look like:
13
+
14
+ brew update
15
+ brew install libcouchbase
16
+
17
+ 3. Install all ruby dependencies. This demo has been tested on latest
18
+ stable version of ruby (`ruby 2.0.0p0 (2013-02-24 revision 39474)
19
+ [x86_64-linux]`)
20
+
21
+ gem install bundler
22
+ bundle install
23
+
24
+ 4. Setup your Couchbase server
25
+ (http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-getting-started.html).
26
+ It should have `default` bucket. Or you can edit connection options
27
+ in `config/app.rb` file.
28
+
29
+ 5. Start the server up
30
+
31
+ ruby app.rb -sv
32
+
33
+ 6. Create an message:
34
+
35
+ $ curl -X POST -Fmessage="Hello world" http://localhost:9000/messages
36
+ {"ok":true,"id":"msg:1","cas":11880713153673363456}
37
+
38
+ 7. If you create a design document called `messages` and put a view
39
+ named `all` with this map function:
40
+
41
+ function(doc, meta) {
42
+ if (doc.timestamp) {
43
+ emit(meta.id, doc)
44
+ }
45
+ }
46
+
47
+ You can fetch all messages with this command:
48
+
49
+ curl -X GET http://localhost:9000/messages
50
+ {"ok":true,"messages":[{"id":"msg:1","key":"msg:1","value":{"timestamp":"2013-04-11T12:43:42+03:00","message":"Hello world"},"cas":11880713153673363456}]}
@@ -0,0 +1,67 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2013 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'em-synchrony'
19
+ require 'couchbase'
20
+ require 'goliath'
21
+ require 'grape'
22
+ require 'date'
23
+
24
+ class Chat < Grape::API
25
+
26
+ format :json
27
+
28
+ resource 'messages' do
29
+ get do
30
+ view = env.couchbase.design_docs["messages"].all(:include_docs => true)
31
+ msgs = view.map do |r|
32
+ {
33
+ "id" => r.id,
34
+ "key" => r.key,
35
+ "value" => r.value,
36
+ "cas" => r.meta["cas"],
37
+ # "doc" => r.doc
38
+ }
39
+ end
40
+ {"ok" => true, "messages" => msgs}
41
+ end
42
+
43
+ post do
44
+ payload = {
45
+ "timestamp" => DateTime.now.iso8601,
46
+ "message" => params["message"]
47
+ }
48
+ id = env.couchbase.incr("msgid", :initial => 1)
49
+ id = "msg:#{id}"
50
+ cas = env.couchbase.set(id, payload)
51
+ {"ok" => true, "id" => id, "cas" => cas}
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ class App < Goliath::API
58
+ def response(env)
59
+ Chat.call(env)
60
+ rescue => e
61
+ [
62
+ 500,
63
+ {'Content-Type' => 'application/json'},
64
+ MultiJson.dump(:error => e, :stacktrace => e.backtrace)
65
+ ]
66
+ end
67
+ end
@@ -0,0 +1,20 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2013 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ config['couchbase'] = EventMachine::Synchrony::ConnectionPool.new(:size => 5) do
19
+ Couchbase::Bucket.new(:engine => :eventmachine)
20
+ end
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'couchbase'
@@ -0,0 +1,59 @@
1
+ # Gzip Transcoder
2
+
3
+ This example demonstrates advanced usage of client-side transcoders.
4
+ In particular it uses GzipWriter and GzipReader classes from ruby
5
+ standard library to keep documents compressed. The example shows basic
6
+ technique, so that it can be used as a starting point to write your
7
+ custom data filters and adaptors.
8
+
9
+ ## Usage
10
+
11
+ 1. Clone the repository. Navigate to directory `examples/transcoders`.
12
+
13
+ 2. Install libcouchbase (http://www.couchbase.com/develop/c/current).
14
+ For MacOS users it will look like:
15
+
16
+ brew update
17
+ brew install libcouchbase
18
+
19
+ 3. Install all ruby dependencies. This demo has been tested on latest
20
+ stable version of ruby (`ruby 2.0.0p0 (2013-02-24 revision 39474)
21
+ [x86_64-linux]`)
22
+
23
+ gem install bundler
24
+ bundle install
25
+
26
+ 4. Setup your Couchbase server
27
+ (http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-getting-started.html).
28
+ It should have `default` bucket. Or you can specify different
29
+ bucket using CLI options.
30
+
31
+ 5. Store some file to the cluster:
32
+
33
+ $ ./cb-zcp Gemfile
34
+ Run with arguments: {:bucket=>"default", :hostname=>"127.0.0.1", :port=>8091, :username=>nil, :password=>nil}
35
+ store "Gemfile" ... ok
36
+
37
+ 6. Get the data back:
38
+
39
+ $ ./cb-zcat Gemfile
40
+ Run with arguments: {:bucket=>"default", :hostname=>"127.0.0.1", :port=>8091, :username=>nil, :password=>nil}
41
+ Gemfile:
42
+ source 'https://rubygems.org'
43
+
44
+ gem 'couchbase'
45
+
46
+ 7. To make sure that the data is in compressed state, you can check it in `irb`:
47
+
48
+ $ bundle exec irb
49
+ 2.0.0p0 (main):001:0> require 'couchbase'
50
+ true
51
+ 2.0.0p0 (main):002:0> conn = Couchbase.connect(:transcoder => nil)
52
+ #<Couchbase::Bucket:0x007fa344886fc8 "http://localhost:8091/pools/default/buckets/default/" transcoder=nil, default_flags=0x0, quiet=false, connected=true, timeout=2500000>
53
+ 2.0.0p0 (main):003:0> File.open("Gemfile.gz", "w+"){|f| f.write(conn.get("Gemfile"))}
54
+ 65
55
+
56
+ $ zcat Gemfile.gz
57
+ source 'https://rubygems.org'
58
+
59
+ gem 'couchbase'
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ # Author:: Couchbase <info@couchbase.com>
3
+ # Copyright:: 2013 Couchbase, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'bundler'
20
+ Bundler.setup
21
+
22
+ require 'couchbase'
23
+
24
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
25
+ require 'gzip_transcoder'
26
+ require 'options'
27
+
28
+ STDERR.puts "Run with arguments: #{OPTIONS.inspect}"
29
+ begin
30
+ conn = Couchbase.connect(OPTIONS)
31
+ conn.transcoder = GzipTranscoder.new
32
+
33
+ ARGV.each do |filename|
34
+ STDERR.puts "#{filename}:"
35
+ STDOUT.puts(conn.get(filename))
36
+ end
37
+ rescue Couchbase::Error::Base => ex
38
+ STDERR.puts "ERROR: #{ex}"
39
+ exit 1
40
+ end