]> source.dussan.org Git - sonarqube.git/blob
4a82ca8224e9a7503b3052c9dee23fe9436c039c
[sonarqube.git] /
1 module ::ArJdbc
2   module FireBird
3
4     def self.extended(mod)
5       unless @lob_callback_added
6         ActiveRecord::Base.class_eval do
7           def after_save_with_firebird_blob
8             self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |c|
9               value = self[c.name]
10               value = value.to_yaml if unserializable_attribute?(c.name, c)
11               next if value.nil?
12               connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
13             end
14           end
15         end
16
17         ActiveRecord::Base.after_save :after_save_with_firebird_blob
18         @lob_callback_added = true
19       end
20     end
21
22     def adapter_name
23       'Firebird'
24     end
25
26     def arel2_visitors
27       require 'arel/visitors/firebird'
28       {'firebird' => ::Arel::Visitors::Firebird, 'firebirdsql' => ::Arel::Visitors::Firebird}
29     end
30
31     def modify_types(tp)
32       tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
33       tp[:string][:limit] = 252
34       tp[:integer][:limit] = nil
35       tp
36     end
37
38     def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc:
39       execute(sql, name)
40       id_value
41     end
42
43     def add_limit_offset!(sql, options) # :nodoc:
44       if options[:limit]
45         limit_string = "FIRST #{options[:limit]}"
46         limit_string << " SKIP #{options[:offset]}" if options[:offset]
47         sql.sub!(/\A(\s*SELECT\s)/i, '\&' + limit_string + ' ')
48       end
49     end
50
51     def prefetch_primary_key?(table_name = nil)
52       true
53     end
54
55     def default_sequence_name(table_name, primary_key) # :nodoc:
56       "#{table_name}_seq"
57     end
58
59     def next_sequence_value(sequence_name)
60       select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
61     end
62
63     def create_table(name, options = {}) #:nodoc:
64       super(name, options)
65       execute "CREATE GENERATOR #{name}_seq"
66     end
67
68     def rename_table(name, new_name) #:nodoc:
69       execute "RENAME #{name} TO #{new_name}"
70       execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
71     end
72
73     def drop_table(name, options = {}) #:nodoc:
74       super(name)
75       execute "DROP GENERATOR #{name}_seq" rescue nil
76     end
77
78     def change_column(table_name, column_name, type, options = {}) #:nodoc:
79       execute "ALTER TABLE #{table_name} ALTER  #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
80     end
81
82     def rename_column(table_name, column_name, new_column_name)
83       execute "ALTER TABLE #{table_name} ALTER  #{column_name} TO #{new_column_name}"
84     end
85
86     def remove_index(table_name, options) #:nodoc:
87       execute "DROP INDEX #{index_name(table_name, options)}"
88     end
89
90     def quote(value, column = nil) # :nodoc:
91       return value.quoted_id if value.respond_to?(:quoted_id)
92
93       # BLOBs are updated separately by an after_save trigger.
94       return value.nil? ? "NULL" : "'#{quote_string(value[0..1])}'" if column && [:binary, :text].include?(column.type)
95
96       if [Time, DateTime].include?(value.class)
97         "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
98       else
99         if column && column.type == :primary_key
100           return value.to_s
101         end
102         super
103       end
104     end
105
106     def quote_string(string) # :nodoc:
107       string.gsub(/'/, "''")
108     end
109
110     def quote_column_name(column_name) # :nodoc:
111       %Q("#{ar_to_fb_case(column_name)}")
112     end
113
114     def quoted_true # :nodoc:
115       quote(1)
116     end
117
118     def quoted_false # :nodoc:
119       quote(0)
120     end
121
122     private
123
124     # Maps uppercase Firebird column names to lowercase for ActiveRecord;
125     # mixed-case columns retain their original case.
126     def fb_to_ar_case(column_name)
127       column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
128     end
129
130     # Maps lowercase ActiveRecord column names to uppercase for Fierbird;
131     # mixed-case columns retain their original case.
132     def ar_to_fb_case(column_name)
133       column_name =~ /[[:upper:]]/ ? column_name : column_name.to_s.upcase
134     end
135   end
136 end