Permalink
Browse files

Separate storage of table options and list of tables to be processed;…

… possibility to exclude tables from processing.
  • Loading branch information...
1 parent 376d5ac commit 9387d6a7a9aa7e7c26016298f5bdf3b861ab3fe6 @alehmann alehmann committed Oct 19, 2008
View
@@ -9,6 +9,6 @@
:syncer => :two_way,
:conflict_handling => :update_right
}
- config.add_tables 'scanner_left_records_only'
- config.add_tables 'table_with_manual_key', :primary_key_names => ['id']
+ config.include_tables 'scanner_left_records_only'
+ config.include_tables 'table_with_manual_key', :primary_key_names => ['id']
end
@@ -151,10 +151,12 @@ def execute
# Use the command line provided table specs if provided. Otherwise the
# ones from the configuration file
- table_specs = options[:table_specs]
- table_specs = Initializer.configuration.tables if table_specs.empty?
+ included_table_specs = options[:table_specs]
+ included_table_specs = Initializer.configuration.included_table_specs if included_table_specs.empty?
- table_pairs = resolver.resolve table_specs
+ table_pairs = resolver.resolve \
+ included_table_specs,
+ Initializer.configuration.excluded_table_specs
table_pairs = prepare_table_pairs(table_pairs)
table_pairs.each do |table_pair|
report_printer.scan table_pair[:left], table_pair[:right] do
@@ -67,32 +67,54 @@ def options=(options)
@options ||= {}
@options = @options.merge! options
end
+
+ # Array of table specifications for tables that should be processed
+ # Refer to #add_table_options for what constitutes a valid table specification.
+ def included_table_specs
+ @included_table_specs ||= []
+ end
+
+ # Array of table specifications for tables that should *not* be processed
+ # Refer to #add_table_options for what constitutes a valid table specification.
+ def excluded_table_specs
+ @excluded_table_specs ||= []
+ end
- # A list of tables that should be processed (scanned, synced, ...) togehter
- # with the table specific options.
+ # A list of tables having table specific options that should be considered
+ # during processing (scanned, synced, ...)
# +tables_with_options+ is a 2 element array with
# * first element: A +table_spec+ (either a table name or a regexp matching multiple tables)
# * second element: The +options+ hash (detailed format described in #add_tables
- # Should only be accessed via #add_tables and #options_for_table
+ # Should only be accessed via #add_table_options and #options_for_table
def tables_with_options
@tables_with_options ||= []
end
- # Returns an array containing the configured table specifications.
- # (#add_tables describes the format of valid table specifications.)
- def tables
- tables_with_options.map {|table_options| table_options[0]}
+ # Adds the specified tables to the list of tables that should be processed.
+ # If options are provided, store them for future processing.
+ # Refer to #add_table_options for detailed description of parameters.
+ def include_tables(table_spec, options = nil)
+ included_table_specs << table_spec unless included_table_specs.include?(table_spec)
+ add_table_options(table_spec, options) if options
+ end
+
+ # Excludes the specified table from the list of tables that should be
+ # processed.
+ # Refer to #add_table_options for detailed description of what constitutes a
+ # valid table specification.
+ def exclude_tables(table_spec)
+ excluded_table_specs << table_spec unless excluded_table_specs.include?(table_spec)
end
- # Adds the specified +table_spec+ and it's options (if provided).
+ # Adds the specified options for the provided +table_spec+.
# A +table_spec+ can be either
# * a table name or
# * a table pair (e. g. "my_left_table, my_right_table")
# * a regexp matching multiple tables.
# +options+ is hash with possible generic values as described under #options.
- # Additional table specific options:
+ # Additional, exclusively table specific options:
# * :+primary_key_names+: array of primary key names
- def add_tables(table_spec, options = {})
+ def add_table_options(table_spec, options)
i = nil
tables_with_options.each_with_index { |table_options, k|
i = k if table_options[0] == table_spec
View
@@ -42,7 +42,7 @@ def right=(connection)
def manual_primary_keys(db_arm)
manual_primary_keys = {}
resolver = TableSpecResolver.new self
- table_pairs = resolver.resolve configuration.tables
+ table_pairs = resolver.resolve configuration.included_table_specs
table_pairs.each do |table_pair|
key_names = configuration.options_for_table(table_pair[:left])[:primary_key_names]
if key_names
@@ -19,14 +19,27 @@ def initialize(session)
# Table specifications are either
# * strings as produced by BaseRunner#get_options or
# * actual regular expressions
+ # If +excluded_table_specs+ is provided, removes all tables that match it
+ # (even if otherwise matching +included_table_specs+).
# Returns an array of table name pairs in Hash form.
# For example something like
# [{:left => 'my_table', :right => 'my_table_backup'}]
# Takes care that a table is only returned once.
- def resolve(table_specs)
+ def resolve(included_table_specs, excluded_table_specs = [])
+ table_pairs = expand_table_specs(included_table_specs)
+ table_pairs = table_pairs_without_duplicates(table_pairs)
+ table_pairs_without_excluded(table_pairs, excluded_table_specs)
+ end
+
+ # Helper for #resolve
+ # Takes the specified table_specifications and expands it into an array of
+ # according table pairs.
+ # Returns the result
+ # Refer to #resolve for a full description of parameters and result.
+ def expand_table_specs(table_specs)
table_pairs = []
table_specs.each do |table_spec|
-
+
# If it is a regexp, convert it in an according string
table_spec = table_spec.inspect if table_spec.kind_of? Regexp
@@ -44,16 +57,32 @@ def resolve(table_specs)
table_pairs << {:left => table_spec.strip, :right => table_spec.strip}
end
end
- remove_duplicate_table_pairs(table_pairs)
+ table_pairs
+ end
+ private :expand_table_specs
+
+ # Helper for #resolve
+ # Takes given table_pairs and removes all tables that are excluded.
+ # Returns the result.
+ # Both the given and the returned table_pairs is an array of hashes with
+ # * :+left+: name of the left table
+ # * :+right+: name of the corresponding right table
+ # +excluded_table_specs+ is the array of table specifications to be excluded.
+ def table_pairs_without_excluded(table_pairs, excluded_table_specs)
+ excluded_tables = expand_table_specs(excluded_table_specs).map do |table_pair|
+ table_pair[:left]
+ end
+ table_pairs.select {|table_pair| not excluded_tables.include? table_pair[:left]}
end
+ private :table_pairs_without_excluded
# Helper for #resolve
# Takes given table_pairs and removes all duplicates.
# Returns the result.
# Both the given and the returned table_pairs is an array of hashes with
- # * :+left_table+: name of the left table
- # * :+right_table+: name of the corresponding right table
- def remove_duplicate_table_pairs(table_pairs)
+ # * :+left+: name of the left table
+ # * :+right+: name of the corresponding right table
+ def table_pairs_without_duplicates(table_pairs)
processed_left_tables = {}
resulting_table_pairs = []
table_pairs.each do |table_pair|
@@ -64,6 +93,6 @@ def remove_duplicate_table_pairs(table_pairs)
end
resulting_table_pairs
end
- private :remove_duplicate_table_pairs
+ private :table_pairs_without_duplicates
end
end
View
@@ -31,25 +31,39 @@
merge(config.options)
end
- it "tables should return the list of added table specifications" do
+ it "included_table_specs should return the list of included table specifications" do
config = Configuration.new
- config.add_tables('a', {:bla => :blub})
- config.add_tables('a, b')
- config.add_tables(/a/)
- config.tables.should == ['a', 'a, b', /a/]
+ config.include_tables('a', {:bla => :blub})
+ config.include_tables('a, b')
+ config.include_tables(/a/)
+ config.included_table_specs.should == ['a', 'a, b', /a/]
+ end
+
+ it "included_table_specs should save the options if provided" do
+ config = Configuration.new
+ config.include_tables('a', {:bla => :blub})
+ config.options_for_table('a')[:bla].should == :blub
+ end
+
+ it "excluded_table_specs should return the list of excluded table specifications" do
+ config = Configuration.new
+ config.exclude_tables('a')
+ config.exclude_tables('a, b')
+ config.exclude_tables(/a/)
+ config.excluded_table_specs.should == ['a', 'a, b', /a/]
end
it "options_for_table should return the general options if there are no matching table specific options" do
config = Configuration.new
- config.add_tables(/a/, {:bla => :blub})
+ config.include_tables(/a/, {:bla => :blub})
config.options_for_table('b').should == \
Syncers::TwoWaySyncer.default_options.clone.
merge(config.options)
end
it "options_for_table should return table specific options mixed in with default options" do
config = Configuration.new
- config.add_tables(/a/, {:bla => :blub})
+ config.include_tables(/a/, {:bla => :blub})
config.options_for_table('a').should == \
Syncers::TwoWaySyncer.default_options.clone.
merge(config.options).
@@ -58,10 +72,10 @@
it "options_for_table should return last added version of added options for matching table spec" do
config = Configuration.new
- config.add_tables(/a/, {:bla => :blub})
- config.add_tables('a', {:bla => :blok})
- config.add_tables(/x/, {:bla => :bar})
- config.add_tables('y', {:bla => :foo})
+ config.include_tables(/a/, {:bla => :blub})
+ config.include_tables('a', {:bla => :blok})
+ config.include_tables(/x/, {:bla => :bar})
+ config.include_tables('y', {:bla => :foo})
config.options_for_table('a').should == \
Syncers::TwoWaySyncer.default_options.clone.
merge(config.options).
@@ -70,44 +84,43 @@
it "options_for_table should match against table pair specs" do
config = Configuration.new
- config.add_tables('a, b', {:bla => :blub})
+ config.add_table_options('a, b', {:bla => :blub})
config.options_for_table('a')[:bla].should == :blub
end
it "options_for_table should match against regular expression specs" do
config = Configuration.new
- config.add_tables(/a/, {:bla => :blub})
+ config.add_table_options(/a/, {:bla => :blub})
config.options_for_table('a')[:bla].should == :blub
end
it "options_for_table should match against pure table name specs" do
config = Configuration.new
- config.add_tables('a', {:bla => :blub})
+ config.add_table_options('a', {:bla => :blub})
config.options_for_table('a')[:bla].should == :blub
end
- it "add_options_for_table should not create table_spec duplicates" do
+ it "add_table_options should not create table_spec duplicates" do
config = Configuration.new
- config.add_tables(/a/, {:bla => :blub})
- config.add_tables(/a/, {:foo => :bar})
+ config.add_table_options(/a/, {:bla => :blub})
+ config.add_table_options(/a/, {:foo => :bar})
config.options_for_table('a').should == \
Syncers::TwoWaySyncer.default_options.clone.
merge(config.options).
merge(:bla => :blub, :foo => :bar)
end
- it "add_options_for_table should include default syncer options" do
+ it "add_table_options should include default syncer options" do
config = Configuration.new
config.options = {:syncer => :one_way}
# overwrite one syncer option
- config.add_tables(/a/, {:delete => true})
+ config.add_table_options(/a/, {:delete => true})
options = config.options_for_table('a')
Syncers::OneWaySyncer.default_options.each do |key, value|
options[key].should == value unless key == :delete
end
options[:delete].should == true
end
-
end
@@ -41,7 +41,7 @@
old_table_specific_options = config.tables_with_options
begin
config.options = {:proxy_block_size => 2}
- config.add_tables 'scanner_records', {:proxy_block_size => 3}
+ config.include_tables 'scanner_records', {:proxy_block_size => 3}
ProxiedTableScan.new(Session.new(config), 'scanner_records').block_size \
.should == 3
ensure
View
@@ -72,17 +72,17 @@
it "initialize should assign manual primary keys to the proxy connections" do
config = deep_copy(standard_config)
- config.tables_with_options.clear
- config.add_tables "table_with_manual_key, extender_without_key", :primary_key_names => ['id']
+ config.included_table_specs.clear
+ config.include_tables "table_with_manual_key, extender_without_key", :primary_key_names => ['id']
session = Session.new config
session.left.manual_primary_keys.should == {'table_with_manual_key'=>['id']}
session.right.manual_primary_keys.should == {'extender_without_key'=>['id']}
end
it "manual_primary_keys should return the correct primary keys" do
config = deep_copy(standard_config)
- config.tables_with_options.clear
- config.add_tables "table_with_manual_key, extender_without_key", :primary_key_names => ['id']
+ config.included_table_specs.clear
+ config.include_tables "table_with_manual_key, extender_without_key", :primary_key_names => ['id']
session = Session.new config
session.manual_primary_keys(:left).should == {'table_with_manual_key'=>['id']}
session.manual_primary_keys(:right).should == {'extender_without_key'=>['id']}
@@ -57,4 +57,13 @@
{:left => 'scanner_records', :right => 'scanner_records'}
]
end
+
+ it "resolve should not return tables that are excluded" do
+ @resolver.resolve(
+ [/SCANNER_RECORDS|scanner_text_key/],
+ [/scanner_text/]
+ ).should == [
+ {:left => 'scanner_records', :right => 'scanner_records'},
+ ]
+ end
end
View
@@ -24,7 +24,7 @@
old_table_specific_options = config.tables_with_options
begin
config.options = {:syncer => :bla}
- config.add_tables 'scanner_records', {:syncer => :blub}
+ config.include_tables 'scanner_records', {:syncer => :blub}
TableSync.new(Session.new(config), 'scanner_records').sync_options[:syncer] \
.should == :blub
ensure

0 comments on commit 9387d6a

Please sign in to comment.