jmoses-couchbase-model 0.5.3

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
@@ -0,0 +1,23 @@
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
+ class String
19
+ def camelize
20
+ res = self.sub(/^[a-z\d]*/) { $&.capitalize }
21
+ res.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
22
+ end
23
+ end
@@ -0,0 +1,29 @@
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
+ class String
19
+ def constantize
20
+ names = self.split('::')
21
+ names.shift if names.empty? || names.first.empty?
22
+
23
+ constant = Object
24
+ names.each do |name|
25
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
26
+ end
27
+ constant
28
+ end
29
+ end
@@ -0,0 +1,24 @@
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
+ class Object
19
+ def singleton_class
20
+ class << self
21
+ self
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,113 @@
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 'thread'
19
+
20
+ module Couchbase
21
+
22
+ class Model
23
+
24
+ # Generator of CouchDB specfic UUIDs. This is the ruby implementation of
25
+ # couch_uuids.erl from couchdb distribution. It is threadsafe.
26
+ #
27
+ # @since 0.0.1
28
+
29
+ class UUID
30
+ # Get default UUID generator. You can create your own if you like.
31
+ #
32
+ # @since 0.0.1
33
+ #
34
+ # @return [UUID]
35
+ def self.generator
36
+ @generator ||= UUID.new
37
+ end
38
+
39
+ # Initialize generator.
40
+ #
41
+ # @since 0.0.1
42
+ #
43
+ # @param [Fixnum] seed seed for pseudorandom number generator.
44
+ def initialize(seed = nil)
45
+ seed ? srand(seed) : srand
46
+ @prefix, _ = rand_bytes(13).unpack('H26')
47
+ @inc = rand(0xfff) + 1
48
+ @lock = Mutex.new
49
+ end
50
+
51
+ # Generate list of UUIDs.
52
+ #
53
+ # @since 0.0.1
54
+ #
55
+ # @param [Fixnum] count number of UUIDs you need
56
+ #
57
+ # @param [Symbol] algorithm Algorithm to use. Known algorithms:
58
+ # [:random]
59
+ # 128 bits of random awesome. All awesome, all the time.
60
+ # [:sequential]
61
+ # Monotonically increasing ids with random increments. First 26 hex
62
+ # characters are random. Last 6 increment in random amounts until an
63
+ # overflow occurs. On overflow, the random prefix is regenerated and
64
+ # the process starts over.
65
+ # [:utc_random]
66
+ # Time since Jan 1, 1970 UTC with microseconds. First 14 characters
67
+ # are the time in hex. Last 18 are random.
68
+ #
69
+ # @return [String, Array] single string value or array of strings. Where
70
+ # each value represents 128-bit number written in hexadecimal format.
71
+ def next(count = 1, algorithm = :sequential)
72
+ raise ArgumentError, 'count should be a positive number' unless count > 0
73
+ uuids = case algorithm
74
+ when :random
75
+ rand_bytes(16 * count).unpack('H32' * count)
76
+ when :utc_random
77
+ now = Time.now.utc
78
+ prefix = '%014x' % [now.to_i * 1_000_000 + now.usec]
79
+ rand_bytes(9 * count).unpack('H18' * count).map do |tail|
80
+ "#{prefix}#{tail}"
81
+ end
82
+ when :sequential
83
+ (1..count).map{ next_seq }
84
+ else
85
+ raise ArgumentError, "Unknown algorithm #{algo}. Should be one :sequential, :random or :utc_random"
86
+ end
87
+ uuids.size == 1 ? uuids[0] : uuids
88
+ end
89
+
90
+ private
91
+
92
+ def next_seq
93
+ @lock.synchronize do
94
+ if @inc >= 0xfff000
95
+ @prefix, _ = rand_bytes(13).unpack('H26')
96
+ @inc = rand(0xfff) + 1
97
+ end
98
+ @inc += rand(0xfff) + 1
99
+ '%s%06x' % [@prefix, @inc]
100
+ end
101
+ end
102
+
103
+ def rand_bytes(count)
104
+ bytes = ''
105
+ count.times { bytes << rand(256) }
106
+ bytes
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,26 @@
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
+ VERSION = '0.5.3'
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,142 @@
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
+ config.couchbase = ActiveSupport::OrderedOptions.new
27
+ config.couchbase.ensure_design_documents ||= true
28
+
29
+ # Determine which generator to use. app_generators was introduced after
30
+ # 3.0.0.
31
+ #
32
+ # @since 0.1.0
33
+ #
34
+ # @example Get the generators method.
35
+ # railtie.generators
36
+ #
37
+ # @return [Symbol] The method name to use.
38
+ def self.generator
39
+ config.respond_to?(:app_generators) ? :app_generators : :generators
40
+ end
41
+
42
+ # Maping of rescued exceptions to HTTP responses
43
+ #
44
+ # @since 0.1.0
45
+ #
46
+ # @example
47
+ # railtie.rescue_responses
48
+ #
49
+ # @return [Hash] rescued responses
50
+ def self.rescue_responses
51
+ {
52
+ 'Couchbase::Error::NotFound' => :not_found,
53
+ 'Couchbase::Error::NotStored' => :unprocessable_entity,
54
+ 'Couchbase::Error::RecordInvalid' => :unprocessable_entity
55
+ }
56
+ end
57
+
58
+ config.send(generator).orm :couchbase, :migration => false
59
+
60
+ if config.action_dispatch.rescue_responses
61
+ config.action_dispatch.rescue_responses.merge!(rescue_responses)
62
+ end
63
+
64
+ # Initialize Couchbase Mode. This will look for a couchbase.yml in the
65
+ # config directory and configure Couchbase connection appropriately.
66
+ #
67
+ # @example couchbase.yml
68
+ #
69
+ # common: &common
70
+ # hostname: localhost
71
+ # port: 8091
72
+ # username:
73
+ # password:
74
+ # pool: default
75
+ #
76
+ # production:
77
+ # <<: *common
78
+ # bucket: example_production
79
+ #
80
+ # test:
81
+ # <<: *common
82
+ # bucket: example_test
83
+ #
84
+ # development:
85
+ # <<: *common
86
+ # bucket: example_development
87
+ #
88
+ initializer 'couchbase.setup_connection' do
89
+ config_file = Rails.root.join('config', 'couchbase.yml')
90
+ if config_file.file? &&
91
+ config = YAML.load(ERB.new(File.read(config_file)).result)[Rails.env]
92
+ ::Couchbase.connection_options = config.with_indifferent_access
93
+ end
94
+ end
95
+
96
+ # After initialization we will warn the user if we can't find a couchbase.yml and
97
+ # alert to create one.
98
+ initializer 'couchbase.warn_configuration_missing' do
99
+ unless ARGV.include?('couchbase:config')
100
+ config.after_initialize do
101
+ unless Rails.root.join('config', 'couchbase.yml').file?
102
+ puts "\nCouchbase config not found. Create a config file at: config/couchbase.yml"
103
+ puts "to generate one run: rails generate couchbase:config\n\n"
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ # Check (and upgrade if needed) all design documents
110
+ initializer 'couchbase.upgrade_design_documents', :after => 'couchbase.setup_connection' do |app|
111
+ ::Couchbase::Model::Configuration.design_documents_paths ||= app.config.paths['app/models']
112
+ if config.couchbase.ensure_design_documents
113
+ config.to_prepare do
114
+ app.config.paths['app/models'].each do |path|
115
+ Dir.glob("#{path}/**/*.rb").sort.each do |file|
116
+ require_dependency(file.gsub("#{path}/" , '').gsub('.rb', ''))
117
+ end
118
+ end
119
+ begin
120
+ ::Couchbase::Model.descendants.each do |model|
121
+ model.ensure_design_document!
122
+ end
123
+ rescue ::Couchbase::Error::Timeout, ::Couchbase::Error::Connect
124
+ # skip connection errors for now
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ # Set the proper error types for Rails. NotFound errors should be
131
+ # 404s and not 500s, validation errors are 422s.
132
+ initializer 'couchbase.load_http_errors' do |app|
133
+ config.after_initialize do
134
+ unless config.action_dispatch.rescue_responses
135
+ ActionDispatch::ShowExceptions.rescue_responses.update(Railtie.rescue_responses)
136
+ end
137
+ end
138
+ end
139
+
140
+ end
141
+ end
142
+ 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'] %>