Skip to content

Commit 306fed3

Browse files
authored
Merge pull request #123 from Mapotempo/update_couchbase
update ruby version and couchbase client
2 parents 5d9cf3f + d89834f commit 306fed3

9 files changed

Lines changed: 89 additions & 69 deletions

File tree

.github/workflows/base_benchmark.yml

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,13 @@ jobs:
1010
checks: write
1111
strategy:
1212
matrix:
13-
include:
14-
- ruby: '2.7'
15-
gemfile: '5.2.7'
16-
couchbase: '7.1.0'
17-
- ruby: '2.7'
18-
gemfile: '6.0.0'
19-
couchbase: '7.1.0'
20-
- ruby: '2.7'
21-
gemfile: '6.0.0'
22-
couchbase: '7.6.3'
23-
- ruby: '2.7'
24-
gemfile: '7.0.0'
25-
couchbase: '7.1.0'
26-
- ruby: '2.7'
27-
gemfile: '7.0.0'
28-
couchbase: '7.6.3'
29-
# ruby 3.0 minimimun required rails 6.0.3
30-
# - ruby: '3.0'
31-
# gemfile: '5.2.7'
32-
# couchbase: '7.1.0'
33-
- ruby: '3.0'
13+
ruby: ['3.0', '3.1', '3.2', '3.3']
14+
gemfile: ['6.1.7.7', '7.0.0', '7.1.0']
15+
couchbase: ['7.2.0', '7.6.3', '8.0.0']
16+
exclude:
17+
# Ruby 3.3 doesn't support Rails 6.1
18+
- ruby: '3.3'
3419
gemfile: '6.1.7.7'
35-
couchbase: '7.1.0'
36-
- ruby: '3.0'
37-
gemfile: '7.0.0'
38-
couchbase: '7.1.0'
39-
- ruby: '3.0'
40-
gemfile: '7.0.0'
41-
couchbase: '7.6.3'
4220
fail-fast: false
4321
runs-on: ubuntu-22.04
4422
name: Base Benchmark ${{ matrix.ruby }} rails-${{ matrix.gemfile }} couchbase-${{ matrix.couchbase }}

.github/workflows/linters.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ jobs:
2222
uses: ruby/setup-ruby@v1
2323
with:
2424
bundler-cache: true
25-
ruby-version: 2.7
25+
ruby-version: 3.0
2626
- name: Run rubocop
2727
run: bundle exec rubocop

.github/workflows/test.yml

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,13 @@ jobs:
1010
test:
1111
strategy:
1212
matrix:
13-
include:
14-
- ruby: '2.7'
15-
gemfile: '5.2.7'
16-
couchbase: '7.1.0'
17-
- ruby: '2.7'
18-
gemfile: '6.0.0'
19-
couchbase: '7.1.0'
20-
- ruby: '2.7'
21-
gemfile: '6.0.0'
22-
couchbase: '7.6.3'
23-
- ruby: '2.7'
24-
gemfile: '7.0.0'
25-
couchbase: '7.1.0'
26-
- ruby: '2.7'
27-
gemfile: '7.0.0'
28-
couchbase: '7.6.3'
29-
# ruby 3.0 minimimun required rails 6.0.3
30-
# - ruby: '3.0'
31-
# gemfile: '5.2.7'
32-
# couchbase: '7.1.0'
33-
- ruby: '3.0'
13+
ruby: ['3.0', '3.1', '3.2', '3.3']
14+
gemfile: ['6.1.7.7', '7.0.0', '7.1.0']
15+
couchbase: ['7.2.0', '7.6.3', '8.0.0']
16+
exclude:
17+
# Ruby 3.3 doesn't support Rails 6.1
18+
- ruby: '3.3'
3419
gemfile: '6.1.7.7'
35-
couchbase: '7.1.0'
36-
- ruby: '3.0'
37-
gemfile: '7.0.0'
38-
couchbase: '7.1.0'
39-
- ruby: '3.0'
40-
gemfile: '7.0.0'
41-
couchbase: '7.6.3'
4220
fail-fast: false
4321
runs-on: ubuntu-22.04
4422
name: ${{ matrix.ruby }} rails-${{ matrix.gemfile }} couchbase-${{ matrix.couchbase }}

.rubocop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require:
99
- rubocop-rake
1010

1111
AllCops:
12-
TargetRubyVersion: 2.7
12+
TargetRubyVersion: 3.0
1313
CacheRootDirectory: rubocop_cache
1414
Exclude:
1515
- 'tmp/**/*'

ci/run_couchbase.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ sudo service couchbase-server status
1414
/opt/couchbase/bin/couchbase-cli cluster-init -c 127.0.0.1:8091 --cluster-username=admin --cluster-password=password --cluster-ramsize=320 --cluster-index-ramsize=256 --cluster-fts-ramsize=256 --services=data,index,query,fts
1515
sleep 5
1616
/opt/couchbase/bin/couchbase-cli server-info -c 127.0.0.1:8091 -u admin -p password
17-
/opt/couchbase/bin/couchbase-cli bucket-create -c 127.0.0.1:8091 -u admin -p password --bucket=$BUCKET --bucket-type=couchbase --bucket-ramsize=160 --bucket-replica=0 --enable-flush=1 --wait
18-
sleep 1
17+
/opt/couchbase/bin/couchbase-cli bucket-create -c 127.0.0.1:8091 -u admin -p password --bucket=$BUCKET --bucket-type=couchbase --bucket-ramsize=160 --bucket-replica=0 --enable-flush=1 --storage-backend couchstore --wait
18+
sleep 3
1919
/opt/couchbase/bin/couchbase-cli user-manage -c 127.0.0.1:8091 -u admin -p password --set --rbac-username $USER --rbac-password $PASSWORD --rbac-name "Auto Tester" --roles admin --auth-domain local
20+
sleep 2
2021
curl http://admin:password@localhost:8093/query/service -d "statement=CREATE INDEX \`default_type\` ON \`$BUCKET\`(\`type\`)"
2122
curl http://admin:password@localhost:8093/query/service -d "statement=CREATE INDEX \`default_rating\` ON \`$BUCKET\`(\`rating\`)"
2223
curl http://admin:password@localhost:8093/query/service -d "statement=CREATE INDEX \`default_name\` ON \`$BUCKET\`(\`name\`)"

couchbase-orm.gemspec

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ Gem::Specification.new do |gem|
1212
gem.summary = 'Couchbase ORM for Rails'
1313
gem.description = 'A Couchbase ORM for Rails'
1414

15-
gem.required_ruby_version = '>= 2.7.0'
15+
gem.required_ruby_version = '>= 3.0'
1616
gem.require_paths = ['lib']
1717

18-
gem.add_runtime_dependency 'activemodel', ENV['ACTIVE_MODEL_VERSION'] || '>= 5.2', '< 7.1'
19-
gem.add_runtime_dependency 'activerecord', ENV['ACTIVE_MODEL_VERSION'] || '>= 5.2', '< 7.1'
18+
gem.add_runtime_dependency 'activemodel', ENV['ACTIVE_MODEL_VERSION'] || '>= 6.1.7.7', '<= 7.1'
19+
gem.add_runtime_dependency 'activerecord', ENV['ACTIVE_MODEL_VERSION'] || '>= 6.1.7.7', '<= 7.1'
2020

21-
gem.add_runtime_dependency 'couchbase', '~> 3.3.0'
21+
gem.add_runtime_dependency 'couchbase', '~> 3.4.5'
2222
gem.add_runtime_dependency 'radix', '~> 2.2' # converting numbers to and from any base
2323

24-
gem.add_development_dependency 'actionpack', ENV['ACTIVE_MODEL_VERSION'] || '>= 5.2', '< 7.1'
24+
gem.add_development_dependency 'actionpack', ENV['ACTIVE_MODEL_VERSION'] || '>= 6.1.7.7', '<= 7.1'
2525
gem.add_development_dependency 'base64'
2626
gem.add_development_dependency 'mapotempo_rubocop', '<1.0'
2727
gem.add_development_dependency 'pry'

docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: '3.7'
22

33
x-app-args: &app-args
44
BUNDLE_VERSION: ${BUNDLE_VERSION:-2.4.22}
5-
RUBY_VERSION: ${RUBY_VERSION:-2.7-slim-bullseye}
5+
RUBY_VERSION: ${RUBY_VERSION:-3.0-slim-bullseye}
66
BUNDLE_WITHOUT: production
77

88
services:
@@ -12,7 +12,7 @@ services:
1212
<<: *app-args
1313
context: .
1414
dockerfile: Dockerfile
15-
image: dev.example.com/mapotempo/couchbase-orm:ruby-${RUBY_VERSION:-2.7-slim-bullseye}_bundle-${BUNDLE_VERSION:-2.4.22}
15+
image: dev.example.com/mapotempo/couchbase-orm:ruby-${RUBY_VERSION:-3.0-slim-bullseye}_bundle-${BUNDLE_VERSION:-2.4.22}
1616
volumes:
1717
- ./:/srv/app/
1818
- app_cache_vendor:/srv/app/vendor
@@ -21,7 +21,7 @@ services:
2121
- COUCHBASE_USER=tester
2222
- COUCHBASE_PASSWORD=password123
2323
- COUCHBASE_BUCKET=default
24-
- ACTIVE_MODEL_VERSION=5.2.7
24+
- ACTIVE_MODEL_VERSION=6.1.7.7
2525
- LOG_LEVEL=debug
2626
tty: true
2727
depends_on:

lib/couchbase-orm/base.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ def table_exists?
6464
true
6565
end
6666

67+
# Stub connection for ActiveRecord::Timestamp compatibility
68+
def connection
69+
@connection ||= Struct.new(:default_timezone).new(:utc)
70+
end
71+
72+
# ActiveRecord 7.1 compatibility
73+
def composite_primary_key?
74+
false
75+
end
76+
6777
def _reflect_on_association(_attribute)
6878
false
6979
end
@@ -85,12 +95,30 @@ def attribute_names
8595
attribute_types.keys
8696
end
8797
end
98+
99+
# Rails 7.1+ renamed generate_alias_attributes to generate_alias_attribute_methods
100+
# ActiveRecord still calls the old method name, so we need to provide compatibility
101+
# The old method had no parameters, so we just provide an empty implementation
102+
if ActiveModel::VERSION::MAJOR >= 7 && ActiveModel::VERSION::MINOR >= 1
103+
def generate_alias_attributes(*args)
104+
# In Rails 7.1+, this method was renamed and signature changed
105+
# ActiveRecord 7.1 still calls it with no args, so we handle that case
106+
return if args.empty?
107+
108+
generate_alias_attribute_methods(*args)
109+
end
110+
end
88111
end
89112

90113
def _has_attribute?(attr_name)
91114
attribute_names.include?(attr_name.to_s)
92115
end
93116

117+
# ActiveRecord 7.1 compatibility
118+
def primary_key_values_present?
119+
!id.nil?
120+
end
121+
94122
def attribute_for_inspect(attr_name)
95123
value = send(attr_name)
96124
value.inspect
@@ -136,6 +164,17 @@ def read_attribute(attr_name, &block)
136164
end
137165

138166
class Document
167+
class << self
168+
def descendants
169+
@__descendants ||= [] # rubocop:disable Naming/MemoizedInstanceVariableName
170+
end
171+
172+
def inherited(subclass)
173+
super
174+
descendants << subclass
175+
end
176+
end
177+
139178
include ::ActiveModel::Model
140179
include ::ActiveModel::Dirty
141180
include ::ActiveModel::Attributes
@@ -154,6 +193,9 @@ class Document
154193
define_model_callbacks :initialize, :find, only: :after
155194
define_model_callbacks :create, :destroy, :save, :update
156195

196+
# Prevent duplicate validation errors (similar to ActiveRecord::AutosaveAssociation)
197+
after_validation :_ensure_no_duplicate_errors
198+
157199
Metadata = Struct.new(:cas)
158200

159201
class MismatchTypeError < RuntimeError; end
@@ -218,6 +260,10 @@ def write_attribute(attr_name, value)
218260

219261
@attributes.write_from_user(name, value)
220262
end
263+
264+
def _ensure_no_duplicate_errors
265+
errors.uniq!
266+
end
221267
end
222268

223269
class NestedDocument < Document

lib/couchbase-orm/views.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,24 @@ def ensure_design_document!
222222
document = Couchbase::Management::DesignDocument.new
223223
document.views = views_actual
224224
document.name = @design_document
225-
bucket.view_indexes.upsert_design_document(document, :production)
225+
226+
# Retry logic for view document creation (handles race conditions and storage backend issues)
227+
max_retries = 3
228+
retry_count = 0
229+
begin
230+
bucket.view_indexes.upsert_design_document(document, :production)
231+
rescue Couchbase::Error::DesignDocumentNotFound, Couchbase::Error::InternalServerFailure => e
232+
retry_count += 1
233+
if retry_count <= max_retries
234+
sleep_time = retry_count * 0.5 # exponential backoff: 0.5s, 1s, 1.5s
235+
CouchbaseOrm.logger.warn("View document upsert failed (attempt #{retry_count}/#{max_retries}), retrying in #{sleep_time}s: #{e.message}")
236+
sleep(sleep_time)
237+
retry
238+
else
239+
CouchbaseOrm.logger.error("View document upsert failed after #{max_retries} retries: #{e.message}")
240+
raise
241+
end
242+
end
226243

227244
true
228245
else

0 commit comments

Comments
 (0)