From 5a78600914fd8ccf65a36e52e7e3d38ee354bcae Mon Sep 17 00:00:00 2001 From: Toon Willems Date: Wed, 18 Apr 2018 09:17:33 +0000 Subject: [PATCH 1/3] store search_path for postgres DBs --- lib/delayed/serialization/sequel.rb | 72 +++++++++++++++-------- spec/delayed/serialization/sequel_spec.rb | 1 + spec/spec_helper.rb | 1 + 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/lib/delayed/serialization/sequel.rb b/lib/delayed/serialization/sequel.rb index 4756162..c31e723 100644 --- a/lib/delayed/serialization/sequel.rb +++ b/lib/delayed/serialization/sequel.rb @@ -2,40 +2,62 @@ module Delayed module Serialization module Sequel - def self.configure(klass) - klass.class_eval do - if YAML.parser.class.name =~ /syck/i - yaml_as "tag:ruby.yaml.org,2002:Sequel" - end + + module ClassMethods + def search_path + search_path_str = self.db["SHOW search_path"].get + search_path_str.split(/[\s,]+/).map{|s| s.gsub(/\A"|"\z/, '')}.map(&:to_sym) end - end - if YAML.parser.class.name =~ /syck/i - module ClassMethods - def yaml_new(klass, tag, val) - pk = val["values"][klass.primary_key] - klass[pk] || - raise(Delayed::DeserializationError, "Sequel Record not found, class: #{klass} , primary key: #{pk}") + def use_search_path(search_path, &block) + self.db.synchronize do + previous_search_path = search_path + begin + set_search_path(search_path) + yield + ensure + set_search_path(previous_search_path) + end end end - end + private + + def set_search_path(search_path) + placeholders = search_path.map{'?'}.join(', ') + placeholders = "''" if placeholders.empty? + self.db["SET search_path TO #{placeholders}", *search_path].get + end + + end module InstanceMethods - if YAML.parser.class.name =~ /syck/i - def to_yaml_properties - ["@values"] - end - else - def encode_with(coder) - coder["values"] = @values - end - def init_with(coder) - @values = coder["values"] + def search_path + self.class.search_path + end + + def use_search_path(search_path, &block) + self.class.use_search_path(search_path, &block) + end + + def postgres? + self.class.db.database_type == :postgres + end + + def encode_with(coder) + coder["values"] = @values + coder["search_path"] = search_path if postgres? + end + + def init_with(coder) + @values = coder["values"] + if postgres? && coder["search_path"] + use_search_path(coder["search_path"]) { reload } + else reload - rescue ::Sequel::Error - raise Delayed::DeserializationError, "Sequel Record not found, class: #{self.class.name} , primary key: #{pk}" end + rescue ::Sequel::Error + raise Delayed::DeserializationError, "Sequel Record not found, class: #{self.class.name} , primary key: #{pk}" end end end diff --git a/spec/delayed/serialization/sequel_spec.rb b/spec/delayed/serialization/sequel_spec.rb index b6b66bc..828365a 100644 --- a/spec/delayed/serialization/sequel_spec.rb +++ b/spec/delayed/serialization/sequel_spec.rb @@ -6,4 +6,5 @@ YAML.load(Story.create.to_yaml) end.not_to raise_error end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1381e43..e7c5104 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -43,6 +43,7 @@ def jruby? end DB.drop_table :delayed_jobs rescue Sequel::DatabaseError +DB.drop_table :another_delayed_jobs rescue Sequel::DatabaseError DB.drop_table :stories rescue Sequel::DatabaseError DB.create_table :delayed_jobs do From b0c282fcc8904ec5ddde565e4896ca9969bb4448 Mon Sep 17 00:00:00 2001 From: Toon Willems Date: Wed, 18 Apr 2018 09:55:17 +0000 Subject: [PATCH 2/3] add spec --- .gitignore | 1 + spec/delayed/serialization/sequel_spec.rb | 29 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/.gitignore b/.gitignore index 06329bf..658b9fe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ Gemfile.lock .DS_Store pkg/* .rvmrc +.*.swp diff --git a/spec/delayed/serialization/sequel_spec.rb b/spec/delayed/serialization/sequel_spec.rb index 828365a..9f9ceb3 100644 --- a/spec/delayed/serialization/sequel_spec.rb +++ b/spec/delayed/serialization/sequel_spec.rb @@ -7,4 +7,33 @@ end.not_to raise_error end + + it "should use the correct search_path for postgres" do + if DB.database_type == :postgres + Story.all.map &:delete + + DB.run "drop schema if exists other_schema CASCADE" + DB.run "create schema other_schema" + + # create a Story inside the other schema + yaml = Story.use_search_path([:other_schema]) do + DB.create_table :stories do + primary_key :story_id + String :text + TrueClass :scoped, :default => true + end + Story.create.to_yaml + end + + # this should be empty as the search has now been reset + expect(Story.all).to be_empty + Story.use_search_path([:other_schema]) do + expect(Story.all).not_to be_empty + end + + expect{YAML.load(yaml)}.not_to raise_error + end + end + + end From 496932bd4c90449978297847d630d710ab9fc50f Mon Sep 17 00:00:00 2001 From: Toon Willems Date: Wed, 18 Apr 2018 10:56:27 +0000 Subject: [PATCH 3/3] drop table for travis --- spec/delayed/serialization/sequel_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/delayed/serialization/sequel_spec.rb b/spec/delayed/serialization/sequel_spec.rb index 9f9ceb3..cc6d0a2 100644 --- a/spec/delayed/serialization/sequel_spec.rb +++ b/spec/delayed/serialization/sequel_spec.rb @@ -17,6 +17,7 @@ # create a Story inside the other schema yaml = Story.use_search_path([:other_schema]) do + DB.drop_table? :stories DB.create_table :stories do primary_key :story_id String :text