]> source.dussan.org Git - sonarqube.git/blob
5938b7f985c2dfd9d0b5eb227275e61f4159e395
[sonarqube.git] /
1 module ::ArJdbc
2   module HSQLDB
3     def self.column_selector
4       [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::ArJdbc::HSQLDB::Column)}]
5     end
6
7     module Column
8       private
9       def simplified_type(field_type)
10         case field_type
11         when /longvarchar/i then :text
12         when /tinyint/i  then :boolean
13         when /real/i     then :float
14         when /decimal/i  then :decimal
15         else
16           super
17         end
18       end
19
20       # Override of ActiveRecord::ConnectionAdapters::Column
21       def extract_limit(sql_type)
22         # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
23         # for AR purposes should be interpreted as "no limit"
24         return nil if sql_type =~ /\(0\)/
25         super
26       end
27
28       # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
29       def default_value(value)
30         # jdbc returns column default strings with actual single quotes around the value.
31         return $1 if value =~ /^'(.*)'$/
32
33         value
34       end
35     end
36
37     def adapter_name #:nodoc:
38       'Hsqldb'
39     end
40
41     def arel2_visitors
42       require 'arel/visitors/hsqldb'
43       {'hsqldb' => ::Arel::Visitors::HSQLDB, 'jdbchsqldb' => ::Arel::Visitors::HSQLDB}
44     end
45
46     def modify_types(tp)
47       tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
48       tp[:integer][:limit] = nil
49       tp[:boolean][:limit] = nil
50       # set text and float limits so we don't see odd scales tacked on
51       # in migrations
52       tp[:boolean] = { :name => "tinyint" }
53       tp[:text][:limit] = nil
54       tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
55       tp[:string][:limit] = 255
56       tp[:datetime] = { :name => "DATETIME" }
57       tp[:timestamp] = { :name => "DATETIME" }
58       tp[:time] = { :name => "TIME" }
59       tp[:date] = { :name => "DATE" }
60       tp
61     end
62
63     def quote(value, column = nil) # :nodoc:
64       return value.quoted_id if value.respond_to?(:quoted_id)
65
66       case value
67       when String
68         if respond_to?(:h2_adapter) && value.empty?
69           "''"
70         elsif column && column.type == :binary
71           "'#{value.unpack("H*")}'"
72         elsif column && (column.type == :integer ||
73                          column.respond_to?(:primary) && column.primary && column.klass != String)
74           value.to_i.to_s
75         else
76           "'#{quote_string(value)}'"
77         end
78       else
79         super
80       end
81     end
82
83     def quote_column_name(name) #:nodoc:
84       name = name.to_s
85       if name =~ /[-]/
86         %Q{"#{name.upcase}"}
87       else
88         name
89       end
90     end
91
92     def quote_string(str)
93       str.gsub(/'/, "''")
94     end
95
96     def quoted_true
97       '1'
98     end
99
100     def quoted_false
101       '0'
102     end
103
104     def add_column(table_name, column_name, type, options = {})
105       add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
106       add_column_options!(add_column_sql, options)
107       execute(add_column_sql)
108     end
109
110     def change_column(table_name, column_name, type, options = {}) #:nodoc:
111       execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
112     end
113
114     def change_column_default(table_name, column_name, default) #:nodoc:
115       execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
116     end
117
118     def rename_column(table_name, column_name, new_column_name) #:nodoc:
119       execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
120     end
121
122     # Maps logical Rails types to MySQL-specific data types.
123     def type_to_sql(type, limit = nil, precision = nil, scale = nil)
124       return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
125
126       type
127     end
128
129     def rename_table(name, new_name)
130       execute "ALTER TABLE #{name} RENAME TO #{new_name}"
131     end
132
133     def last_insert_id
134       Integer(select_value("CALL IDENTITY()"))
135     end
136
137     def _execute(sql, name = nil)
138       result = super
139       ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
140     end
141
142     def add_limit_offset!(sql, options) #:nodoc:
143       if sql =~ /^select/i
144         offset = options[:offset] || 0
145         bef = sql[7..-1]
146         if limit = options[:limit]
147           sql.replace "SELECT LIMIT #{offset} #{limit} #{bef}"
148         elsif offset > 0
149           sql.replace "SELECT LIMIT #{offset} 0 #{bef}"
150         end
151       end
152     end
153
154     # override to filter out system tables that otherwise end
155     # up in db/schema.rb during migrations.  JdbcConnection#tables
156     # now takes an optional block filter so we can screen out
157     # rows corresponding to system tables.  HSQLDB names its
158     # system tables SYSTEM.*, but H2 seems to name them without
159     # any kind of convention
160     def tables
161       @connection.tables.select {|row| row.to_s !~ /^system_/i }
162     end
163
164     def remove_index(table_name, options = {})
165       execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
166     end
167
168     def recreate_database(name)
169       drop_database(name)
170     end
171     
172     # do nothing since database gets created upon connection. However
173     # this method gets called by rails db rake tasks so now we're
174     # avoiding method_missing error
175     def create_database(name)
176     end
177
178     def drop_database(name)
179       execute("DROP ALL OBJECTS")
180     end    
181   end
182 end