couchbase 1.3.4-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +22 -0
- data/.yardopts +5 -0
- data/CONTRIBUTING.markdown +75 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/Makefile +3 -0
- data/README.markdown +649 -0
- data/RELEASE_NOTES.markdown +796 -0
- data/Rakefile +20 -0
- data/couchbase.gemspec +49 -0
- data/examples/chat-em/Gemfile +7 -0
- data/examples/chat-em/README.markdown +45 -0
- data/examples/chat-em/server.rb +82 -0
- data/examples/chat-goliath-grape/Gemfile +5 -0
- data/examples/chat-goliath-grape/README.markdown +50 -0
- data/examples/chat-goliath-grape/app.rb +67 -0
- data/examples/chat-goliath-grape/config/app.rb +20 -0
- data/examples/transcoders/Gemfile +3 -0
- data/examples/transcoders/README.markdown +59 -0
- data/examples/transcoders/cb-zcat +40 -0
- data/examples/transcoders/cb-zcp +45 -0
- data/examples/transcoders/gzip_transcoder.rb +49 -0
- data/examples/transcoders/options.rb +54 -0
- data/ext/couchbase_ext/.gitignore +4 -0
- data/ext/couchbase_ext/arguments.c +956 -0
- data/ext/couchbase_ext/arithmetic.c +307 -0
- data/ext/couchbase_ext/bucket.c +1370 -0
- data/ext/couchbase_ext/context.c +65 -0
- data/ext/couchbase_ext/couchbase_ext.c +1364 -0
- data/ext/couchbase_ext/couchbase_ext.h +644 -0
- data/ext/couchbase_ext/delete.c +163 -0
- data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
- data/ext/couchbase_ext/extconf.rb +168 -0
- data/ext/couchbase_ext/get.c +316 -0
- data/ext/couchbase_ext/gethrtime.c +129 -0
- data/ext/couchbase_ext/http.c +432 -0
- data/ext/couchbase_ext/multithread_plugin.c +1090 -0
- data/ext/couchbase_ext/observe.c +171 -0
- data/ext/couchbase_ext/plugin_common.c +171 -0
- data/ext/couchbase_ext/result.c +129 -0
- data/ext/couchbase_ext/stats.c +163 -0
- data/ext/couchbase_ext/store.c +542 -0
- data/ext/couchbase_ext/timer.c +192 -0
- data/ext/couchbase_ext/touch.c +186 -0
- data/ext/couchbase_ext/unlock.c +176 -0
- data/ext/couchbase_ext/utils.c +551 -0
- data/ext/couchbase_ext/version.c +142 -0
- data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
- data/lib/active_support/cache/couchbase_store.rb +430 -0
- data/lib/couchbase.rb +155 -0
- data/lib/couchbase/bucket.rb +457 -0
- data/lib/couchbase/cluster.rb +119 -0
- data/lib/couchbase/connection_pool.rb +58 -0
- data/lib/couchbase/constants.rb +12 -0
- data/lib/couchbase/result.rb +26 -0
- data/lib/couchbase/transcoder.rb +120 -0
- data/lib/couchbase/utils.rb +62 -0
- data/lib/couchbase/version.rb +21 -0
- data/lib/couchbase/view.rb +506 -0
- data/lib/couchbase/view_row.rb +272 -0
- data/lib/ext/multi_json_fix.rb +56 -0
- data/lib/rack/session/couchbase.rb +108 -0
- data/tasks/benchmark.rake +6 -0
- data/tasks/compile.rake +158 -0
- data/tasks/test.rake +100 -0
- data/tasks/util.rake +21 -0
- data/test/profile/.gitignore +1 -0
- data/test/profile/Gemfile +6 -0
- data/test/profile/benchmark.rb +195 -0
- data/test/setup.rb +178 -0
- data/test/test_arithmetic.rb +185 -0
- data/test/test_async.rb +316 -0
- data/test/test_bucket.rb +250 -0
- data/test/test_cas.rb +235 -0
- data/test/test_couchbase.rb +77 -0
- data/test/test_couchbase_connection_pool.rb +77 -0
- data/test/test_couchbase_rails_cache_store.rb +361 -0
- data/test/test_delete.rb +120 -0
- data/test/test_errors.rb +82 -0
- data/test/test_eventmachine.rb +70 -0
- data/test/test_format.rb +164 -0
- data/test/test_get.rb +407 -0
- data/test/test_stats.rb +57 -0
- data/test/test_store.rb +216 -0
- data/test/test_timer.rb +42 -0
- data/test/test_touch.rb +97 -0
- data/test/test_unlock.rb +119 -0
- data/test/test_utils.rb +58 -0
- data/test/test_version.rb +52 -0
- metadata +336 -0
@@ -0,0 +1,272 @@
|
|
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
|
+
module Couchbase
|
19
|
+
# This class encapsulates structured JSON document
|
20
|
+
#
|
21
|
+
# @since 1.2.0
|
22
|
+
#
|
23
|
+
# It behaves like Hash for document included into row, and has access methods to row data as well.
|
24
|
+
#
|
25
|
+
# @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-datastore.html
|
26
|
+
class ViewRow
|
27
|
+
include Constants
|
28
|
+
|
29
|
+
# Undefine as much methods as we can to free names for views
|
30
|
+
instance_methods.each do |m|
|
31
|
+
undef_method(m) if m.to_s !~ /(?:^__|^nil\?$|^send$|^object_id$|^class$|)/
|
32
|
+
end
|
33
|
+
|
34
|
+
# The hash built from JSON document.
|
35
|
+
#
|
36
|
+
# @since 1.2.0
|
37
|
+
#
|
38
|
+
# This is complete response from the Couchbase
|
39
|
+
#
|
40
|
+
# @return [Hash]
|
41
|
+
attr_accessor :data
|
42
|
+
|
43
|
+
# The key which was emitted by map function
|
44
|
+
#
|
45
|
+
# @since 1.2.0
|
46
|
+
#
|
47
|
+
# @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-map.html
|
48
|
+
#
|
49
|
+
# Usually it is String (the object +_id+) but it could be also any
|
50
|
+
# compount JSON value.
|
51
|
+
#
|
52
|
+
# @return [Object]
|
53
|
+
attr_accessor :key
|
54
|
+
|
55
|
+
# The value which was emitted by map function
|
56
|
+
#
|
57
|
+
# @since 1.2.0
|
58
|
+
#
|
59
|
+
# @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-map.html
|
60
|
+
#
|
61
|
+
# @return [Object]
|
62
|
+
attr_accessor :value
|
63
|
+
|
64
|
+
# The document hash.
|
65
|
+
#
|
66
|
+
# @since 1.2.0
|
67
|
+
#
|
68
|
+
# It usually available when view executed with +:include_doc+ argument.
|
69
|
+
#
|
70
|
+
# @return [Hash]
|
71
|
+
attr_accessor :doc
|
72
|
+
|
73
|
+
# The identificator of the document
|
74
|
+
#
|
75
|
+
# @since 1.2.0
|
76
|
+
#
|
77
|
+
# @return [String]
|
78
|
+
attr_accessor :id
|
79
|
+
|
80
|
+
# The meta data linked to the document
|
81
|
+
#
|
82
|
+
# @since 1.2.0
|
83
|
+
#
|
84
|
+
# @return [Hash]
|
85
|
+
attr_accessor :meta
|
86
|
+
|
87
|
+
# Initialize the document instance
|
88
|
+
#
|
89
|
+
# @since 1.2.0
|
90
|
+
#
|
91
|
+
# It takes reference to the bucket, data hash.
|
92
|
+
#
|
93
|
+
# @param [Couchbase::Bucket] bucket the reference to connection
|
94
|
+
# @param [Hash] data the data hash, which was built from JSON document
|
95
|
+
# representation
|
96
|
+
def initialize(bucket, data)
|
97
|
+
@bucket = bucket
|
98
|
+
@data = data
|
99
|
+
@key = data[S_KEY]
|
100
|
+
@value = data[S_VALUE]
|
101
|
+
if data[S_DOC]
|
102
|
+
@meta = data[S_DOC][S_META]
|
103
|
+
@doc = data[S_DOC][S_VALUE]
|
104
|
+
end
|
105
|
+
@id = data[S_ID] || @meta && @meta[S_ID]
|
106
|
+
@last = data.delete(S_IS_LAST) || false
|
107
|
+
end
|
108
|
+
|
109
|
+
# Wraps data hash into ViewRow instance
|
110
|
+
#
|
111
|
+
# @since 1.2.0
|
112
|
+
#
|
113
|
+
# @see ViewRow#initialize
|
114
|
+
#
|
115
|
+
# @param [Couchbase::Bucket] bucket the reference to connection
|
116
|
+
# @param [Hash] data the data hash, which was built from JSON document
|
117
|
+
# representation
|
118
|
+
#
|
119
|
+
# @return [ViewRow]
|
120
|
+
def self.wrap(bucket, data)
|
121
|
+
self.new(bucket, data)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Get attribute of the document
|
125
|
+
#
|
126
|
+
# @since 1.2.0
|
127
|
+
#
|
128
|
+
# Fetches attribute from underlying document hash
|
129
|
+
#
|
130
|
+
# @param [String] key the attribute name
|
131
|
+
#
|
132
|
+
# @return [Object] property value or nil
|
133
|
+
def [](key)
|
134
|
+
@doc[key]
|
135
|
+
end
|
136
|
+
|
137
|
+
# Check attribute existence
|
138
|
+
#
|
139
|
+
# @since 1.2.0
|
140
|
+
#
|
141
|
+
# @param [String] key the attribute name
|
142
|
+
#
|
143
|
+
# @return [true, false] +true+ if the given attribute is present in in
|
144
|
+
# the document.
|
145
|
+
def has_key?(key)
|
146
|
+
@doc.has_key?(key)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Set document attribute
|
150
|
+
#
|
151
|
+
# @since 1.2.0
|
152
|
+
#
|
153
|
+
# Set or update the attribute in the document hash
|
154
|
+
#
|
155
|
+
# @param [String] key the attribute name
|
156
|
+
# @param [Object] value the attribute value
|
157
|
+
#
|
158
|
+
# @return [Object] the value
|
159
|
+
def []=(key, value)
|
160
|
+
@doc[key] = value
|
161
|
+
end
|
162
|
+
|
163
|
+
# Signals if this row is last in a stream
|
164
|
+
#
|
165
|
+
# @since 1.2.1
|
166
|
+
#
|
167
|
+
# @return [true, false] +true+ if this row is last in a stream
|
168
|
+
def last?
|
169
|
+
@last
|
170
|
+
end
|
171
|
+
|
172
|
+
def inspect
|
173
|
+
desc = "#<#{self.class.name}:#{self.object_id}"
|
174
|
+
[:@id, :@key, :@value, :@doc, :@meta].each do |iv|
|
175
|
+
desc << " #{iv}=#{instance_variable_get(iv).inspect}"
|
176
|
+
end
|
177
|
+
desc << ">"
|
178
|
+
desc
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# This class encapsulates information about design docs
|
183
|
+
#
|
184
|
+
# @since 1.2.1
|
185
|
+
#
|
186
|
+
# It is subclass of ViewRow, but also gives access to view creation through method_missing
|
187
|
+
#
|
188
|
+
# @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-datastore.html
|
189
|
+
class DesignDoc < ViewRow
|
190
|
+
# It isn't allowed to change design document ID after
|
191
|
+
# initialization
|
192
|
+
undef id=
|
193
|
+
|
194
|
+
# Initialize the design doc instance
|
195
|
+
#
|
196
|
+
# @since 1.2.1
|
197
|
+
#
|
198
|
+
# It takes reference to the bucket, data hash. It will define view
|
199
|
+
# methods if the data object looks like design document.
|
200
|
+
#
|
201
|
+
# @param [Couchbase::Bucket] bucket the reference to connection
|
202
|
+
# @param [Hash] data the data hash, which was built from JSON document
|
203
|
+
# representation
|
204
|
+
def initialize(bucket, data)
|
205
|
+
super
|
206
|
+
@all_views = {}
|
207
|
+
@views = @doc.has_key?('views') ? @doc['views'].keys : []
|
208
|
+
@spatial = @doc.has_key?('spatial') ? @doc['spatial'].keys : []
|
209
|
+
@views.each{|name| @all_views[name] = "#{@id}/_view/#{name}"}
|
210
|
+
@spatial.each{|name| @all_views[name] = "#{@id}/_spatial/#{name}"}
|
211
|
+
end
|
212
|
+
|
213
|
+
def method_missing(meth, *args)
|
214
|
+
if path = @all_views[meth.to_s]
|
215
|
+
View.new(@bucket, path, *args)
|
216
|
+
else
|
217
|
+
super
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def respond_to?(meth, *args)
|
222
|
+
if @all_views[meth.to_s]
|
223
|
+
true
|
224
|
+
else
|
225
|
+
super
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def method(meth, *args)
|
230
|
+
if path = @all_views[meth.to_s]
|
231
|
+
lambda{|*p| View.new(@bucket, path, *p)}
|
232
|
+
else
|
233
|
+
super
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# The list of views defined or empty array
|
238
|
+
#
|
239
|
+
# @since 1.2.1
|
240
|
+
#
|
241
|
+
# @return [Array<View>]
|
242
|
+
attr_accessor :views
|
243
|
+
|
244
|
+
# The list of spatial views defined or empty array
|
245
|
+
#
|
246
|
+
# @since 1.2.1
|
247
|
+
#
|
248
|
+
# @return [Array<View>]
|
249
|
+
attr_accessor :spatial
|
250
|
+
|
251
|
+
# Check if the document has views defines
|
252
|
+
#
|
253
|
+
# @since 1.2.1
|
254
|
+
#
|
255
|
+
# @see DesignDoc#views
|
256
|
+
#
|
257
|
+
# @return [true, false] +true+ if the document have views
|
258
|
+
def has_views?
|
259
|
+
!@views.empty?
|
260
|
+
end
|
261
|
+
|
262
|
+
def inspect
|
263
|
+
desc = "#<#{self.class.name}:#{self.object_id}"
|
264
|
+
[:@id, :@views, :@spatial].each do |iv|
|
265
|
+
desc << " #{iv}=#{instance_variable_get(iv).inspect}"
|
266
|
+
end
|
267
|
+
desc << ">"
|
268
|
+
desc
|
269
|
+
end
|
270
|
+
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,56 @@
|
|
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
|
+
# This patch fixing loading primitives like strings, numbers and booleans
|
19
|
+
# using json_gem. It amends behaviour of MultiJson::Engines::JsonGem#load
|
20
|
+
# when it receives JSON string which neither Array nor Object.
|
21
|
+
|
22
|
+
if MultiJson.respond_to?(:engine)
|
23
|
+
multi_json_engine = MultiJson.send(:engine)
|
24
|
+
else
|
25
|
+
multi_json_engine = MultiJson.send(:adapter)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Patch for MultiJson versions < 1.3.3
|
29
|
+
require 'multi_json/version'
|
30
|
+
version = begin
|
31
|
+
MultiJson::VERSION
|
32
|
+
rescue NameError
|
33
|
+
MultiJson::Version.to_s
|
34
|
+
end.dup # because Gem::Version modifies it
|
35
|
+
if Gem::Version.new(version) < Gem::Version.new('1.3.3')
|
36
|
+
class << MultiJson
|
37
|
+
alias :dump :encode
|
38
|
+
alias :load :decode
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
if multi_json_engine.name =~ /JsonGem$/
|
43
|
+
class << multi_json_engine
|
44
|
+
alias _load_object load
|
45
|
+
def load(string, options = {})
|
46
|
+
if string.respond_to?(:read)
|
47
|
+
string = string.read
|
48
|
+
end
|
49
|
+
if string =~ /\A\s*[{\[]/
|
50
|
+
_load_object(string, options)
|
51
|
+
else
|
52
|
+
_load_object("[#{string}]", options)[0]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,108 @@
|
|
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
|
+
require 'rack/session/abstract/id'
|
19
|
+
require 'couchbase'
|
20
|
+
require 'thread'
|
21
|
+
|
22
|
+
module Rack
|
23
|
+
module Session
|
24
|
+
|
25
|
+
# This is Couchbase-powered session store for rack applications
|
26
|
+
#
|
27
|
+
# To use it just load it as usual middleware in your `config.ru` file
|
28
|
+
#
|
29
|
+
# require 'rack/session/couchbase'
|
30
|
+
# use Rack::Session::Couchbase
|
31
|
+
#
|
32
|
+
# You can also pass additional options:
|
33
|
+
#
|
34
|
+
# require 'rack/session/couchbase'
|
35
|
+
# use Rack::Session::Couchbase, :expire_after => 5.minutes,
|
36
|
+
# :couchbase => {:bucket => "sessions", :default_format => :document}
|
37
|
+
#
|
38
|
+
# By default sessions will be serialized using Marshal class. But
|
39
|
+
# you can store them as JSON (+:default_format => :document+), to
|
40
|
+
# allow analyse them using Map/Reduce. In this case you should
|
41
|
+
# care about serialization of all custom objects like
|
42
|
+
# ActionDispatch::Flash::FlashHash
|
43
|
+
#
|
44
|
+
class Couchbase < Abstract::ID
|
45
|
+
attr_reader :mutex, :pool
|
46
|
+
|
47
|
+
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge(
|
48
|
+
:couchbase => {:quiet => true, :default_format => :marshal,
|
49
|
+
:key_prefix => 'rack:session:'})
|
50
|
+
|
51
|
+
def initialize(app, options = {})
|
52
|
+
# Support old :expires option
|
53
|
+
options[:expire_after] ||= options[:expires]
|
54
|
+
super
|
55
|
+
|
56
|
+
@default_options[:couchbase][:default_ttl] ||= options[:expire_after]
|
57
|
+
@default_options[:couchbase][:key_prefix] ||= options[:namespace]
|
58
|
+
@namespace = @default_options[:couchbase][:key_prefix]
|
59
|
+
@mutex = Mutex.new
|
60
|
+
@pool = ::Couchbase.connect(@default_options[:couchbase])
|
61
|
+
end
|
62
|
+
|
63
|
+
def generate_sid
|
64
|
+
while true
|
65
|
+
sid = super
|
66
|
+
break sid unless @pool.get(sid)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_session(env, sid)
|
71
|
+
with_lock(env, [nil, {}]) do
|
72
|
+
unless sid and session = @pool.get(sid)
|
73
|
+
sid, session = generate_sid, {}
|
74
|
+
@pool.set(sid, session)
|
75
|
+
end
|
76
|
+
[sid, session]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_session(env, session_id, new_session, options)
|
81
|
+
with_lock(env, false) do
|
82
|
+
@pool.set(session_id, new_session, options)
|
83
|
+
session_id
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def destroy_session(env, session_id, options)
|
88
|
+
with_lock(env) do
|
89
|
+
@pool.delete(session_id)
|
90
|
+
generate_sid unless options[:drop]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def with_lock(env, default = nil)
|
95
|
+
@mutex.lock if env['rack.multithread']
|
96
|
+
yield
|
97
|
+
rescue ::Couchbase::Error::Connect, ::Couchbase::Error::Timeout
|
98
|
+
if $VERBOSE
|
99
|
+
warn "#{self} is unable to find Couchbase server."
|
100
|
+
warn $!.inspect
|
101
|
+
end
|
102
|
+
default
|
103
|
+
ensure
|
104
|
+
@mutex.unlock if @mutex.locked?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
desc 'Run benchmarks and compare them to memcached and dalli gems'
|
2
|
+
task :benchmark => [:clean, :compile] do
|
3
|
+
cd File.expand_path(File.join(__FILE__, '..', '..', 'test', 'profile')) do
|
4
|
+
sh "bundle install && bundle exec ruby benchmark.rb | tee benchmark-#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}.log"
|
5
|
+
end
|
6
|
+
end
|
data/tasks/compile.rake
ADDED
@@ -0,0 +1,158 @@
|
|
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
|
+
gem 'rake-compiler', '>= 0.7.5'
|
19
|
+
require "rake/extensiontask"
|
20
|
+
|
21
|
+
def gemspec
|
22
|
+
@clean_gemspec ||= eval(File.read(File.expand_path('../../couchbase.gemspec', __FILE__)))
|
23
|
+
end
|
24
|
+
|
25
|
+
version_router = lambda do |t|
|
26
|
+
File.open(t.name, 'wb') do |f|
|
27
|
+
f.write <<-RUBY
|
28
|
+
require "couchbase/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/couchbase_ext"
|
29
|
+
RUBY
|
30
|
+
end
|
31
|
+
end
|
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
|
+
|
63
|
+
# Setup compile tasks. Configuration can be passed via ENV.
|
64
|
+
# Example:
|
65
|
+
# rake compile with_libcouchbase_include=/opt/couchbase/include
|
66
|
+
# with_libcouchbase_lib=/opt/couchbase/lib
|
67
|
+
#
|
68
|
+
# or
|
69
|
+
#
|
70
|
+
# rake compile with_libcouchbase_dir=/opt/couchbase
|
71
|
+
#
|
72
|
+
Rake::ExtensionTask.new("couchbase_ext", gemspec) do |ext|
|
73
|
+
ext.cross_compile = true
|
74
|
+
ext.cross_platform = ENV['TARGET']
|
75
|
+
if ENV['RUBY_CC_VERSION']
|
76
|
+
ext.lib_dir = "lib/couchbase"
|
77
|
+
end
|
78
|
+
ext.cross_compiling do |spec|
|
79
|
+
spec.files.delete("lib/couchbase/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"])
|
82
|
+
file "#{ext.tmp_dir}/#{ext.cross_platform}/stage/lib/couchbase_ext.rb", &version_router
|
83
|
+
end
|
84
|
+
|
85
|
+
CLEAN.include "#{ext.lib_dir}/*.#{RbConfig::CONFIG['DLEXT']}"
|
86
|
+
|
87
|
+
ENV.each do |key, val|
|
88
|
+
next unless key =~ /\Awith_(\w+)\z/i
|
89
|
+
opt = $1.downcase.tr('_', '-')
|
90
|
+
if File.directory?(path = File.expand_path(val))
|
91
|
+
ext.config_options << "--with-#{opt}=#{path}"
|
92
|
+
else
|
93
|
+
warn "No such directory: #{opt}: #{path}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
require 'rubygems/package_task'
|
99
|
+
Gem::PackageTask.new(gemspec) do |pkg|
|
100
|
+
pkg.need_tar = pkg.need_zip = false
|
101
|
+
end
|
102
|
+
|
103
|
+
require 'mini_portile'
|
104
|
+
require 'rake/extensioncompiler'
|
105
|
+
|
106
|
+
class MiniPortile
|
107
|
+
alias :cook_without_checkpoint :cook
|
108
|
+
def cook
|
109
|
+
checkpoint = "ports/.#{name}-#{version}-#{host}.installed"
|
110
|
+
unless File.exist?(checkpoint)
|
111
|
+
cook_without_checkpoint
|
112
|
+
FileUtils.touch(checkpoint)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
file "lib/couchbase_ext.rb", &version_router
|
118
|
+
|
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
|
140
|
+
recipe.files << "http://packages.couchbase.com/clients/c/libcouchbase-#{recipe.version}.tar.gz"
|
141
|
+
recipe.configure_options.push("--disable-debug",
|
142
|
+
"--disable-dependency-tracking",
|
143
|
+
"--disable-couchbasemock",
|
144
|
+
"--disable-cxx",
|
145
|
+
"--disable-plugins",
|
146
|
+
"--disable-examples",
|
147
|
+
"--disable-tools")
|
148
|
+
recipe.cook
|
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")
|
157
|
+
end
|
158
|
+
end
|