couchbase-jruby-model 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ // The map function is the most critical part of any view as it provides the
2
+ // logical mapping between the input fields of the individual objects stored
3
+ // within Couchbase to the information output when the view is accessed.
4
+ //
5
+ // Read more about how to write map functions at:
6
+ // http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-map.html
7
+
8
+ function(doc, meta) {
9
+ emit(meta.id, null);
10
+ }
11
+
12
+ // You can also check out following examples
13
+ //
14
+ // The simplest example of a map function:
15
+ //
16
+ // function(doc, meta) {
17
+ // emit(meta.id, doc);
18
+ // }
19
+ //
20
+ // Slightly more complex example of a function that defines a view on values
21
+ // computed from customer documents:
22
+ //
23
+ // function(doc, meta) {
24
+ // if (doc.type == "customer") {
25
+ // emit(meta.id, {last_name: doc.last_name, first_name: doc.first_name});
26
+ // }
27
+ // }
28
+ //
29
+ // To be able to filter or sort the view by some document property, you
30
+ // would use that property for the key. For example, the following view
31
+ // would allow you to lookup customer documents by the last_name or
32
+ // first_name fields (your keys could be compound, e.g. arrays):
33
+ //
34
+ // function(doc, meta) {
35
+ // if (doc.type == "customer") {
36
+ // emit(doc.last_name, {first_name: doc.first_name});
37
+ // emit(doc.first_name, {last_name: doc.last_name});
38
+ // }
39
+ // }
40
+ //
@@ -0,0 +1,61 @@
1
+ // If a view has a reduce function, it is used to produce aggregate results
2
+ // for that view. A reduce function is passed a set of intermediate values
3
+ // and combines them to a single value. Reduce functions must accept, as
4
+ // input, results emitted by its corresponding map function as well as
5
+ // results returned by the reduce function itself. The latter case is
6
+ // referred to as a rereduce.
7
+ //
8
+ // function (key, values, rereduce) {
9
+ // return sum(values);
10
+ // }
11
+ //
12
+ // Reduce functions must handle two cases:
13
+ //
14
+ // 1. When rereduce is false:
15
+ //
16
+ // reduce([ [key1,id1], [key2,id2], [key3,id3] ], [value1,value2,value3], false)
17
+ //
18
+ // * key will be an array whose elements are arrays of the form [key,id],
19
+ // where key is a key emitted by the map function and id is that of the
20
+ // document from which the key was generated.
21
+ // * values will be an array of the values emitted for the respective
22
+ // elements in keys
23
+ //
24
+ // 2. When rereduce is true:
25
+ //
26
+ // reduce(null, [intermediate1,intermediate2,intermediate3], true)
27
+ //
28
+ // * key will be null
29
+ // * values will be an array of values returned by previous calls to the
30
+ // reduce function
31
+ //
32
+ // Reduce functions should return a single value, suitable for both the
33
+ // value field of the final view and as a member of the values array passed
34
+ // to the reduce function.
35
+ //
36
+ // NOTE: If this file is empty, reduce part will be skipped in design document
37
+ //
38
+ // There is number of built-in functions, which could be used instead of
39
+ // javascript implementation of reduce function.
40
+ //
41
+ // The _count function provides a simple count of the input rows from the
42
+ // map function, using the keys and group level to provide to provide a
43
+ // count of the correlated items. The values generated during the map()
44
+ // stage are ignored.
45
+ //
46
+ // _count
47
+ //
48
+ // The built-in _sum function collates the output from the map function
49
+ // call. The information can either be a single number or an array of numbers.
50
+ //
51
+ // _sum
52
+ //
53
+ // The _stats built-in produces statistical calculations for the input data.
54
+ // Like the _sum call the source information should be a number. The
55
+ // generated statistics include the sum, count, minimum (min), maximum (max)
56
+ // and sum squared (sumsqr) of the input rows.
57
+ //
58
+ // _stats
59
+ //
60
+ // Read more about how to write reduce functions at:
61
+ // http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-reduce.html
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Author:: Couchbase <info@couchbase.com>
4
+ # Copyright:: 2012 Couchbase, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'rails/generators/couchbase_generator'
21
+
22
+ module Couchbase
23
+ module Generators
24
+ class ViewGenerator < Rails::Generators::Base
25
+ desc 'Creates a Couchbase views skeletons for map/reduce functions'
26
+
27
+ argument :model_name, :type => :string
28
+ argument :view_name, :type => :string
29
+
30
+ source_root File.expand_path('../templates', __FILE__)
31
+
32
+ def app_name
33
+ Rails::Application.subclasses.first.parent.to_s.underscore
34
+ end
35
+
36
+ def create_map_reduce_files
37
+ template 'map.js', File.join('app', 'models', model_name, view_name, 'map.js')
38
+ template 'reduce.js', File.join('app', 'models', model_name, view_name, 'reduce.js')
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Author:: Couchbase <info@couchbase.com>
4
+ # Copyright:: 2012 Couchbase, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'rails/generators/named_base'
21
+ require 'rails/generators/active_model'
22
+
23
+ module Couchbase #:nodoc:
24
+ module Generators #:nodoc:
25
+
26
+ class Base < ::Rails::Generators::NamedBase #:nodoc:
27
+
28
+ def self.source_root
29
+ @_couchbase_source_root ||=
30
+ File.expand_path("../#{base_name}/#{generator_name}/templates", __FILE__)
31
+ end
32
+
33
+ unless methods.include?(:module_namespacing)
34
+ def module_namespacing(&block)
35
+ yield if block
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 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 'rubygems/package_task'
19
+
20
+ # def gemspec
21
+ # @clean_gemspec ||= eval(File.read(File.expand_path('../../couchbase-model.gemspec', __FILE__)))
22
+ # end
23
+
24
+ # Gem::PackageTask.new(gemspec) do |pkg|
25
+ # pkg.need_tar = true
26
+ # end
27
+
data/tasks/test.rake ADDED
@@ -0,0 +1,34 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 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 'rake/testtask'
19
+ require 'rake/clean'
20
+
21
+ rule 'test/CouchbaseMock.jar' do |task|
22
+ jar_path = "0.5-SNAPSHOT/CouchbaseMock-0.5-20120726.220757-19.jar"
23
+ sh %{wget -q -O test/CouchbaseMock.jar http://files.couchbase.com/maven2/org/couchbase/mock/CouchbaseMock/#{jar_path}}
24
+ end
25
+
26
+ CLOBBER << 'test/CouchbaseMock.jar'
27
+
28
+ Rake::TestTask.new do |test|
29
+ test.libs << "test" << "."
30
+ test.pattern = 'test/test_*.rb'
31
+ test.options = '--verbose'
32
+ end
33
+
34
+ Rake::Task['test'].prerequisites.unshift('test/CouchbaseMock.jar')
data/tasks/util.rake ADDED
@@ -0,0 +1,21 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 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
+ desc 'Start an irb session and load the library.'
19
+ task :console do
20
+ exec "irb -I lib -rcouchbase-model"
21
+ end
data/test/setup.rb ADDED
@@ -0,0 +1,168 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 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 'minitest/autorun'
19
+ require 'couchbase'
20
+ require 'couchbase/model'
21
+
22
+ require 'socket'
23
+ require 'open-uri'
24
+
25
+ class CouchbaseServer
26
+ attr_accessor :host, :port, :num_nodes, :buckets_spec
27
+
28
+ def real?
29
+ true
30
+ end
31
+
32
+ def initialize(params = {})
33
+ @host, @port = ['localhost', 8091] #ENV['COUCHBASE_SERVER'].split(':')
34
+ @port = @port.to_i
35
+
36
+ if @host.nil? || @host.empty? || @port == 0
37
+ raise ArgumentError, 'Check COUCHBASE_SERVER variable. It should be hostname:port'
38
+ end
39
+
40
+ @config = MultiJson.load(open("http://#{@host}:#{@port}/pools/default"))
41
+ @num_nodes = @config['nodes'].size
42
+ @buckets_spec = params[:buckets_spec] || 'default:' # "default:,protected:secret,cache::memcache"
43
+ end
44
+
45
+ def start
46
+ # flush all buckets
47
+ @buckets_spec.split(',') do |bucket|
48
+ name, password, _ = bucket.split(':')
49
+ connection = Couchbase.new(:hostname => @host,
50
+ :port => @port,
51
+ :username => name,
52
+ :bucket => name,
53
+ :password => password)
54
+ connection.flush
55
+ end
56
+ end
57
+ def stop; end
58
+ end
59
+
60
+ class CouchbaseMock
61
+ Monitor = Struct.new(:pid, :client, :socket, :port)
62
+
63
+ attr_accessor :host, :port, :buckets_spec, :num_nodes, :num_vbuckets
64
+
65
+ def real?
66
+ false
67
+ end
68
+
69
+ def initialize(params = {})
70
+ @host = '127.0.0.1'
71
+ @port = 0
72
+ @num_nodes = 10
73
+ @num_vbuckets = 4096
74
+ @buckets_spec = 'default:' # "default:,protected:secret,cache::memcache"
75
+ params.each do |key, value|
76
+ send("#{key}=", value)
77
+ end
78
+ yield self if block_given?
79
+ if @num_vbuckets < 1 || (@num_vbuckets & (@num_vbuckets - 1) != 0)
80
+ raise ArgumentError, 'Number of vbuckets should be a power of two and greater than zero'
81
+ end
82
+ end
83
+
84
+ def start
85
+ @monitor = Monitor.new
86
+ @monitor.socket = TCPServer.new(nil, 0)
87
+ @monitor.socket.listen(10)
88
+ _, @monitor.port, _, _ = @monitor.socket.addr
89
+ trap('CLD') do
90
+ puts 'CouchbaseMock.jar died unexpectedly during startup'
91
+ exit(1)
92
+ end
93
+ @monitor.pid = fork
94
+ if @monitor.pid.nil?
95
+ rc = exec(command_line("--harakiri-monitor=:#{@monitor.port}"))
96
+ else
97
+ trap('CLD', 'SIG_DFL')
98
+ @monitor.client, _ = @monitor.socket.accept
99
+ @port = @monitor.client.recv(100).to_i
100
+ end
101
+ end
102
+
103
+ def stop
104
+ @monitor.client.close
105
+ @monitor.socket.close
106
+ Process.kill('TERM', @monitor.pid)
107
+ Process.wait(@monitor.pid)
108
+ end
109
+
110
+ def failover_node(index, bucket = 'default')
111
+ @monitor.client.send("failover,#{index},#{bucket}", 0)
112
+ end
113
+
114
+ def respawn_node(index, bucket = 'default')
115
+ @monitor.client.send("respawn,#{index},#{bucket}", 0)
116
+ end
117
+
118
+ protected
119
+
120
+ def command_line(extra = nil)
121
+ cmd = "java -jar #{File.dirname(__FILE__)}/CouchbaseMock.jar"
122
+ cmd << " --host #{@host}" if @host
123
+ cmd << " --port #{@port}" if @port
124
+ cmd << " --nodes #{@num_nodes}" if @num_nodes
125
+ cmd << " --vbuckets #{@num_vbuckets}" if @num_vbuckets
126
+ cmd << " --buckets #{@buckets_spec}" if @buckets_spec
127
+ cmd << " #{extra}"
128
+ cmd
129
+ end
130
+ end
131
+
132
+ class MiniTest::Unit::TestCase
133
+
134
+ def start_mock(params = {})
135
+ mock = nil
136
+ if true # ENV['COUCHBASE_SERVER']
137
+ mock = CouchbaseServer.new(params)
138
+ if (params[:port] && mock.port != params[:port]) ||
139
+ (params[:host] && mock.host != params[:host]) ||
140
+ mock.buckets_spec != 'default:'
141
+ skip("Unable to configure real cluster. Requested config is: #{params.inspect}")
142
+ end
143
+ else
144
+ mock = CouchbaseMock.new(params)
145
+ end
146
+ mock.start
147
+ mock
148
+ end
149
+
150
+ def stop_mock(mock)
151
+ assert(mock)
152
+ mock.stop
153
+ end
154
+
155
+ def with_mock(params = {})
156
+ mock = nil
157
+ if block_given?
158
+ mock = start_mock(params)
159
+ yield mock
160
+ end
161
+ ensure
162
+ stop_mock(mock) if mock
163
+ end
164
+
165
+ def uniq_id(*suffixes)
166
+ [caller.first[/.*[` ](.*)'/, 1], suffixes].join('_')
167
+ end
168
+ end