static_db 0.0.1 → 0.0.3

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: bd3f2f094d3c3ab0c462e0eba2798ec64c381df7383334adf8af3bdad6ba471c
4
- data.tar.gz: 9adfc8dc949619e3cad19f68c8e566fc79ac31ee0cbbecdb0d1c95373d59e832
3
+ metadata.gz: 57ead27ee0cc81c76fcb1f83c2b279819f3680895a59ab3e4dfcb80e26dad472
4
+ data.tar.gz: ac0d29ebfcc4a433f47b3e7e636e239937e2b41ecd905aabc280d045dd173ab8
5
5
  SHA512:
6
- metadata.gz: 53ebfcd55d3e094489d6e662aa38b2735c2832dda24dce4fb45e3ccc4e243193628a873647b93dce524a712a50819d7b358471f5aaca95bea4b61159941273cc
7
- data.tar.gz: be1ebfc35a13130da12a498418667cf964d8bde2d6758ff476d10132867121aea0635c3ff191955ecdd334b447f0780425358178149baf840c0f7ac4d8eccb64
6
+ metadata.gz: b070a834bc54a708fa340a65645160d36612774eabbd712893e9875e2e45e7ade87e40632f51f5e9eb489dc6b4cf8230b85a1f43ad0b46f05693de596db69cd6
7
+ data.tar.gz: 9dbb730c2a93af6ac1d8f70e0ea277ddb7394e4ccbdefe6f6a2278d3bbf4c877c2798e53f5a04dccede9a2ea941e0e109f2ccb32fbcaa953bbf28b6a02f49434
data/README.md CHANGED
@@ -4,36 +4,41 @@
4
4
 
5
5
  # static_db
6
6
 
7
- TBD
7
+ Dump DB contents to YAML and load them back again. Aimed at SQLite. Committable to git.
8
8
 
9
9
  ## Installation
10
10
 
11
- Adding to a gem:
11
+ WARNING: This gem modifies the Rails startup sequence. Don't use this gem unless you want to build a static site generator. This gem also creates and drops the DB for you.
12
12
 
13
- ```ruby
14
- # my-cool-gem.gemspec
15
- Gem::Specification.new do |spec|
16
- # ...
17
- spec.add_dependency "static_db"
18
- # ...
19
- end
20
- ```
21
-
22
- Or adding to your project:
13
+ Add it to your Rails project:
23
14
 
24
15
  ```ruby
25
16
  # Gemfile
26
17
  gem "static_db"
18
+
19
+ # config/initializer/static_db.rb
20
+ StaticDb.configure do |config|
21
+ # `content/data` is the default. You only need this initializer,
22
+ # if you want a custom path.
23
+ config.fixture_path = Rails.root.join("content", "data")
24
+ end
27
25
  ```
28
26
 
29
27
  ### Supported Ruby versions
30
28
 
31
- - Ruby (MRI) >= 2.7.0
32
- - JRuby >= 9.3.0
29
+ - Ruby (MRI) >= 3.2.0
33
30
 
34
31
  ## Usage
35
32
 
36
- TBD
33
+ Only use on Rails projects with SQLite. Have a valid `db/schema.rb`. For additional dramatic effect, do a `rails db:drop`.
34
+
35
+ Start your app with `bin/dev`. You will notice that a DB gets created for you. It will be empty.
36
+
37
+ Create some records. Then, stop your server with Ctrl+C.
38
+
39
+ The DB contents will have been dumped to `content/data`. Your SQLite DB will be gone.
40
+
41
+ Restart your server with `bin/dev`. Your SQLite DB will be back and populated with all previously stored data, recreated from `content/data`.
37
42
 
38
43
  ## Contributing
39
44
 
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StaticDb
4
+ class Dump
5
+
6
+ attr_reader :fixture_path, :models_to_be_saved
7
+
8
+ def initialize(fixture_path:)
9
+ @fixture_path = Pathname.new(fixture_path)
10
+ @models_to_be_saved = models
11
+ end
12
+
13
+ def perform
14
+ exit 1 if $skip_active_fixtures_dump
15
+
16
+ reenable_rake_tasks!
17
+ validate_records!
18
+
19
+ puts green("Dumping fixtures ...")
20
+
21
+ dump_fixtures!
22
+ Rake::Task["db:drop"].invoke
23
+
24
+ puts green("Done!")
25
+ end
26
+
27
+ private
28
+
29
+ def reenable_rake_tasks!
30
+ ["db:drop"].each do |task_name|
31
+ Rake::Task[task_name].reenable
32
+ end
33
+ end
34
+
35
+ def validate_records!
36
+ puts green("Validating records ...")
37
+
38
+ errors = []
39
+
40
+ models_to_be_saved.each do |model|
41
+ model.find_each do |record|
42
+ unless record.valid?
43
+ errors << { model: model.name, slug: record.slug, errors: record.errors.full_messages }
44
+ end
45
+ end
46
+ end
47
+
48
+ if errors.any?
49
+ puts red("Found #{errors.length} invalid records!")
50
+ errors.each do |error|
51
+ puts "- #{error[:model]} #{error[:slug]}: #{error[:errors].join(", ")}"
52
+ end
53
+ if ARGV.first == "build"
54
+ puts red("Build failed!")
55
+ exit 1
56
+ else
57
+ puts red("Please fix the invalid records before creating a PR!")
58
+ end
59
+ else
60
+ puts green("Done!")
61
+ end
62
+ end
63
+
64
+ def dump_fixtures!
65
+ reset_data_directory!
66
+ models_to_be_saved.each { |model| format_and_write_yaml_file!(model) }
67
+ end
68
+
69
+ def reset_data_directory!
70
+ FileUtils.rm_rf(fixture_path)
71
+ FileUtils.mkdir_p(fixture_path)
72
+ end
73
+
74
+ def format_and_write_yaml_file!(model)
75
+ instances = fetch_model_instances(model)
76
+ output = format_instances(model: model, instances: instances)
77
+ write_yaml_file!(model: model, data: output)
78
+ end
79
+
80
+ def fetch_model_instances(model)
81
+ model.unscoped.all.order('id ASC')
82
+ end
83
+
84
+ # TODO: check against old implementation!
85
+ def format_instances(model:, instances:)
86
+ output = {}
87
+
88
+ instances.each.with_index(1) do |instance, index|
89
+ attrs = {}
90
+
91
+ model.columns.each do |column|
92
+ value = instance.read_attribute_before_type_cast(column.name)
93
+ attrs[column.name] = value unless value.nil?
94
+ end
95
+
96
+ output["#{model}_#{index}"] = attrs
97
+ end
98
+
99
+ output
100
+ end
101
+
102
+ def write_yaml_file!(model:, data:)
103
+ File.open(yaml_file_path(model), 'w') { |file| file << data.to_yaml }
104
+ end
105
+
106
+ def models
107
+ Rails.application.eager_load!
108
+ models = ActiveRecord::Base.descendants
109
+ models.select! { |model| model.table_exists? && model.any? }
110
+ models.delete(ActiveRecord::SchemaMigration)
111
+ models
112
+ end
113
+
114
+ def yaml_file_path(model)
115
+ File.join(fixture_path, generate_file_name(model) + '.yml')
116
+ end
117
+
118
+ def generate_file_name(model)
119
+ model.table_name
120
+ end
121
+
122
+ def green(text)
123
+ "\e[32m#{text}\e[0m"
124
+ end
125
+
126
+ def red(text)
127
+ "\e[31m#{text}\e[0m"
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "static_db/initializer"
4
+
5
+ module StaticDb # :nodoc:
6
+ class Engine < ::Rails::Engine # :nodoc:
7
+ isolate_namespace StaticDb
8
+
9
+ rake_tasks do
10
+ load File.expand_path("./tasks/static.rake", __dir__)
11
+ end
12
+
13
+ initializer "static_db.configure" do |app|
14
+ if defined?(Rails::Server) || defined?(Rails::Console) || ARGV.first == "build"
15
+ Rails.application.config.after_initialize do
16
+ unless Object.const_defined?("Rake::Task") && Rake::Task.task_defined?("static:load")
17
+ Rails.application.load_tasks
18
+ end
19
+
20
+ Rake::Task["static:load"].invoke
21
+ end
22
+
23
+ at_exit do
24
+ unless Object.const_defined?("Rake::Task") && Rake::Task.task_defined?("static:dump")
25
+ Rails.application.load_tasks
26
+ end
27
+
28
+ Rake::Task["static:dump"].invoke
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ostruct"
4
+
5
+ module StaticDb
6
+ # Configuration and setup utility. The engine automatically requires this
7
+ # file during Rails initialization, so applications can simply call
8
+ # `StaticDb.configure` from **any** initializer (or even the engine's own
9
+ # initializer). It behaves exactly like an initializer placed in
10
+ # `config/initializers` of a Rails project.
11
+ #
12
+ # Example usage from a host application:
13
+ #
14
+ # # config/initializers/static_db.rb
15
+ # StaticDb.configure do |config|
16
+ # config.dump_path = Rails.root.join("content", "data")
17
+ # #
18
+ # # The rake tasks also accept an explicit path argument which is passed to
19
+ # # the `StaticDb::Dump`/`Load` constructors; the configuration value is
20
+ # # used when the argument is omitted.
21
+ # end
22
+ #
23
+ # The configuration object is a plain OpenStruct and may be extended by
24
+ # the application or other libraries.
25
+ def self.configure
26
+ @config ||= OpenStruct.new
27
+ yield @config if block_given?
28
+ @config.fixture_path ||= Rails.root.join("content", "data")
29
+ @config
30
+ end
31
+
32
+ def self.config
33
+ @config || configure
34
+ end
35
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StaticDb
4
+ class Load
5
+
6
+ attr_reader :fixture_path
7
+
8
+ def initialize(fixture_path:)
9
+ @fixture_path = Pathname.new(fixture_path)
10
+ end
11
+
12
+ def perform
13
+ puts green("Loading fixtures ...")
14
+
15
+ reenable_rake_tasks!
16
+ Rake::Task["db:create"].invoke
17
+ Rake::Task["db:schema:load"].invoke
18
+ load_fixtures!
19
+
20
+ puts green("Done!")
21
+ rescue => e
22
+ puts red("Failed to load fixtures: #{e.message}")
23
+ puts red("Exiting and skipping active_fixtures:dump!")
24
+ $skip_active_fixtures_dump = true
25
+ exit 1
26
+ end
27
+
28
+ private
29
+
30
+ def reenable_rake_tasks!
31
+ ["db:create", "db:schema:load"].each do |task_name|
32
+ Rake::Task[task_name].reenable
33
+ end
34
+ end
35
+
36
+ def load_fixtures!
37
+ base_names = Dir.glob(File.join(fixture_path, "*.yml")).map do |file|
38
+ File.basename(file, ".*")
39
+ end
40
+
41
+ ActiveRecord::FixtureSet.create_fixtures(fixture_path, base_names)
42
+ end
43
+
44
+ def green(text)
45
+ "\e[32m#{text}\e[0m"
46
+ end
47
+
48
+ def red(text)
49
+ "\e[31m#{text}\e[0m"
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :static do
4
+ desc "Create fixtures from database; accepts optional path argument"
5
+ task :dump, [:path] => :environment do |t, args|
6
+ path = if args[:path].blank?
7
+ StaticDb.config.fixture_path
8
+ else
9
+ Rails.root.join(args[:path])
10
+ end
11
+
12
+ StaticDb::Dump.new(fixture_path: path).perform
13
+ end
14
+
15
+ desc "Create database from fixtures; accepts optional path argument"
16
+ task :load, [:path] => :environment do |t, args|
17
+ path = if args[:path].blank?
18
+ StaticDb.config.fixture_path
19
+ else
20
+ Rails.root.join(args[:path])
21
+ end
22
+
23
+ StaticDb::Load.new(fixture_path: path).perform
24
+ end
25
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StaticDb # :nodoc:
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.3"
5
5
  end
data/lib/static_db.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "static_db/version"
4
- require "static_db/railtie" if defined?(Rails::Railtie)
4
+ require "static_db/dump"
5
+ require "static_db/load"
6
+ require "static_db/engine" if defined?(Rails::Railtie)
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.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Klaus Weidinger
@@ -9,6 +9,20 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '7.0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: bundler
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -76,7 +90,11 @@ files:
76
90
  - LICENSE.txt
77
91
  - README.md
78
92
  - lib/static_db.rb
79
- - lib/static_db/railtie.rb
93
+ - lib/static_db/dump.rb
94
+ - lib/static_db/engine.rb
95
+ - lib/static_db/initializer.rb
96
+ - lib/static_db/load.rb
97
+ - lib/static_db/tasks/static.rake
80
98
  - lib/static_db/version.rb
81
99
  homepage: https://github.com/dunkelziffer/static_db
82
100
  licenses:
@@ -95,14 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
113
  requirements:
96
114
  - - ">="
97
115
  - !ruby/object:Gem::Version
98
- version: '2.7'
116
+ version: '3.2'
99
117
  required_rubygems_version: !ruby/object:Gem::Requirement
100
118
  requirements:
101
119
  - - ">="
102
120
  - !ruby/object:Gem::Version
103
121
  version: '0'
104
122
  requirements: []
105
- rubygems_version: 3.6.7
123
+ rubygems_version: 4.0.8
106
124
  specification_version: 4
107
125
  summary: Example description
108
126
  test_files: []
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StaticDb # :nodoc:
4
- class Railtie < ::Rails::Railtie # :nodoc:
5
- end
6
- end