]> source.dussan.org Git - sonarqube.git/blob
55d10efef612868d821fea2fa72ffc7aefa4db8e
[sonarqube.git] /
1 module ::ActiveRecord
2   class Base
3     after_save :write_lobs
4
5   private
6     def write_lobs
7       if connection.is_a?(ArJdbc::Informix)
8         self.class.columns.each do |c|
9           if [:text, :binary].include? c.type
10             value = self[c.name]
11             value = value.to_yaml if unserializable_attribute?(c.name, c)
12
13             unless value.nil? || (value == '')
14               connection.write_large_object(c.type == :binary,
15                                             c.name,
16                                             self.class.table_name,
17                                             self.class.primary_key,
18                                             quote_value(id),
19                                             value)
20             end
21           end
22         end
23       end
24     end
25   end
26 end
27
28 module ::ArJdbc
29   module Informix
30     def self.extended(base)
31       @@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
32     end
33
34     def self.column_selector
35       [ /informix/i,
36         lambda { |cfg, column| column.extend(::ArJdbc::Informix::Column) } ]
37     end
38
39     def self.jdbc_connection_class
40       ::ActiveRecord::ConnectionAdapters::InformixJdbcConnection
41     end
42
43     module Column
44     private
45       # TODO: Test all Informix column types.
46       def simplified_type(field_type)
47         if field_type =~ /serial/i
48           :primary_key
49         else
50           super
51         end
52       end
53     end
54
55     def modify_types(tp)
56       tp[:primary_key] = "SERIAL PRIMARY KEY"
57       tp[:string]      = { :name => "VARCHAR", :limit => 255 }
58       tp[:integer]     = { :name => "INTEGER" }
59       tp[:float]       = { :name => "FLOAT" }
60       tp[:decimal]     = { :name => "DECIMAL" }
61       tp[:datetime]    = { :name => "DATETIME YEAR TO FRACTION(5)" }
62       tp[:timestamp]   = { :name => "DATETIME YEAR TO FRACTION(5)" }
63       tp[:time]        = { :name => "DATETIME HOUR TO FRACTION(5)" }
64       tp[:date]        = { :name => "DATE" }
65       tp[:binary]      = { :name => "BYTE" }
66       tp[:boolean]     = { :name => "BOOLEAN" }
67       tp
68     end
69
70     def prefetch_primary_key?(table_name = nil)
71       true
72     end
73
74     def supports_migrations?
75       true
76     end
77
78     def default_sequence_name(table, column)
79       "#{table}_seq"
80     end
81
82     def add_limit_offset!(sql, options)
83       if options[:limit]
84         limit = "FIRST #{options[:limit]}"
85         # SKIP available only in IDS >= 10
86         offset = (@@db_major_version >= 10 && options[:offset]?
87                   "SKIP #{options[:offset]}" : "")
88         sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
89       end
90       sql
91     end
92
93     def next_sequence_value(sequence_name)
94       select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
95     end
96
97     # TODO: Add some smart quoting for newlines in string and text fields.
98     def quote_string(string)
99       string.gsub(/\'/, "''")
100     end
101
102     def quote(value, column = nil)
103       if column && [:binary, :text].include?(column.type)
104         # LOBs are updated separately by an after_save trigger.
105         "NULL"
106       elsif column && column.type == :date
107         "'#{value.mon}/#{value.day}/#{value.year}'"
108       else
109         super
110       end
111     end
112
113     def create_table(name, options = {})
114       super(name, options)
115       execute("CREATE SEQUENCE #{name}_seq")
116     end
117
118     def rename_table(name, new_name)
119       execute("RENAME TABLE #{name} TO #{new_name}")
120       execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
121     end
122
123     def drop_table(name)
124       super(name)
125       execute("DROP SEQUENCE #{name}_seq")
126     end
127
128     def remove_index(table_name, options = {})
129       @connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
130     end
131
132   private
133     def select(sql, name = nil)
134       # Informix does not like "= NULL", "!= NULL", or "<> NULL".
135       execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), name)
136     end
137   end # module Informix
138 end # module ::ArJdbc