Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STEP 2 Activemodel7 couchbase ruby client #40

Merged
merged 48 commits into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
20991b9
add query_fn
CedricCouton Jul 18, 2022
8716f50
can have custom_order
CedricCouton Jul 18, 2022
1c8cae6
don't remove nil values but add them in request
DamienVoreiter Jul 19, 2022
19523c7
oupsi move =
DamienVoreiter Jul 19, 2022
9c7cc56
try to add is missing
DamienVoreiter Jul 19, 2022
4bfd2dd
re add select (wanted ?) to fix test
DamienVoreiter Jul 20, 2022
30534a7
try to remove values empty but keep nil values
DamienVoreiter Jul 20, 2022
8d885da
have a read_fn
CedricCouton Jul 22, 2022
808d91e
Merge branch 'activemodel7-couchbase-ruby-client' of github.com:docto…
CedricCouton Jul 22, 2022
87c8331
add example with include_docs false
CedricCouton Jul 25, 2022
9806edf
add column_names & attribute_names to orm
DamienVoreiter Jul 25, 2022
04cfdea
add options in params of query_fn
CedricCouton Jul 25, 2022
373c022
Merge branch 'activemodel7-couchbase-ruby-client' of github.com:docto…
CedricCouton Jul 25, 2022
6914cb9
clean
CedricCouton Jul 28, 2022
99a2ca8
fix n1ql
CedricCouton Jul 28, 2022
203f469
fix n1ql
CedricCouton Jul 28, 2022
3bbd3e6
fix n1ql
CedricCouton Jul 28, 2022
6337bd1
clean
CedricCouton Jul 28, 2022
95227c1
fix test
CedricCouton Jul 28, 2022
08a139a
fix test
CedricCouton Jul 28, 2022
db72a7d
fix test
CedricCouton Jul 28, 2022
b2e1113
try fix ci
CedricCouton Jul 28, 2022
fb59dae
try fix ci
CedricCouton Jul 28, 2022
a0d184c
Merge branch 'Mapotempo:master' into activemodel7-couchbase-ruby-client
DamienVoreiter Sep 8, 2022
d480a6b
update .gitignore to ignore .rbenv-vars
simkim Sep 9, 2022
f5a05ed
Merge remote-tracking branch 'origin/master' into activemodel7-couchb…
DamienVoreiter Sep 12, 2022
3aa996b
Update lib/couchbase-orm/connection.rb
DamienVoreiter Sep 13, 2022
093ac90
Encryption for CBLite3
xdm67x Aug 29, 2022
84d5785
Rename fn
adrien-jeser-doctolib Sep 12, 2022
7595d2c
try fix ci starts_with -> start_with
DamienVoreiter Sep 14, 2022
8a3ad53
Merge pull request #6 from doctolib/new_tanker_encryption_cblite3
DamienVoreiter Sep 14, 2022
4166029
Merge remote-tracking branch 'mapotempo/master' into activemodel7-cou…
DamienVoreiter Sep 15, 2022
ab479ab
remove select
DamienVoreiter Sep 15, 2022
bdcd207
revert useless
DamienVoreiter Sep 15, 2022
66e3289
Merge remote-tracking branch 'mapotempo/master'
DamienVoreiter Sep 15, 2022
3f9c24e
Update .gitignore
DamienVoreiter Sep 16, 2022
b5bc324
Merge branch 'master' into activemodel7-couchbase-ruby-client
DamienVoreiter Sep 16, 2022
67f81fb
revert a modify test
DamienVoreiter Sep 16, 2022
77a1280
Merge branch 'activemodel7-couchbase-ruby-client' of github.com:docto…
DamienVoreiter Sep 16, 2022
cbabc75
2 to 4 spaces
DamienVoreiter Sep 16, 2022
d876005
split tests
DamienVoreiter Sep 16, 2022
3905c57
remove useless code
DamienVoreiter Sep 16, 2022
39567d8
fix master
DamienVoreiter Sep 19, 2022
2907b63
Merge branch 'Mapotempo:master' into master
DamienVoreiter Sep 19, 2022
bbaafdb
Merge remote-tracking branch 'origin/master' into activemodel7-couchb…
DamienVoreiter Sep 19, 2022
3e41628
oups revert encrypt part
DamienVoreiter Sep 19, 2022
149dc68
fix some tests
DamienVoreiter Sep 19, 2022
43862c6
fix all tests
DamienVoreiter Sep 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ci/run_couchbase.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ sleep 5
sleep 1
/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
curl http://admin:password@localhost:8093/query/service -d "statement=CREATE INDEX \`default_type\` ON \`$BUCKET\`(\`type\`)"
curl http://admin:password@localhost:8093/query/service -d "statement=CREATE INDEX \`default_rating\` ON \`$BUCKET\`(\`rating\`)"
curl http://admin:password@localhost:8093/query/service -d "statement=CREATE INDEX \`default_name\` ON \`$BUCKET\`(\`name\`)"
13 changes: 7 additions & 6 deletions lib/couchbase-orm/n1ql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module ClassMethods
# # ...
# end
# TODO: add range keys [:startkey, :endkey]
def n1ql(name, query_fn: nil, emit_key: [], **options)
def n1ql(name, query_fn: nil, emit_key: [], custom_order: nil, **options)
emit_key = Array.wrap(emit_key)
emit_key.each do |key|
raise "unknown emit_key attribute for n1ql :#{name}, emit_key: :#{key}" if key && !attribute_names.include?(key.to_s)
Expand All @@ -50,7 +50,8 @@ def n1ql(name, query_fn: nil, emit_key: [], **options)
singleton_class.__send__(:define_method, name) do |**opts, &result_modifier|
opts = options.merge(opts).reverse_merge(scan_consistency: :request_plus)
values = convert_values(method_opts[:emit_key], opts.delete(:key)) if opts[:key]
current_query = run_query(method_opts[:emit_key], values, query_fn, **opts.except(:include_docs, :key))
current_query = run_query(method_opts[:emit_key], values, query_fn, custom_order: custom_order, **opts.except(:include_docs, :key))

if result_modifier
opts[:include_docs] = true
current_query.results &result_modifier
Expand Down Expand Up @@ -81,7 +82,7 @@ def index_n1ql(attr, validate: true, find_method: nil, n1ql_method: nil)

def convert_values(keys, values)
raise ArgumentError, "Empty keys but values are present, can't type cast" if keys.empty? && Array.wrap(values).any?
keys.zip(Array.wrap(values)).map do |key, value_before_type_cast|
keys.zip(Array.wrap(values)).map do |key, value_before_type_cast|
# cast value to type
value = if value_before_type_cast.is_a?(Array)
value_before_type_cast.map do |v|
Expand Down Expand Up @@ -121,13 +122,13 @@ def build_limit(limit)
limit ? "limit #{limit}" : ""
end

def run_query(keys, values, query_fn, descending: false, limit: nil, **options)
def run_query(keys, values, query_fn, custom_order: nil, descending: false, limit: nil, **options)
if query_fn
N1qlProxy.new(query_fn.call(bucket, values, Couchbase::Options::Query.new(**options)))
N1qlProxy.new(query_fn.call(bucket, values, cluster, Couchbase::Options::Query.new(**options)))
else
bucket_name = bucket.name
where = build_where(keys, values)
order = build_order(keys, descending)
order = custom_order || build_order(keys, descending)
limit = build_limit(limit)
n1ql_query = "select raw meta().id from `#{bucket_name}` where #{where} order by #{order} #{limit}"
result = cluster.query(n1ql_query, Couchbase::Options::Query.new(**options))
Expand Down
1 change: 0 additions & 1 deletion lib/couchbase-orm/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
module Rails #:nodoc:
module Couchbase #:nodoc:
class Railtie < Rails::Railtie #:nodoc:

config.couchbase_orm = ActiveSupport::OrderedOptions.new
config.couchbase_orm.ensure_design_documents = true

Expand Down
255 changes: 128 additions & 127 deletions spec/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,169 +2,170 @@

require File.expand_path("../support", __FILE__)


class BaseTest < CouchbaseOrm::Base
attribute :name, :string
attribute :job, :string
attribute :name, :string
attribute :job, :string
attribute(:prescribing_date, type: String, read_fn: proc { |value| encode_date(value) }) # timestamp without time zone,

class << self
def encode_date(value)
return DateTime.strptime(value, '%Y-%m-%d') if value.present? && value.is_a?(String) && value.length == 10
return DateTime.strptime(value, '%Y-%m-%d %H:%M:%s %z') if value.present? && value.is_a?(String)
value
end
end
end

class CompareTest < CouchbaseOrm::Base
attribute :age, :integer
attribute :age, :integer
end

class TimestampTest < CouchbaseOrm::Base
attribute :created_at, :datetime
end

class TypeNamedTest < CouchbaseOrm::Base
attribute :count
end


describe CouchbaseOrm::Base do
it "should be comparable to other objects" do
base = BaseTest.create!(name: 'joe')
base2 = BaseTest.create!(name: 'joe')
base3 = BaseTest.create!(ActiveSupport::HashWithIndifferentAccess.new(name: 'joe'))

expect(base).to eq(base)
expect(base).to be(base)
expect(base).not_to eq(base2)

same_base = BaseTest.find(base.id)
expect(base).to eq(same_base)
expect(base).not_to be(same_base)
expect(base2).not_to eq(same_base)

base.delete
base2.delete
base3.delete
end
it "should be comparable to other objects" do
DamienVoreiter marked this conversation as resolved.
Show resolved Hide resolved
base = BaseTest.create!(name: 'joe', prescribing_date: Time.now)
base.reload
base.update({ prescribing_date: '2022-07-01' })

it "should be inspectable" do
base = BaseTest.create!(name: 'joe')
expect(base.inspect).to eq("#<BaseTest id: \"#{base.id}\", name: \"joe\", job: nil>")
end
end

it "should load database responses" do
base = BaseTest.create!(name: 'joe')
resp = BaseTest.bucket.default_collection.get(base.id)
it "should be inspectable" do
base = BaseTest.create!(name: 'joe')
expect(base.inspect).to eq("#<BaseTest id: \"#{base.id}\", name: \"joe\", job: nil>")
end

base_loaded = BaseTest.new(resp, id: base.id)
it "should load database responses" do
base = BaseTest.create!(name: 'joe')
resp = BaseTest.bucket.default_collection.get(base.id)

expect(base_loaded.id).to eq(base.id)
expect(base_loaded).to eq(base)
expect(base_loaded).not_to be(base)
base_loaded = BaseTest.new(resp, id: base.id)

base.destroy
end
expect(base_loaded.id).to eq(base.id)
expect(base_loaded).to eq(base)
expect(base_loaded).not_to be(base)

it "should not load objects if there is a type mismatch" do
base = BaseTest.create!(name: 'joe')
base.destroy
end

expect { CompareTest.find_by_id(base.id) }.to raise_error(CouchbaseOrm::Error::TypeMismatchError)
it "should not load objects if there is a type mismatch" do
base = BaseTest.create!(name: 'joe')

base.destroy
end
expect { CompareTest.find_by_id(base.id) }.to raise_error(CouchbaseOrm::Error::TypeMismatchError)

it "should support serialisation" do
base = BaseTest.create!(name: 'joe')
base.destroy
end

base_id = base.id
expect(base.to_json).to eq({id: base_id, name: 'joe', job: nil}.to_json)
expect(base.to_json(only: :name)).to eq({name: 'joe'}.to_json)
it "should support serialisation" do
base = BaseTest.create!(name: 'joe')

base.destroy
end
base_id = base.id
expect(base.to_json).to eq({ id: base_id, name: 'joe', job: nil, prescribing_date:nil }.to_json)
expect(base.to_json(only: :name)).to eq({ name: 'joe' }.to_json)

it "should support dirty attributes" do
DamienVoreiter marked this conversation as resolved.
Show resolved Hide resolved
begin
base = BaseTest.new
expect(base.changes.empty?).to be(true)
expect(base.previous_changes.empty?).to be(true)

base.name = 'change'
expect(base.changes.empty?).to be(false)

# Attributes are set by key
base = BaseTest.new
base[:name] = 'bob'
expect(base.changes.empty?).to be(false)

# Attributes are set by initializer from hash
base = BaseTest.new({name: 'bob'})
expect(base.changes.empty?).to be(false)
expect(base.previous_changes.empty?).to be(true)

# A saved model should have no changes
base = BaseTest.create!(name: 'joe')
expect(base.changes.empty?).to be(true)

# Attributes are copied from the existing model
base = BaseTest.new(base)
expect(base.changes.empty?).to be(false)
expect(base.previous_changes.empty?).to be(true)

ensure
base.destroy if base.id
end
end
base.destroy
end

it "should try to load a model with nothing but an ID" do
begin
base = BaseTest.create!(name: 'joe')
obj = CouchbaseOrm.try_load(base.id)
expect(obj).to eq(base)
ensure
base.destroy
end
end
it "should support dirty attributes" do
begin
base = BaseTest.new
expect(base.changes.empty?).to be(true)
expect(base.previous_changes.empty?).to be(true)

it "should try to load a model with nothing but single-multiple ID" do
begin
bases = [BaseTest.create!(name: 'joe')]
objs = CouchbaseOrm.try_load(bases.map(&:id))
expect(objs).to match_array(bases)
ensure
bases.each(&:destroy)
end
end
base.name = 'change'
expect(base.changes.empty?).to be(false)

it "should try to load a model with nothing but multiple ID" do
begin
bases = [BaseTest.create!(name: 'joe'), CompareTest.create!(age: 12)]
objs = CouchbaseOrm.try_load(bases.map(&:id))
expect(objs).to match_array(bases)
ensure
bases.each(&:destroy)
end
end
# Attributes are set by key
base = BaseTest.new
base[:name] = 'bob'
expect(base.changes.empty?).to be(false)

it "should set the attribute on creation" do
base = BaseTest.create!(name: 'joe')
expect(base.name).to eq('joe')
# Attributes are set by initializer from hash
base = BaseTest.new({ name: 'bob' })
expect(base.changes.empty?).to be(false)
expect(base.previous_changes.empty?).to be(true)

# A saved model should have no changes
base = BaseTest.create!(name: 'joe')
expect(base.changes.empty?).to be(true)
expect(base.previous_changes.empty?).to be(false)

# Attributes are copied from the existing model
base = BaseTest.new(base)
expect(base.changes.empty?).to be(false)
expect(base.previous_changes.empty?).to be(true)
ensure
base.destroy
base.destroy if base.id
end
end

it "should support getting the attribute by key" do
base = BaseTest.create!(name: 'joe')
expect(base[:name]).to eq('joe')
it "should try to load a model with nothing but an ID" do
begin
base = BaseTest.create!(name: 'joe')
obj = CouchbaseOrm.try_load(base.id)
expect(obj).to eq(base)
ensure
base.destroy
base.destroy
end
end

if ActiveModel::VERSION::MAJOR >= 6
it "should have timestamp attributes for create in model" do
expect(TimestampTest.timestamp_attributes_for_create_in_model).to eq(["created_at"])
end
it "should try to load a model with nothing but single-multiple ID" do
begin
bases = [BaseTest.create!(name: 'joe')]
objs = CouchbaseOrm.try_load(bases.map(&:id))
expect(objs).to match_array(bases)
ensure
bases.each(&:destroy)
end
end

it "should generate a timestamp on creation" do
base = TimestampTest.create!()
expect(base.created_at).to be_a(Time)
it "should try to load a model with nothing but multiple ID" do
begin
bases = [BaseTest.create!(name: 'joe'), CompareTest.create!(age: 12)]
objs = CouchbaseOrm.try_load(bases.map(&:id))
expect(objs).to match_array(bases)
ensure
bases.each(&:destroy)
end

describe BaseTest do
it_behaves_like "ActiveModel"
end

it "should set the attribute on creation" do
base = BaseTest.create!(name: 'joe')
expect(base.name).to eq('joe')
ensure
base.destroy
end

it "should support getting the attribute by key" do
base = BaseTest.create!(name: 'joe')
expect(base[:name]).to eq('joe')
ensure
base.destroy
end

if ActiveModel::VERSION::MAJOR >= 6
it "should have timestamp attributes for create in model" do
expect(TimestampTest.timestamp_attributes_for_create_in_model).to eq(["created_at"])
end
end

describe CompareTest do
it_behaves_like "ActiveModel"
end
it "should generate a timestamp on creation" do
base = TimestampTest.create!()
expect(base.created_at).to be_a(Time)
end

describe BaseTest do
it_behaves_like "ActiveModel"
end

describe CompareTest do
it_behaves_like "ActiveModel"
end
end
Loading