backhoe 0.6.1 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0da54b2284a8f477b20d0175cdb1023ffd28e03365598000e8cdf7403fb12dc4
4
- data.tar.gz: a298c3b656be2bd65b52731ae749d27317b5bbd26e2401370a4ccbbfc22f73c1
3
+ metadata.gz: 100b63cead65cdff8255681cc6ea2e228efa706f48662dc08e0b594de8415dcc
4
+ data.tar.gz: d1abde4f85cbb93f40d94d7485184772d18d35669aa748fb27a529da43d2651f
5
5
  SHA512:
6
- metadata.gz: 90cf47702daa8c845795bfba48175718016f3f929b34c3924d86ad3d51979ca91e2cfae4973d2839197ec333e8735c92b02347095256674f444998ec951118e8
7
- data.tar.gz: 335c9e882afd7c4f8591f8b449b4cc1dc3205d74d7194a1112a0b2b9492af30223ebddad7c18583db96471ac2663e7b360eb569a40e8b9e91bd5ba6db4af32a2
6
+ metadata.gz: 3cb9ede3f8a8704611184842add89dd94755e53c2781c1aa8a0b529cb439bd2268bac4139beeac49fd6d10a7bae964e9496d44204de8de97ced4fd61b8d706b3
7
+ data.tar.gz: d8208ae606c0790f84adc8c501630ffc9bdf2be0775a6ec580a8c7dd788a06ebc4b6fa13fb043a5be71d32bbd7ed7bbb9dd68184d323c0af35b0431537d15160
@@ -5,17 +5,24 @@ jobs:
5
5
  strategy:
6
6
  fail-fast: false
7
7
  matrix:
8
- gemfile: [ activerecord_6.0, activerecord_6.1, activerecord_7.0 ]
9
- ruby: [ '3.0', 3.1, 3.2 ]
8
+ gemfile: [ activerecord_6.0, activerecord_6.1, activerecord_7.0, activerecord_7.1 ]
9
+ ruby: [ '3.0', 3.1, 3.2, 3.3 ]
10
10
 
11
11
  runs-on: ubuntu-20.04
12
12
  env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
13
13
  BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
14
+ POSTGRES_HOST_AUTH_METHOD: trust
15
+
14
16
  steps:
15
17
  - name: Set up MySQL
16
18
  run: |
17
- sudo /etc/init.d/mysql start
19
+ sudo service mysql start
18
20
  sudo mysql -uroot -proot -e"ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '';"
21
+ - name: Set up PostgreSQL
22
+ run: |
23
+ sudo service postgresql start
24
+ sudo -u postgres createuser --superuser runner
25
+ createdb runner
19
26
  - uses: actions/checkout@v3
20
27
  - uses: ruby/setup-ruby@v1
21
28
  with:
data/Appraisals CHANGED
@@ -10,3 +10,7 @@ appraise "activerecord-7.0" do
10
10
  gem "activerecord", "~>7.0.0"
11
11
  end
12
12
 
13
+ appraise "activerecord-7.1" do
14
+ gem "activerecord", "~>7.1.0"
15
+ end
16
+
data/README.md CHANGED
@@ -17,8 +17,7 @@ Backhoe.load "data.sql.gz" # => can also load a gzipped sql file
17
17
  Backhoe.load "data.sql", drop_and_create: true # injects DROP and CREATE statements into the SQL invocation
18
18
 
19
19
  # Backup db to S3
20
- Backhoe.backup "bucket-name/folder" # => dumps db to e.g. s3://bucket-name/folder/2023-04-09T16:41:26Z.sql.gz via AWS CLI, assuming that credentials are already configured.
21
- Backhoe.backup "bucket-name/folder", access_key: "abc123", secret_key: "def456" # => manually specify AWS creds
20
+ Backhoe.backup "bucket-name/folder", access_key: "abc123", secret_key: "def456" # => must specify AWS creds
22
21
  ```
23
22
 
24
23
  ## Development
data/backhoe.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rspec", "~> 3.0"
28
28
  spec.add_development_dependency "appraisal"
29
29
  spec.add_development_dependency "mysql2"
30
+ spec.add_development_dependency "pg"
30
31
  spec.add_development_dependency "byebug"
31
32
  spec.add_development_dependency "timecop"
32
33
  end
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~>7.1.0"
6
+
7
+ gemspec path: "../"
@@ -1,16 +1,66 @@
1
+ require "net/http"
2
+ require "openssl"
3
+ require "base64"
4
+
1
5
  module Backhoe
2
6
  class Backup < Struct.new(:s3_path, :access_key, :secret_key)
3
7
  def call
8
+ @time = Time.now
9
+
4
10
  Backhoe.dump path
5
- Kernel.system "#{creds} aws s3 mv #{path} s3://#{s3_path}/#{filename}".strip
11
+
12
+ uri = URI("https://s3-us-west-2.amazonaws.com/#{s3_path}/#{filename}")
13
+
14
+ req = Net::HTTP::Put.new(uri, {
15
+ "Content-Length": File.size(path).to_s,
16
+ "Content-Type": content_type,
17
+ "Date": date,
18
+ "Authorization": "AWS #{access_key}:#{signature}",
19
+ "x-amz-storage-class": "STANDARD",
20
+ "x-amz-acl": "private",
21
+ })
22
+ req.body_stream = File.open(path)
23
+ Net::HTTP.start(uri.hostname) { |http| http.request(req) }
6
24
  end
7
25
 
8
26
  private
9
27
 
10
- def creds
11
- if access_key && secret_key
12
- "AWS_ACCESS_KEY_ID=#{access_key} AWS_SECRET_ACCESS_KEY=#{secret_key}"
13
- end
28
+ def signature
29
+ digester = OpenSSL::Digest::SHA1.new
30
+ digest = OpenSSL::HMAC.digest(digester, secret_key, key)
31
+ Base64.strict_encode64(digest)
32
+ end
33
+
34
+ def key
35
+ [
36
+ "PUT",
37
+ "",
38
+ content_type,
39
+ date,
40
+ acl,
41
+ storage_type,
42
+ full_s3_path,
43
+ ].join("\n")
44
+ end
45
+
46
+ def content_type
47
+ "application/gzip"
48
+ end
49
+
50
+ def date
51
+ @time.rfc2822
52
+ end
53
+
54
+ def acl
55
+ "x-amz-acl:private"
56
+ end
57
+
58
+ def storage_type
59
+ "x-amz-storage-class:STANDARD"
60
+ end
61
+
62
+ def full_s3_path
63
+ "/#{s3_path}/#{filename}"
14
64
  end
15
65
 
16
66
  def path
@@ -18,10 +68,7 @@ module Backhoe
18
68
  end
19
69
 
20
70
  def filename
21
- @filename ||= begin
22
- require "time"
23
- "#{Time.now.utc.iso8601}.sql.gz"
24
- end
71
+ "#{@time.utc.iso8601}.sql.gz"
25
72
  end
26
73
  end
27
74
  end
@@ -26,6 +26,18 @@ module Backhoe
26
26
  config["database"]
27
27
  end
28
28
 
29
+ def adapter
30
+ config["adapter"]
31
+ end
32
+
33
+ def postgresql?
34
+ config["adapter"] == "postgresql"
35
+ end
36
+
37
+ def mysql?
38
+ %w[mysql2 trilogy].include?(config["adapter"])
39
+ end
40
+
29
41
  private
30
42
 
31
43
  def load_config
data/lib/backhoe/dump.rb CHANGED
@@ -11,7 +11,11 @@ module Backhoe
11
11
  end
12
12
 
13
13
  def call
14
+ if skip_tables.any?
15
+ raise NotImplementedError if database.postgresql?
16
+ end
14
17
  if skip_columns.any?
18
+ raise NotImplementedError if database.postgresql?
15
19
  SanitizedDatabase.new(skip_columns, file_path).dump do |tables|
16
20
  self.skip_tables += tables
17
21
  dump
@@ -24,7 +28,13 @@ module Backhoe
24
28
  private
25
29
 
26
30
  def dump
27
- sh "#{mysqldump} --no-create-db --single-transaction --quick -e #{skip_table_options} #{database.to_mysql_options} #{database.name} | #{pipe} > #{file_path}"
31
+ if database.mysql?
32
+ sh "#{mysqldump} --no-create-db --single-transaction --quick -e #{skip_table_options} #{database.to_mysql_options} #{database.name} | #{pipe} > #{file_path}"
33
+ elsif database.postgresql?
34
+ sh "#{pg_dump} --column-inserts #{database.name} | #{pipe} > #{file_path}"
35
+ else
36
+ raise "don't know how to dump #{database.adapter}"
37
+ end
28
38
  end
29
39
 
30
40
  private
@@ -35,6 +45,12 @@ module Backhoe
35
45
  cmd
36
46
  end
37
47
 
48
+ def pg_dump
49
+ cmd = `which pg_dump`.strip
50
+ raise RuntimeError, "Cannot find pg_dump." if cmd.blank?
51
+ cmd
52
+ end
53
+
38
54
  def pipe
39
55
  file_path =~ /\.gz$/ ? "gzip -9f" : "cat"
40
56
  end
data/lib/backhoe/load.rb CHANGED
@@ -5,12 +5,19 @@ module Backhoe
5
5
  include Rake::DSL
6
6
 
7
7
  def call
8
- sh command
8
+ case database.adapter
9
+ when "mysql2"
10
+ sh mysql_command
11
+ when "postgresql"
12
+ sh psql_command
13
+ else
14
+ raise "don't know how to load #{database.adapter}"
15
+ end
9
16
  end
10
17
 
11
18
  private
12
19
 
13
- def command
20
+ def mysql_command
14
21
  cmd = "#{cat} #{file_path} | "
15
22
  cmd += if drop_and_create
16
23
  "#{pipe} | #{mysql} #{database.to_mysql_options}"
@@ -19,6 +26,15 @@ module Backhoe
19
26
  end
20
27
  end
21
28
 
29
+ def psql_command
30
+ cmd = "#{cat} #{file_path} | "
31
+ if drop_and_create
32
+ cmd = "dropdb -f #{database.name}; createdb #{database.name}; #{cmd}"
33
+ end
34
+ cmd += "#{psql} -P pager=off -q -d#{database.name}"
35
+ cmd
36
+ end
37
+
22
38
  def cat
23
39
  file_path =~ /\.gz$/ ? "zcat" : "cat"
24
40
  end
@@ -40,6 +56,12 @@ module Backhoe
40
56
  raise RuntimeError, "Cannot find mysql." if cmd.blank?
41
57
  cmd
42
58
  end
59
+
60
+ def psql
61
+ cmd = `which psql`.strip
62
+ raise RuntimeError, "Cannot find psql." if cmd.blank?
63
+ cmd
64
+ end
43
65
  end
44
66
  end
45
67
 
@@ -1,3 +1,3 @@
1
1
  module Backhoe
2
- VERSION = "0.6.1"
2
+ VERSION = "0.8.0"
3
3
  end
data/lib/backhoe.rb CHANGED
@@ -15,7 +15,7 @@ module Backhoe
15
15
  Load.new(Database.new, file_path, drop_and_create).call
16
16
  end
17
17
 
18
- def backup s3_path, access_key: nil, secret_key: nil
18
+ def backup s3_path, access_key:, secret_key:
19
19
  Backup.new(s3_path, access_key, secret_key).call
20
20
  end
21
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backhoe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micah Geisel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-09 00:00:00.000000000 Z
11
+ date: 2024-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pg
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: byebug
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -130,6 +144,7 @@ files:
130
144
  - gemfiles/activerecord_6.0.gemfile
131
145
  - gemfiles/activerecord_6.1.gemfile
132
146
  - gemfiles/activerecord_7.0.gemfile
147
+ - gemfiles/activerecord_7.1.gemfile
133
148
  - lib/backhoe.rb
134
149
  - lib/backhoe/backup.rb
135
150
  - lib/backhoe/database.rb
@@ -155,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
170
  - !ruby/object:Gem::Version
156
171
  version: '0'
157
172
  requirements: []
158
- rubygems_version: 3.3.26
173
+ rubygems_version: 3.5.1
159
174
  signing_key:
160
175
  specification_version: 4
161
176
  summary: Dump and load current database to and from a file.