lib/og/connection.rb in og-0.9.5 vs lib/og/connection.rb in og-0.10.0

- old
+ new

@@ -1,8 +1,8 @@ # * George Moschovitis <gm@navel.gr> # (c) 2004-2005 Navel, all rights reserved. -# $Id: connection.rb 248 2005-01-31 13:38:34Z gmosx $ +# $Id: connection.rb 254 2005-02-10 12:44:05Z gmosx $ class Og; require 'glue/property' require 'glue/array' @@ -10,45 +10,142 @@ # A Connection to the Database. This file defines the skeleton # functionality. A backend specific implementation file (driver) # implements all methods. # -# === Future +# == Future # # - support caching. # - support prepared statements. class Connection - # The frontend (Og) contains useful strucutres. + + # The Og database object. - attr_reader :og - - # The backend - attr_reader :db - # If set to true, the select methods deserialize the - # resultset to create entities. + # The actual connection to the backend store. - attr_accessor :deserialize - + attr_accessor :store + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # :section: Backend connection methods. + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Initialize a connection to the database. - def initialize(og) - @og = og - @db = @og.config[:backend].new(@og.config) - @deserialize = true + def initialize(db) + @db = db Logger.debug "Created DB connection." if $DBG end # Close the connection to the database. - def close() - @db.close() + def close + @store.close Logger.debug "Closed DB connection." if $DBG end + # Create the managed object table. The properties of the + # object are mapped to the table columns. Additional sql relations + # and constrains are created (indicices, sequences, etc). + + def create_table(klass) + raise 'Not implemented!' + end + + # Drop the managed object table. + + def drop_table(klass) + exec "DROP TABLE #{klass::DBTABLE}" + end + + # Prepare an sql statement. + + def prepare(sql) + raise 'Not implemented!' + end + + # Execute an SQL query and return the result. + + def query(sql) + raise 'Not implemented!' + end + + # Execute an SQL query, no result returned. + + def exec(sql) + raise 'Not implemented!' + end + alias_method :execute, :exec + + # Start a new transaction. + + def start + exec 'START TRANSACTION' + end + + # Commit a transaction. + + def commit + exec 'COMMIT' + end + + # Rollback a transaction. + + def rollback + exec 'ROLLBACK' + end + + # Transaction helper. In the transaction block use + # the db pointer to the backend. + + def transaction(&block) + begin + start + yield(self) + commit + rescue => ex + Logger.error "DB Error: ERROR IN TRANSACTION" + Logger.error "#{ex}" + Logger.error "#{ex.backtrace}" + rollback + end + end + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # :section: Deserialization methods. + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + # Is the given resultset valid? + + def valid_res?(res) + return !(res.nil?) + end + + # Read (deserialize) one row of the resultset. + + def read_one(res, klass) + raise 'Not implemented!' + end + + # Read (deserialize) all rows of the resultset. + + def read_all(res, klass) + raise 'Not implemented!' + end + + # Read the first column of the resultset as an Integer. + + def read_int(res, idx = 0) + raise 'Not implemented!' + end + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # :section: Managed object methods. + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Save an object to the database. Insert if this is a new object or # update if this is already stored in the database. def save(obj) if obj.oid @@ -108,28 +205,28 @@ # Load an object by oid. def load_by_oid(oid, klass) res = query "SELECT * FROM #{klass::DBTABLE} WHERE oid=#{oid}" - @deserialize? @db.deserialize_one(res, klass) : res + read_one(res, klass) end alias_method :get_by_oid, :load_by_oid # Load an object by name. def load_by_name(name, klass) res = query "SELECT * FROM #{klass::DBTABLE} WHERE name='#{name}'" - @deserialize? @db.deserialize_one(res, klass) : res + read_one(res, klass) end alias_method :get_by_name, :load_by_name # Load all objects of the given klass. # Used to be called 'collect' in an earlier version. def load_all(klass, extrasql = nil) res = query "SELECT * FROM #{klass::DBTABLE} #{extrasql}" - @deserialize? @db.deserialize_all(res, klass) : res + read_all(res, klass) end alias_method :get_all, :load_all # Perform a standard SQL query to the database. Deserializes the # results. @@ -137,35 +234,34 @@ def select(sql, klass) unless sql =~ /SELECT/i sql = "SELECT * FROM #{klass::DBTABLE} WHERE #{sql}" end - res = @db.safe_query(sql) - @deserialize? @db.deserialize_all(res, klass) : res + res = query(sql) + read_all(res, klass) end # Optimized for one result. def select_one(sql, klass) unless sql =~ /SELECT/i sql = "SELECT * FROM #{klass::DBTABLE} WHERE #{sql}" end - res = @db.safe_query(sql) - @deserialize? @db.deserialize_one(res, klass) : res + res = query(sql) + read_one(res, klass) end # Perform a count query. def count(sql, klass = nil) unless sql =~ /SELECT/i sql = "SELECT COUNT(*) FROM #{klass::DBTABLE} WHERE #{sql}" end - res = @db.safe_query(sql) - - return @db.get_int(res) + res = query(sql) + return read_int(res) end # Delete an object from the database. Allways perform a deep delete. # # No need to optimize here with pregenerated code. Deletes are @@ -196,69 +292,9 @@ end end end end alias_method :delete!, :delete - - # Create the managed object table. The properties of the - # object are mapped to the table columns. Additional sql relations - # and constrains are created (indicices, sequences, etc). - - def create_table(klass) - @db.create_table(klass) - end - - # Drop the managed object table. - - def drop_table(klass) - @db.drop_table(klass) - end - - # Execute an SQL query and return the result - - def query(sql) - @db.safe_query(sql) - end - - # Execute an SQL query, no result returned. - - def exec(sql) - @db.safe_exec(sql) - end - - # Start a new transaction. - - def start - @db.start - end - - # Commit a transaction. - - def commit - @db.commit - end - - # Rollback transaction. - - def rollback - @db.rollback - end - - # Transaction helper. In the transaction block use - # the db pointer to the backend. - - def transaction(&block) - begin - @db.start - yield(@db) - @db.commit - rescue => ex - Logger.error "DB Error: ERROR IN TRANSACTION" - Logger.error #{ex} - Logger.error #{ex.backtrace} - @db.rollback - end - end end end