# File lib/rubyrep/proxy_connection.rb, line 168 def primary_key_names(table_name, options = {}) return connection.primary_key_names(table_name) if options[:raw] self.primary_key_names_cache ||= {} result = primary_key_names_cache[table_name] unless result result = manual_primary_keys[table_name] || connection.primary_key_names(table_name) primary_key_names_cache[table_name] = result end result end
class RR::ProxyConnection
This class represents a remote activerecord database connection. Normally created by DatabaseProxy
Attributes
A hash as described by ActiveRecord::Base#establish_connection
The database connection
Hash to register cursors. Purpose:
Objects only referenced remotely via DRb can be garbage collected. We register them in this hash to protect them from unintended garbage collection.
A hash of manually overwritten primary keys:
-
key: table_name
-
value: array of primary key names
Caching the primary keys. This is a hash with
* key: table name * value: array of primary key names
Hash of table_name => array of column names pairs.
2-level Hash of table_name => column_name => Column objects.
Public Class Methods
Create a session on the proxy side according to provided configuration hash. config
is a hash as described by ActiveRecord::Base#establish_connection
# File lib/rubyrep/proxy_connection.rb, line 239 def initialize(config) self.connection = ConnectionExtenders.db_connect config self.config = config self.manual_primary_keys = {} end
Public Instance Methods
Returns an array of column names of the given table name. The array is ordered in the sequence as returned by the database. The result is cached for higher speed.
# File lib/rubyrep/proxy_connection.rb, line 291 def column_names(table) self.table_column_names ||= {} unless table_column_names.include? table table_column_names[table] = columns(table).map {|c| c.name} end table_column_names[table] end
Create a cursor for the given table.
* +cursor_class+: should specify the Cursor class (e. g. ProxyBlockCursor or ProxyRowCursor). * +table+: name of the table * +options+: An option hash that is used to construct the SQL query. See ProxyCursor#construct_query for details.
# File lib/rubyrep/proxy_connection.rb, line 275 def create_cursor(cursor_class, table, options = {}) cursor = cursor_class.new self, table cursor.prepare_fetch options save_cursor cursor cursor end
Creates a table Call forwarded to ActiveRecord::ConnectionAdapters::SchemaStatements#create_table Provides an empty block (to prevent DRB from calling back the client)
# File lib/rubyrep/proxy_connection.rb, line 183 def create_table(*params) connection.create_table(*params) {} end
Deletes the specified record from the named table
. values
is a hash of column_name => value pairs. (Only the primary key values will be used and must be included in the hash.) Returns the number of deleted records.
# File lib/rubyrep/proxy_connection.rb, line 437 def delete_record(table, values) delete table_delete_query(table, values) end
Destroys the session
# File lib/rubyrep/proxy_connection.rb, line 246 def destroy cursors.each_key do |cursor| cursor.destroy end cursors.clear if connection.log_subscriber ActiveSupport::Notifications.notifier.unsubscribe connection.log_subscriber connection.log_subscriber = nil end self.connection.disconnect! end
Destroys the provided cursor and removes it from the register
# File lib/rubyrep/proxy_connection.rb, line 283 def destroy_cursor(cursor) cursor.destroy cursors.delete cursor end
Inserts the specified records into the named table
. values
is a hash of column_name => value pairs.
# File lib/rubyrep/proxy_connection.rb, line 389 def insert_record(table, values) execute table_insert_query(table, values) end
Returns an array of primary key names for the given table_name
. Caches the result for future calls. Allows manual overwrites through the Configuration
options :primary_key_names
or :primary_key_only_limit
.
Parameters:
-
table_name
: name of the table -
options
: An option hash with the following valid options:-
:
raw
: iftrue
, than don't use manual overwrites and don't cache
-
Quotes the given value. It is assumed that the value belongs to the specified column name and table name. Caches the column objects for higher speed.
# File lib/rubyrep/proxy_connection.rb, line 262 def quote_value(table, column, value) self.table_columns ||= {} unless table_columns.include? table table_columns[table] = {} columns(table).each {|c| table_columns[table][c.name] = c} end connection.column_aware_quote value, table_columns[table][column.to_s] end
Store a cursor in the register to protect it from the garbage collector.
# File lib/rubyrep/proxy_connection.rb, line 193 def save_cursor(cursor) cursors[cursor] = cursor end
Returns a cusor as produced by the select_cursor
method of the connection extenders.
Two modes of operation: Either
-
execute the specified query (takes precedense) OR
-
first build the query based on options forwarded to
table_select_query
options
is a hash with
-
:
query
: executes the given query -
further options as taken by
table_select_query
to build the query -
:
row_buffer_size
: Integer controlling how many rows a read into memory at one time.
# File lib/rubyrep/proxy_connection.rb, line 208 def select_cursor(options) cursor = ResultFetcher.new(self, options) cursor = TypeCastingCursor.new(self, options[:table], cursor) cursor end
Reads the designated record from the database. Refer to select_cursor
for details parameter description. Returns the first matching row (column_name => value hash or nil
).
# File lib/rubyrep/proxy_connection.rb, line 217 def select_record(options) cursor = select_cursor({:row_buffer_size => 1}.merge(options)) row = cursor.next? ? cursor.next_row : nil cursor.clear row end
Reads the designated records from the database. Refer to select_cursor
for details parameter description. Returns an array of matching rows (column_name => value hashes).
# File lib/rubyrep/proxy_connection.rb, line 227 def select_records(options) cursor = select_cursor(options) rows = [] while cursor.next? rows << cursor.next_row end cursor.clear rows end
Returns an SQL delete query for the given table
and values
values
is a hash of column_name => value pairs. (Only the primary key values will be used and must be included in the hash.)
# File lib/rubyrep/proxy_connection.rb, line 425 def table_delete_query(table, values) query = "delete from #{quote_table_name(table)}" query << " where (" << quote_key_list(table) << ") = (" query << primary_key_names(table).map do |key| quote_value(table, key, values[key]) end.join(', ') << ")" end
Returns an SQL insert query for the given table
and values
. values
is a hash of column_name => value pairs.
# File lib/rubyrep/proxy_connection.rb, line 376 def table_insert_query(table, values) query = "insert into #{quote_table_name(table)}" query << '(' << values.keys.map do |column_name| quote_column_name(column_name) end.join(', ') << ') ' query << 'values(' << values.map do |column_name, value| quote_value(table, column_name, value) end.join(', ') << ')' query end
Returns an SQL query string for the given table
based on the provided options
. options
is a hash that can contain any of the following:
* :+from+: nil OR the hash of primary key => value pairs designating the start of the selection * :+exclude_starting_row+: if true, do not include the row specified by :+from+ * :+to+: nil OR the hash of primary key => value pairs designating the end of the selection * :+row_keys+: an array of primary key => value hashes specify the target rows.
# File lib/rubyrep/proxy_connection.rb, line 337 def table_select_query(table, options = {}) query = "select #{quote_column_list(table)}" query << " from #{quote_table_name(table)}" query << " where" if [:from, :to, :row_keys].any? {|key| options.include? key} first_condition = true if options[:from] first_condition = false matching_condition = options[:exclude_starting_row] ? '>' : '>=' query << row_condition(table, options[:from], matching_condition) end if options[:to] query << ' and' unless first_condition first_condition = false query << row_condition(table, options[:to], '<=') end if options[:row_keys] query << ' and' unless first_condition if options[:row_keys].empty? query << ' false' else query << ' (' << quote_key_list(table) << ') in (' first_key = true options[:row_keys].each do |row| query << ', ' unless first_key first_key = false query << '(' << primary_key_names(table).map do |key| quote_value(table, key, row[key]) end.join(', ') << ')' end query << ')' end end query << " order by #{quote_key_list(table)}" query end
Returns an SQL update query.
-
table
: name of the target table -
values
: a hash of column_name => value pairs -
org_key
: A hash of column_name => value pairs. Ifnil
, use the key specified byvalues
instead.
# File lib/rubyrep/proxy_connection.rb, line 399 def table_update_query(table, values, org_key = nil) org_key ||= values query = "update #{quote_table_name(table)} set " query << values.map do |column_name, value| "#{quote_column_name(column_name)} = #{quote_value(table, column_name, value)}" end.join(', ') query << " where (" << quote_key_list(table) << ") = (" query << primary_key_names(table).map do |key| quote_value(table, key, org_key[key]) end.join(', ') << ")" end
Updates the specified records of the specified table.
-
table
: name of the target table -
values
: a hash of column_name => value pairs. -
org_key
: A hash of column_name => value pairs. Ifnil
, use the key specified byvalues
instead.
Returns the number of modified records.
# File lib/rubyrep/proxy_connection.rb, line 418 def update_record(table, values, org_key = nil) update table_update_query(table, values, org_key) end
Private Instance Methods
Returns a list of quoted column names for the given table
as comma separated string.
# File lib/rubyrep/proxy_connection.rb, line 301 def quote_column_list(table) column_names(table).map do |column_name| quote_column_name(column_name) end.join(', ') end
Returns a list of quoted primary key names for the given table
as comma separated string.
# File lib/rubyrep/proxy_connection.rb, line 310 def quote_key_list(table) primary_key_names(table).map do |column_name| quote_column_name(column_name) end.join(', ') end
Generates an sql condition string for the given table
based on
* +row+: a hash of primary key => value pairs designating the target row * +condition+: the type of sql condition (something like '>=' or '=', etc.)
# File lib/rubyrep/proxy_connection.rb, line 321 def row_condition(table, row, condition) query_part = "" query_part << ' (' << quote_key_list(table) << ') ' << condition query_part << ' (' << primary_key_names(table).map do |key| quote_value(table, key, row[key]) end.join(', ') << ')' query_part end