class Flounder::Domain
Attributes
connection_pool[R]
logger[RW]
savepoints[R]
Public Class Methods
new(connection_pool)
click to toggle source
# File lib/flounder/domain.rb, line 18 def initialize connection_pool @connection_pool = connection_pool # maps from plural/singular names to entities in this domain @plural = {} @singular = {} # Maps table names to entities @entity_by_table_name = {} # maps OIDs of entities to entities @oids_entity_map = Hash.new { |hash, oid| hash[oid] = entity_from_oid(oid) } @logger = Logger.new(NilDevice.new) @savepoints = Hash.new(0) end
Public Instance Methods
[](name)
click to toggle source
Returns the entity with the given plural name.
# File lib/flounder/domain.rb, line 84 def [] name raise NoSuchEntity, "No such entity #{name.inspect} in this domain." \ unless @plural.has_key?(name) @plural.fetch(name) end
by_oid(oid)
click to toggle source
Returns an entity by table oid.
# File lib/flounder/domain.rb, line 129 def by_oid oid return nil if oid==0 # computed fields @oids_entity_map[oid] end
entities()
click to toggle source
Returns all entities as an array.
# File lib/flounder/domain.rb, line 93 def entities @plural.values end
entity(plural, singular, table_name) { |e| ... }
click to toggle source
Define a database entity and alias it to plural and singular names that will be used in the code.
# File lib/flounder/domain.rb, line 113 def entity plural, singular, table_name entity = Entity.new(self, plural, singular, table_name). tap { |e| yield e if block_given? } raise ArgumentError, "Table #{table_name} was already associated with an entity." \ if @entity_by_table_name.has_key?(table_name) @plural[plural] = entity @singular[singular] = entity @entity_by_table_name[table_name] = entity entity end
expr(&block)
click to toggle source
Builds an SQL expression.
domain.expr { concat('1', '2') }
# File lib/flounder/domain.rb, line 61 def expr &block builder = Expression::Builder.new(self) builder.call(&block) end
has_entity?(name)
click to toggle source
# File lib/flounder/domain.rb, line 96 def has_entity? name @plural.has_key? name end
log_bm(measure)
click to toggle source
# File lib/flounder/domain.rb, line 105 def log_bm measure stats << measure.total * 1_000 @logger.info "Query took #{measure}." end
log_sql(sql)
click to toggle source
Logs sql statements that are prepared for execution.
# File lib/flounder/domain.rb, line 102 def log_sql sql @logger.info sql end
reset_stats()
click to toggle source
Resets this threads stats.
# File lib/flounder/domain.rb, line 78 def reset_stats Thread.current[:__flounder_stats] = nil end
stats()
click to toggle source
Returns an aggregate of all query wall clock times. Please see github.com/josephruscio/aggregate for more information on this object.
@return [Aggregate] statistics for this thread
# File lib/flounder/domain.rb, line 72 def stats Thread.current[:__flounder_stats] ||= Aggregate.new end
transaction(&block)
click to toggle source
# File lib/flounder/domain.rb, line 45 def transaction &block with_connection do |conn| if in_transaction?(conn) savepoint(conn) { block.call(conn) } else conn.transaction do savepoint(conn) { block.call(conn) } end end end end
Private Instance Methods
dec_sp(connection)
click to toggle source
# File lib/flounder/domain.rb, line 141 def dec_sp connection savepoints[connection.object_id] -= 1 if savepoints[connection.object_id] < 0 fail "ASSERTION FAILURE: Savepoint count cannot drop below zero!" end nil end
entity_from_oid(oid)
click to toggle source
# File lib/flounder/domain.rb, line 167 def entity_from_oid oid connection_pool.with_connection do |conn| table_name = conn.exec(%Q(SELECT #{oid}::regclass)). getvalue(0,0) @entity_by_table_name[table_name] end end
in_transaction?(connection)
click to toggle source
# File lib/flounder/domain.rb, line 149 def in_transaction? connection sp_count(connection) > 0 end
inc_sp(connection)
click to toggle source
# File lib/flounder/domain.rb, line 138 def inc_sp connection savepoints[connection.object_id] += 1 end
savepoint(connection) { || ... }
click to toggle source
# File lib/flounder/domain.rb, line 152 def savepoint connection, &block sp_number = inc_sp(connection) sp_name = "s#{sp_number}" connection.exec("SAVEPOINT #{sp_name};") begin yield rescue Exception connection.exec("ROLLBACK TO SAVEPOINT #{sp_name};") raise ensure dec_sp(connection) end end
sp_count(connection)
click to toggle source
# File lib/flounder/domain.rb, line 135 def sp_count connection savepoints[connection.object_id] end