Skip to content

Commit

Permalink
Add support for database views
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewmcgarvey committed Dec 4, 2020
1 parent 38c74a7 commit 61a9a4f
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 0 deletions.
14 changes: 14 additions & 0 deletions db/migrations/20201202225520_create_admin_users_view.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreateAdminUsersView::V20201202225520 < Avram::Migrator::Migration::V1
def migrate
execute <<-SQL
CREATE VIEW admin_users AS
SELECT users.*
FROM users
JOIN admins on admins.name = users.name;
SQL
end

def rollback
execute "DROP VIEW admin_users;"
end
end
14 changes: 14 additions & 0 deletions db/migrations/20201202231134_create_nickname_infos_view.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreateNicknameInfosView::V20201202231134 < Avram::Migrator::Migration::V1
def migrate
execute <<-SQL
CREATE VIEW nickname_infos AS
SELECT users.nickname, COUNT(nickname)
FROM users
GROUP BY nickname;
SQL
end

def rollback
execute "DROP VIEW nickname_infos;"
end
end
16 changes: 16 additions & 0 deletions spec/support/models/admin_user.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# an AdminUser is a User who's name is also found in the Admin table
class AdminUser < BaseModel
view do
primary_key id : Int64
timestamps
column name : String
column age : Int32
column year_born : Int16?
column nickname : String?
column joined_at : Time
column total_score : Int64?
column average_score : Float64?
column available_for_hire : Bool?
has_one sign_in_credential : SignInCredential?
end
end
6 changes: 6 additions & 0 deletions spec/support/models/nickname_info.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class NicknameInfo < BaseModel
view do
column nickname : String
column count : Int64
end
end
23 changes: 23 additions & 0 deletions spec/view_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require "./spec_helper"

include LazyLoadHelpers

describe "views" do
it "works with a primary key" do
user = UserBox.create
AdminBox.new.name(user.name).create
admin_user = AdminUser::BaseQuery.find(user.id)

admin_user.name.should eq user.name
end

it "works without a primary key" do
UserBox.new.nickname("Johnny").create
UserBox.new.nickname("Johnny").create
UserBox.new.nickname("Johnny").create
nickname_info = NicknameInfo::BaseQuery.first

nickname_info.nickname.should eq "Johnny"
nickname_info.count.should eq 3
end
end
18 changes: 18 additions & 0 deletions src/avram/model.cr
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ abstract class Avram::Model
setup(Avram::SchemaEnforcer.setup)
end

macro view(view_name = nil)
{% unless view_name %}
{% view_name = run("../run_macros/infer_table_name.cr", @type.id) %}
{% end %}

{{ yield }}

class_getter table_name = {{ view_name.id.symbolize }}
TABLE_NAME = {{ view_name.id.symbolize }}
setup(Avram::Model.setup_initialize)
setup(Avram::Model.setup_db_mapping)
setup(Avram::Model.setup_getters)
setup(Avram::Model.setup_column_info_methods)
setup(Avram::Model.setup_association_queries)
setup(Avram::BaseQueryTemplate.setup)
setup(Avram::SchemaEnforcer.setup)
end

macro primary_key(type_declaration)
PRIMARY_KEY_TYPE = {{ type_declaration.type }}
PRIMARY_KEY_NAME = {{ type_declaration.var.symbolize }}
Expand Down

0 comments on commit 61a9a4f

Please # to comment.