static_db 0.1.1 → 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 +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +30 -12
- data/Rakefile +1 -1
- data/lib/static_db/dump.rb +44 -56
- data/lib/static_db/engine.rb +18 -5
- data/lib/static_db/load.rb +21 -16
- data/lib/static_db/tasks/static.rake +10 -10
- data/lib/static_db/version.rb +1 -1
- metadata +1 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d592e282b1c5d72ea6a18964d5e9ac5e98fa8c42f9c417c11ea21454a8e6273
|
|
4
|
+
data.tar.gz: 136cb048f205ffb2bb54334ba3f95bc099fbbb17712a2afe9aea1487b565250b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 54feb805dff8f4e80228178f3c6d1180fa5d8be3ff23297824d711dc58656834fe68fc54fb9e1fff38a9b78db4e56ed8bc732e45c6b8c0dc4b009a3fdb7ef5ca
|
|
7
|
+
data.tar.gz: 455ce380cc64e703dfd1058742eb26c6568f0497e7c307dbff16a7cb803904b410cca2e104fe39021876ceee75631fe7b2a5c50c0d898dfc25d864b80d307ea0
|
data/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,30 @@ This project adheres to [Break Versioning](https://www.taoensso.com/break-versio
|
|
|
12
12
|
|
|
13
13
|
-
|
|
14
14
|
|
|
15
|
+
## [0.2.1] - 2026-05-08
|
|
16
|
+
|
|
17
|
+
### Breaking
|
|
18
|
+
|
|
19
|
+
-
|
|
20
|
+
|
|
21
|
+
### Non-breaking
|
|
22
|
+
|
|
23
|
+
- Drop post-install message
|
|
24
|
+
|
|
25
|
+
## [0.2.0] - 2026-05-08
|
|
26
|
+
|
|
27
|
+
### Breaking
|
|
28
|
+
|
|
29
|
+
- Config option `fixture_path` was renamed to `static_db_path`.
|
|
30
|
+
- The Rails boot sequence hooks are no longer active automatically. You need to opt-in via the config options `load` and `dump`.
|
|
31
|
+
- The Rails boot sequence hooks no longer run for any `* build` command. They only run for `parklife build`.
|
|
32
|
+
|
|
33
|
+
### Non-breaking
|
|
34
|
+
|
|
35
|
+
- All config options now support Procs or any other object responding to `.call()`.
|
|
36
|
+
- The default Proc for config option `static_db_path` now gets evaluated correctly.
|
|
37
|
+
- Internal code cleanup
|
|
38
|
+
|
|
15
39
|
## [0.1.1] - 2026-05-03
|
|
16
40
|
|
|
17
41
|
### Breaking
|
data/README.md
CHANGED
|
@@ -3,11 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
# static_db
|
|
5
5
|
|
|
6
|
-
Dump DB contents to YAML and load them back again.
|
|
6
|
+
Dump DB contents to YAML and load them back again.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This gem provides:
|
|
9
|
+
- Methods: `StaticDb::Load.new.perform` and `StaticDb::Dump.new.perform`
|
|
10
|
+
- Rake tasks: `static:load` and `static:dump` (available automatically in Rails projects)
|
|
11
|
+
- Hooks for the Rails boot sequence: off by default, but the main purpose of this gem. See configuration below.
|
|
12
|
+
|
|
13
|
+
> ℹ️ The original main use case for this gem are static site generators built on top of Ruby on Rails.
|
|
14
|
+
> However, the DB (de)serialization functionality is useful enough on its own, so the decision was made
|
|
15
|
+
> to disable any behavior by default, which could result in data loss for regular Rails applications.
|
|
16
|
+
> You can opt into the Rails boot sequence hooks via config.
|
|
9
17
|
|
|
10
|
-
|
|
18
|
+
## Installation
|
|
11
19
|
|
|
12
20
|
Add it to your Rails project:
|
|
13
21
|
|
|
@@ -16,26 +24,36 @@ Add it to your Rails project:
|
|
|
16
24
|
gem "static_db"
|
|
17
25
|
```
|
|
18
26
|
|
|
27
|
+
This example initializer shows a flexible way how to opt into the Rails boot sequency hooks:
|
|
28
|
+
|
|
19
29
|
```ruby
|
|
20
30
|
# config/initializer/static_db.rb
|
|
21
31
|
StaticDb.configure do |config|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
config.static_db_path = Rails.root.join("content", "data")
|
|
33
|
+
|
|
34
|
+
# Selectively activate loading and dumping. Active by default. Set to any other value to disable.
|
|
35
|
+
config.load = ENV["STATIC_DB"].in? [ "load", nil, "on", "true", "1" ]
|
|
36
|
+
config.dump = ENV["STATIC_DB"].in? [ "dump", nil, "on", "true", "1" ]
|
|
25
37
|
end
|
|
26
38
|
```
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
Now, starting your Rails server will reset your DB and load YAML fixtures from `content/data`. Exiting the server with `Ctrl+C` will dump out your DB as YAML fixtures to that directory.
|
|
29
41
|
|
|
30
|
-
|
|
42
|
+
All config options support procs.
|
|
31
43
|
|
|
32
|
-
|
|
44
|
+
## Hook activation
|
|
33
45
|
|
|
34
|
-
|
|
46
|
+
The boot sequence hooks are active in the following scenarios:
|
|
47
|
+
- When you run any server command: `bin/rails s`
|
|
48
|
+
- When you run any console command: `bin/rails c`
|
|
49
|
+
- When you run `parklife build`
|
|
35
50
|
|
|
36
|
-
|
|
51
|
+
> ℹ️ If you already have your dev server running and want to start an additional console, avoid conflicts by using `STATIC_DB=0 bin/rails c` (with the example initializer from above).
|
|
37
52
|
|
|
38
|
-
|
|
53
|
+
The boot sequence hooks are inactive in all other cases, e.g.:
|
|
54
|
+
- When you run tests: `bin/rails t` or `bin/rails test:system`
|
|
55
|
+
- When you run migrations: `bin/rails db:migrate`
|
|
56
|
+
- When you run any other rake tasks
|
|
39
57
|
|
|
40
58
|
## Contributing
|
|
41
59
|
|
data/Rakefile
CHANGED
data/lib/static_db/dump.rb
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
module StaticDb
|
|
2
2
|
class Dump
|
|
3
|
+
attr_reader :models_to_be_saved
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def initialize(fixture_path: StaticDb.config.fixture_path)
|
|
7
|
-
@fixture_path = Pathname.new(fixture_path)
|
|
5
|
+
def initialize(static_db_path: StaticDb.path)
|
|
6
|
+
@static_db_path = Pathname.new(static_db_path)
|
|
8
7
|
@models_to_be_saved = models
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
def perform
|
|
12
|
-
exit 1 if $
|
|
11
|
+
exit 1 if $skip_static_db_dump
|
|
13
12
|
|
|
14
13
|
validate_records!
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
dump_fixtures!
|
|
18
|
-
puts green("Done!")
|
|
14
|
+
reset_data_directory!
|
|
15
|
+
dump_data!
|
|
19
16
|
end
|
|
20
17
|
|
|
21
18
|
private
|
|
@@ -27,84 +24,76 @@ module StaticDb
|
|
|
27
24
|
|
|
28
25
|
models_to_be_saved.each do |model|
|
|
29
26
|
model.find_each do |record|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
next if record.valid?
|
|
28
|
+
|
|
29
|
+
debug_data = { model: model.name, id: record.id, errors: record.errors.full_messages }
|
|
30
|
+
debug_data[:slug] = record.slug if record.respond_to?(:slug)
|
|
31
|
+
|
|
32
|
+
errors << debug_data
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
if errors.any?
|
|
37
37
|
puts red("Found #{errors.length} invalid records!")
|
|
38
38
|
errors.each do |error|
|
|
39
|
-
puts "- #{error[:model]} #{error[:slug]}: #{error[:errors].join(", ")}"
|
|
39
|
+
puts "- #{error[:model]} #{error[:slug] || error[:id]}: #{error[:errors].join(", ")}"
|
|
40
40
|
end
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
if StaticDb.parklife?
|
|
42
43
|
puts red("Build failed!")
|
|
43
44
|
exit 1
|
|
44
45
|
else
|
|
45
|
-
puts red("
|
|
46
|
+
puts red("PROCEEDING TO DUMP DATA DESPITE VALIDATION ERRORS!!!")
|
|
47
|
+
puts
|
|
48
|
+
puts red("Set `config.load = false` to preserve the invalid data in your DB when restarting. Then you can fix the validation errors and retry dumping.")
|
|
46
49
|
end
|
|
47
50
|
else
|
|
48
51
|
puts green("Done!")
|
|
49
52
|
end
|
|
50
53
|
end
|
|
51
54
|
|
|
52
|
-
def dump_fixtures!
|
|
53
|
-
reset_data_directory!
|
|
54
|
-
models_to_be_saved.each { |model| format_and_write_yaml_file!(model) }
|
|
55
|
-
end
|
|
56
|
-
|
|
57
55
|
def reset_data_directory!
|
|
58
|
-
FileUtils.rm_rf(
|
|
59
|
-
FileUtils.mkdir_p(
|
|
56
|
+
FileUtils.rm_rf(@static_db_path)
|
|
57
|
+
FileUtils.mkdir_p(@static_db_path)
|
|
60
58
|
end
|
|
61
59
|
|
|
62
|
-
def
|
|
63
|
-
|
|
64
|
-
output = format_instances(model: model, instances: instances)
|
|
65
|
-
write_yaml_file!(model: model, data: output)
|
|
66
|
-
end
|
|
60
|
+
def dump_data!
|
|
61
|
+
puts green("Dumping data ...")
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
model.unscoped.all.order('id ASC')
|
|
70
|
-
end
|
|
63
|
+
models_to_be_saved.each { |model| write_file!(path: file_path(model), data: data(model)) }
|
|
71
64
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
output = {}
|
|
65
|
+
puts green("Done!")
|
|
66
|
+
end
|
|
75
67
|
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
def write_file!(path:, data:)
|
|
69
|
+
File.open(path, "w") { |file| file << data.to_yaml }
|
|
70
|
+
end
|
|
78
71
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
end
|
|
72
|
+
def file_path(model)
|
|
73
|
+
File.join(@static_db_path, "#{model.table_name}.yml")
|
|
74
|
+
end
|
|
83
75
|
|
|
84
|
-
|
|
76
|
+
def data(model)
|
|
77
|
+
model.unscoped.order(:id).to_h do |instance|
|
|
78
|
+
[ "#{model}_#{instance.id}", instance_data(instance, model.columns) ]
|
|
85
79
|
end
|
|
86
|
-
|
|
87
|
-
output
|
|
88
80
|
end
|
|
89
81
|
|
|
90
|
-
def
|
|
91
|
-
|
|
82
|
+
def instance_data(instance, columns)
|
|
83
|
+
columns.filter_map do |column|
|
|
84
|
+
value = instance.read_attribute_before_type_cast(column.name)
|
|
85
|
+
next if value.nil?
|
|
86
|
+
|
|
87
|
+
[ column.name, value ]
|
|
88
|
+
end.to_h
|
|
92
89
|
end
|
|
93
90
|
|
|
94
91
|
def models
|
|
95
92
|
Rails.application.eager_load!
|
|
96
|
-
models = ActiveRecord::Base.descendants
|
|
97
|
-
models.select! { |model| model.table_exists? && model.any? }
|
|
98
|
-
models.delete(ActiveRecord::SchemaMigration)
|
|
99
|
-
models
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def yaml_file_path(model)
|
|
103
|
-
File.join(fixture_path, generate_file_name(model) + '.yml')
|
|
104
|
-
end
|
|
105
93
|
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
ActiveRecord::Base.descendants.select do |model|
|
|
95
|
+
model.table_exists? && model.any? && model != ActiveRecord::SchemaMigration
|
|
96
|
+
end
|
|
108
97
|
end
|
|
109
98
|
|
|
110
99
|
def green(text)
|
|
@@ -114,6 +103,5 @@ module StaticDb
|
|
|
114
103
|
def red(text)
|
|
115
104
|
"\e[31m#{text}\e[0m"
|
|
116
105
|
end
|
|
117
|
-
|
|
118
106
|
end
|
|
119
107
|
end
|
data/lib/static_db/engine.rb
CHANGED
|
@@ -11,7 +11,21 @@ module StaticDb # :nodoc:
|
|
|
11
11
|
# - regular initializers from `config/initializers/`
|
|
12
12
|
include StaticDb::Configurable
|
|
13
13
|
|
|
14
|
-
config_accessor :
|
|
14
|
+
config_accessor :static_db_path, instance_accessor: false, default: -> { Rails.root.join("content", "data") }
|
|
15
|
+
config_accessor :load, instance_accessor: false, default: false
|
|
16
|
+
config_accessor :dump, instance_accessor: false, default: false
|
|
17
|
+
|
|
18
|
+
def self.unproc(value_or_proc)
|
|
19
|
+
value_or_proc.respond_to?(:call) ? value_or_proc.call : value_or_proc
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.path = unproc(config.static_db_path)
|
|
23
|
+
def self.load? = unproc(config.load)
|
|
24
|
+
def self.dump? = unproc(config.dump)
|
|
25
|
+
|
|
26
|
+
def self.parklife?
|
|
27
|
+
File.basename($PROGRAM_NAME) == "parklife" && ARGV.first == "build"
|
|
28
|
+
end
|
|
15
29
|
|
|
16
30
|
class Engine < ::Rails::Engine # :nodoc:
|
|
17
31
|
isolate_namespace StaticDb
|
|
@@ -21,16 +35,15 @@ module StaticDb # :nodoc:
|
|
|
21
35
|
end
|
|
22
36
|
|
|
23
37
|
initializer "static_db.configure" do |app|
|
|
24
|
-
if defined?(Rails::Server) || defined?(Rails::Console) ||
|
|
38
|
+
if defined?(Rails::Server) || defined?(Rails::Console) || StaticDb.parklife?
|
|
25
39
|
Rails.application.config.after_initialize do
|
|
26
|
-
StaticDb::Load.new.perform
|
|
40
|
+
StaticDb::Load.new.perform if StaticDb.load?
|
|
27
41
|
end
|
|
28
42
|
|
|
29
43
|
at_exit do
|
|
30
|
-
StaticDb::Dump.new.perform
|
|
44
|
+
StaticDb::Dump.new.perform if StaticDb.dump?
|
|
31
45
|
end
|
|
32
46
|
end
|
|
33
47
|
end
|
|
34
|
-
|
|
35
48
|
end
|
|
36
49
|
end
|
data/lib/static_db/load.rb
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
1
|
module StaticDb
|
|
2
2
|
class Load
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def initialize(fixture_path: StaticDb.config.fixture_path)
|
|
7
|
-
@fixture_path = Pathname.new(fixture_path)
|
|
3
|
+
def initialize(static_db_path: StaticDb.path)
|
|
4
|
+
@static_db_path = Pathname.new(static_db_path)
|
|
8
5
|
end
|
|
9
6
|
|
|
10
7
|
def perform
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
load_fixtures!
|
|
14
|
-
puts green("Done!")
|
|
8
|
+
reset_database!
|
|
9
|
+
load_data!
|
|
15
10
|
rescue => e
|
|
16
|
-
puts red("Failed to load
|
|
17
|
-
puts red("Exiting and skipping
|
|
18
|
-
$
|
|
11
|
+
puts red("Failed to load data: #{e.message}")
|
|
12
|
+
puts red("Exiting and skipping StaticDb::Dump.")
|
|
13
|
+
$skip_static_db_dump = true
|
|
19
14
|
exit 1
|
|
20
15
|
end
|
|
21
16
|
|
|
22
17
|
private
|
|
23
18
|
|
|
24
|
-
def
|
|
25
|
-
|
|
19
|
+
def reset_database!
|
|
20
|
+
puts green("Resetting database ...")
|
|
21
|
+
|
|
22
|
+
system("bin/rails", "db:drop", "db:create", "db:schema:load")
|
|
23
|
+
|
|
24
|
+
puts green("Done!")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load_data!
|
|
28
|
+
puts green("Loading data ...")
|
|
29
|
+
|
|
30
|
+
base_names = Dir.glob(File.join(@static_db_path, "*.yml")).map do |file|
|
|
26
31
|
File.basename(file, ".*")
|
|
27
32
|
end
|
|
33
|
+
ActiveRecord::FixtureSet.create_fixtures(@static_db_path, base_names)
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
puts green("Done!")
|
|
30
36
|
end
|
|
31
37
|
|
|
32
38
|
def green(text)
|
|
@@ -36,6 +42,5 @@ module StaticDb
|
|
|
36
42
|
def red(text)
|
|
37
43
|
"\e[31m#{text}\e[0m"
|
|
38
44
|
end
|
|
39
|
-
|
|
40
45
|
end
|
|
41
46
|
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
namespace :static do
|
|
2
|
-
desc "
|
|
3
|
-
task :
|
|
4
|
-
if args[:
|
|
5
|
-
StaticDb::
|
|
2
|
+
desc "Reset database and load YAML fixtures"
|
|
3
|
+
task :load, [ :static_db_path ] => :environment do |t, args|
|
|
4
|
+
if args[:static_db_path].blank?
|
|
5
|
+
StaticDb::Load.new.perform
|
|
6
6
|
else
|
|
7
|
-
StaticDb::
|
|
7
|
+
StaticDb::Load.new(static_db_path: Rails.root.join(args[:static_db_path])).perform
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
desc "
|
|
12
|
-
task :
|
|
13
|
-
if args[:
|
|
14
|
-
StaticDb::
|
|
11
|
+
desc "Dump database to YAML fixtures"
|
|
12
|
+
task :dump, [ :static_db_path ] => :environment do |t, args|
|
|
13
|
+
if args[:static_db_path].blank?
|
|
14
|
+
StaticDb::Dump.new.perform
|
|
15
15
|
else
|
|
16
|
-
StaticDb::
|
|
16
|
+
StaticDb::Dump.new(static_db_path: Rails.root.join(args[:static_db_path])).perform
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
data/lib/static_db/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: static_db
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Klaus Weidinger
|
|
@@ -52,9 +52,6 @@ metadata:
|
|
|
52
52
|
bug_tracker_uri: https://github.com/dunkelziffer/static_db/issues
|
|
53
53
|
documentation_uri: https://github.com/dunkelziffer/static_db/blob/main/README.md
|
|
54
54
|
rubygems_mfa_required: 'true'
|
|
55
|
-
post_install_message: "⚠️ This gem modifies the Rails startup sequence. Don't use
|
|
56
|
-
this gem unless you want to build a static site generator. This gem also creates
|
|
57
|
-
and drops the DB for you."
|
|
58
55
|
rdoc_options: []
|
|
59
56
|
require_paths:
|
|
60
57
|
- lib
|