solid_backup 0.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE.txt +20 -0
- data/README.md +87 -0
- data/lib/puma/plugin/solid_backup.rb +15 -0
- data/lib/solid_backup/backup/api.rb +38 -0
- data/lib/solid_backup/backup/none.rb +25 -0
- data/lib/solid_backup/backup/vacuum_into.rb +9 -0
- data/lib/solid_backup/backup.rb +101 -0
- data/lib/solid_backup/configuration.rb +50 -0
- data/lib/solid_backup/generators/install_generator.rb +54 -0
- data/lib/solid_backup/railtie.rb +13 -0
- data/lib/solid_backup/version.rb +3 -0
- data/lib/solid_backup.rb +28 -0
- metadata +139 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ee957011ccc278fb06096635c8b158939f283538bb5ccc25869ba07d3bb7bb5a
|
|
4
|
+
data.tar.gz: ea9cdbdbd9e9ae3ae0fdb4b252b9db1c412e80d3288258c8ccf4062e59a70b66
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: '0802038b0aeac7c0b0bebbf1b8b6d68054b52621ef1c50c9c21f1a640866fb2f1e51ee9a3d98bc6fef80a5b63ab85c4ed9cec500e7ba86ddc24bf45fe65d3c33'
|
|
7
|
+
data.tar.gz: 82bec8bad5efe105b5ad7247b6f0754fda99381baafdcaff36704c249a36996c86bf0d1e65e1d4cd81a896a03513cc631a0c4540dc6b501115b5b3134f0936c5
|
data/MIT-LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2026 Greg Navis
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Solid Backup
|
|
2
|
+
|
|
3
|
+
Solid Backup provides simple backups for SQLite databases in Ruby on Rails apps.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
In order to install Solid Backup run:
|
|
8
|
+
|
|
9
|
+
1. `bundle add solid_backup`.
|
|
10
|
+
2. `bin/rails generate solid_backup:install`.
|
|
11
|
+
|
|
12
|
+
The generator will go over all production SQLite databases and ask you whether
|
|
13
|
+
you want to back up each one of them. By default, it uses the `API` mode. It'll
|
|
14
|
+
also create `storage/backups` and install the Puma plugin.
|
|
15
|
+
|
|
16
|
+
That's it! Read the following section to learn how to customize the backup
|
|
17
|
+
process.
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
Solid Backup **REQUIRES** each SQLite production database to have a backup mode set,
|
|
22
|
+
with the goal of ensuring all databases were taken into consideration and none
|
|
23
|
+
will lack backups due to omission. There are three database backup modes:
|
|
24
|
+
|
|
25
|
+
- `SolidBackup::Backup::None` - don't back up.
|
|
26
|
+
- `SolidBackup::Backup::API` - use [the SQLite3 backup API].
|
|
27
|
+
- `SolidBackup::Backup::VacuumInto` - use [`VACUUM INTO`].
|
|
28
|
+
|
|
29
|
+
Modes other than `SolidBackup::Backup::None` take the following parameters:
|
|
30
|
+
|
|
31
|
+
- `destination` - a `strftime` template used to generate backup file names; the
|
|
32
|
+
directory under which the files are placed must already exist
|
|
33
|
+
and be writeable.
|
|
34
|
+
- `interval_in_minutes` - the number of minutes to the beginning of the next
|
|
35
|
+
backup after the previous one finished.
|
|
36
|
+
|
|
37
|
+
Additionally, `SolidBackup::Backup::API` takes the following parameters:
|
|
38
|
+
|
|
39
|
+
- `step` - the number of database pages to back up in one step.
|
|
40
|
+
- `wait` - how many seconds to wait in case the backup process run into a lock.
|
|
41
|
+
|
|
42
|
+
The following example configuration file demonstrates how to use each backup
|
|
43
|
+
mode in practice:
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
SolidBackup.configure do |config|
|
|
47
|
+
# Back up the primary database using the SQLite backup API.
|
|
48
|
+
config.backup "primary",
|
|
49
|
+
SolidBackup::Backup::API,
|
|
50
|
+
destination: "storage/backups/primary_%Y%m%dT%H%M%S.sqlite3",
|
|
51
|
+
interval_in_minutes: 15, # Start the next backup 15 minutes after the previous one.
|
|
52
|
+
step: 100, # Back up in 100-page increments.
|
|
53
|
+
wait: 0.1 # Wait 0.1 seconds if a lock interrupts a backup step.
|
|
54
|
+
|
|
55
|
+
# Don't back up the cache database.
|
|
56
|
+
config.backup "cache", SolidBackup::Backup::None
|
|
57
|
+
|
|
58
|
+
# Back up the queue database using VACUUM INTO.
|
|
59
|
+
config.backup "queue",
|
|
60
|
+
SolidBackup::Backup::VacuumInto,
|
|
61
|
+
destination: "storage/backups/queue_%Y%m%dT%H%M%S.sqlite3",
|
|
62
|
+
interval_in_minutes: 60 # Start the next backup 60 minutes after the previous one.
|
|
63
|
+
end
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Puma plugin
|
|
67
|
+
|
|
68
|
+
Solid Backup ships with a Puma plugin that runs the backup process in the
|
|
69
|
+
background on schedule. The install generator installs it automatically, but if
|
|
70
|
+
you need to install it manually you can add the following line to `puma.rb`:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
plugin "solid_backup"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Ruby and Rails Compatibility Policy
|
|
77
|
+
|
|
78
|
+
Solid Backup supports Rails versions supported by the Rails Core Team and Ruby
|
|
79
|
+
versions supported by all supported Rails versions.
|
|
80
|
+
|
|
81
|
+
## Author
|
|
82
|
+
|
|
83
|
+
This gem was created and is maintained by [Greg Navis].
|
|
84
|
+
|
|
85
|
+
[Greg Navis]: https://www.gregnavis.com/
|
|
86
|
+
[the SQLite3 backup API]: https://sqlite.org/c3ref/backup_finish.html
|
|
87
|
+
[`VACUUM INTO`]: https://sqlite.org/lang_vacuum.html#vacuuminto
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class SolidBackup::Backup::API < SolidBackup::Backup
|
|
2
|
+
def initialize(step:, wait:, **)
|
|
3
|
+
super(**)
|
|
4
|
+
|
|
5
|
+
self.step = Integer(step)
|
|
6
|
+
self.wait = Float(wait)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
attr_accessor :step, :wait
|
|
12
|
+
|
|
13
|
+
def do_perform(backup_path)
|
|
14
|
+
with_connection do |connection|
|
|
15
|
+
source = connection.raw_connection
|
|
16
|
+
destination = SQLite3::Database.new(backup_path)
|
|
17
|
+
|
|
18
|
+
backup = SQLite3::Backup.new(destination, "main", source, "main")
|
|
19
|
+
|
|
20
|
+
loop do
|
|
21
|
+
result = backup.step(step)
|
|
22
|
+
case result
|
|
23
|
+
when SQLite3::Constants::ErrorCode::DONE
|
|
24
|
+
break
|
|
25
|
+
when SQLite3::Constants::ErrorCode::OK
|
|
26
|
+
next
|
|
27
|
+
when SQLite3::Constants::ErrorCode::BUSY, SQLite3::Constants::ErrorCode::LOCKED
|
|
28
|
+
sleep(wait)
|
|
29
|
+
else
|
|
30
|
+
raise "SQLite backup failed with #{result.inspect}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
backup.finish
|
|
35
|
+
destination.close
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# None is a special case: all other backup methods need a destination and
|
|
2
|
+
# interval, but it doesn't make sense to pass them to None. That's why it
|
|
3
|
+
# overrides:
|
|
4
|
+
#
|
|
5
|
+
# - tick - to avoid the countdown
|
|
6
|
+
# - perform - to avoid creating lock files and emitting instrumentation events
|
|
7
|
+
# - destination and interval_in_minutes - to allow nil values
|
|
8
|
+
class SolidBackup::Backup::None < SolidBackup::Backup
|
|
9
|
+
def initialize(name:)
|
|
10
|
+
super(name:, destination: nil, interval_in_minutes: 0)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def tick
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def perform
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
attr_writer :destination, :interval_in_minutes
|
|
22
|
+
|
|
23
|
+
def do_perform(backup_path)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module SolidBackup
|
|
2
|
+
class Backup
|
|
3
|
+
attr_reader :name
|
|
4
|
+
|
|
5
|
+
def initialize(name:, destination:, interval_in_minutes:)
|
|
6
|
+
self.name = name
|
|
7
|
+
self.destination = destination
|
|
8
|
+
self.interval_in_minutes = interval_in_minutes
|
|
9
|
+
|
|
10
|
+
reset_countdown
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def tick
|
|
14
|
+
if countdown > 0
|
|
15
|
+
self.countdown -= 1
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if countdown <= 0
|
|
19
|
+
perform
|
|
20
|
+
reset_countdown
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def perform
|
|
25
|
+
ActiveSupport::Notifications.instrument("backup.solid_backup", name:) do
|
|
26
|
+
lock do
|
|
27
|
+
do_perform(Time.now.utc.strftime(destination.to_s))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
attr_accessor :countdown
|
|
35
|
+
attr_writer :name
|
|
36
|
+
attr_reader :destination, :interval_in_minutes
|
|
37
|
+
|
|
38
|
+
def interval_in_minutes=(value)
|
|
39
|
+
if !value.is_a?(Integer) && value <= 0
|
|
40
|
+
raise TypeError.new(<<~ERROR)
|
|
41
|
+
invalid backup configuration for #{name}: interval_in_minutes is set to #{interval_in_minutes.inspect}, but should be set to a positive integer
|
|
42
|
+
ERROR
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
@interval_in_minutes = value
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def destination=(value)
|
|
49
|
+
value = Pathname(value)
|
|
50
|
+
directory = value.dirname
|
|
51
|
+
|
|
52
|
+
if !directory.directory?
|
|
53
|
+
raise "invalid backup configuration for #{name}: destination directory #{directory} must exist"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test_path = directory / "solid_backup.txt"
|
|
57
|
+
begin
|
|
58
|
+
test_path.write("Solid Backup Test")
|
|
59
|
+
rescue Errno::EACCESS
|
|
60
|
+
raise "invalid backup configuration for #{name}: destination directory #{directory} must be writeable"
|
|
61
|
+
ensure
|
|
62
|
+
test_path.unlink
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@destination = value
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def reset_countdown
|
|
69
|
+
self.countdown = 60 * interval_in_minutes
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def do_perform(backup_path)
|
|
73
|
+
raise "must be implemented by a subclass"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def connection_pool
|
|
77
|
+
ActiveRecord::Base.connection_handler.establish_connection(name.to_sym)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
delegate :with_connection, to: :connection_pool
|
|
81
|
+
|
|
82
|
+
def lock
|
|
83
|
+
path = destination.dirname / ".solid_backup.#{name}.lock"
|
|
84
|
+
|
|
85
|
+
File.open(path, File::RDWR | File::CREAT) do |f|
|
|
86
|
+
if f.flock(File::LOCK_EX | File::LOCK_NB)
|
|
87
|
+
begin
|
|
88
|
+
yield
|
|
89
|
+
ensure
|
|
90
|
+
f.flock(File::LOCK_UN)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
begin
|
|
96
|
+
File.unlink(path)
|
|
97
|
+
rescue ERRNO::ENOENT
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module SolidBackup
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_accessor :enabled
|
|
4
|
+
attr_reader :algorithms
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
self.enabled = nil
|
|
8
|
+
self.algorithms = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def backup(name, algorithm_class, **algorithm_arguments)
|
|
12
|
+
name = name.to_s
|
|
13
|
+
if algorithms.find { it.name == name }
|
|
14
|
+
raise ArgumentError.new("#{name} has had backups configured already")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
algorithms << algorithm_class.new(name:, **algorithm_arguments)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def validate!
|
|
21
|
+
if [true, false].exclude?(enabled)
|
|
22
|
+
raise TypeError.new("enabled is set to #{enabled.inspect}, but allowed values are true or false")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
configured_database_names = algorithms.map(&:name)
|
|
26
|
+
all_database_names = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).select do |db_config|
|
|
27
|
+
db_config.adapter == "sqlite3"
|
|
28
|
+
end.map(&:name)
|
|
29
|
+
|
|
30
|
+
if (missing_databases = all_database_names - configured_database_names).present?
|
|
31
|
+
raise "SQLite databases missing from backup configuration: #{missing_databases.join(", ")}"
|
|
32
|
+
end
|
|
33
|
+
if (unknown_databases = configured_database_names - all_database_names).present?
|
|
34
|
+
raise "unknown SQLite databases present in backup configuration: #{unknown_databases.join(", ")}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def enabled?
|
|
39
|
+
enabled
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def disabled?
|
|
43
|
+
!enabled?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
attr_writer :algorithms
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module SolidBackup
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
desc "Creates a Solid Backup initializer"
|
|
9
|
+
|
|
10
|
+
def copy_initializer
|
|
11
|
+
backups = []
|
|
12
|
+
|
|
13
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "production").each do |db_config|
|
|
14
|
+
backups << if yes?("Back up #{db_config.name} in production?")
|
|
15
|
+
<<~CODE.chomp
|
|
16
|
+
config.backup #{db_config.name.inspect},
|
|
17
|
+
SolidBackup::Backup::API,
|
|
18
|
+
destination: "storage/backups/#{db_config.name}_%Y%m%dT%H%M%S.sqlite3",
|
|
19
|
+
interval_in_minutes: 60,
|
|
20
|
+
step: 100,
|
|
21
|
+
wait: 0.1
|
|
22
|
+
CODE
|
|
23
|
+
else
|
|
24
|
+
"config.backup #{db_config.name.inspect}, SolidBackup::Backup::None"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
initializer "solid_backup.rb", <<~CODE
|
|
29
|
+
SolidBackup.configure do |config|
|
|
30
|
+
# Enable or disable Solid Backup globally.
|
|
31
|
+
config.enabled = Rails.env.production?
|
|
32
|
+
|
|
33
|
+
# Backup configuration for each database.
|
|
34
|
+
#
|
|
35
|
+
# IMPORTANT: all databases must be explicitly configured, even if they're not
|
|
36
|
+
# backed up, to avoid accidentally excluding new databases from backups.
|
|
37
|
+
#{backups.join("\n").indent(2)}
|
|
38
|
+
end
|
|
39
|
+
CODE
|
|
40
|
+
|
|
41
|
+
insert_into_file "config/puma.rb", <<~CODE
|
|
42
|
+
|
|
43
|
+
# Run Solid Backup in the background.
|
|
44
|
+
plugin :solid_backup
|
|
45
|
+
CODE
|
|
46
|
+
|
|
47
|
+
empty_directory "storage/backups"
|
|
48
|
+
create_file "storage/backups/.keep"
|
|
49
|
+
|
|
50
|
+
insert_into_file ".gitignore", "!/storage/backups/.keep\n", after: "!/storage/.keep\n"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/solid_backup.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "solid_backup/backup"
|
|
2
|
+
require "solid_backup/backup/none"
|
|
3
|
+
require "solid_backup/backup/api"
|
|
4
|
+
require "solid_backup/backup/vacuum_into"
|
|
5
|
+
require "solid_backup/configuration"
|
|
6
|
+
require "solid_backup/version"
|
|
7
|
+
require "solid_backup/railtie"
|
|
8
|
+
|
|
9
|
+
module SolidBackup
|
|
10
|
+
class << self
|
|
11
|
+
delegate :enabled?, :disabled?, to: :configuration
|
|
12
|
+
|
|
13
|
+
attr_reader :configuration
|
|
14
|
+
|
|
15
|
+
def configure
|
|
16
|
+
self.configuration ||= Configuration.new
|
|
17
|
+
yield(configuration)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def tick
|
|
21
|
+
configuration.algorithms.each(&:tick)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
attr_writer :configuration
|
|
27
|
+
end
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: solid_backup
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Greg Navis
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activerecord
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.2'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '8.2'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.2'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '8.2'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: railties
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '7.2'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '8.2'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '7.2'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '8.2'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: sqlite3
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '1.4'
|
|
59
|
+
type: :runtime
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '1.4'
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: rake
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - "~>"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '13.4'
|
|
73
|
+
type: :development
|
|
74
|
+
prerelease: false
|
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - "~>"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '13.4'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: standard
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - "~>"
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '1.56'
|
|
87
|
+
type: :development
|
|
88
|
+
prerelease: false
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - "~>"
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '1.56'
|
|
94
|
+
description: Solid Backup makes it easy to backup SQLite databases using VACUUM INTO
|
|
95
|
+
or the backup API.
|
|
96
|
+
email:
|
|
97
|
+
- contact@gregnavis.com
|
|
98
|
+
executables: []
|
|
99
|
+
extensions: []
|
|
100
|
+
extra_rdoc_files: []
|
|
101
|
+
files:
|
|
102
|
+
- MIT-LICENSE.txt
|
|
103
|
+
- README.md
|
|
104
|
+
- lib/puma/plugin/solid_backup.rb
|
|
105
|
+
- lib/solid_backup.rb
|
|
106
|
+
- lib/solid_backup/backup.rb
|
|
107
|
+
- lib/solid_backup/backup/api.rb
|
|
108
|
+
- lib/solid_backup/backup/none.rb
|
|
109
|
+
- lib/solid_backup/backup/vacuum_into.rb
|
|
110
|
+
- lib/solid_backup/configuration.rb
|
|
111
|
+
- lib/solid_backup/generators/install_generator.rb
|
|
112
|
+
- lib/solid_backup/railtie.rb
|
|
113
|
+
- lib/solid_backup/version.rb
|
|
114
|
+
homepage: https://github.com/gregnavis/solid_backup
|
|
115
|
+
licenses:
|
|
116
|
+
- MIT
|
|
117
|
+
metadata:
|
|
118
|
+
source_code_uri: https://github.com/gregnavis/solid_backup
|
|
119
|
+
bug_tracker_uri: https://github.com/gregnavis/solid_backup/issues
|
|
120
|
+
rubygems_mfa_required: 'true'
|
|
121
|
+
rdoc_options: []
|
|
122
|
+
require_paths:
|
|
123
|
+
- lib
|
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - ">="
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: 3.1.0
|
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
|
+
requirements:
|
|
131
|
+
- - ">="
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: '0'
|
|
134
|
+
requirements: []
|
|
135
|
+
rubygems_version: 4.0.10
|
|
136
|
+
specification_version: 4
|
|
137
|
+
summary: Solid Backup provides simple backups for SQLite databases in Ruby on Rails
|
|
138
|
+
apps.
|
|
139
|
+
test_files: []
|