Skip to content

Commit

Permalink
allow to configure definition path
Browse files Browse the repository at this point in the history
fix #261
  • Loading branch information
gagalago committed Jan 25, 2021
1 parent 3600a48 commit 39aa540
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 41 deletions.
25 changes: 10 additions & 15 deletions lib/generators/scenic/view/view_generator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require "rails/generators"
require "rails/generators/active_record"
require "generators/scenic/materializable"
require "scenic/definition"
require "scenic/definitions"

module Scenic
module Generators
Expand All @@ -11,16 +13,16 @@ class ViewGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)

def create_views_directory
unless views_directory_path.exist?
empty_directory(views_directory_path)
unless Scenic.configuration.definitions_path.exist?
empty_directory(Scenic.configuration.definitions_path)
end
end

def create_view_definition
if creating_new_view?
create_file definition.path
else
copy_file previous_definition.full_path, definition.full_path
copy_file previous_definition.path, definition.path
end
end

Expand All @@ -44,10 +46,7 @@ def self.next_migration_number(dir)

no_tasks do
def previous_version
@previous_version ||=
Dir.entries(views_directory_path)
.map { |name| version_regex.match(name).try(:[], "version").to_i }
.max
@previous_version ||= previous_definition.version
end

def version
Expand Down Expand Up @@ -79,24 +78,20 @@ def file_name
super.tr(".", "_")
end

def views_directory_path
@views_directory_path ||= Rails.root.join("db", "views")
end

def version_regex
/\A#{plural_file_name}_v(?<version>\d+)\.sql\z/
def definitions
@definitions ||= Scenic::Definitions.new(plural_file_name)
end

def creating_new_view?
previous_version.zero?
definitions.none?
end

def definition
Scenic::Definition.new(plural_file_name, version)
end

def previous_definition
Scenic::Definition.new(plural_file_name, previous_version)
definitions.max || Scenic::Definition.new(plural_file_name, 0)
end

def destroying?
Expand Down
1 change: 0 additions & 1 deletion lib/scenic.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require "scenic/configuration"
require "scenic/adapters/postgres"
require "scenic/command_recorder"
require "scenic/definition"
require "scenic/railtie"
require "scenic/schema_dumper"
require "scenic/statements"
Expand Down
11 changes: 10 additions & 1 deletion lib/scenic/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require_relative "adapters/postgres"

module Scenic
class Configuration
# The Scenic database adapter instance to use when executing SQL.
Expand All @@ -6,8 +8,15 @@ class Configuration
# @return Scenic adapter
attr_accessor :database

# The full path where is stored views definition sql files.
#
# Defaults to `Rails.root.join("db", "views")` an instance of {Pathname}
# @return the path
attr_accessor :definitions_path

def initialize
@database = Scenic::Adapters::Postgres.new
self.database = Scenic::Adapters::Postgres.new
self.definitions_path = Rails.root.join("db", "views")
end
end

Expand Down
18 changes: 9 additions & 9 deletions lib/scenic/definition.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
module Scenic
# @api private
class Definition
include Comparable

attr_reader :name, :version

def initialize(name, version)
@name = name
@version = version.to_i
end

def to_sql
File.read(full_path).tap do |content|
File.read(path).tap do |content|
if content.empty?
raise "Define view query in #{path} before migrating."
end
end
end

def full_path
Rails.root.join(path)
end

def path
File.join("db", "views", filename)
Scenic.configuration.definitions_path.join(filename)
end

def version
@version.to_s.rjust(2, "0")
def <=>(other)
version <=> other.version
end

private

def filename
"#{@name.to_s.tr('.', '_')}_v#{version}.sql"
"#{name.to_s.tr('.', '_')}_v#{version.to_s.rjust(2, '0')}.sql"
end
end
end
35 changes: 35 additions & 0 deletions lib/scenic/definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require_relative "definition"

module Scenic
# @api private
class Definitions
include Enumerable
include Comparable

attr_reader :name, :views_directory_path

def initialize(name)
@name = name
end

def each
versions.each do |version|
yield Scenic::Definition.new(name, version)
end
end

def versions
@versions ||= Dir.entries(Scenic.configuration.definitions_path)
.map { |filename| /\A#{name}_v(?<version>\d+)\.sql\z/.match(filename) }
.compact
.map { |match| match["version"].to_i }
.sort
end

private

def version_regex
/\A#{name}_v(?<version>\d+)\.sql\z/
end
end
end
1 change: 1 addition & 0 deletions lib/scenic/statements.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require_relative "definition"
module Scenic
# Methods that are made available in migrations for managing Scenic views.
module Statements
Expand Down
1 change: 1 addition & 0 deletions spec/generators/scenic/view/view_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
allow(Dir).to receive(:entries).and_return(["aired_episodes_v01.sql"])

run_generator ["aired_episode", "--materialized"]

migration = migration_file(
"db/migrate/update_aired_episodes_to_version_2.rb",
)
Expand Down
17 changes: 5 additions & 12 deletions spec/scenic/definition_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module Scenic

describe "path" do
it "returns a sql file in db/views with padded version and view name" do
expected = "db/views/searches_v01.sql"
expected = Rails.root.join("db/views/searches_v01.sql")

definition = Definition.new("searches", 1)

Expand All @@ -32,30 +32,23 @@ module Scenic

it "handles schema qualified view names" do
definition = Definition.new("non_public.searches", 1)
expected = Rails.root.join("db/views/non_public_searches_v01.sql")

expect(definition.path).to eq "db/views/non_public_searches_v01.sql"
end
end

describe "full_path" do
it "joins the path with Rails.root" do
definition = Definition.new("searches", 15)

expect(definition.full_path).to eq Rails.root.join(definition.path)
expect(definition.path).to eq expected
end
end

describe "version" do
it "pads the version number with 0" do
definition = Definition.new(:_, 1)

expect(definition.version).to eq "01"
expect(definition.version).to eq 1
end

it "doesn't pad more than 2 characters" do
definition = Definition.new(:_, 15)

expect(definition.version).to eq "15"
expect(definition.version).to eq 15
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions spec/support/generator_spec_setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@
destination fake_rails_root
prepare_destination
end

config.before(:each) do
Scenic.configure do |configuration|
configuration.definitions_path = Rails.root.join("db", "views")
end
end
end
6 changes: 3 additions & 3 deletions spec/support/view_definition_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module ViewDefinitionHelpers
def with_view_definition(name, version, schema)
definition = Scenic::Definition.new(name, version)
FileUtils.mkdir_p(File.dirname(definition.full_path))
File.open(definition.full_path, "w") { |f| f.write(schema) }
FileUtils.mkdir_p(File.dirname(definition.path))
File.open(definition.path, "w") { |f| f.write(schema) }
yield
ensure
FileUtils.rm_f(definition.full_path)
FileUtils.rm_f(definition.path)
end
end

0 comments on commit 39aa540

Please sign in to comment.