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)
10 # Returns a record hash with the column names as keys and column values
12 def select_one(sql
, name
= nil)
13 result
= select_all(sql
, name
)
14 result
.first
if result
17 # Returns a single value from a record
18 def select_value(sql
, name
= nil)
19 if result
= select_one(sql
, name
)
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] }
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"
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"
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
)
47 # Executes the update statement and returns the number of rows affected.
48 def update(sql
, name
= nil)
52 # Executes the delete statement and returns the number of rows affected.
53 def delete(sql
, name
= nil)
57 # Wrap a block in a transaction. Returns result of block.
58 def transaction(start_db_transaction
= true)
59 transaction_open
= false
62 if start_db_transaction
64 transaction_open
= true
68 rescue Exception
=> database_transaction_rollback
70 transaction_open
= false
71 rollback_db_transaction
73 raise unless database_transaction_rollback
.is_a
? ActiveRecord
::Rollback
79 rescue Exception
=> database_transaction_rollback
80 rollback_db_transaction
86 # Begins the transaction (and turns off auto-committing).
87 def begin_db_transaction() end
89 # Commits the transaction (and turns on auto-committing).
90 def commit_db_transaction() end
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
96 # Alias for <tt>add_limit_offset!</tt>.
97 def add_limit
!(sql
, options
)
98 add_limit_offset
!(sql
, options
) if options
101 # Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
102 # fragment that has the same semantics as LIMIT and OFFSET.
104 # +options+ must be a Hash which contains a +:limit+ option (required)
105 # and an +:offset+ option (optional).
107 # This method *modifies* the +sql+ parameter.
110 # add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
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}"
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}"
135 def default_sequence_name(table
, column
)
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, ...
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'
150 def empty_insert_statement(table_name
)
151 "INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
154 def case_sensitive_equality_operator
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})"
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"
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)
175 # Executes the update statement and returns the number of rows affected.
176 def update_sql(sql
, name
= nil)
180 # Executes the delete statement and returns the number of rows affected.
181 def delete_sql(sql
, name
= nil)
182 update_sql(sql
, name
)
185 # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
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.
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
)
194 limit
.to_s
.split(',').map
{ |i
| i
.to_i
}.join(',')