]> source.dussan.org Git - sonarqube.git/blob
53df2c0469d7594bb1595fc0fa273d59dacdf16a
[sonarqube.git] /
1 module ArJdbc
2   module MissingFunctionalityHelper
3     #Taken from SQLite adapter
4
5     def alter_table(table_name, options = {}) #:nodoc:
6       table_name = table_name.to_s.downcase
7       altered_table_name = "altered_#{table_name}"
8       caller = lambda {|definition| yield definition if block_given?}
9
10       transaction do
11         # A temporary table might improve performance here, but
12         # it doesn't seem to maintain indices across the whole move.
13         move_table(table_name, altered_table_name,
14           options)
15         move_table(altered_table_name, table_name, &caller)
16       end
17     end
18
19     def move_table(from, to, options = {}, &block) #:nodoc:
20       copy_table(from, to, options, &block)
21       drop_table(from)
22     end
23
24     def copy_table(from, to, options = {}) #:nodoc:
25       options = options.merge(:id => (!columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s))
26       create_table(to, options) do |definition|
27         @definition = definition
28         columns(from).each do |column|
29           column_name = options[:rename] ?
30             (options[:rename][column.name] ||
31              options[:rename][column.name.to_sym] ||
32              column.name) : column.name
33
34           @definition.column(column_name, column.type,
35             :limit => column.limit, :default => column.default,
36             :null => column.null)
37         end
38         @definition.primary_key(primary_key(from)) if primary_key(from)
39         yield @definition if block_given?
40       end
41
42       copy_table_indexes(from, to, options[:rename] || {})
43       copy_table_contents(from, to,
44         @definition.columns.map {|column| column.name},
45         options[:rename] || {})
46     end
47
48     def copy_table_indexes(from, to, rename = {}) #:nodoc:
49       indexes(from).each do |index|
50         name = index.name.downcase
51         if to == "altered_#{from}"
52           name = "temp_#{name}"
53         elsif from == "altered_#{to}"
54           name = name[5..-1]
55         end
56
57         to_column_names = columns(to).map(&:name)
58         columns = index.columns.map {|c| rename[c] || c }.select do |column|
59           to_column_names.include?(column)
60         end
61
62         unless columns.empty?
63           # index name can't be the same
64           opts = { :name => name.gsub(/(_?)(#{from})_/, "\\1#{to}_") }
65           opts[:unique] = true if index.unique
66           add_index(to, columns, opts)
67         end
68       end
69     end
70
71     def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
72       column_mappings = Hash[*columns.map {|name| [name, name]}.flatten]
73       rename.inject(column_mappings) {|map, a| map[a.last] = a.first; map}
74       from_columns = columns(from).collect {|col| col.name}
75       columns = columns.find_all{|col| from_columns.include?(column_mappings[col])}
76       quoted_columns = columns.map { |col| quote_column_name(col) } * ','
77
78       quoted_to = quote_table_name(to)
79       execute("SELECT * FROM #{quote_table_name(from)}").each do |row|
80         sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
81         sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
82         sql << ')'
83         execute sql
84       end
85     end
86   end
87 end