couchbase-model 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
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
+ module Couchbase
19
+
20
+ class Model
21
+
22
+ module Configuration
23
+ extend self
24
+
25
+ attr_accessor :design_documents_paths
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -23,15 +23,23 @@ module Couchbase
23
23
 
24
24
  # Generator of CouchDB specfic UUIDs. This is the ruby implementation of
25
25
  # couch_uuids.erl from couchdb distribution. It is threadsafe.
26
+ #
27
+ # @since 0.0.1
26
28
 
27
29
  class UUID
28
30
  # Get default UUID generator. You can create your own if you like.
31
+ #
32
+ # @since 0.0.1
33
+ #
34
+ # @return [UUID]
29
35
  def self.generator
30
36
  @generator ||= UUID.new
31
37
  end
32
38
 
33
39
  # Initialize generator.
34
40
  #
41
+ # @since 0.0.1
42
+ #
35
43
  # @param [Fixnum] seed seed for pseudorandom number generator.
36
44
  def initialize(seed = nil)
37
45
  seed ? srand(seed) : srand
@@ -42,6 +50,8 @@ module Couchbase
42
50
 
43
51
  # Generate list of UUIDs.
44
52
  #
53
+ # @since 0.0.1
54
+ #
45
55
  # @param [Fixnum] count number of UUIDs you need
46
56
  #
47
57
  # @param [Symbol] algorithm Algorithm to use. Known algorithms:
@@ -19,7 +19,7 @@ module Couchbase
19
19
 
20
20
  class Model
21
21
 
22
- VERSION = "0.0.1"
22
+ VERSION = "0.1.0"
23
23
 
24
24
  end
25
25
 
@@ -0,0 +1,136 @@
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 'couchbase/model'
21
+
22
+ module Rails #:nodoc:
23
+ module Couchbase #:nodoc:
24
+ class Railtie < Rails::Railtie #:nodoc:
25
+
26
+ # Determine which generator to use. app_generators was introduced after
27
+ # 3.0.0.
28
+ #
29
+ # @since 0.1.0
30
+ #
31
+ # @example Get the generators method.
32
+ # railtie.generators
33
+ #
34
+ # @return [Symbol] The method name to use.
35
+ def self.generator
36
+ config.respond_to?(:app_generators) ? :app_generators : :generators
37
+ end
38
+
39
+ # Maping of rescued exceptions to HTTP responses
40
+ #
41
+ # @since 0.1.0
42
+ #
43
+ # @example
44
+ # railtie.rescue_responses
45
+ #
46
+ # @return [Hash] rescued responses
47
+ def self.rescue_responses
48
+ {
49
+ "Couchbase::Error::NotFound" => :not_found,
50
+ "Couchbase::Error::NotStored" => :unprocessable_entity
51
+ }
52
+ end
53
+
54
+ config.send(generator).orm :couchbase, :migration => false
55
+
56
+ if config.action_dispatch.rescue_responses
57
+ config.action_dispatch.rescue_responses.merge!(rescue_responses)
58
+ end
59
+
60
+ # Initialize Couchbase Mode. This will look for a couchbase.yml in the
61
+ # config directory and configure Couchbase connection appropriately.
62
+ #
63
+ # @example couchbase.yml
64
+ #
65
+ # common: &common
66
+ # hostname: localhost
67
+ # port: 8091
68
+ # username:
69
+ # password:
70
+ # pool: default
71
+ #
72
+ # production:
73
+ # <<: *common
74
+ # bucket: example_production
75
+ #
76
+ # test:
77
+ # <<: *common
78
+ # bucket: example_test
79
+ #
80
+ # development:
81
+ # <<: *common
82
+ # bucket: example_development
83
+ #
84
+ initializer "couchbase.setup_connection" do
85
+ config_file = Rails.root.join("config", "couchbase.yml")
86
+ if config_file.file? &&
87
+ config = YAML.load(ERB.new(File.read(config_file)).result)[Rails.env]
88
+ ::Couchbase.connection_options = config.with_indifferent_access
89
+ end
90
+ end
91
+
92
+ # After initialization we will warn the user if we can't find a couchbase.yml and
93
+ # alert to create one.
94
+ initializer "couchbase.warn_configuration_missing" do
95
+ unless ARGV.include?("couchbase:config")
96
+ config.after_initialize do
97
+ unless Rails.root.join("config", "couchbase.yml").file?
98
+ puts "\nCouchbase config not found. Create a config file at: config/couchbase.yml"
99
+ puts "to generate one run: rails generate couchbase:config\n\n"
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ # Check (and upgrade if needed) all design documents
106
+ initializer "couchbase.upgrade_design_documents", :after =>"couchbase.setup_connection" do |app|
107
+ config.to_prepare do
108
+ ::Couchbase::Model::Configuration.design_documents_paths ||= app.config.paths["app/models"]
109
+ app.config.paths["app/models"].each do |path|
110
+ Dir.glob("#{path}/**/*.rb").sort.each do |file|
111
+ require_dependency(file.gsub("#{path}/" , "").gsub(".rb", ""))
112
+ end
113
+ end
114
+ begin
115
+ ::Couchbase::Model.descendants.each do |model|
116
+ model.ensure_design_document!
117
+ end
118
+ rescue ::Couchbase::Error::Timeout, ::Couchbase::Error::Connect
119
+ # skip connection errors for now
120
+ end
121
+ end
122
+ end
123
+
124
+ # Set the proper error types for Rails. NotFound errors should be
125
+ # 404s and not 500s, validation errors are 422s.
126
+ initializer "couchbase.load_http_errors" do |app|
127
+ config.after_initialize do
128
+ unless config.action_dispatch.rescue_responses
129
+ ActionDispatch::ShowExceptions.rescue_responses.update(Railtie.rescue_responses)
130
+ end
131
+ end
132
+ end
133
+
134
+ end
135
+ end
136
+ end
@@ -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 ConfigGenerator < Rails::Generators::Base
25
+ desc "Creates a Couchbase configuration file at config/couchbase.yml"
26
+
27
+ argument :database_name, :type => :string, :optional => true
28
+
29
+ def self.source_root
30
+ @_couchbase_source_root ||= File.expand_path("../templates", __FILE__)
31
+ end
32
+
33
+ def app_name
34
+ Rails::Application.subclasses.first.parent.to_s.underscore
35
+ end
36
+
37
+ def create_config_file
38
+ template 'couchbase.yml', File.join('config', "couchbase.yml")
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ common: &common
2
+ hostname: localhost
3
+ port: 8091
4
+ username:
5
+ password:
6
+ pool: default
7
+
8
+ development:
9
+ <<: *common
10
+ bucket: <%= database_name || app_name %>_development
11
+
12
+ test:
13
+ <<: *common
14
+ bucket: <%= database_name || app_name %>_test
15
+
16
+ # set these environment variables on your production server
17
+ production:
18
+ hostname: <%%= ENV['COUCHBASE_HOST'] %>
19
+ port: <%%= ENV['COUCHBASE_PORT'] %>
20
+ username: <%%= ENV['COUCHBASE_USERNAME'] %>
21
+ password: <%%= ENV['COUCHBASE_PASSWORD'] %>
22
+ pool: <%%= ENV['COUCHBASE_POOL'] %>
23
+ bucket: <%%= ENV['COUCHBASE_BUCKET'] %>
@@ -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) {
9
+ emit(doc._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) {
17
+ // emit(doc._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) {
24
+ // if (doc.type == "customer") {
25
+ // emit(doc._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) {
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