Skip to content

Commit

Permalink
improvements to dumper, raise exception if schema is empty, fix for p…
Browse files Browse the repository at this point in the history
…luralized migration classnames
  • Loading branch information
igorkasyanchuk committed Feb 12, 2022
1 parent f0cc6bc commit 0821abe
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ gem "pry"
gem "wrapped_print"

# Start debugger with binding.b [https://github.com/ruby/debug]
# gem "debug", ">= 1.0.0"
# gem "debug", ">= 1.0.0"
7 changes: 6 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
sql_view (0.0.1)
sql_view (0.0.2)
rails

GEM
Expand Down Expand Up @@ -91,6 +91,7 @@ GEM
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
mini_portile2 (2.7.1)
minitest (5.15.0)
net-imap (0.2.3)
digest
Expand All @@ -108,6 +109,9 @@ GEM
net-protocol
timeout
nio4r (2.5.8)
nokogiri (1.13.1)
mini_portile2 (~> 2.7.0)
racc (~> 1.4)
nokogiri (1.13.1-x86_64-linux)
racc (~> 1.4)
pg (1.3.1)
Expand Down Expand Up @@ -158,6 +162,7 @@ GEM
zeitwerk (2.5.4)

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
Expand Down
16 changes: 11 additions & 5 deletions lib/generators/sql_view/view/view_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ def create_everything
class #{class_name}View < SqlView::Model
#{top_code}
schema -> {#{schema_code} }
schema -> #{schema_code}
extend_model_with do
# sample how you can extend it, similar to regular AR model
#
# include SomeConcern
#
# belongs_to :user
# has_many :posts
#
Expand All @@ -28,7 +30,7 @@ class #{class_name}View < SqlView::Model
end
FILE

create_file "db/migrate/#{self.class.next_migration_number("db/migrate")}_create_#{file_name}s_view.rb", <<-FILE
create_file "db/migrate/#{self.class.next_migration_number("db/migrate")}_create_#{file_name}_view.rb", <<-FILE
class #{migration_class_name} < #{activerecord_migration_class}
def up
#{class_name}View.sql_view.up
Expand Down Expand Up @@ -59,11 +61,15 @@ def materialized_code
end

def schema_code
" #{args[0].presence || "\n # ActiveRecord::Relation or SQL\n # for example: User.where(active: true)\n " }"
if args[0].present?
"{ #{args[0]} }"
else
" { #{ "\n # ActiveRecord::Relation or SQL\n # for example: User.where(active: true)\n }" }"
end
end

def migration_class_name
"Create#{class_name.tr('.', '').pluralize}View"
"Create#{class_name.tr('.', '')}View"
end

def activerecord_migration_class
Expand All @@ -85,4 +91,4 @@ def file_name

end
end
end
end
8 changes: 8 additions & 0 deletions lib/sql_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def refresh

def up
view_sql = parent.sql_view_options[:sql_or_proc].call
raise "Please configure schema for #{parent} (association or SQL) for the view" if view_sql.to_s == ""
sql = <<-SQL
CREATE #{materialized_or_not} VIEW #{parent.view_name} AS
#{view_sql.respond_to?(:to_sql) ? view_sql.to_sql : view_sql };
Expand Down Expand Up @@ -103,6 +104,13 @@ def readonly?
if parent.sql_view_options[:extend_model_with].present?
klass.class_eval(&parent.sql_view_options[:extend_model_with])
end
# to use e.associations.count for example
# because of the error undefined scan for nil class
klass.class_eval %Q{
def self.name
"#{parent.class}"
end
}
klass
end
end
Expand Down
30 changes: 19 additions & 11 deletions lib/sql_view/schema_dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ module SqlView
# @api private
module SchemaDumper
class DBView < OpenStruct
def to_schema
<<-DEFINITION
create_sql_view "#{self.viewname}", sql: <<-\SQL
CREATE #{materialized_or_not} VIEW "#{self.viewname}" AS
#{escaped_definition.indent(2)}
SQL\n
DEFINITION
end

private
def materialized?
self.kind == "m"
end
Expand All @@ -15,15 +24,6 @@ def materialized_or_not
materialized? ? " MATERIALIZED " : nil
end

def to_schema
<<-DEFINITION
create_sql_view "#{self.viewname}", sql: <<-\SQL
CREATE #{materialized_or_not} VIEW "#{self.viewname}" AS
#{escaped_definition.indent(2)}
SQL
DEFINITION
end

def escaped_definition
definition.gsub("\\", "\\\\\\")
end
Expand All @@ -40,15 +40,23 @@ def views(stream)
end

dumpable_views_in_database.each do |viewname|
next if already_indexed?(viewname)
view = DBView.new(get_view_info(viewname))
#puts view.to_schema
stream.puts(view.to_schema)
#indexes(view.name, stream)
indexes(viewname, stream)
end
end

private

# make sure view was added one time, because somehow was adding views two times
def already_indexed?(viewname)
@already_indexed ||= []
return true if @already_indexed.include?(viewname)
@already_indexed << viewname
false
end

def dumpable_views_in_database
@dumpable_views_in_database ||= ActiveRecord::Base.connection.views.reject do |viewname|
ignored?(viewname)
Expand Down
2 changes: 1 addition & 1 deletion lib/sql_view/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module SqlView
VERSION = "0.0.1"
VERSION = "0.0.2"
end
3 changes: 3 additions & 0 deletions test/dummy/app/sql_views/a_view.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class AView < SqlView::Model
schema -> { }
end
17 changes: 17 additions & 0 deletions test/dummy/app/sql_views/bulgaria_view.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class BulgariaView < SqlView::Model
materialized

schema -> { User.all }

extend_model_with do
# sample how you can extend it, similar to regular AR model
#
# include SomeConcern
#
# belongs_to :user
# has_many :posts
#
# scope :ordered, -> { order(:created_at) }
# scope :by_role, ->(role) { where(role: role) }
end
end
9 changes: 9 additions & 0 deletions test/dummy/db/migrate/20220212105622_create_bulgaria_view.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreateBulgariaView < ActiveRecord::Migration[7.0]
def up
BulgariaView.sql_view.up
end

def down
BulgariaView.sql_view.down
end
end
31 changes: 22 additions & 9 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2022_02_10_181859) do
ActiveRecord::Schema.define(version: 2022_02_12_105622) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -31,24 +31,37 @@
end


create_sql_view "active_account_views", sql: <<-SQL
CREATE VIEW "active_account_views" AS
SELECT accounts.id,
create_sql_view "active_account_views", sql: <<-SQL
CREATE VIEW "active_account_views" AS
SELECT accounts.id,
accounts.name,
accounts.active,
accounts.created_at,
accounts.updated_at
FROM accounts
WHERE (accounts.active = true);
SQL
create_sql_view "deleted_account_views", sql: <<-SQL
CREATE MATERIALIZED VIEW "deleted_account_views" AS
SELECT accounts.id,
SQL

create_sql_view "deleted_account_views", sql: <<-SQL
CREATE MATERIALIZED VIEW "deleted_account_views" AS
SELECT accounts.id,
accounts.name,
accounts.active,
accounts.created_at,
accounts.updated_at
FROM accounts
WHERE (1 = 0);
SQL
SQL

create_sql_view "bulgaria_views", sql: <<-SQL
CREATE MATERIALIZED VIEW "bulgaria_views" AS
SELECT users.id,
users.name,
users.country,
users.age,
users.created_at,
users.updated_at
FROM users;
SQL

end
4 changes: 4 additions & 0 deletions test/sql_view_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ class SqlViewTest < ActiveSupport::TestCase
AnotherView.sql_view.down
end

test 'empty schema' do
assert_raise { AView.sql_view.up }
end

test 'view from app' do
assert_equal 0, ActiveAccountView.model.count
end
Expand Down

0 comments on commit 0821abe

Please sign in to comment.