# File lib/rubyrep/proxy_connection.rb, line 150 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 229 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 281 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 265 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 165 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 427 def delete_record(table, values) delete table_delete_query(table, values) end
Destroys the session
# File lib/rubyrep/proxy_connection.rb, line 236 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 273 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 379 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 252 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.quote value, table_columns[table][column] end
Store a cursor in the register to protect it from the garbage collector.
# File lib/rubyrep/proxy_connection.rb, line 175 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 -
:
type_cast
: Unless explicitely disabled withfalse
, build type casting cursor around result. -
:
table
: Name of the table from which to read data. Required unless type casting is disabled. -
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 196 def select_cursor(options) cursor = ResultFetcher.new(self, options) unless options[:type_cast] == false cursor = TypeCastingCursor.new(self, options[:table], cursor) end 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 207 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 217 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 415 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 366 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 327 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 389 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 408 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 291 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 300 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 311 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