lib/og/backends/psql.rb in nitro-0.7.0 vs lib/og/backends/psql.rb in nitro-0.8.0
- old
+ new
@@ -2,22 +2,60 @@
# * George Moschovitis <gm@navel.gr>
#
# (c) 2004 Navel, all rights reserved.
# $Id: psql.rb 194 2004-12-20 20:23:57Z gmosx $
-require "postgres"
+require 'postgres'
-require "og/backend"
+require 'og/backend'
-module Og
+class Og
-# = Utils
+# = PsqlBackend
#
-# A collection of useful utilities.
+# Implements a PostgreSQL powered backend.
+# This backend is compatible with Michael Neumann's postgres-pr
+# pure ruby driver.
#
-module Utils
+class PsqlBackend < Og::Backend
+ # A mapping between Ruby and SQL types.
+ #
+ TYPEMAP = {
+ Integer => 'integer',
+ Fixnum => 'integer',
+ Float => 'float',
+ String => 'text',
+ Time => 'timestamp',
+ Date => 'date',
+ TrueClass => 'boolean',
+ Object => 'text',
+ Array => 'text',
+ Hash => 'text'
+ }
+
+ # Intitialize the connection to the RDBMS.
+ #
+ def initialize(config)
+ begin
+ @conn = PGconn.connect(nil, nil, nil, nil, config[:database],
+ config[:user], config[:password])
+ rescue => ex
+ # gmosx: any idea how to better test this?
+ if ex.to_s =~ /database .* does not exist/i
+ Logger.info "Database '#{config[:database]}' not found!"
+ PsqlBackend.create_db(config[:database], config[:user])
+ retry
+ end
+ raise
+ end
+ end
+
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ # Utilities
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
# Escape an SQL string
#
def self.escape(str)
return nil unless str
return PGconn.escape(str)
@@ -65,19 +103,19 @@
if p.klass.ancestors.include?(Integer)
return "#\{@#{p.symbol} || 'NULL'\}"
elsif p.klass.ancestors.include?(Float)
return "#\{@#{p.symbol} || 'NULL'\}"
elsif p.klass.ancestors.include?(String)
- return "'#\{Og::Utils.escape(@#{p.symbol})\}'"
+ return "'#\{Og::PsqlBackend.escape(@#{p.symbol})\}'"
elsif p.klass.ancestors.include?(Time)
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
+ return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
elsif p.klass.ancestors.include?(Date)
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.date(@#{p.symbol})\}'" : 'NULL'\}|
+ return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.date(@#{p.symbol})\}'" : 'NULL'\}|
elsif p.klass.ancestors.include?(TrueClass)
return "#\{@#{p.symbol} || 'NULL'\}"
else
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
+ return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
end
end
# Return an evaluator for reading the property.
# No need to optimize this, used only to precalculate code.
@@ -88,13 +126,13 @@
elsif p.klass.ancestors.include?(Float)
return "res.getvalue(tuple, #{idx}).to_f()"
elsif p.klass.ancestors.include?(String)
return "res.getvalue(tuple, #{idx})"
elsif p.klass.ancestors.include?(Time)
- return "Og::Utils.parse_timestamp(res.getvalue(tuple, #{idx}))"
+ return "Og::PsqlBackend.parse_timestamp(res.getvalue(tuple, #{idx}))"
elsif p.klass.ancestors.include?(Date)
- return "Og::Utils.parse_date(res.getvalue(tuple, #{idx}))"
+ return "Og::PsqlBackend.parse_date(res.getvalue(tuple, #{idx}))"
elsif p.klass.ancestors.include?(TrueClass)
return "('true' == res.getvalue(tuple, #{idx}))"
else
return "YAML::load(res.getvalue(tuple, #{idx}))"
end
@@ -130,106 +168,69 @@
def self.eval_og_oid(klass)
klass.class_eval %{
prop_accessor :oid, Fixnum, :sql => "integer PRIMARY KEY"
}
end
-end
-# = PsqlBackend
-#
-# Implements a PostgreSQL powered backend.
-# This backend is compatible with Michael Neumann's postgres-pr
-# pure ruby driver.
-#
-class PsqlBackend < Og::Backend
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ # Connection methods.
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # A mapping between Ruby and SQL types.
- #
- TYPEMAP = {
- Integer => "integer",
- Fixnum => "integer",
- Float => "float",
- String => "text",
- Time => "timestamp",
- Date => "date",
- TrueClass => "boolean",
- Object => "text",
- Array => "text",
- Hash => "text"
- }
-
- # Intitialize the connection to the RDBMS.
- #
- def initialize(config)
- begin
- @conn = PGconn.connect(nil, nil, nil, nil, config[:database],
- config[:user], config[:password])
- rescue => ex
- # gmosx: any idea how to better test this?
- if ex.to_s =~ /database .* does not exist/i
- $log.info "Database '#{config[:database]}' not found!"
- PsqlBackend.create_db(config[:database], config[:user])
- retry
- end
- raise
- end
- end
-
# Create the database.
#
def self.create_db(database, user = nil, password = nil)
- $log.info "Creating database '#{database}'."
+ Logger.info "Creating database '#{database}'."
`createdb #{database} -U #{user}`
end
# Drop the database.
#
def self.drop_db(database, user = nil, password = nil)
- $log.info "Dropping database '#{database}'."
+ Logger.info "Dropping database '#{database}'."
`dropdb #{database} -U #{user}`
end
# Execute an SQL query and return the result
#
def query(sql)
- $log.debug sql if $DBG
+ Logger.debug sql if $DBG
return @conn.exec(sql)
end
# Execute an SQL query, no result returned.
#
def exec(sql)
- $log.debug sql if $DBG
+ Logger.debug sql if $DBG
res = @conn.exec(sql)
res.clear()
end
# Execute an SQL query and return the result. Wrapped in a rescue
# block.
#
def safe_query(sql)
- $log.debug sql if $DBG
+ Logger.debug sql if $DBG
begin
return @conn.exec(sql)
rescue => ex
- $log.error "DB error #{ex}, [#{sql}]"
- $log.error ex.backtrace
+ Logger.error "DB error #{ex}, [#{sql}]"
+ Logger.error ex.backtrace
return nil
end
end
# Execute an SQL query, no result returned. Wrapped in a rescue
# block.
#
def safe_exec(sql)
- $log.debug sql if $DBG
+ Logger.debug sql if $DBG
begin
res = @conn.exec(sql)
res.clear()
rescue => ex
- $log.error "DB error #{ex}, [#{sql}]"
- $log.error ex.backtrace
+ Logger.error "DB error #{ex}, [#{sql}]"
+ Logger.error ex.backtrace
end
end
# Check if it is a valid resultset.
#
@@ -266,30 +267,30 @@
end
end
begin
exec(sql)
- $log.info "Created table '#{klass::DBTABLE}'."
+ Logger.info "Created table '#{klass::DBTABLE}'."
rescue => ex
# gmosx: any idea how to better test this?
if ex.to_s =~ /relation .* already exists/i
- $log.debug "Table already exists" if $DBG
+ Logger.debug "Table already exists" if $DBG
else
raise
end
end
# create the sequence for this table. Even if the table
# uses the oids_seq, attempt to create it. This makes
# the system more fault tolerant.
begin
exec "CREATE SEQUENCE #{klass::DBSEQ}"
- $log.info "Created sequence '#{klass::DBSEQ}'."
+ Logger.info "Created sequence '#{klass::DBSEQ}'."
rescue => ex
# gmosx: any idea how to better test this?
if ex.to_s =~ /relation .* already exists/i
- $log.debug "Sequence already exists" if $DBG
+ Logger.debug "Sequence already exists" if $DBG
else
raise
end
end
@@ -301,34 +302,34 @@
# the class to join to and some options.
join_class, options = *data
# gmosx: dont use DBTABLE here, perhaps the join class
# is not managed yet.
- join_table = "#{Og::Utils.join_table(klass, join_class)}"
- join_src = "#{Og::Utils.encode(klass)}_oid"
- join_dst = "#{Og::Utils.encode(join_class)}_oid"
+ join_table = "#{self.class.join_table(klass, join_class)}"
+ join_src = "#{self.class.encode(klass)}_oid"
+ join_dst = "#{self.class.encode(join_class)}_oid"
begin
exec "CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )"
exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
rescue => ex
# gmosx: any idea how to better test this?
if ex.to_s =~ /relation .* already exists/i
- $log.debug "Join table already exists" if $DBG
+ Logger.debug "Join table already exists" if $DBG
else
raise
end
end
end
end
begin
exec(sql)
- $log.info "Created join table '#{join_table}'."
+ Logger.info "Created join table '#{join_table}'."
rescue => ex
# gmosx: any idea how to better test this?
if ex.to_s =~ /relation .* already exists/i
- $log.debug "Join table already exists" if $DBG
+ Logger.debug "Join table already exists" if $DBG
else
raise
end
end