history_extension 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 169fa2f7f855056c7a79fab871e46ad69afe8b65ba42207c95a0d87d82791518
4
+ data.tar.gz: '086d78982b855aed16c845a4d05b74a3958bdde63b3e5e1531cc04a1f8d79b64'
5
+ SHA512:
6
+ metadata.gz: dd604fc72a189ab2db6c289da4aff04dd59dcd5e7ab099be8fe713d49e904db6ef6e21cfbc526565f528a5437c9e3ddbc8de8bfee82e96b05a299897285c2126
7
+ data.tar.gz: e7cb39f842a18bc17cd74842c07a475d5e9f98429d27a2de6d22c7bc7923b2960ce901342c89c5881f88670ab40cabb16bc1a8df2daf256a9d9160222f57f159
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ # These are some examples of commonly ignored file patterns.
2
+ # You should customize this list as applicable to your project.
3
+ # Learn more about .gitignore:
4
+ # https://www.atlassian.com/git/tutorials/saving-changes/gitignore
5
+
6
+ # Node artifact files
7
+ node_modules/
8
+ dist/
9
+
10
+ # Compiled Java class files
11
+ *.class
12
+
13
+ # Compiled Python bytecode
14
+ *.py[cod]
15
+
16
+ # Log files
17
+ *.log
18
+
19
+ # Package files
20
+ *.jar
21
+
22
+ # Maven
23
+ target/
24
+ dist/
25
+
26
+ # JetBrains IDE
27
+ .idea/
28
+
29
+ # Unit test reports
30
+ TEST*.xml
31
+
32
+ # Generated by MacOS
33
+ .DS_Store
34
+
35
+ # Generated by Windows
36
+ Thumbs.db
37
+
38
+ # Applications
39
+ *.app
40
+ *.exe
41
+ *.war
42
+
43
+ # Large media files
44
+ *.mp4
45
+ *.tiff
46
+ *.avi
47
+ *.flv
48
+ *.mov
49
+ *.wmv
50
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://gems.sd.laxino.com'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ history_extension (1.4.1)
5
+ bundler (~> 1.12)
6
+ sequel (= 5.23.0)
7
+
8
+ GEM
9
+ remote: http://gems.sd.laxino.com/
10
+ specs:
11
+ diff-lcs (1.3)
12
+ rspec (3.8.0)
13
+ rspec-core (~> 3.8.0)
14
+ rspec-expectations (~> 3.8.0)
15
+ rspec-mocks (~> 3.8.0)
16
+ rspec-core (3.8.2)
17
+ rspec-support (~> 3.8.0)
18
+ rspec-expectations (3.8.4)
19
+ diff-lcs (>= 1.2.0, < 2.0)
20
+ rspec-support (~> 3.8.0)
21
+ rspec-mocks (3.8.1)
22
+ diff-lcs (>= 1.2.0, < 2.0)
23
+ rspec-support (~> 3.8.0)
24
+ rspec-support (3.8.2)
25
+ sequel (5.23.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ history_extension!
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 1.16.6
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # History Database Extension for Sequel
2
+
3
+ ## Objective
4
+
5
+ For all application service, we will create a history database to archive the data record from application operation database. The difference of database schema between operation database and history database is mainly in following two points:
6
+ 1. Remove index with option operation: :only;
7
+ 2. Remove all foreign key constrain;
8
+ 3. Remove column with option operation: :only
9
+
10
+ Before this, we need to maintain two git repositories of the application, one for original application code repository, another mainly for storing the migration script for history database. This approach is facing many challenge when data schema change in term of migration script synchronisation between these two git repository, and this approach need to repeat in all applications.
11
+
12
+ How to eliminate this challenge? So that we can remain only one migration script in original application code repository, that can run on operation database and history database without any changes.
13
+
14
+ ## Solution
15
+
16
+ The solution is simple. We create a sequel extension to ignore constrain during index and foreign key creation, so than we can apply this extension on whatever the migration script is applied.
17
+ After read code of sequel and here is the methods in database class need to be overwrite:
18
+
19
+ ```ruby
20
+ =====Index Method=====
21
+ index(columns, opts = OPTS)
22
+ add_index(columns, opts = OPTS)
23
+ drop_index(columns, options=OPTS)
24
+ =====Foreign Key Method=====
25
+ foreign_key(name, table=nil, opts = OPTS)
26
+ add_foreign_key(name, table, opts = OPTS)
27
+ drop_composite_foreign_key(columns, opts)
28
+ add_composite_foreign_key(columns, table, opts)
29
+ =====Support operation options=====
30
+ add_column(name, type, opts = OPTS)
31
+ rename_column(name, new_name, opts = OPTS)
32
+ drop_column(name, opts=OPTS)
33
+
34
+ ```
35
+
36
+ Detail pls checkout my private repository[histroy_extension](http://stash.mo.laxino.com/users/ben.wu/repos/history_extension/browse)
37
+
38
+ ## Usage
39
+
40
+ ### Foreign Key Removal
41
+
42
+ Current version of history_extension is 1.1.1, which is deployed to the gem server. To use this gem, first need to add this gem in Gemfile:
43
+
44
+ ```ruby
45
+ gem 'history_extension', '1.0.1'
46
+ ```
47
+
48
+ Next, we need to determine environment valuable to control enable this extension, such as HISTORY and update sequel.rake file:
49
+
50
+ ```ruby
51
+ namespace :db do
52
+ require 'sequel'
53
+ ------------Add from Here------------------------------
54
+ if ENV['HISTORY']
55
+ require 'sequel/extensions/history_extension'
56
+ Sequel::Database.register_extension(:history_extension, Sequel::HistoryExtension)
57
+ Sequel::Database.extension :history_extension
58
+ end
59
+ -----------To Here---------------------------------
60
+ namespace :migrate do
61
+ Sequel.extension :migration
62
+ ```
63
+
64
+ ### Operation Only Column Removal
65
+
66
+ In order to remove the column only existing in operation database, we need to add an option to indication it is operation only column and will not migration to history database, here is example in migration script
67
+
68
+ ```ruby
69
+ create_table :properties do
70
+ primary_key :id
71
+ String :name
72
+ String :description
73
+ Datetime :purge_at, operation: :only
74
+ index :name
75
+ end
76
+
77
+ create_table :games do
78
+ primary_key :id
79
+ String :name
80
+ String :description
81
+ column :purge_at, DateTime, operation: :only
82
+ index :name, operation: :only
83
+ end
84
+
85
+ alter_table(:rounds) do
86
+ add_column :purge_at, DateTime, operation: :only
87
+ end
88
+
89
+ alter_table(:rounds) do
90
+ rename_column :purge_at, :purged_at, operation: :only
91
+ end
92
+ ```
93
+
94
+ Currently, we support these column operation to indicate operation option:
95
+
96
+ * Create Table
97
+ 1. Missing method to define column(such as: DateTime :purge_at, operation: :only)
98
+ 2. column method to define column(such as: column :purge_at, operation: :only)
99
+
100
+ * Alter Table
101
+ 1. add_column to define column(such as: add_column :purge_at, operation: :only)
102
+ 2. rename_column to rename column(such as: rename_column :purge_at, operation: :only)
103
+
104
+ But we still have some operations of column are not support operation option:
105
+ 1.set_column_default
106
+ 2.set_column_type
107
+ 3.set_column_allow_null
108
+ 4.set_column_allow_not_null
109
+
110
+ ### Command
111
+ Above to check HISTORY environment, if defined, then require extension, register, and extend it in Database Class.
112
+ Here is command to execute for history database migration(using axle as example)
113
+
114
+ ```bash
115
+ HISTORY=true DATABASE_URL='mysql2://laxino:password@10.0.1.2:3306/axle__history' rake db:migrate:up
116
+ ```
117
+
118
+ ### Todo
119
+ - [ ] set_column_default
120
+ - [ ] set_column_type
121
+ - [ ] set_column_allow_null
122
+ - [ ] set_column_allow_not_null
123
+
124
+
125
+ ## Thank you!
126
+ Pls let me know if you have any problems.
@@ -0,0 +1 @@
1
+ ruby-2.5.0
data/example/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'http://gems.sd.laxino.com'
2
+
3
+ gem 'mysql2', '0.5.1'
4
+ gem 'sequel', '5.23.0'
5
+ gem 'rake', '12.3.1'
6
+ gem 'history_extension', '1.4.0'
@@ -0,0 +1,21 @@
1
+ GEM
2
+ remote: http://gems.sd.laxino.com/
3
+ specs:
4
+ history_extension (1.4.0)
5
+ bundler (~> 1.12)
6
+ sequel (= 5.23.0)
7
+ mysql2 (0.5.1)
8
+ rake (12.3.1)
9
+ sequel (5.23.0)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ history_extension (= 1.4.0)
16
+ mysql2 (= 0.5.1)
17
+ rake (= 12.3.1)
18
+ sequel (= 5.23.0)
19
+
20
+ BUNDLED WITH
21
+ 1.16.6
@@ -0,0 +1,3 @@
1
+ # Migration Script Writing Guideline
2
+
3
+ Pls refer confluence page: http://conf.sd.laxino.com/display/OP/Migration+Script+Writing+Guideline
@@ -0,0 +1,12 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ # require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ #require 'rake/rdoctask'
9
+ require 'rdoc/task'
10
+ Dir.glob('tasks/*.rake').each { |r| import r }
11
+
12
+ task :default => :spec
@@ -0,0 +1,18 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table :properties do |t|
4
+ primary_key :id
5
+ column :created_at, DateTime, null: false
6
+ column :updated_at, DateTime, null: false
7
+ column :purge_at, DateTime, operation: :only
8
+ end
9
+
10
+ alter_table :properties do |t|
11
+ set_column_type(:id, "int unsigned")
12
+ end
13
+ end
14
+
15
+ down do
16
+ drop_table :properties
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table :players do |t|
4
+ primary_key :id
5
+ foreign_key :property_id, :properties, type: "int unsigned", null: false, key: [:id]
6
+ String :name
7
+ String :description
8
+ Datetime :purge_at, operation: :only
9
+ index :name
10
+ index :purge_at, operation: :only
11
+ end
12
+ end
13
+
14
+ down do
15
+ drop_table :players
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table :players do |t|
4
+ add_column :token, String, operation: :only
5
+ end
6
+ end
7
+
8
+ down do
9
+ alter_table :players do |t|
10
+ drop_column :token, operation: :only
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table :players do |t|
4
+ add_index :token, operation: :only
5
+ end
6
+ end
7
+
8
+ down do
9
+ alter_table :players do |t|
10
+ drop_index :token, operation: :only
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table :players do |t|
4
+ add_index :description, operation: :only
5
+ end
6
+ end
7
+
8
+ down do
9
+ alter_table :players do |t|
10
+ drop_index :description, operation: :only
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ namespace :db do
2
+ require 'sequel'
3
+ if ENV['HISTORY']
4
+ require 'sequel/extensions/history_extension'
5
+ Sequel::Database.register_extension(:history_extension, Sequel::HistoryExtension)
6
+ Sequel::Database.extension :history_extension
7
+ end
8
+ namespace :migrate do
9
+ Sequel.extension :migration
10
+ task :connect do
11
+ url = ENV['DATABASE_URL'] || "#{ENV.fetch('MYSQL_ADAPTER', 'mysql2')}://#{ENV.fetch('MYSQL_USER', 'laxino')}:#{ENV.fetch('MYSQL_PASSWORD', 'password')}@#{ENV.fetch('MYSQL_HOST', 'db')}/#{ENV.fetch('MYSQL_DATABASE', 'application')}"
12
+ DB = Sequel.connect(url)
13
+ end
14
+
15
+ desc 'Perform migration reset (full erase and migration up).'
16
+ task :reset => [:connect] do
17
+ Sequel::Migrator.run(DB, 'db/migrations', :target => 0, :allow_missing_migration_files => true)
18
+ Sequel::Migrator.run(DB, 'db/migrations', :allow_missing_migration_files => true)
19
+ puts '*** db:migrate:reset executed ***'
20
+ end
21
+
22
+ desc 'Perform migration up/down to VERSION.'
23
+ task :to => [:connect] do
24
+ version = ENV['VERSION'].to_i
25
+ if version == 0
26
+ puts 'VERSION must be larger than 0. Use rake db:migrate:down to erase all data.'
27
+ exit false
28
+ end
29
+
30
+ Sequel::Migrator.run(DB, 'db/migrations', :target => version, :allow_missing_migration_files => true)
31
+ puts "*** db:migrate:to VERSION=[#{version}] executed ***"
32
+ end
33
+
34
+ desc 'Perform migration up to latest migration available.'
35
+ task :up => [:connect] do
36
+ Sequel::Migrator.run(DB, 'db/migrations', :allow_missing_migration_files => true)
37
+ puts '*** db:migrate:up executed ***'
38
+ end
39
+
40
+ desc 'Perform migration down (erase all data).'
41
+ task :down => [:connect] do
42
+ Sequel::Migrator.run(DB, 'db/migrations', :target => 0, :allow_missing_migration_files => true)
43
+ puts '*** db:migrate:down executed ***'
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "history_extension"
8
+ spec.version = Sequel::HistoryExtension::VERSION
9
+ spec.authors = ["Ben Wu"]
10
+ spec.email = ["ben.wu@laxino.com"]
11
+
12
+ spec.summary = %q{Sequel Extension for History DB Migration.}
13
+ spec.description = %q{Sequel Extension for History DB Migration, to remove index and foreign key constrain}
14
+ spec.homepage = "http://github.com/cheokman"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ #spec.files = %w(LICENSE CHANGELOG.md README.md) + Dir["{spec,lib}/**/*.{rb,RB}"]
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "rspec", "~> 3.0"
31
+
32
+ spec.add_dependency "bundler", "~> 1.12"
33
+ spec.add_runtime_dependency 'sequel', '5.23.0'
34
+ end
@@ -0,0 +1,82 @@
1
+ module Sequel
2
+ module HistoryExtension
3
+ def create_table_generator(&block)
4
+ super do
5
+ extend HistoryCreateExtensionMethods
6
+ instance_eval(&block) if block
7
+ end
8
+ end
9
+
10
+ def alter_table_generator(&block)
11
+ super do
12
+ extend HistoryAlterExtensionMethods
13
+ instance_eval(&block) if block
14
+ end
15
+ end
16
+
17
+ module HistoryCreateExtensionMethods
18
+ def column(name, type, opts = OPTS)
19
+ return if opts[:operation] == :only
20
+ self.class.instance_method(:column).bind(self).call(name, type, opts)
21
+ end
22
+
23
+ def index(columns, opts = OPTS)
24
+ return if opts[:operation] == :only
25
+ self.class.instance_method(:index).bind(self).call(columns, opts)
26
+ end
27
+
28
+ def foreign_key(name, table=nil, opts = OPTS)
29
+ self.class.instance_method(:foreign_key).bind(self).call(name,nil,opts)
30
+ end
31
+
32
+ private
33
+
34
+ # Add a composite foreign key constraint
35
+ def composite_foreign_key(columns, opts); end
36
+ end
37
+
38
+ module HistoryAlterExtensionMethods
39
+ #
40
+ # TODO support column operation:
41
+ #. set_column_default
42
+ #. set_column_type
43
+ #. set_column_allow_null
44
+ #. set_column_allow_not_null
45
+ #
46
+ def add_index(columns, opts = OPTS)
47
+ return if opts[:operation] == :only
48
+ self.class.instance_method(:add_index).bind(self).call(columns, opts)
49
+ end
50
+
51
+ def drop_index(columns, opts=OPTS)
52
+ return if opts[:operation] == :only
53
+ self.class.instance_method(:drop_index).bind(self).call(columns, opts)
54
+ end
55
+
56
+ def add_column(name, type, opts = OPTS)
57
+ return if opts[:operation] == :only
58
+ self.class.instance_method(:add_column).bind(self).call(name, type, opts)
59
+ end
60
+
61
+ def rename_column(name, new_name, opts = OPTS)
62
+ return if opts[:operation] == :only
63
+ self.class.instance_method(:rename_column).bind(self).call(name, new_name, opts)
64
+ end
65
+
66
+ def drop_column(name, opts=OPTS)
67
+ return if opts[:operation] == :only
68
+ self.class.instance_method(:drop_column).bind(self).call(name, opts)
69
+ end
70
+
71
+ def add_foreign_key(name, table, opts = OPTS)
72
+ self.class.instance_method(:add_foreign_key).bind(self).call(name, nil, opts)
73
+ end
74
+
75
+ private
76
+
77
+ def drop_composite_foreign_key(columns, opts); end
78
+
79
+ def add_composite_foreign_key(columns, table, opts); end
80
+ end
81
+ end
82
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Sequel
2
+ module HistoryExtension
3
+ VERSION = '1.4.1'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: history_extension
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Wu
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-06-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sequel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 5.23.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 5.23.0
55
+ description: Sequel Extension for History DB Migration, to remove index and foreign
56
+ key constrain
57
+ email:
58
+ - ben.wu@laxino.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - example/.ruby-version
68
+ - example/Gemfile
69
+ - example/Gemfile.lock
70
+ - example/MIGRATION_SCRIPT_WRITING_GUIDELINE.md
71
+ - example/Rakefile.rb
72
+ - example/db/migrations/201703210929_create_properties.rb
73
+ - example/db/migrations/201703210930_create_players.rb
74
+ - example/db/migrations/201703291142_add_token_to_players.rb
75
+ - example/db/migrations/201703291144_add_index_to_players_token.rb
76
+ - example/db/migrations/201703291145_add_index_to_players_description.rb
77
+ - example/tasks/sequel.rake
78
+ - history_extension.gemspec
79
+ - lib/sequel/extensions/history_extension.rb
80
+ - lib/version.rb
81
+ homepage: http://github.com/cheokman
82
+ licenses: []
83
+ metadata:
84
+ allowed_push_host: https://rubygems.org
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.0.3.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Sequel Extension for History DB Migration.
104
+ test_files: []