view-model 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +18 -2
- data/Rakefile +1 -1
- data/init.rb +1 -1
- data/lib/adapters/abstract_adapter.rb +14 -0
- data/lib/adapters/postgresql_adapter.rb +25 -0
- data/lib/view_model.rb +37 -47
- metadata +5 -2
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= ViewModel
|
2
2
|
|
3
|
-
Some model magic for ActiveRecord Models & Postgresql 8.
|
3
|
+
Some model magic for ActiveRecord Models & Postgresql >= 8.2
|
4
4
|
|
5
5
|
Usage:
|
6
6
|
In your Model:
|
@@ -24,4 +24,20 @@ Warning: There is no automatic versioning support and no fallback functionality.
|
|
24
24
|
= Depending Views:
|
25
25
|
|
26
26
|
If you have depending views which would block a "DROP VIEW", ViewModel automatically searches the models,
|
27
|
-
checks if they have a view_definition, drops them and recreates them after the current view is migrated.
|
27
|
+
checks if they have a view_definition, drops them and recreates them after the current view is migrated.
|
28
|
+
|
29
|
+
= Creating an Adapter for your database:
|
30
|
+
- check how to get view dependencies on your desired database
|
31
|
+
- create a new adapter under adapters/
|
32
|
+
- name the class after the ActiveRecord adapter name
|
33
|
+
Get it with:
|
34
|
+
ActiveRecord::Base.connection.class.to_s.demodulize
|
35
|
+
- require view_model
|
36
|
+
|
37
|
+
|
38
|
+
= TODO:
|
39
|
+
|
40
|
+
- document code!
|
41
|
+
- create tests!
|
42
|
+
- support more databases?
|
43
|
+
|
data/Rakefile
CHANGED
data/init.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require "view_model"
|
1
|
+
require "view_model"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ViewModel
|
2
|
+
|
3
|
+
class PostgreSQLAdapter < AbstractAdapter
|
4
|
+
|
5
|
+
# returns an Array of Dependent models
|
6
|
+
def self.get_dependencies(connection, table_name)
|
7
|
+
sql = "select distinct(cl2.relname) from pg_depend dep
|
8
|
+
join pg_class cl ON dep.refobjid = cl.oid
|
9
|
+
join pg_rewrite on dep.objid = pg_rewrite.oid
|
10
|
+
join pg_class cl2 on pg_rewrite.ev_class = cl2.oid
|
11
|
+
where cl.relname='#{table_name}' and cl2.relname != '#{table_name}' and deptype='n' "
|
12
|
+
result = connection.execute(sql)
|
13
|
+
view_dependencies = []
|
14
|
+
result.each do |row|
|
15
|
+
view_dependencies << get_model(row["relname"])
|
16
|
+
end
|
17
|
+
if view_dependencies.size > 0
|
18
|
+
puts "found dependencies: "
|
19
|
+
puts view_dependencies.inspect
|
20
|
+
end
|
21
|
+
view_dependencies
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/view_model.rb
CHANGED
@@ -1,37 +1,36 @@
|
|
1
|
+
# = ViewModel
|
2
|
+
# See README for details
|
3
|
+
require "adapters/abstract_adapter"
|
4
|
+
require "adapters/postgresql_adapter"
|
5
|
+
|
6
|
+
|
1
7
|
module ViewModel
|
2
8
|
|
3
|
-
def self.included(model)
|
9
|
+
def self.included(model)
|
4
10
|
model.extend self
|
5
11
|
end
|
6
12
|
|
7
|
-
#
|
8
|
-
# If in any case you have other views depending on this view,
|
9
|
-
# define them in depending_views.
|
10
|
-
# If the current view is migrated, it will drop the views depending on this one.
|
11
|
-
#
|
12
|
-
# TODO: find a better solution to store this information.
|
13
|
-
# def depending_views(*opts)
|
14
|
-
# @view_dependencies ||= []
|
15
|
-
# unless opts.kind_of? Array
|
16
|
-
# @view_dependencies << get_model(opts)
|
17
|
-
# else
|
18
|
-
# @view_dependencies += opts.map{|o| get_model(o)}
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
# alias :depending_view :depending_views
|
22
|
-
#
|
23
|
-
def get_model(sym)
|
24
|
-
sym.to_s.classify.constantize
|
25
|
-
end
|
26
|
-
|
13
|
+
# sets the view_definition in the model
|
27
14
|
def view_definition(sql)
|
28
15
|
@view_definition = sql
|
29
16
|
end
|
30
17
|
|
18
|
+
# shortcut for connection.execute(sql)
|
31
19
|
def execute(sql)
|
32
20
|
connection.execute(sql)
|
33
21
|
end
|
34
22
|
|
23
|
+
# gets the adapter needed which has a custom method to get its dependencies
|
24
|
+
def get_adapter
|
25
|
+
adapter = connection.class.to_s.demodulize
|
26
|
+
begin
|
27
|
+
return ("ViewModel::"+adapter).constantize
|
28
|
+
rescue
|
29
|
+
raise "ViewModel: can't find adapter for ConnectionAdapter #{adapter}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# checks for dependent views
|
35
34
|
def check_dependencies
|
36
35
|
return if @view_dependencies == nil
|
37
36
|
@view_dependencies.each do |dep|
|
@@ -41,6 +40,7 @@ module ViewModel
|
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
43
|
+
# drops all dependent views
|
44
44
|
def drop_dependencies!
|
45
45
|
return if @view_dependencies == nil
|
46
46
|
@view_dependencies.each do |dep|
|
@@ -48,6 +48,7 @@ module ViewModel
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
# create all dependent views
|
51
52
|
def create_dependencies!
|
52
53
|
return if @view_dependencies == nil
|
53
54
|
@view_dependencies.each do |dep|
|
@@ -61,41 +62,30 @@ module ViewModel
|
|
61
62
|
|
62
63
|
# checks Postgresql relations for any view that uses current view.
|
63
64
|
def get_dependencies
|
64
|
-
|
65
|
-
join pg_class cl ON dep.refobjid = cl.oid
|
66
|
-
join pg_rewrite on dep.objid = pg_rewrite.oid
|
67
|
-
join pg_class cl2 on pg_rewrite.ev_class = cl2.oid
|
68
|
-
where cl.relname='#{table_name}' and cl2.relname != '#{table_name}' and deptype='n' "
|
69
|
-
result = execute(sql)
|
70
|
-
@view_dependencies = []
|
71
|
-
result.each do |row|
|
72
|
-
@view_dependencies << get_model(row["relname"])
|
73
|
-
end
|
74
|
-
if @view_dependencies.size > 0
|
75
|
-
puts "found dependencies: "
|
76
|
-
puts @view_dependencies.inspect
|
77
|
-
end
|
78
|
-
|
65
|
+
@view_dependencies = get_adapter.get_dependencies(connection, table_name)
|
79
66
|
end
|
80
67
|
|
81
68
|
def migrate!
|
82
69
|
raise "Please provide a view_definition inside the model" if !view_definition_set?
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
70
|
+
get_dependencies
|
71
|
+
check_dependencies
|
72
|
+
drop_dependencies!
|
73
|
+
drop_view!
|
74
|
+
create_view!
|
75
|
+
create_dependencies!
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
# Create the model's view according to it's definition.
|
80
|
+
def create_view!
|
81
|
+
puts "creating view #{table_name}"
|
94
82
|
sql = "CREATE OR REPLACE VIEW #{table_name} AS "
|
95
83
|
sql << @view_definition
|
96
84
|
execute(sql)
|
97
85
|
end
|
98
86
|
|
87
|
+
# Drops a view if exists.
|
88
|
+
# note: "if exists" works only on Postgresql 8.2 or later. Older versions are not supported.
|
99
89
|
def drop_view!
|
100
90
|
puts "dropping view #{table_name}"
|
101
91
|
execute("DROP VIEW if exists #{table_name}")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joachim Glauche
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-21 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -23,6 +23,9 @@ extra_rdoc_files:
|
|
23
23
|
- README
|
24
24
|
files:
|
25
25
|
- lib/view_model.rb
|
26
|
+
- lib/adapters
|
27
|
+
- lib/adapters/abstract_adapter.rb
|
28
|
+
- lib/adapters/postgresql_adapter.rb
|
26
29
|
- init.rb
|
27
30
|
- LICENSE
|
28
31
|
- README
|