tapsoob 0.1.35 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0514df0bb69707476f8e3ba408967fbbb74e6af6
4
- data.tar.gz: 2bb8bc052da152786710e94bef38cdbb65bf089c
2
+ SHA256:
3
+ metadata.gz: 3e28274d8d5730a830f2f8a1f64a10f4cf5a0973598473a7c2eadaaa93ff88cc
4
+ data.tar.gz: e01694dfcf507d66cb80edc7855c068898077da06c88a29c61f19d42d6654a65
5
5
  SHA512:
6
- metadata.gz: b70ce1b460011a223aafcf061af81dd23dc5341545bebcc2fc4c8c662b85521bb05a74747eb3f2edf87731e0eaff95b4bed8d617b6de447393f8ec92083ec200
7
- data.tar.gz: 7be56b1c90040d0be6ddb7b38fe1e3c540ef9f4251ce41abaefac0b0aea8f4db01e44ef6eb2fbe039eaf68a7bc374fdda4173c64772048f37adcedbeb8e09e31
6
+ metadata.gz: 8ed2bd463e75ccbcf9605d41d75551c6ab47bcb0483f809207be1b21a6729cb5f7d86d20fa54f18d47964e34b391228a52ad28e0aa0e05b20fee7a12042665b2
7
+ data.tar.gz: e09b0e823cd9756d6422e95ee9b416569bc79414c86e8ad5230d450164cf87b9c8458f58f7811a5fa59fdd108106794bf658e7ee6b110b3780b50420cfe1c8ff
data/.gitignore CHANGED
@@ -1,5 +1,10 @@
1
1
  # Ignore dev stuffs
2
+ config/
2
3
  coverage/
3
4
  db/
5
+ dist/
6
+ lib/java/
4
7
  *.dat
5
8
  *.gem
9
+ *.lock
10
+ .ruby-version
data/Gemfile CHANGED
@@ -1,8 +1,43 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # load the gem's dependencies
3
+ # monkey patching to support dual booting
4
+ module Bundler::SharedHelpers
5
+ def default_lockfile=(path)
6
+ @default_lockfile = path
7
+ end
8
+ def default_lockfile
9
+ @default_lockfile ||= Pathname.new("#{default_gemfile}.lock")
10
+ end
11
+ end
12
+
13
+ module ::Kernel
14
+ def jruby?
15
+ !(RUBY_PLATFORM =~ /java/).nil?
16
+ end
17
+ end
18
+
19
+ if jruby?
20
+ Bundler::SharedHelpers.default_lockfile = Pathname.new("#{Bundler::SharedHelpers.default_gemfile}_jruby.lock")
21
+
22
+ # Bundler::Dsl.evaluate already called with an incorrect lockfile ... fix it
23
+ class Bundler::Dsl
24
+ # A bit messy, this can be called multiple times by bundler, avoid blowing the stack
25
+ unless self.method_defined? :to_definition_unpatched
26
+ alias_method :to_definition_unpatched, :to_definition
27
+ end
28
+ def to_definition(bad_lockfile, unlock)
29
+ to_definition_unpatched(Bundler::SharedHelpers.default_lockfile, unlock)
30
+ end
31
+ end
32
+ end
33
+
34
+ # gemspec
4
35
  gemspec
5
36
 
37
+ group :development do
38
+ gem 'warbler', '~> 2.0.4', platform: :jruby, require: false
39
+ end
40
+
6
41
  group :test do
7
42
  gem 'rspec', '~> 3.2.0'
8
43
  gem 'simplecov', '~> 0.9.2'
data/Rakefile CHANGED
@@ -0,0 +1,4 @@
1
+ unless (RUBY_PLATFORM =~ /java/).nil?
2
+ require 'warbler'
3
+ Warbler::Task.new
4
+ end
data/bin/tapsoob CHANGED
@@ -1,6 +1,191 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'rubygems'
4
+ require 'fileutils'
5
+ require 'sequel'
6
+ require 'tempfile'
7
+ require 'thor'
8
+
3
9
  $:.unshift File.dirname(__FILE__) + '/../lib'
4
- require 'tapsoob/cli'
10
+ require 'tapsoob/config'
11
+ require 'tapsoob/log'
12
+ require 'tapsoob/operation'
13
+ require 'tapsoob/schema'
14
+ require 'tapsoob/version'
15
+
16
+ Tapsoob::Config.tapsoob_database_url = ENV['TAPSOOB_DATABASE_URL'] || begin
17
+ # this is dirty but it solves a weird problem where the tempfile disappears mid-process
18
+ #require ((RUBY_PLATFORM =~ /java/).nil? ? 'sqlite3' : 'jdbc-sqlite3')
19
+ $__taps_database = Tempfile.new('tapsoob.db')
20
+ $__taps_database.open()
21
+ "sqlite://#{$__taps_database.path}"
22
+ end
23
+
24
+ module TapsoobCLI
25
+ class Schema < Thor
26
+ desc "console DATABASE_URL", "Create an IRB REPL connected to a database"
27
+ def console(database_url)
28
+ $db = Sequel.connect(database_url)
29
+ require 'irb'
30
+ require 'irb/completion'
31
+ IRB.start
32
+ end
33
+
34
+ desc "dump DATABASE_URL", "Dump a database using a database URL"
35
+ def dump(database_url)
36
+ puts Tapsoob::Schema.dump(database_url)
37
+ end
38
+
39
+ desc "dump_table DATABASE_URL TABLE", "Dump a table from a database using a database URL"
40
+ def dump_table(database_url, table)
41
+ puts Tapsoob::Schema.dump_table(database_url, table)
42
+ end
43
+
44
+ desc "indexes DATABASE_URL", "Dump indexes from a database using a database URL"
45
+ def indexes(database_url)
46
+ puts Tapsoob::Schema.indexes(database_url)
47
+ end
48
+
49
+ desc "indexes_individual DATABASE_URL", "Dump indexes per table individually using a database URL"
50
+ def indexes_individual(database_url)
51
+ puts Tapsoob::Schema.indexes_individual(database_url)
52
+ end
53
+
54
+ desc "reset_db_sequences DATABASE_URL", "Reset database sequences using a database URL"
55
+ def reset_db_sequences(database_url)
56
+ Tapsoob::Schema.reset_db_sequences(database_url)
57
+ end
58
+
59
+ desc "load DATABASE_URL FILENAME", "Load a database schema from a file to a database using a database URL"
60
+ def load(database_url, filename)
61
+ schema = File.read(filename) rescue help
62
+ Tapsoob::Schema.load(database_url, schema)
63
+ end
64
+
65
+ desc "load_indexes DATABASE_URL FILENAME", "Load indexes from a file to a database using a database URL"
66
+ def load_indexes(database_url, filename)
67
+ indexes = File.read(filename) rescue help
68
+ Tapsoob::Schema.load_indexes(database_url, indexes)
69
+ end
70
+ end
71
+
72
+ class Root < Thor
73
+ desc "pull DUMP_PATH DATABASE_URL", "Pull a dump from a database to a folder"
74
+ option :"skip-schema", desc: "Don't transfer the schema just data", default: false, type: :boolean, aliases: "-s"
75
+ option :"indexes-first", desc: "Transfer indexes first before data", default: false, type: :boolean, aliases: "-i"
76
+ option :resume, desc: "Resume a Tapsoob Session from a stored file", type: :string, aliases: "-r"
77
+ option :chunksize, desc: "Initial chunksize", default: 1000, type: :numeric, aliases: "-c"
78
+ option :"disable-compression", desc: "Disable Compression", default: false, type: :boolean, aliases: "-g"
79
+ option :filter, desc: "Regex Filter for tables", type: :string, aliases: "-f"
80
+ option :tables, desc: "Shortcut to filter on a list of tables", type: :array, aliases: "-t"
81
+ option :"exclude-tables", desc: "Shortcut to exclude a list of tables", type: :array, aliases: "-e"
82
+ option :debug, desc: "Enable debug messages", default: false, type: :boolean, aliases: "-d"
83
+ def pull(dump_path, database_url)
84
+ opts = parse_opts(options)
85
+ Tapsoob.log.level = Logger::DEBUG if opts[:debug]
86
+ if opts[:resume_filename]
87
+ clientresumexfer(:pull, dump_path, database_url, opts)
88
+ else
89
+ clientxfer(:pull, dump_path, database_url, opts)
90
+ end
91
+ end
92
+
93
+ desc "push DUMP_PATH DATABASE_URL", "Push a previously tapsoob dump to a database"
94
+ option :"skip-schema", desc: "Don't transfer the schema just data", default: false, type: :boolean, aliases: "-s"
95
+ option :"indexes-first", desc: "Transfer indexes first before data", default: false, type: :boolean, aliases: "-i"
96
+ option :resume, desc: "Resume a Tapsoob Session from a stored file", type: :string, aliases: "-r"
97
+ option :chunksize, desc: "Initial chunksize", default: 1000, type: :numeric, aliases: "-c"
98
+ option :"disable-compression", desc: "Disable Compression", default: false, type: :boolean, aliases: "-g"
99
+ option :filter, desc: "Regex Filter for tables", type: :string, aliases: "-f"
100
+ option :tables, desc: "Shortcut to filter on a list of tables", type: :array, aliases: "-t"
101
+ option :"exclude-tables", desc: "Shortcut to exclude a list of tables", type: :array, aliases: "-e"
102
+ option :debug, desc: "Enable debug messages", default: false, type: :boolean, aliases: "-d"
103
+ def push(dump_path, database_url)
104
+ opts = parse_opts(options)
105
+ Tapsoob.log.level = Logger::DEBUG if opts[:debug]
106
+ if opts[:resume_filename]
107
+ clientresumexfer(:push, dump_path, database_url, opts)
108
+ else
109
+ clientxfer(:push, dump_path, database_url, opts)
110
+ end
111
+ end
112
+
113
+ desc "version", "Show tapsoob version"
114
+ def version
115
+ puts Tapsoob::VERSION.dup
116
+ end
117
+
118
+ desc "schema SUBCOMMAND ...ARGS", "Direct access to Tapsoob::Schema class methods"
119
+ subcommand "schema", Schema
120
+
121
+ private
122
+ def parse_opts(options)
123
+ # Default options
124
+ opts = {
125
+ skip_schema: options[:"skip-schema"],
126
+ indexes_first: options[:"indexes_first"],
127
+ disable_compression: options[:"disable-compression"],
128
+ debug: options[:debug]
129
+ }
130
+
131
+ # Resume
132
+ if options[:resume]
133
+ if File.exists?(options[:resume])
134
+ opts[:resume_file] = options[:resume]
135
+ else
136
+ raise "Unable to find resume file."
137
+ end
138
+ end
139
+
140
+ # Default chunksize
141
+ if options[:chunksize]
142
+ opts[:default_chunksize] = (options[:chunksize] < 10 ? 10 : options[:chunksize])
143
+ end
144
+
145
+ # Regex filter
146
+ opts[:table_filter] = options[:filter] if options[:filter]
147
+
148
+ # Table filter
149
+ if options[:tables]
150
+ r_tables = options[:tables].collect { |t| "^#{t}" }.join("|")
151
+ opts[:table_filter] = "#{r_tables}"
152
+ end
153
+
154
+ # Exclude tables
155
+ opts[:exclude_tables] = options[:"exclude-tables"] if options[:"exclude-tables"]
156
+
157
+ opts
158
+ end
159
+
160
+ def clientxfer(method, dump_path, database_url, opts)
161
+ Tapsoob::Config.verify_database_url(database_url)
162
+
163
+ FileUtils.mkpath "#{dump_path}/schemas"
164
+ FileUtils.mkpath "#{dump_path}/data"
165
+ FileUtils.mkpath "#{dump_path}/indexes"
166
+
167
+ require 'tapsoob/operation'
168
+
169
+ Tapsoob::Operation.factory(method, database_url, dump_path, opts).run
170
+ end
171
+
172
+ def clientresumexfer(method, dump_path, database_url, opts)
173
+ session = JSON.parse(File.read(opts.delete(:resume_filename)))
174
+ session.symbolize_recursively!
175
+
176
+ dump_path = dump_path || session.delete(:dump_path)
177
+
178
+ require 'taps/operation'
179
+
180
+ newsession = session.merge({
181
+ :default_chunksize => opts[:default_chunksize],
182
+ :disable_compression => opts[:disable_compression],
183
+ :resume => true
184
+ })
185
+
186
+ Tapsoob::Operation.factory(method, database_url, dump_path, newsession).run
187
+ end
188
+ end
189
+ end
5
190
 
6
- Tapsoob::Cli.new(ARGV.dup).run
191
+ TapsoobCLI::Root.start(ARGV)
data/lib/tapsoob.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
- $:.unshift File.dirname(__FILE__)
3
-
4
- # internal requires
5
2
  require 'tapsoob/operation'
6
3
 
7
4
  module Tapsoob
data/lib/tapsoob/utils.rb CHANGED
@@ -155,7 +155,7 @@ Data : #{data}
155
155
  end
156
156
 
157
157
  def schema_bin(*args)
158
- bin_path = File.expand_path("#{File.dirname(__FILE__)}/../../bin/#{bin('schema')}")
158
+ bin_path = File.expand_path("#{File.dirname(__FILE__)}/../../bin/#{bin('tapsoob schema')}")
159
159
  `#{Gem.ruby} -S "#{bin_path}" #{args.map { |a| "'#{a}'" }.join(' ') }`
160
160
  end
161
161
 
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Tapsoob
3
- VERSION = "0.1.35".freeze
3
+ VERSION = "0.2.1".freeze
4
4
  end
@@ -71,7 +71,7 @@ namespace :tapsoob do
71
71
 
72
72
  case connection_config['adapter']
73
73
  when "mysql", "mysql2"
74
- uri = "#{connection_config['adapter']}://#{connection_config['host']}/#{connection_config['database']}?user=#{connection_config['username']}&password=#{connection_config['password']}"
74
+ uri = "mysql://#{connection_config['host']}/#{connection_config['database']}?user=#{connection_config['username']}&password=#{connection_config['password']}"
75
75
  when "postgresql", "postgres", "pg"
76
76
  uri = "://#{connection_config['host']}/#{connection_config['database']}?user=#{connection_config['username']}&password=#{connection_config['password']}"
77
77
  uri = ((RUBY_PLATFORM =~ /java/).nil? ? "postgres" : "postgresql") + uri
data/tapsoob.gemspec CHANGED
@@ -1,6 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "tapsoob/version"
2
+ require "./lib/tapsoob/version" unless defined? Tapsoob::VERSION
4
3
 
5
4
  Gem::Specification.new do |s|
6
5
  # Metadata
@@ -17,13 +16,22 @@ Gem::Specification.new do |s|
17
16
  s.files = `git ls-files`.split("\n")
18
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.bindir = 'bin'
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  # Dependencies
23
23
  s.add_dependency "sequel", "~> 5.0.0"
24
+ s.add_dependency "thor", "~> 0.20.0"
24
25
 
25
- s.add_development_dependency "mysql", "~> 2.9.1"
26
- s.add_development_dependency "mysql2", "~> 0.4.2"
27
- s.add_development_dependency "pg", "~> 0.18.4"
28
- s.add_development_dependency "sqlite3", "~> 1.3.11"
26
+ if (RUBY_PLATFORM =~ /java/).nil?
27
+ s.add_development_dependency "mysql2", "~> 0.4.10"
28
+ s.add_development_dependency "pg", "~> 1.0.0"
29
+ s.add_development_dependency "sqlite3", "~> 1.3.11"
30
+ else
31
+ s.platform = 'java'
32
+
33
+ s.add_development_dependency "jdbc-mysql", "~> 5.1.44"
34
+ s.add_development_dependency "jdbc-postgres", "~> 42.1.4"
35
+ s.add_development_dependency "jdbc-sqlite3", "~> 3.20.1"
36
+ end
29
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapsoob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.35
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Félix Bellanger
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-08 00:00:00.000000000 Z
12
+ date: 2018-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel
@@ -26,47 +26,47 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: 5.0.0
28
28
  - !ruby/object:Gem::Dependency
29
- name: mysql
29
+ name: thor
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 2.9.1
35
- type: :development
34
+ version: 0.20.0
35
+ type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 2.9.1
41
+ version: 0.20.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: mysql2
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 0.4.2
48
+ version: 0.4.10
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 0.4.2
55
+ version: 0.4.10
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: pg
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: 0.18.4
62
+ version: 1.0.0
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: 0.18.4
69
+ version: 1.0.0
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: sqlite3
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -85,7 +85,6 @@ description: Simple tool to import/export databases inspired by taps but OOB, me
85
85
  databases are imported/exported from the filesystem.
86
86
  email: felix.bellanger@faveod.com
87
87
  executables:
88
- - schema
89
88
  - tapsoob
90
89
  extensions: []
91
90
  extra_rdoc_files: []
@@ -93,14 +92,11 @@ files:
93
92
  - ".gitignore"
94
93
  - ".rspec"
95
94
  - Gemfile
96
- - Gemfile.lock
97
95
  - README.md
98
96
  - Rakefile
99
- - bin/schema
100
97
  - bin/tapsoob
101
98
  - lib/tapsoob.rb
102
99
  - lib/tapsoob/chunksize.rb
103
- - lib/tapsoob/cli.rb
104
100
  - lib/tapsoob/config.rb
105
101
  - lib/tapsoob/data_stream.rb
106
102
  - lib/tapsoob/errors.rb
@@ -136,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
132
  version: '0'
137
133
  requirements: []
138
134
  rubyforge_project:
139
- rubygems_version: 2.6.12
135
+ rubygems_version: 2.7.3
140
136
  signing_key:
141
137
  specification_version: 4
142
138
  summary: Simple tool to import/export databases.
data/Gemfile.lock DELETED
@@ -1,50 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- tapsoob (0.1.26)
5
- sequel (~> 4.30.0)
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- diff-lcs (1.2.5)
11
- docile (1.1.5)
12
- multi_json (1.11.0)
13
- mysql (2.9.1)
14
- mysql2 (0.4.2)
15
- pg (0.18.4)
16
- rspec (3.2.0)
17
- rspec-core (~> 3.2.0)
18
- rspec-expectations (~> 3.2.0)
19
- rspec-mocks (~> 3.2.0)
20
- rspec-core (3.2.3)
21
- rspec-support (~> 3.2.0)
22
- rspec-expectations (3.2.1)
23
- diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.2.0)
25
- rspec-mocks (3.2.1)
26
- diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.2.0)
28
- rspec-support (3.2.2)
29
- sequel (4.30.0)
30
- simplecov (0.9.2)
31
- docile (~> 1.1.0)
32
- multi_json (~> 1.0)
33
- simplecov-html (~> 0.9.0)
34
- simplecov-html (0.9.0)
35
- sqlite3 (1.3.11)
36
-
37
- PLATFORMS
38
- ruby
39
-
40
- DEPENDENCIES
41
- mysql (~> 2.9.1)
42
- mysql2 (~> 0.4.2)
43
- pg (~> 0.18.4)
44
- rspec (~> 3.2.0)
45
- simplecov (~> 0.9.2)
46
- sqlite3 (~> 1.3.11)
47
- tapsoob!
48
-
49
- BUNDLED WITH
50
- 1.11.2
data/bin/schema DELETED
@@ -1,54 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'sequel'
5
-
6
- $:.unshift File.dirname(__FILE__) + '/../lib'
7
-
8
- require 'tapsoob/schema'
9
-
10
- cmd = ARGV.shift.strip rescue ''
11
- database_url = ARGV.shift.strip rescue ''
12
-
13
- def show_usage_and_exit
14
- puts <<EOTXT
15
- schema console <database_url>
16
- schema dump <database_url>
17
- schema dump_table <database_url> <table>
18
- schema indexes <database_url>
19
- schema indexes_individual <database_url>
20
- schema reset_db_sequences <database_url>
21
- schema load <database_url> <schema_file>
22
- schema load_indexes <database_url> <indexes_file>
23
- EOTXT
24
- exit(1)
25
- end
26
-
27
- case cmd
28
- when 'dump'
29
- puts Tapsoob::Schema.dump(database_url)
30
- when 'dump_table'
31
- table = ARGV.shift.strip
32
- puts Tapsoob::Schema.dump_table(database_url, table)
33
- when 'indexes'
34
- puts Tapsoob::Schema.indexes(database_url)
35
- when 'indexes_individual'
36
- puts Tapsoob::Schema.indexes_individual(database_url)
37
- when 'load_indexes'
38
- filename = ARGV.shift.strip rescue ''
39
- indexes = File.read(filename) rescue show_usage_and_exit
40
- Tapsoob::Schema.load_indexes(database_url, indexes)
41
- when 'load'
42
- filename = ARGV.shift.strip rescue ''
43
- schema = File.read(filename) rescue show_usage_and_exit
44
- Tapsoob::Schema.load(database_url, schema)
45
- when 'reset_db_sequences'
46
- Tapsoob::Schema.reset_db_sequences(database_url)
47
- when 'console'
48
- $db = Sequel.connect(database_url)
49
- require 'irb'
50
- require 'irb/completion'
51
- IRB.start
52
- else
53
- show_usage_and_exit
54
- end
data/lib/tapsoob/cli.rb DELETED
@@ -1,145 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'fileutils'
3
- require 'optparse'
4
- require 'tempfile'
5
- require 'tapsoob/config'
6
- require 'tapsoob/log'
7
-
8
- Tapsoob::Config.tapsoob_database_url = ENV['TAPSOOB_DATABASE_URL'] || begin
9
- # this is dirty but it solves a weird problem where the tempfile disappears mid-process
10
- require 'sqlite3'
11
- $__taps_database = Tempfile.new('tapsoob.db')
12
- $__taps_database.open()
13
- "sqlite://#{$__taps_database.path}"
14
- end
15
-
16
- module Tapsoob
17
- class Cli
18
- attr_accessor :argv
19
-
20
- def initialize(argv)
21
- @argv = argv
22
- end
23
-
24
- def run
25
- method = (argv.shift || 'help').to_sym
26
- if [:pull, :push, :version].include? method
27
- send(method)
28
- else
29
- help
30
- end
31
- end
32
-
33
- def pull
34
- opts = clientoptparse(:pull)
35
- Tapsoob.log.level = Logger::DEBUG if opts[:debug]
36
- if opts[:resume_filename]
37
- clientresumexfer(:pull, opts)
38
- else
39
- clientxfer(:pull, opts)
40
- end
41
- end
42
-
43
- def push
44
- opts = clientoptparse(:push)
45
- Tapsoob.log.level = Logger::DEBUG if opts[:debug]
46
- if opts[:resume_filename]
47
- clientresumexfer(:push, opts)
48
- else
49
- clientxfer(:push, opts)
50
- end
51
- end
52
-
53
- def version
54
- puts Tapsoob.version
55
- end
56
-
57
- def help
58
- puts <<EOHELP
59
- Options
60
- =======
61
- pull Pull a database and export it into a directory
62
- push Push a database from a directory
63
- version Tapsoob version
64
-
65
- Add '-h' to any command to see their usage
66
- EOHELP
67
- end
68
-
69
- def clientoptparse(cmd)
70
- opts={:default_chunksize => 1000, :database_url => nil, :dump_path => nil, :debug => false, :resume_filename => nil, :disable_compression => false, :indexes_first => false}
71
- OptionParser.new do |o|
72
- o.banner = "Usage: #{File.basename($0)} #{cmd} [OPTIONS] <dump_path> <database_url>"
73
-
74
- case cmd
75
- when :pull
76
- o.define_head "Pull a database and export it into a directory"
77
- when :push
78
- o.define_head "Push a database from a directory"
79
- end
80
-
81
- o.on("-s", "--skip-schema", "Don't transfer the schema just data") { |v| opts[:skip_schema] = true }
82
- o.on("-i", "--indexes-first", "Transfer indexes first before data") { |v| opts[:indexes_first] = true }
83
- o.on("-r", "--resume=file", "Resume a Tapsoob Session from a stored file") { |v| opts[:resume_filename] = v }
84
- o.on("-c", "--chunksize=N", "Initial Chunksize") { |v| opts[:default_chunksize] = (v.to_i < 10 ? 10 : v.to_i) }
85
- o.on("-g", "--disable-compression", "Disable Compression") { |v| opts[:disable_compression] = true }
86
- o.on("-f", "--filter=regex", "Regex Filter for tables") { |v| opts[:table_filter] = v }
87
- o.on("-t", "--tables=A,B,C", Array, "Shortcut to filter on a list of tables") do |v|
88
- r_tables = v.collect { |t| "^#{t}" }.join("|")
89
- opts[:table_filter] = "#{r_tables}"
90
- end
91
- o.on("-e", "--exclude-tables=A,B,C", Array, "Shortcut to exclude a list of tables") { |v| opts[:exclude_tables] = v }
92
- o.on("-d", "--debug", "Enable Debug Messages") { |v| opts[:debug] = true }
93
-
94
- opts[:dump_path] = argv.shift
95
- opts[:database_url] = argv.shift
96
-
97
- if opts[:database_url].nil?
98
- $stderr.puts "Missing Database URL"
99
- puts o
100
- exit 1
101
- end
102
- if opts[:dump_path].nil?
103
- $stderr.puts "Missing Tapsoob Dump Path"
104
- puts o
105
- exist 1
106
- end
107
- end
108
-
109
- opts
110
- end
111
-
112
- def clientxfer(method, opts)
113
- database_url = opts.delete(:database_url)
114
- dump_path = opts.delete(:dump_path)
115
-
116
- Tapsoob::Config.verify_database_url(database_url)
117
-
118
- FileUtils.mkpath "#{dump_path}/schemas"
119
- FileUtils.mkpath "#{dump_path}/data"
120
- FileUtils.mkpath "#{dump_path}/indexes"
121
-
122
- require 'tapsoob/operation'
123
-
124
- Tapsoob::Operation.factory(method, database_url, dump_path, opts).run
125
- end
126
-
127
- def clientresumexfer(method, opts)
128
- session = JSON.parse(File.read(opts.delete(:resume_filename)))
129
- session.symbolize_recursively!
130
-
131
- database_url = opts.delete(:database_url)
132
- dump_path = opts.delete(:dump_path) || session.delete(:dump_path)
133
-
134
- require 'taps/operation'
135
-
136
- newsession = session.merge({
137
- :default_chunksize => opts[:default_chunksize],
138
- :disable_compression => opts[:disable_compression],
139
- :resume => true
140
- })
141
-
142
- Tapsoob::Operation.factory(method, database_url, dump_path, newsession).run
143
- end
144
- end
145
- end