diff --git a/CHANGELOG b/CHANGELOG index 3e7a59c4e..3b08be343 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ === master +* Sort caches before marshalling when using schema_caching, index_caching, static_cache_cache, and pg_auto_constraint_validations (jeremyevans) + * Change the defaults_setter plugin do a deep-copy of database default hash/array values and delegates (jeremyevans) (#2069) * Add pg_auto_parameterize_in_array extension, for converting IN/NOT IN to = ANY or != ALL for more types (jeremyevans) diff --git a/lib/sequel/extensions/index_caching.rb b/lib/sequel/extensions/index_caching.rb index 9eb4c764c..0ad9c01ac 100644 --- a/lib/sequel/extensions/index_caching.rb +++ b/lib/sequel/extensions/index_caching.rb @@ -56,7 +56,11 @@ def self.extended(db) # Dump the index cache to the filename given in Marshal format. def dump_index_cache(file) - File.open(file, 'wb'){|f| f.write(Marshal.dump(@indexes))} + indexes = {} + @indexes.sort.each do |k, v| + indexes[k] = v + end + File.open(file, 'wb'){|f| f.write(Marshal.dump(indexes))} nil end diff --git a/lib/sequel/extensions/schema_caching.rb b/lib/sequel/extensions/schema_caching.rb index 53c007e49..a53937095 100644 --- a/lib/sequel/extensions/schema_caching.rb +++ b/lib/sequel/extensions/schema_caching.rb @@ -52,7 +52,7 @@ module SchemaCaching # Dump the cached schema to the filename given in Marshal format. def dump_schema_cache(file) sch = {} - @schemas.each do |k,v| + @schemas.sort.each do |k,v| sch[k] = v.map do |c, h| h = Hash[h] h.delete(:callable_default) diff --git a/lib/sequel/plugins/pg_auto_constraint_validations.rb b/lib/sequel/plugins/pg_auto_constraint_validations.rb index 24166b8e1..3e2b56804 100644 --- a/lib/sequel/plugins/pg_auto_constraint_validations.rb +++ b/lib/sequel/plugins/pg_auto_constraint_validations.rb @@ -133,7 +133,11 @@ module ClassMethods # Dump the in-memory cached metadata to the cache file. def dump_pg_auto_constraint_validations_cache raise Error, "No pg_auto_constraint_validations setup" unless file = @pg_auto_constraint_validations_cache_file - File.open(file, 'wb'){|f| f.write(Marshal.dump(@pg_auto_constraint_validations_cache))} + pg_auto_constraint_validations_cache = {} + @pg_auto_constraint_validations_cache.sort.each do |k, v| + pg_auto_constraint_validations_cache[k] = v + end + File.open(file, 'wb'){|f| f.write(Marshal.dump(pg_auto_constraint_validations_cache))} nil end diff --git a/lib/sequel/plugins/static_cache_cache.rb b/lib/sequel/plugins/static_cache_cache.rb index b33870011..2325ba594 100644 --- a/lib/sequel/plugins/static_cache_cache.rb +++ b/lib/sequel/plugins/static_cache_cache.rb @@ -26,7 +26,11 @@ def self.configure(model, file) module ClassMethods # Dump the in-memory cached rows to the cache file. def dump_static_cache_cache - File.open(@static_cache_cache_file, 'wb'){|f| f.write(Marshal.dump(@static_cache_cache))} + static_cache_cache = {} + @static_cache_cache.sort.each do |k, v| + static_cache_cache[k] = v + end + File.open(@static_cache_cache_file, 'wb'){|f| f.write(Marshal.dump(static_cache_cache))} nil end diff --git a/spec/extensions/index_caching_spec.rb b/spec/extensions/index_caching_spec.rb index 7f20591cb..1d033d701 100644 --- a/spec/extensions/index_caching_spec.rb +++ b/spec/extensions/index_caching_spec.rb @@ -42,6 +42,14 @@ File.size(@filename).must_be :>, 0 end + it "Database#dump_index_cache should dump index information sorted by table" do + @indexes['"foo"'] = {:table_idx_unique=>{:columns=>[:first_col, :second_col], :unique=>true, :deferrable=>nil}} + @db.dump_index_cache(@filename) + @db.instance_variable_get(:@indexes).keys.must_equal ['"table"', '"foo"'] + @db.load_index_cache(@filename) + @db.instance_variable_get(:@indexes).keys.must_equal ['"foo"', '"table"'] + end + it "Database#load_index_cache should load the index cache from the given file dumped by #dump_index_cache" do @db.dump_index_cache(@filename) db = Sequel::Database.new.extension(:index_caching) diff --git a/spec/extensions/pg_auto_constraint_validations_spec.rb b/spec/extensions/pg_auto_constraint_validations_spec.rb index 92c714b67..9088c41c9 100644 --- a/spec/extensions/pg_auto_constraint_validations_spec.rb +++ b/spec/extensions/pg_auto_constraint_validations_spec.rb @@ -216,6 +216,41 @@ def c.name; 'Foo' end end end + it "should sort cache file by table name" do + cache_file = "spec/files/pgacv-spec-#{$$}.cache" + begin + c = Class.new(Sequel::Model) + c.plugin :pg_auto_constraint_validations, :cache_file=>cache_file + + @ds = @db[:items] + @ds.send(:columns=, [:id, :i]) + @db.fetch = @metadata_results.dup + @db.sqls + c1 = c::Model(@ds) + def c1.name; 'Foo' end + @db.sqls.length.must_equal 5 + + @ds = @db[:bars] + @ds.send(:columns=, [:id, :i]) + @db.fetch = @metadata_results.dup + @db.sqls + c2 = c::Model(@ds) + c2.set_dataset @ds + def c2.name; 'Bar' end + @db.sqls.length.must_equal 5 + + c.instance_variable_get(:@pg_auto_constraint_validations_cache).keys.must_equal %w["items" "bars"] + c.dump_pg_auto_constraint_validations_cache + c.instance_variable_get(:@pg_auto_constraint_validations_cache).keys.must_equal %w["items" "bars"] + + c3 = Class.new(Sequel::Model) + c3.plugin :pg_auto_constraint_validations, :cache_file=>cache_file + c3.instance_variable_get(:@pg_auto_constraint_validations_cache).keys.must_equal %w["bars" "items"] + ensure + File.delete(cache_file) if File.file?(cache_file) + end + end + it "should raise error if attempting to dump cached metadata when not using caching" do proc{@c.dump_pg_auto_constraint_validations_cache}.must_raise Sequel::Error end diff --git a/spec/extensions/schema_caching_spec.rb b/spec/extensions/schema_caching_spec.rb index 4a1951cb7..94d7155b9 100644 --- a/spec/extensions/schema_caching_spec.rb +++ b/spec/extensions/schema_caching_spec.rb @@ -18,6 +18,14 @@ File.size(@filename).must_be :>, 0 end + it "Database#dump_schema_cache should dump schema sorted by table name" do + @schemas['"foo"'] = [[:column, {:db_type=>"integer", :default=>"nextval('table_id_seq'::regclass)", :allow_null=>false, :primary_key=>true, :type=>:integer, :ruby_default=>nil}]] + @db.dump_schema_cache(@filename) + @db.instance_variable_get(:@schemas).keys.must_equal ['"table"', '"foo"'] + @db.load_schema_cache(@filename) + @db.instance_variable_get(:@schemas).keys.must_equal ['"foo"', '"table"'] + end + it "Database#dump_schema_cache/load_schema_cache should work with :callable_default values set in schema_post_process" do @schemas['"table"'][0][1][:callable_default] = lambda{1} @schemas['"table"'][0][1][:default] = 'call_1' diff --git a/spec/extensions/static_cache_cache_spec.rb b/spec/extensions/static_cache_cache_spec.rb index 3414b307e..5b547a05b 100644 --- a/spec/extensions/static_cache_cache_spec.rb +++ b/spec/extensions/static_cache_cache_spec.rb @@ -32,4 +32,22 @@ def c.name; 'Foo' end @db.sqls.must_be_empty @c.all.must_equal [@c.load(:id=>1, :name=>'A'), @c.load(:id=>2, :name=>'B')] end + + it "should sort cache file by model name" do + @c.plugin :static_cache_cache, @file + c1 = Class.new(@c) + def c1.name; 'Foo' end + c1.plugin :static_cache + c2 = Class.new(@c) + def c2.name; 'Bar' end + c2.plugin :static_cache + + @c.instance_variable_get(:@static_cache_cache).keys.must_equal %w'Foo Bar' + @c.dump_static_cache_cache + @c.instance_variable_get(:@static_cache_cache).keys.must_equal %w'Foo Bar' + + c = Class.new(Sequel::Model) + c.plugin :static_cache_cache, @file + c.instance_variable_get(:@static_cache_cache).keys.must_equal %w'Bar Foo' + end end