oracle_to_mysql 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ module OracleToMysql
2
+ module PrivateInstanceMethods
3
+ def otm_set_strategy(strategy,options={})
4
+ raise "Invalid strategy #{strategy}" unless OTM_VALID_STRATEGIES.include?(strategy)
5
+ @otm_strategy = strategy
6
+ # TODO: verify options
7
+ @otm_strategy_options = options
8
+ end
9
+
10
+ # LOGGING FUNCTIONS BEGIN
11
+ def otm_output(msg)
12
+ puts "[#{self.to_s}]#{msg}"
13
+ end
14
+ def otm_started(msg)
15
+ self.otm_output("[started t=#{self.otm_time_elapsed_since_otm_timestamp}]#{msg}")
16
+ end
17
+ def otm_finished(msg)
18
+ self.otm_output("[finished t=#{self.otm_time_elapsed_since_otm_timestamp}]#{msg}")
19
+ end
20
+ # LOGGING FUNCTIONS END
21
+
22
+ def otm_time_elapsed_since_otm_timestamp
23
+ if @otm_timestamp.nil?
24
+ self.otm_timestamp # calling this first, causes the lazily loaded timestamp to load...
25
+ 0
26
+ else
27
+ Time.now - self.otm_timestamp
28
+ end
29
+ end
30
+
31
+ # This reflects on the various strategy, retain, and other options that the client class has specified
32
+ # and generates a linear sequence of command names that will be executed
33
+ # on .otm_execute
34
+ #
35
+ def otm_execute_command_names
36
+ if @otm_execute_command_names.nil?
37
+ case self.otm_strategy
38
+ when :atomic_rename
39
+ @otm_execute_command_names = [
40
+ :write_sqlplus_commands_to_file,
41
+ :fork_and_execute_sqlplus_commands_file,
42
+ :write_and_execute_mysql_commands_to_bash_file
43
+ ]
44
+ when :accumulative
45
+ @otm_execute_command_names = [
46
+ :write_sqlplus_commands_to_file,
47
+ :fork_and_execute_sqlplus_commands_file,
48
+ :write_and_execute_mysql_commands_to_bash_file_in_replace_mode
49
+ ]
50
+ else
51
+ raise "Invalid otm_strategy=#{@otm_strategy}"
52
+ end
53
+
54
+ ## All strategies should cleanup after themselves lastly
55
+ @otm_execute_command_names << :delete_temp_files
56
+ end
57
+ @otm_execute_command_names
58
+ end
59
+
60
+ # This generates a temp file suffixed with the specified x
61
+ # it is used
62
+ def generate_tmp_file_name(x)
63
+ File.join(self.tmp_directory,"#{self.otm_target_table}_#{self.otm_timestamp.to_i}_#{x}")
64
+ end
65
+
66
+ # Must pass an argument, retain_n is "the number tables old relative to the current table"
67
+ # if n is 1, the retained table is simple <TBL>_old
68
+ # if its greater, there a dynamic "show retained tables for this table", sort lexically,
69
+ # and return the -nth retain_n (i think) (negative nth) from the list
70
+ #
71
+ def otm_retained_target_table(retain_n)
72
+ if retain_n == 1
73
+ "#{self.otm_target_table}#{OTM_RETAIN_KEY}"
74
+ else
75
+ raise "TODO: HAVE NOT DEALT WITH n != 1 retain option"
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,18 @@
1
+ module OracleToMysql
2
+ module ProtectedClassMethods
3
+ def otm_default_strategy
4
+ :atomic_rename # can also be :accumulative
5
+ end
6
+
7
+ # These options set what happens to an existing target if it exists
8
+ # a retain value of n=1, means "keep the last table arround"
9
+ #
10
+ def otm_default_retain_options
11
+ return {
12
+ :n => 1,
13
+ :table_name_pattern => Proc.new {|dest_table| Regexp.new(/(#{dest_table})(#{self.class::OTM_RETAIN_KEY})(\d+)/)},
14
+ :new_table_name => Proc.new {|dest_table| "#{dest_table}#{self.class::OTM_RETAIN_KEY}#{Time.now.to_i.to_s}"}
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{oracle_to_mysql}
8
+ s.version = "1.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Joe Goggins", "Chris Dinger"]
12
+ s.date = %q{2010-11-15}
13
+ s.description = %q{Wraps the sqlplus binary and mysql binary does not currently require OCI8 or MySQL gems (might someday tho)}
14
+ s.email = %q{joe.goggins@umn.edu}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".specification",
21
+ "README.rdoc",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/oracle_to_mysql.rb",
25
+ "lib/oracle_to_mysql/api_instance_methods.rb",
26
+ "lib/oracle_to_mysql/command.rb",
27
+ "lib/oracle_to_mysql/command/delete_temp_files.rb",
28
+ "lib/oracle_to_mysql/command/fork_and_execute_sqlplus_command.rb",
29
+ "lib/oracle_to_mysql/command/write_and_execute_mysql_commands_to_bash_file.rb",
30
+ "lib/oracle_to_mysql/command/write_and_execute_mysql_commands_to_bash_file_in_replace_mode.rb",
31
+ "lib/oracle_to_mysql/command/write_sqlplus_commands_to_file.rb",
32
+ "lib/oracle_to_mysql/must_override_instance_methods.rb",
33
+ "lib/oracle_to_mysql/optional_override_instance_methods.rb",
34
+ "lib/oracle_to_mysql/private_instance_methods.rb",
35
+ "lib/oracle_to_mysql/protected_class_methods.rb",
36
+ "oracle_to_mysql.gemspec",
37
+ "test/demo/ps_term_tbl.rb",
38
+ "test/demo/ps_term_tbl_accumulative.rb",
39
+ "test/demo/test_oracle_to_mysql_against_ps_term_tbl.rb",
40
+ "test/helper.rb",
41
+ "test/oracle_to_mysql.example.yml",
42
+ "test/test_against_ps_term_tbl_accumulative.rb",
43
+ "test/test_oracle_to_mysql.rb"
44
+ ]
45
+ s.homepage = %q{http://github.com/joegoggins/oracle_to_mysql}
46
+ s.require_paths = ["lib"]
47
+ s.rubygems_version = %q{1.3.7}
48
+ s.summary = %q{A gem for mirroring data from an oracle db to a mysql db}
49
+ s.test_files = [
50
+ "test/demo/ps_term_tbl.rb",
51
+ "test/demo/ps_term_tbl_accumulative.rb",
52
+ "test/demo/test_oracle_to_mysql_against_ps_term_tbl.rb",
53
+ "test/helper.rb",
54
+ "test/test_against_ps_term_tbl_accumulative.rb",
55
+ "test/test_oracle_to_mysql.rb"
56
+ ]
57
+
58
+ if s.respond_to? :specification_version then
59
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
60
+ s.specification_version = 3
61
+
62
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
63
+ s.add_runtime_dependency(%q<POpen4>, [">= 0"])
64
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
65
+ else
66
+ s.add_dependency(%q<POpen4>, [">= 0"])
67
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<POpen4>, [">= 0"])
71
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
72
+ end
73
+ end
74
+
@@ -0,0 +1,63 @@
1
+ class PsTermTbl
2
+ include OracleToMysql
3
+
4
+ def otm_target_table
5
+ "otm_ps_term_tbl"
6
+ end
7
+
8
+ def otm_source_sql
9
+ "select
10
+ trim(INSTITUTION) || CHR(9) ||
11
+ trim(ACAD_CAREER) || CHR(9) ||
12
+ trim(STRM) || CHR(9) ||
13
+ trim(DESCR) || CHR(9) ||
14
+ trim(DESCRSHORT) || CHR(9) ||
15
+ case when TERM_BEGIN_DT is null then '\\N' else to_char(TERM_BEGIN_DT, 'YYYY-MM-DD') end || CHR(9) ||
16
+ case when TERM_END_DT is null then '\\N' else to_char(TERM_END_DT, 'YYYY-MM-DD') end || CHR(9) ||
17
+ trim(SESSION_CODE) || CHR(9) ||
18
+ WEEKS_OF_INSTRUCT || CHR(9) ||
19
+ trim(TERM_CATEGORY) || CHR(9) ||
20
+ trim(ACAD_YEAR) || CHR(9) ||
21
+ trim(TRANSCIPT_DT_PRT) || CHR(9) ||
22
+ trim(HOLIDAY_SCHEDULE) || CHR(9) ||
23
+ case when SIXTY_PCT_DT is null then '\\N' else to_char(SIXTY_PCT_DT, 'YYYY-MM-DD') end || CHR(9) ||
24
+ trim(USE_DYN_CLASS_DATE) || CHR(9) ||
25
+ trim(INCLUDE_IN_SS) || CHR(9) ||
26
+ case when SSR_TRMAC_LAST_DT is null then '\\N' else to_char(SSR_TRMAC_LAST_DT, 'YYYY-MM-DD') end || CHR(9) ||
27
+ case when SSR_PLNDISPONLY_DT is null then '\\N' else to_char(SSR_PLNDISPONLY_DT, 'YYYY-MM-DD') end || CHR(9) ||
28
+ case when SSR_SSENRLAVAIL_DT is null then '\\N' else to_char(SSR_SSENRLAVAIL_DT, 'YYYY-MM-DD') end || CHR(9)
29
+ from ps_term_tbl
30
+ where institution='UMNTC'"
31
+ end
32
+ def otm_target_sql
33
+ "
34
+ create table if not exists #{self.otm_target_table} (
35
+ institution varchar(5),
36
+ acad_career varchar(4),
37
+ strm varchar(4),
38
+ descr varchar(30),
39
+ descrshort varchar(10),
40
+ term_begin_dt date,
41
+ term_end_dt date,
42
+ session_code varchar(3),
43
+ weeks_of_instruct integer,
44
+ term_category varchar(1),
45
+ acad_year varchar(4),
46
+ transcipt_dt_prt varchar(2),
47
+ holiday_schedule varchar(6),
48
+ sixty_pct_dt date,
49
+ use_dyn_class_date varchar(1),
50
+ include_in_ss varchar(1),
51
+ ssr_trmac_last_dt date,
52
+ ssr_plndisponly_dt date,
53
+ ssr_ssenrlavail_dt date,
54
+ primary key (institution, acad_career, strm),
55
+ key (institution),
56
+ key (acad_career),
57
+ key (strm),
58
+ key (term_begin_dt),
59
+ key (term_end_dt)
60
+ )
61
+ "
62
+ end
63
+ end
@@ -0,0 +1,11 @@
1
+ # This class extends from demo/ps_term_tbl to
2
+ # demo/test the accumulative mirror option
3
+ # It also tests that child classes effectively can override OracleToMysql options
4
+ # set in the parent
5
+ require 'ps_term_tbl'
6
+ class PsTermTblAccumulative < PsTermTbl
7
+ # OVERRIDDEN from default to test :accumulative option
8
+ def otm_strategy
9
+ :accumulative
10
+ end
11
+ end
@@ -0,0 +1,59 @@
1
+ require 'helper'
2
+
3
+ # test.demo is already in the load path, hence the omission of "demo/" here
4
+ # require 'ps_um_dept_tree'
5
+ # require 'job_queue_run'
6
+ require 'ps_term_tbl'
7
+ class TestOracleToMysql < Test::Unit::TestCase
8
+ context "Test API against ps_term_tbl" do
9
+ setup do
10
+ @ps_term_tbl_inst = PsTermTbl.new
11
+ # @ps_um_dept_tree = PsUmDeptTree.new
12
+ end
13
+ should "Assert the otm_strategy's default is an atomic_rename" do
14
+ assert_equal(@ps_term_tbl_inst.otm_strategy, :atomic_rename)
15
+ end
16
+
17
+ should "Assert an instance override the default" do
18
+ @ps_term_tbl_inst.otm_set_strategy(:accumulative)
19
+ assert_equal(@ps_term_tbl_inst.otm_strategy, :accumulative)
20
+ @ps_term_tbl_inst.otm_set_strategy(:atomic_rename)
21
+ assert_equal(@ps_term_tbl_inst.otm_strategy, :atomic_rename)
22
+ end
23
+
24
+ should "Have default otm_retain_options" do
25
+ retain_options = @ps_term_tbl_inst.otm_retain_options
26
+ assert(retain_options.has_key?(:n))
27
+ assert(retain_options.has_key?(:table_name_pattern))
28
+ assert(retain_options.has_key?(:new_table_name))
29
+ end
30
+
31
+ should "be able to invoke otm_execute" do
32
+ @ps_term_tbl_inst.otm_execute
33
+ end
34
+ #
35
+ # should "Should be able to do a dry-run that outputs what the otm_execute will do" do
36
+ # assert_nothing_raised do
37
+ # x = PsTermTbl.otm_execute_command_names.each do |command_name|
38
+ # puts command_name
39
+ # end
40
+ # end
41
+ # end
42
+ #
43
+ # should "implement the required ClientInterfaceClassMethods" do
44
+ # [PsTermTbl,PsUmDeptTree].each do |klass|
45
+ # [:otm_source_sql, :otm_target_table, :otm_target_sql].each do |meth|
46
+ # puts klass.send(meth)
47
+ # end
48
+ # end
49
+ # end
50
+ #
51
+ # should "have hashes for their target and source" do
52
+ # [PsTermTbl,PsUmDeptTree].each do |klass|
53
+ # [:otm_source_config_hash, :otm_target_config_hash].each do |meth|
54
+ # puts klass.send(meth).inspect
55
+ # end
56
+ # end
57
+ # end
58
+ end
59
+ end
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'oracle_to_mysql'
8
+
9
+ # Add the demo dir and load for test cases
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__),'demo'))
11
+
12
+ class Test::Unit::TestCase
13
+ end
@@ -0,0 +1,13 @@
1
+ oracle_source:
2
+ username: TODO
3
+ password: TODO
4
+ host: TODO
5
+ database: TODO
6
+ port: 1521
7
+
8
+ mysql_target:
9
+ username: TODO
10
+ password: TODO
11
+ host: TODO
12
+ port: 3306
13
+ database: TODO
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+ require 'ps_term_tbl_accumulative'
3
+ class TestAgainstPsTermTblAccumulative < Test::Unit::TestCase
4
+ context "Test API against ps_term_tbl" do
5
+ setup do
6
+ @ps_term_tbl_inst = PsTermTblAccumulative.new
7
+ end
8
+ should "be able to invoke otm_execute" do
9
+ @ps_term_tbl_inst.otm_execute
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestOracleToMysql < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oracle_to_mysql
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 0
10
+ version: 1.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Joe Goggins
14
+ - Chris Dinger
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-11-15 00:00:00 -06:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: POpen4
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: thoughtbot-shoulda
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :development
49
+ version_requirements: *id002
50
+ description: Wraps the sqlplus binary and mysql binary does not currently require OCI8 or MySQL gems (might someday tho)
51
+ email: joe.goggins@umn.edu
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - README.rdoc
58
+ files:
59
+ - .document
60
+ - .specification
61
+ - README.rdoc
62
+ - Rakefile
63
+ - VERSION
64
+ - lib/oracle_to_mysql.rb
65
+ - lib/oracle_to_mysql/api_instance_methods.rb
66
+ - lib/oracle_to_mysql/command.rb
67
+ - lib/oracle_to_mysql/command/delete_temp_files.rb
68
+ - lib/oracle_to_mysql/command/fork_and_execute_sqlplus_command.rb
69
+ - lib/oracle_to_mysql/command/write_and_execute_mysql_commands_to_bash_file.rb
70
+ - lib/oracle_to_mysql/command/write_and_execute_mysql_commands_to_bash_file_in_replace_mode.rb
71
+ - lib/oracle_to_mysql/command/write_sqlplus_commands_to_file.rb
72
+ - lib/oracle_to_mysql/must_override_instance_methods.rb
73
+ - lib/oracle_to_mysql/optional_override_instance_methods.rb
74
+ - lib/oracle_to_mysql/private_instance_methods.rb
75
+ - lib/oracle_to_mysql/protected_class_methods.rb
76
+ - oracle_to_mysql.gemspec
77
+ - test/demo/ps_term_tbl.rb
78
+ - test/demo/ps_term_tbl_accumulative.rb
79
+ - test/demo/test_oracle_to_mysql_against_ps_term_tbl.rb
80
+ - test/helper.rb
81
+ - test/oracle_to_mysql.example.yml
82
+ - test/test_against_ps_term_tbl_accumulative.rb
83
+ - test/test_oracle_to_mysql.rb
84
+ has_rdoc: true
85
+ homepage: http://github.com/joegoggins/oracle_to_mysql
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 3
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.3.7
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: A gem for mirroring data from an oracle db to a mysql db
118
+ test_files:
119
+ - test/demo/ps_term_tbl.rb
120
+ - test/demo/ps_term_tbl_accumulative.rb
121
+ - test/demo/test_oracle_to_mysql_against_ps_term_tbl.rb
122
+ - test/helper.rb
123
+ - test/test_against_ps_term_tbl_accumulative.rb
124
+ - test/test_oracle_to_mysql.rb