Class: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

Inherits:
AbstractAdapter
  • Object
show all
Includes:
SchemaProcs
Defined in:
lib/connection_adapters/postgresql_adapter.rb

Overview

TODO – Add Aggregates ability

Constant Summary collapse

@@ignore_namespaces =
%w(pg_toast pg_temp_1 pg_catalog public information_schema)

Instance Method Summary collapse

Methods included from SchemaProcs

#behavior, #cascade_or_restrict, #definer_or_invoker, #strict_or_null

Instance Method Details

#add_trigger(table, events, options = {}) ⇒ Object

Add a trigger to a table



127
128
129
130
131
132
# File 'lib/connection_adapters/postgresql_adapter.rb', line 127

def add_trigger(table, events, options={})
  events += [:row]    if options.delete(:row)
  events += [:before] if options.delete(:before)
  trigger = TriggerDefinition.new(0, table, options[:name], events, options[:function])
  execute trigger.to_sql_create
end

#columns(table_name, name = nil) ⇒ Object



80
81
82
83
84
85
# File 'lib/connection_adapters/postgresql_adapter.rb', line 80

def columns(table_name, name = nil)
  # Limit, precision, and scale are all handled by the superclass.
  column_definitions(table_name).collect do |name, type, default, notnull|
    PostgreSQLColumn.new(name, default, type, notnull == 'f')
  end
end

#create_proc(name, columns = [], options = {}, &block) ⇒ Object

Create a stored procedure



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/connection_adapters/postgresql_adapter.rb', line 141

def create_proc(name, columns=[], options={}, &block)
  if select_value("SELECT count(oid) FROM pg_language WHERE lanname = 'plpgsql' ","count").to_i == 0
    execute("CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS '$libdir/plpgsql', 'plpgsql_call_handler' LANGUAGE c")
    execute("CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql HANDLER plpgsql_call_handler")
  end

  if options[:force]
    drop_proc(name, columns) rescue nil
  end

  if block_given?
    execute get_proc_query(name, columns, options) { yield }
  elsif options[:resource]
    execute get_proc_query(name, columns, options)
  else
    raise StatementInvalid.new("Missing function source")
  end
end

#create_schema(name, owner = 'postgres', options = {}) ⇒ Object



109
110
111
112
113
114
115
116
# File 'lib/connection_adapters/postgresql_adapter.rb', line 109

def create_schema(name, owner='postgres', options={})
  if schema = schemas.find {|schema| schema.name.to_s == name.to_s }
    drop_schema(schema.name, :cascade => true)
  end
  execute (schema = SchemaDefinition.new(name, owner)).to_sql(:create, options)
  self.schema_search_path = (self.schema_search_path.split(",") | [schema.name]).join(',')
#        self.schema_search_path = ( [schema.name] | self.schema_search_path.split(",") ).join(',')
end

#create_type(name, *columns) ⇒ Object



87
88
89
90
91
92
# File 'lib/connection_adapters/postgresql_adapter.rb', line 87

def create_type(name, *columns)
  if type = types.find {|typ| typ.name == name.to_s }
    drop_type(type.name, true)
  end
  execute get_type_query(name, *columns)
end

#create_view(name, columns = [], options = {}, &block) ⇒ Object



99
100
101
102
# File 'lib/connection_adapters/postgresql_adapter.rb', line 99

def create_view(name, columns=[], options={}, &block)
     view = ViewDefinition.new(0, name, columns) { yield } 
     execute view.to_sql(:create, options)
end

#drop_database(name) ⇒ Object



9
10
11
# File 'lib/connection_adapters/postgresql_adapter.rb', line 9

def drop_database name
  execute "DROP DATABASE#{' IF EXISTS' if postgresql_version >= 80200} #{name}"
end

#drop_proc(name, columns = [], cascade = false) ⇒ Object

DROP FUNCTION name ( [ type [, …] ] ) [ CASCADE | RESTRICT ]

default RESTRICT


162
163
164
# File 'lib/connection_adapters/postgresql_adapter.rb', line 162

def drop_proc(name, columns=[], cascade=false)
  execute "DROP FUNCTION #{name.to_sql_name}(#{columns.collect {|column| column}.join(", ")}) #{cascade_or_restrict(cascade)};"
end

#drop_schema(name, options = {}) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/connection_adapters/postgresql_adapter.rb', line 118

def drop_schema(name, options={})
  search_path = self.schema_search_path.split(",")
  self.schema_search_path = search_path.join(',') if search_path.delete(name.to_s)
  if schema = schemas.find {|schema| schema.name.to_s == name.to_s }
    execute SchemaDefinition.new(name).to_sql(:drop, options)
  end
end

#drop_type(name, cascade = false) ⇒ Object



94
95
96
97
# File 'lib/connection_adapters/postgresql_adapter.rb', line 94

def drop_type(name, cascade=false)
#        puts "drop_type(#{name.to_sql_name})"
  execute "DROP TYPE #{name.to_sql_name} #{cascade_or_restrict(cascade)}"
end

#drop_view(name, options = {}) ⇒ Object



104
105
106
107
# File 'lib/connection_adapters/postgresql_adapter.rb', line 104

def drop_view(name, options={})
  view = ViewDefinition.new(0, name)
  execute view.to_sql(:drop, options)
end

#procedures(lang = nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/connection_adapters/postgresql_adapter.rb', line 22

def procedures(lang=nil)
  query "    SELECT P.oid, proname, pronamespace, proowner, lanname, proisagg, prosecdef, proisstrict, proretset, provolatile, pronargs, prorettype, proargtypes, proargnames, prosrc, probin, proacl\n      FROM pg_proc P\n      JOIN pg_language L ON (P.prolang = L.oid)\n      JOIN pg_namespace N ON (P.pronamespace = N.oid)\n     WHERE N.nspname = 'public'\n       AND (proisagg = 'f')\n      \#{'AND (lanname ' + lang + ')'unless lang.nil?}\n  end_sql\nend\n"

#remove_trigger(table, name, options = {}) ⇒ Object

DROP TRIGGER name ON table [ CASCADE | RESTRICT ]



135
136
137
138
# File 'lib/connection_adapters/postgresql_adapter.rb', line 135

def remove_trigger(table, name, options={})
  options[:name] = name
  execute "DROP TRIGGER #{trigger_name(table, [], options).to_sql_name} ON #{table} #{cascade_or_restrict(options[:deep])};"
end

#schemasObject



13
14
15
16
17
18
19
20
# File 'lib/connection_adapters/postgresql_adapter.rb', line 13

def schemas 
  query("    SELECT N.nspname, S.usename\n      FROM pg_namespace N\n      JOIN pg_shadow    S ON (N.nspowner = S.usesysid)\n     WHERE N.nspname NOT IN (\#{@@ignore_namespaces.collect {|nsp| nsp.to_sql_value }.join(',')})\n  end_sql\nend\n").collect {|row| SchemaDefinition.new(*row) }

#triggers(table_name) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/connection_adapters/postgresql_adapter.rb', line 34

def triggers(table_name)
  query("    SELECT T.oid, C.relname, T.tgname, T.tgtype, P.proname\n      FROM pg_trigger T\n      JOIN pg_class   C ON (T.tgrelid = C.OID AND C.relname = '\#{table_name}' AND T.tgisconstraint = 'f')\n      JOIN pg_proc    P ON (T.tgfoid = P.OID)\n  end_sql\nend\n").collect {|row| TriggerDefinition.new(*row) }

#typesObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/connection_adapters/postgresql_adapter.rb', line 43

def types
  result = query("    SELECT T.oid, T.typname, A.attname, format_type(A.atttypid, A.atttypmod) AS type\n      FROM pg_type      T\n      JOIN pg_class     C ON (T.typrelid = C.oid)\n      JOIN pg_attribute A ON (A.attrelid = C.oid AND C.relkind = 'c')\n  end_sql\n\n  type_id = nil\n  types = []\n  result.each { |row|\n    if type_id != row[0]\n      types << TypeDefinition.new(row[0], row[1], [])\n      type_id = row[0]\n    end\n\n    types.last.columns << [row[2], row[3]]\n  }\n\n  types\nend\n")

#viewsObject

TODO Implement this



77
78
# File 'lib/connection_adapters/postgresql_adapter.rb', line 77

def views #:nodoc:
end