Froze rails gems
[depot.git] / vendor / rails / activerecord / lib / active_record / connection_adapters / abstract / database_statements.rb
1 module ActiveRecord
2 module ConnectionAdapters # :nodoc:
3 module DatabaseStatements
4 # Returns an array of record hashes with the column names as keys and
5 # column values as values.
6 def select_all(sql, name = nil)
7 select(sql, name)
8 end
9
10 # Returns a record hash with the column names as keys and column values
11 # as values.
12 def select_one(sql, name = nil)
13 result = select_all(sql, name)
14 result.first if result
15 end
16
17 # Returns a single value from a record
18 def select_value(sql, name = nil)
19 if result = select_one(sql, name)
20 result.values.first
21 end
22 end
23
24 # Returns an array of the values of the first column in a select:
25 # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
26 def select_values(sql, name = nil)
27 result = select_rows(sql, name)
28 result.map { |v| v[0] }
29 end
30
31 # Returns an array of arrays containing the field values.
32 # Order is the same as that returned by +columns+.
33 def select_rows(sql, name = nil)
34 raise NotImplementedError, "select_rows is an abstract method"
35 end
36
37 # Executes the SQL statement in the context of this connection.
38 def execute(sql, name = nil)
39 raise NotImplementedError, "execute is an abstract method"
40 end
41
42 # Returns the last auto-generated ID from the affected table.
43 def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
44 insert_sql(sql, name, pk, id_value, sequence_name)
45 end
46
47 # Executes the update statement and returns the number of rows affected.
48 def update(sql, name = nil)
49 update_sql(sql, name)
50 end
51
52 # Executes the delete statement and returns the number of rows affected.
53 def delete(sql, name = nil)
54 delete_sql(sql, name)
55 end
56
57 # Wrap a block in a transaction. Returns result of block.
58 def transaction(start_db_transaction = true)
59 transaction_open = false
60 begin
61 if block_given?
62 if start_db_transaction
63 begin_db_transaction
64 transaction_open = true
65 end
66 yield
67 end
68 rescue Exception => database_transaction_rollback
69 if transaction_open
70 transaction_open = false
71 rollback_db_transaction
72 end
73 raise unless database_transaction_rollback.is_a? ActiveRecord::Rollback
74 end
75 ensure
76 if transaction_open
77 begin
78 commit_db_transaction
79 rescue Exception => database_transaction_rollback
80 rollback_db_transaction
81 raise
82 end
83 end
84 end
85
86 # Begins the transaction (and turns off auto-committing).
87 def begin_db_transaction() end
88
89 # Commits the transaction (and turns on auto-committing).
90 def commit_db_transaction() end
91
92 # Rolls back the transaction (and turns on auto-committing). Must be
93 # done if the transaction block raises an exception or returns false.
94 def rollback_db_transaction() end
95
96 # Alias for <tt>add_limit_offset!</tt>.
97 def add_limit!(sql, options)
98 add_limit_offset!(sql, options) if options
99 end
100
101 # Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
102 # fragment that has the same semantics as LIMIT and OFFSET.
103 #
104 # +options+ must be a Hash which contains a +:limit+ option (required)
105 # and an +:offset+ option (optional).
106 #
107 # This method *modifies* the +sql+ parameter.
108 #
109 # ===== Examples
110 # add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
111 # generates
112 # SELECT * FROM suppliers LIMIT 10 OFFSET 50
113 def add_limit_offset!(sql, options)
114 if limit = options[:limit]
115 sql << " LIMIT #{sanitize_limit(limit)}"
116 if offset = options[:offset]
117 sql << " OFFSET #{offset.to_i}"
118 end
119 end
120 sql
121 end
122
123 # Appends a locking clause to an SQL statement.
124 # This method *modifies* the +sql+ parameter.
125 # # SELECT * FROM suppliers FOR UPDATE
126 # add_lock! 'SELECT * FROM suppliers', :lock => true
127 # add_lock! 'SELECT * FROM suppliers', :lock => ' FOR UPDATE'
128 def add_lock!(sql, options)
129 case lock = options[:lock]
130 when true; sql << ' FOR UPDATE'
131 when String; sql << " #{lock}"
132 end
133 end
134
135 def default_sequence_name(table, column)
136 nil
137 end
138
139 # Set the sequence to the max value of the table's column.
140 def reset_sequence!(table, column, sequence = nil)
141 # Do nothing by default. Implement for PostgreSQL, Oracle, ...
142 end
143
144 # Inserts the given fixture into the table. Overridden in adapters that require
145 # something beyond a simple insert (eg. Oracle).
146 def insert_fixture(fixture, table_name)
147 execute "INSERT INTO #{quote_table_name(table_name)} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
148 end
149
150 def empty_insert_statement(table_name)
151 "INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
152 end
153
154 def case_sensitive_equality_operator
155 "="
156 end
157
158 def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
159 "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{quoted_table_name} #{where_sql})"
160 end
161
162 protected
163 # Returns an array of record hashes with the column names as keys and
164 # column values as values.
165 def select(sql, name = nil)
166 raise NotImplementedError, "select is an abstract method"
167 end
168
169 # Returns the last auto-generated ID from the affected table.
170 def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
171 execute(sql, name)
172 id_value
173 end
174
175 # Executes the update statement and returns the number of rows affected.
176 def update_sql(sql, name = nil)
177 execute(sql, name)
178 end
179
180 # Executes the delete statement and returns the number of rows affected.
181 def delete_sql(sql, name = nil)
182 update_sql(sql, name)
183 end
184
185 # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
186 #
187 # +limit+ may be anything that can evaluate to a string via #to_s. It
188 # should look like an integer, or a comma-delimited list of integers.
189 #
190 # Returns the sanitized limit parameter, either as an integer, or as a
191 # string which contains a comma-delimited list of integers.
192 def sanitize_limit(limit)
193 if limit.to_s =~ /,/
194 limit.to_s.split(',').map{ |i| i.to_i }.join(',')
195 else
196 limit.to_i
197 end
198 end
199 end
200 end
201 end