db_meta 0.1.1 → 0.1.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile.lock +4 -4
  5. data/README.md +52 -2
  6. data/db_meta.gemspec +1 -1
  7. data/lib/db_meta/abstract.rb +13 -5
  8. data/lib/db_meta/constant.rb +45 -0
  9. data/lib/db_meta/logger.rb +15 -0
  10. data/lib/db_meta/oracle/base.rb +54 -0
  11. data/lib/db_meta/oracle/connection.rb +39 -0
  12. data/lib/db_meta/oracle/helper.rb +37 -0
  13. data/lib/db_meta/oracle/objects.rb +204 -0
  14. data/lib/db_meta/oracle/oracle.rb +172 -3
  15. data/lib/db_meta/oracle/types/column.rb +70 -0
  16. data/lib/db_meta/oracle/types/comment.rb +20 -0
  17. data/lib/db_meta/oracle/types/constraint.rb +91 -0
  18. data/lib/db_meta/oracle/types/constraint_collection.rb +46 -0
  19. data/lib/db_meta/oracle/types/database_link.rb +33 -0
  20. data/lib/db_meta/oracle/types/function.rb +30 -0
  21. data/lib/db_meta/oracle/types/grant.rb +46 -0
  22. data/lib/db_meta/oracle/types/grant_collection.rb +42 -0
  23. data/lib/db_meta/oracle/types/index.rb +43 -0
  24. data/lib/db_meta/oracle/types/lob.rb +13 -0
  25. data/lib/db_meta/oracle/types/materialized_view.rb +65 -0
  26. data/lib/db_meta/oracle/types/package.rb +42 -0
  27. data/lib/db_meta/oracle/types/package_body.rb +13 -0
  28. data/lib/db_meta/oracle/types/procedure.rb +30 -0
  29. data/lib/db_meta/oracle/types/sequence.rb +41 -0
  30. data/lib/db_meta/oracle/types/synonym.rb +42 -0
  31. data/lib/db_meta/oracle/types/synonym_collection.rb +42 -0
  32. data/lib/db_meta/oracle/types/table.rb +164 -0
  33. data/lib/db_meta/oracle/types/table_data_collection.rb +85 -0
  34. data/lib/db_meta/oracle/types/trigger.rb +64 -0
  35. data/lib/db_meta/oracle/types/type.rb +41 -0
  36. data/lib/db_meta/oracle/types/type_body.rb +13 -0
  37. data/lib/db_meta/oracle/types/view.rb +60 -0
  38. data/lib/db_meta/version.rb +1 -1
  39. data/lib/db_meta.rb +18 -6
  40. data/todo.txt +43 -0
  41. metadata +36 -5
@@ -1,7 +1,176 @@
1
+ require 'oci8'
2
+ require 'fileutils'
3
+
4
+ require_relative 'connection'
5
+ require_relative 'helper'
6
+ require_relative 'base'
7
+ require_relative 'objects'
8
+
9
+ Dir[File.dirname(__FILE__) + '/types/*.rb'].each {|file| require file }
10
+
1
11
  module DbMeta
12
+ module Oracle
13
+ class Oracle < DbMeta::Abstract
14
+ include Helper
2
15
 
3
- class Oracle < DbMeta::Abstract
4
- register_type(:oracle)
5
- end
16
+ register_type(:oracle)
17
+
18
+ def initialize(args={})
19
+ super(args)
20
+
21
+ Connection.instance.set(@username, @password, @instance, @worker)
22
+
23
+ @objects = Objects.new
24
+ end
25
+
26
+ def fetch(args={})
27
+ @include_pattern = args[:include]
28
+ @exclude_pattern = args[:exclude]
29
+
30
+ Objects.all.each do |object|
31
+ next if @exclude_pattern =~ object.name if @exclude_pattern
32
+ next unless @include_pattern =~ object.name if @include_pattern
33
+ @objects << object
34
+ end
35
+
36
+ # parallel fetching of object details
37
+ @objects.fetch
38
+ ensure
39
+ Connection.instance.disconnect
40
+ end
41
+
42
+ def extract(args={})
43
+ format = args[:format] || :sql
44
+
45
+ # validate args
46
+ raise "Format [#{format}] is not supported" unless EXTRACT_FORMATS.include?(format)
47
+
48
+ remove_folder(@base_folder)
49
+ create_folder(@base_folder)
50
+
51
+ @objects.merge_synonyms
52
+ @objects.merge_grants
53
+ @objects.embed_indexes
54
+ @objects.embed_constraints
55
+ @objects.merge_constraints
56
+ @objects.embed_triggers
57
+ @objects.handle_table_data(args)
58
+
59
+ extract_summary
60
+ extract_create_all(args)
61
+ extract_drop_all(args)
62
+
63
+ # extract all default objects
64
+ @objects.default_each do |object|
65
+ folder = File.join(@base_folder, "#{"%02d" % type_sequence(object.type)}_#{object.type}")
66
+ create_folder(folder)
67
+
68
+ filename = File.join(folder, "#{object.name}.#{format.to_s}")
69
+ write_buffer_to_file(object.extract(args), filename)
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def extract_summary
76
+ Log.info("Summarizing...")
6
77
 
78
+ buffer = [block("Summary of #{@username}"), nil]
79
+
80
+ total = 0
81
+ @objects.summary_each do |type, count|
82
+ total += count
83
+ buffer << "#{SUMMARY_COLUMN_FORMAT_NAME % type.upcase.to_s}#{"%5d" % count} #{"(#{@objects.summary_system_object[type]} system #{pluralize(@objects.summary_system_object[type], 'object')})" if @objects.summary_system_object[type] > 0}"
84
+ end
85
+ buffer << nil
86
+
87
+ buffer << "#{SUMMARY_COLUMN_FORMAT_NAME % 'Total Objects'}#{"%5d" % total}"
88
+ buffer << nil
89
+ buffer << nil
90
+
91
+ # invalid objects
92
+ if @objects.invalids?
93
+ buffer << 'Invalid/Disabled Objects'
94
+ @objects.invalid_each do |type, objects|
95
+ buffer << "#{SUMMARY_COLUMN_FORMAT_NAME % type.upcase.to_s}#{"%5d" % objects.size}"
96
+ objects.each do |object|
97
+ buffer << "#{SUMMARY_COLUMN_FORMAT_NAME_RIGHT % object.name}"
98
+ end
99
+ buffer << nil
100
+ end
101
+ else
102
+ buffer << 'No invalid/disabled objects'
103
+ end
104
+ buffer << nil
105
+
106
+ filename = File.join(@base_folder, "#{"%02d" % type_sequence('SUMMARY')}_summary.txt")
107
+ write_buffer_to_file(buffer, filename)
108
+ end
109
+
110
+ def extract_create_all(args={})
111
+ Log.info("Extracting create all script...")
112
+
113
+ buffer = [block("#{@username} - CREATE ALL")]
114
+
115
+ current_type = nil
116
+ @objects.default_each do |object|
117
+ if current_type != object.type
118
+ buffer << nil;
119
+ buffer << block(object.type, 40)
120
+ end
121
+
122
+ folder = "#{'%02d' % type_sequence(object.type)}_#{object.type}"
123
+ file = "#{object.name}.sql"
124
+ buffer << "@#{File.join(folder,file).downcase.gsub(' ', '_')}"
125
+ current_type = object.type
126
+ end
127
+ buffer << nil
128
+ buffer << compile_invalid_script
129
+ buffer << nil
130
+
131
+ filename = File.join(@base_folder,"#{'%02d' % type_sequence('CREATE')}_create_all.sql")
132
+ write_buffer_to_file(buffer, filename)
133
+ end
134
+
135
+ def extract_drop_all(args={})
136
+ Log.info("Extracting drop all script...")
137
+
138
+ buffer = [block("#{@username} - DROP ALL")]
139
+
140
+ current_type = nil
141
+ @objects.reverse_default_each do |object|
142
+
143
+ if current_type != object.type
144
+ buffer << nil;
145
+ buffer << block(object.type, 40)
146
+ end
147
+
148
+ buffer << object.ddl_drop
149
+ current_type = object.type
150
+ end
151
+ buffer << nil
152
+
153
+ filename = File.join(@base_folder,"#{'%02d' % type_sequence('DROP')}_drop_all.sql")
154
+ write_buffer_to_file(buffer, filename)
155
+ end
156
+
157
+ def compile_invalid_script
158
+ buffer = [block('Compile invalid objects if needed', 40)]
159
+ buffer << "declare"
160
+ buffer << "begin"
161
+ buffer << " for rec in (select object_name, object_type from user_objects where status = 'INVALID') loop"
162
+ buffer << " if rec.object_type = 'PACKAGE' or rec.object_type = 'PACKAGE BODY' then"
163
+ buffer << " execute immediate 'alter PACKAGE ' || rec.object_name || ' compile';"
164
+ buffer << " execute immediate 'alter PACKAGE ' || rec.object_name || ' compile body';"
165
+ buffer << " else"
166
+ buffer << " execute immediate 'alter ' || rec.object_type || ' ' || rec.object_name || ' compile';"
167
+ buffer << " end if;"
168
+ buffer << " end loop;"
169
+ buffer << "end;"
170
+ buffer << "/"
171
+ buffer.join("\n")
172
+ end
173
+
174
+ end
175
+ end
7
176
  end
@@ -0,0 +1,70 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Column
4
+
5
+ attr_accessor :name, :type, :data_length, :data_precision, :data_scale, :nullable, :data_default, :comment
6
+
7
+ def initialize(args={})
8
+ end
9
+
10
+ def extract
11
+ buffer = "#{'%-30s' % @name}"
12
+ buffer << " #{convert_type}"
13
+ buffer << " DEFAULT #{@data_default}".strip if @data_default.size > 0
14
+ return buffer
15
+ end
16
+
17
+ def self.all(args={})
18
+ columns = []
19
+ connection = Connection.instance.get
20
+ cursor = connection.exec("select column_name, data_type, data_length, data_precision, data_scale, nullable, data_default from user_tab_columns where table_name = '#{args[:object_name]}' order by column_id")
21
+ while row = cursor.fetch()
22
+ column = Column.new(row)
23
+ column.name = row[0].to_s
24
+ column.type = row[1].to_s
25
+ column.data_length = row[2].to_i
26
+ column.data_precision = row[3].to_i
27
+ column.data_scale = row[4].to_i
28
+ column.nullable = row[5].to_s
29
+ column.data_default = row[6].to_s
30
+
31
+ # column comments
32
+ cursor2 = connection.exec("select comments from user_col_comments where table_name = '#{args[:object_name]}' and column_name = '#{column.name}'")
33
+ while row2 = cursor2.fetch()
34
+ column.comment = row2[0].to_s
35
+ end
36
+ cursor2.close
37
+ columns << column
38
+
39
+ end
40
+ cursor.close
41
+
42
+ columns
43
+ rescue
44
+ connection.loggoff
45
+ end
46
+
47
+ private
48
+
49
+ def convert_type
50
+ case @type
51
+ when 'FLOAT'
52
+ buffer = "#{@type}"
53
+ buffer << "(#{@data_precision})" unless @data_precision == 0
54
+ return buffer
55
+ when 'NUMBER'
56
+ buffer = "#{@type}"
57
+ buffer << "(#{@data_precision}" unless @data_precision == 0
58
+ buffer << ",#{@data_scale}" unless @data_scale == 0
59
+ buffer << ")" if buffer.include?("(")
60
+ return buffer
61
+ when /CHAR|RAW/
62
+ return "#{@type}(#{@data_length} BYTE)"
63
+ else
64
+ return @type
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,20 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Comment
4
+ attr_reader :text
5
+
6
+ def self.find(args={})
7
+
8
+ connection = Connection.instance.get
9
+ cursor = connection.exec("select comments from user_tab_comments where table_type = '#{args[:type]}' and table_name = '#{args[:name]}'")
10
+ while row = cursor.fetch()
11
+ @text = row[0]
12
+ end
13
+
14
+ ensure
15
+ connection.logoff
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,91 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Constraint < Base
4
+ register_type('CONSTRAINT')
5
+
6
+ attr_reader :constraint_type, :table_name, :search_condition, :referential_constraint, :delete_rule, :columns
7
+
8
+ def initialize(args={})
9
+ super(args)
10
+
11
+ @extract_type = :embedded
12
+ @columns = []
13
+ end
14
+
15
+ def fetch(args={})
16
+ connection = Connection.instance.get
17
+ cursor = connection.exec("select * from user_constraints where constraint_name = '#{@name}'")
18
+ cursor.fetch_hash do |item|
19
+ @constraint_type = translate_constraint_type(item['CONSTRAINT_TYPE'])
20
+ @extract_type = :merged if @constraint_type == 'FOREIGN KEY'
21
+ @table_name = item['TABLE_NAME']
22
+ @search_condition = item['SEARCH_CONDITION']
23
+ @delete_rule = item['DELETE_RULE']
24
+
25
+ if @constraint_type == 'FOREIGN KEY'
26
+ constraint = Constraint.new('OBJECT_TYPE' => 'CONSTRAINT', 'OBJECT_NAME' => item['R_CONSTRAINT_NAME'])
27
+ constraint.fetch
28
+ @referential_constraint = constraint
29
+ end
30
+ end
31
+ cursor.close
32
+
33
+ # get affected columns
34
+ cursor = connection.exec("select * from user_cons_columns where constraint_name = '#{@name}' order by position")
35
+ cursor.fetch_hash do |item|
36
+ @columns << item['COLUMN_NAME']
37
+ end
38
+ cursor.close
39
+
40
+ ensure
41
+ connection.logoff
42
+ end
43
+
44
+
45
+ def extract(args={})
46
+ buffer = []
47
+ buffer << "ALTER TABLE #{@table_name} ADD ("
48
+ buffer << " CONSTRAINT #{@name}"
49
+
50
+ case @constraint_type
51
+ when 'CHECK'
52
+ buffer << " #{@constraint_type} (#{@search_condition})"
53
+ when 'FOREIGN KEY'
54
+ buffer << " #{@constraint_type} (#{@columns.join(', ')})"
55
+ buffer << " REFERENCES #{@referential_constraint.table_name} (#{@referential_constraint.columns.join(', ')})"
56
+ else
57
+ buffer << " #{@constraint_type} (#{@columns.join(', ')})"
58
+ end
59
+
60
+ buffer << " ON DELETE CASCADE" if @delete_rule == 'CASCADE'
61
+ buffer << " ENABLE VALIDATE"
62
+ buffer << ");"
63
+
64
+ (0..buffer.size-1).each { |n| buffer[n] = ('-- ' + buffer[n])} if args[:comment] == true
65
+
66
+ buffer << nil
67
+ buffer.join("\n")
68
+ end
69
+
70
+ def self.sort_value(type)
71
+ ['PRIMARY KEY', 'FOREIGN KEY', 'UNIQUE', 'CHECK'].index(type)
72
+ end
73
+
74
+ private
75
+
76
+ def translate_constraint_type(type)
77
+ case type
78
+ when 'P'
79
+ return 'PRIMARY KEY'
80
+ when 'U'
81
+ return 'UNIQUE'
82
+ when 'C'
83
+ return 'CHECK'
84
+ when 'R'
85
+ return 'FOREIGN KEY'
86
+ end
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,46 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class ConstraintCollection
4
+ include DbMeta::Oracle::Helper
5
+
6
+ attr_reader :name, :type, :status, :extract_type, :collection
7
+
8
+ def initialize(args={})
9
+ @name = args[:name]
10
+ @type = args[:type]
11
+ @status = :valid
12
+ @extract_type = :default
13
+ @collection = []
14
+ end
15
+
16
+ def empty?
17
+ @collection.size == 0
18
+ end
19
+
20
+ def <<(object)
21
+ @collection << object
22
+ end
23
+
24
+ def extract(args={})
25
+ buffer = [block(@name)]
26
+ title = nil
27
+ @collection.sort_by{ |o| [o.table_name, o.name]}.each do |object|
28
+ buffer << block(object.table_name, 40) if title != object.table_name
29
+ buffer << object.extract(args)
30
+ title = object.table_name
31
+ end
32
+ buffer.join("\n")
33
+ end
34
+
35
+ def ddl_drop
36
+ '-- will automatically be dropped with table object'
37
+ end
38
+
39
+ def system_object?
40
+ false
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,33 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class DatabaseLink < Base
4
+ register_type('DATABASE LINK')
5
+
6
+ attr_reader :username, :password, :host
7
+
8
+ def fetch(args={})
9
+ connection = Connection.instance.get
10
+ cursor = connection.exec("select username, password, host from user_db_links where db_link = '#{@name}'")
11
+ while row = cursor.fetch()
12
+ @username = row[0].to_s
13
+ @password = row[1].to_s
14
+ @host = row[2].to_s
15
+ end
16
+ cursor.close
17
+ ensure
18
+ connection.logoff
19
+ end
20
+
21
+ def extract(args={})
22
+ buffer = []
23
+ buffer << "CREATE DATABASE LINK #{@name}"
24
+ buffer << " CONNECT TO #{@username}"
25
+ buffer << " IDENTIFIED BY :1"
26
+ buffer << " USING '#{@host}';"
27
+ buffer << nil
28
+ buffer.join("\n")
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Function < Base
4
+ register_type('FUNCTION')
5
+
6
+ attr_reader :source
7
+
8
+ def fetch
9
+ @source = ""
10
+ connection = Connection.instance.get
11
+ cursor = connection.exec("select text from user_source where type = 'FUNCTION' and name = '#{@name}' order by line")
12
+ while row = cursor.fetch()
13
+ @source << row[0].to_s
14
+ end
15
+ cursor.close
16
+ ensure
17
+ connection.logoff
18
+ end
19
+
20
+ def extract(args={})
21
+ buffer = [block(@name)]
22
+ buffer << @source.strip
23
+ buffer << '/'
24
+ buffer << nil
25
+ buffer.join("\n")
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Grant < Base
4
+ register_type('GRANT')
5
+
6
+ attr_reader :grantee, :owner, :table_name, :grantor, :privilege, :grantable
7
+
8
+ def initialize(args={})
9
+ super(args)
10
+ @extract_type = :merged
11
+ end
12
+
13
+ def fetch(args={})
14
+ # definition is comma seperated in the name to prevent re-fetching table for every grant
15
+ @grantee, @owner, @table_name, @grantor, @privilege, @grantable = @name.split(',')
16
+ end
17
+
18
+ def extract(args={})
19
+ buffer = ""
20
+ buffer << ( '%-30s' % "-- granted via #{@grantor}: ") if external_grant?
21
+ buffer << "GRANT #{"%-18s" % @privilege} ON #{"%-32s" % @table_name} TO #{@grantee}"
22
+ buffer << " WITH GRANT OPTION" if @grantable == 'YES'
23
+ buffer << ";"
24
+ buffer
25
+ end
26
+
27
+ def ddl_drop
28
+ buffer = ""
29
+
30
+ buffer << ( '%-30s' % "-- granted via #{@grantor}: ") if external_grant?
31
+ buffer << "REVOKE #{"%-18s" % @privilege} ON #{"%-32s" % @table_name} FROM #{@grantee};"
32
+ buffer
33
+ end
34
+
35
+ def external_grant?
36
+ @grantee == Connection.instance.username.upcase
37
+ end
38
+
39
+ def sort_value
40
+ return ["2", @grantor, @privilege, @table_name] if external_grant?
41
+ return ["1", @grantee, @privilege, @table_name]
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class GrantCollection
4
+ include DbMeta::Oracle::Helper
5
+
6
+ attr_reader :name, :type, :status, :extract_type, :collection
7
+
8
+ def initialize(args={})
9
+ @name = args[:name]
10
+ @type = args[:type]
11
+ @status = :valid
12
+ @extract_type = :default
13
+ @collection = []
14
+ end
15
+
16
+ def empty?
17
+ @collection.size == 0
18
+ end
19
+
20
+ def <<(object)
21
+ @collection << object
22
+ end
23
+
24
+ def extract(args={})
25
+ buffer = [block(@name)]
26
+ buffer << @collection.map{ |o| o.extract(args) }
27
+ buffer << nil
28
+ buffer.join("\n")
29
+ end
30
+
31
+ def ddl_drop
32
+ @collection.reverse_each.map{ |o| o.ddl_drop }.join("\n")
33
+ end
34
+
35
+ def system_object?
36
+ false
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Index < Base
4
+ register_type('INDEX')
5
+
6
+ attr_reader :index_type, :table_name, :uniqueness, :tablespace
7
+
8
+ def initialize(args={})
9
+ super(args)
10
+
11
+ @extract_type = :embedded
12
+ @columns = []
13
+ end
14
+
15
+ def fetch(args={})
16
+ connection = Connection.instance.get
17
+ cursor = connection.exec("select index_type, table_name, uniqueness, tablespace_name from user_indexes where index_name = '#{@name}'")
18
+ while row = cursor.fetch()
19
+ @index_type = row[0].to_s
20
+ @table_name = row[1].to_s
21
+ @uniqueness = row[2].to_s
22
+ @tablespace = row[3].to_s
23
+ end
24
+ cursor.close
25
+
26
+ # involved columns
27
+ cursor = connection.exec("select column_name from user_ind_columns where index_name = '#{@name}' order by column_position")
28
+ while row = cursor.fetch()
29
+ @columns << row[0].to_s
30
+ end
31
+ cursor.close
32
+
33
+ ensure
34
+ connection.logoff
35
+ end
36
+
37
+ def extract(args={})
38
+ "CREATE#{ @uniqueness == 'UNIQUE' ? ' UNIQUE' : nil } INDEX #{@name} ON #{@table_name}(#{@columns.join(', ')});"
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class Lob < Base
4
+ register_type('LOB')
5
+
6
+ def initialize(args={})
7
+ super(args)
8
+ @extract_type = :embedded
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,65 @@
1
+ module DbMeta
2
+ module Oracle
3
+ class MaterializedView < Base
4
+ register_type('MATERIALIZED VIEW')
5
+
6
+ attr_reader :query, :build_mode, :refresh_mode, :refresh_method, :interval, :next_date, :rewrite_enabled, :columns
7
+
8
+ def fetch(args={})
9
+ connection = Connection.instance.get
10
+
11
+ cursor = connection.exec("select * from user_mviews where mview_name = '#{@name}'")
12
+ cursor.fetch_hash do |item|
13
+ @query = item['QUERY']
14
+ @build_mode = item['BUILD_MODE']
15
+ @refresh_mode = item['REFRESH_MODE']
16
+ @refresh_method = item['REFRESH_METHOD']
17
+ @rewrite_enabled = item['REWRITE_ENABLED'] == 'Y' ? 'ENABLE' : 'DISABLE'
18
+ end
19
+ cursor.close
20
+
21
+ cursor = connection.exec("select * from user_refresh where rname = '#{@name}'")
22
+ cursor.fetch_hash do |item|
23
+ @interval = item['INTERVAL']
24
+ @next_date = item['NEXT_DATE']
25
+ end
26
+ cursor.close
27
+
28
+ @columns = Column.all(object_name: @name)
29
+
30
+ # comments on materialized views
31
+ cursor = connection.exec("select * from user_mview_comments where mview_name = '#{@name}'")
32
+ cursor.fetch_hash do |item|
33
+ @comment = item['COMMENTS']
34
+ end
35
+ cursor.close
36
+
37
+ ensure
38
+ connection.logoff
39
+ end
40
+
41
+
42
+ def extract(args={})
43
+ buffer = [block(@name)]
44
+ buffer << "CREATE MATERIALIZED VIEW #{@name}(#{@columns.map{ |c| c.name}.join(', ')})"
45
+ buffer << "BUILD #{@build_mode}"
46
+ buffer << "REFRESH #{@refresh_method} ON #{@refresh_mode}"
47
+ buffer << "START WITH TO_DATE('#{@next_date}') NEXT #{@interval}" if @interval
48
+ buffer << "#{@rewrite_enabled} QUERY REWRITE"
49
+ buffer << 'AS'
50
+ buffer << @query
51
+ buffer << '/'
52
+ buffer << nil
53
+
54
+ # materialized view comments
55
+ if @comment
56
+ buffer << "COMMENT ON MATERIALIZED VIEW #{@name} IS '#{@comment.gsub("'","''")}';"
57
+ buffer << nil
58
+ end
59
+
60
+ buffer.join("\n")
61
+ end
62
+
63
+ end
64
+ end
65
+ end