tapsoob 0.1.35 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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