Namespace

Class Index [+]

Quicksearch

ArJdbc::PostgreSQL

Public Class Methods

column_selector() click to toggle source
    # File lib/arjdbc/postgresql/adapter.rb, line 13
13:     def self.column_selector
14:       [/postgre/, lambda {|cfg,col| col.extend(::ArJdbc::PostgreSQL::Column)}]
15:     end
extended(mod) click to toggle source
    # File lib/arjdbc/postgresql/adapter.rb, line 7
 7:     def self.extended(mod)
 8:       mod.class.class_eval do
 9:         alias_chained_method :insert, :query_dirty, :insert
10:       end
11:     end
jdbc_connection_class() click to toggle source
    # File lib/arjdbc/postgresql/adapter.rb, line 17
17:     def self.jdbc_connection_class
18:       ::ActiveRecord::ConnectionAdapters::PostgresJdbcConnection
19:     end

Public Instance Methods

add_column(table_name, column_name, type, options = {}) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 476
476:     def add_column(table_name, column_name, type, options = {})
477:       execute("ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}")
478:       change_column_default(table_name, column_name, options[:default]) unless options[:default].nil?
479:       if options[:null] == false
480:         execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)} = '#{options[:default]}'") if options[:default]
481:         execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} SET NOT NULL")
482:       end
483:     end
add_order_by_for_association_limiting!(sql, options) click to toggle source

ORDER BY clause for the passed order option.

PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this by wrapping the sql as a sub-select and ordering in that query.

     # File lib/arjdbc/postgresql/adapter.rb, line 402
402:     def add_order_by_for_association_limiting!(sql, options)
403:       return sql if options[:order].blank?
404: 
405:       order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
406:       order.map! { |s| 'DESC' if s =~ /\bdesc$/ }
407:       order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')
408: 
409:       sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
410:     end
all_schemas() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 340
340:     def all_schemas
341:       select('select nspname from pg_namespace').map {|r| r["nspname"] }
342:     end
arel2_visitors() click to toggle source
    # File lib/arjdbc/postgresql/adapter.rb, line 93
93:     def arel2_visitors
94:       {'jdbcpostgresql' => ::Arel::Visitors::PostgreSQL}
95:     end
change_column_null(table_name, column_name, null, default = nil) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 504
504:     def change_column_null(table_name, column_name, null, default = nil)
505:       unless null || default.nil?
506:         execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
507:       end
508:       execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
509:     end
columns(table_name, name=nil) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 271
271:     def columns(table_name, name=nil)
272:       schema_name = @config[:schema_search_path]
273:       if table_name =~ /\./
274:         parts = table_name.split(/\./)
275:         table_name = parts.pop
276:         schema_name = parts.join(".")
277:       end
278:       @connection.columns_internal(table_name, name, schema_name)
279:     end
create_database(name, options = {}) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 324
324:     def create_database(name, options = {})
325:       execute "CREATE DATABASE \"#{name}\" ENCODING='#{options[:encoding] || 'utf8'}'"
326:     end
create_savepoint() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 146
146:     def create_savepoint
147:       execute("SAVEPOINT #{current_savepoint_name}")
148:     end
create_schema(schema_name, pg_username) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 332
332:     def create_schema(schema_name, pg_username)
333:       execute("CREATE SCHEMA \"#{schema_name}\" AUTHORIZATION \"#{pg_username}\"")
334:     end
default_sequence_name(table_name, pk = nil) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 164
164:     def default_sequence_name(table_name, pk = nil)
165:       default_pk, default_seq = pk_and_sequence_for(table_name)
166:       default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq"
167:     end
distinct(columns, order_by) click to toggle source

SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.

PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and requires that the ORDER BY include the distinct column.

  distinct("posts.id", "posts.created_at desc")
     # File lib/arjdbc/postgresql/adapter.rb, line 383
383:     def distinct(columns, order_by)
384:       return "DISTINCT #{columns}" if order_by.blank?
385: 
386:       # construct a clean list of column names from the ORDER BY clause, removing
387:       # any asc/desc modifiers
388:       order_columns = order_by.split(',').collect { |s| s.split.first }
389:       order_columns.delete_if(&:blank?)
390:       order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
391: 
392:       # return a DISTINCT ON() clause that's distinct on the columns we want but includes
393:       # all the required columns for the ORDER BY to work properly
394:       sql = "DISTINCT ON (#{columns}) #{columns}, "
395:       sql << order_columns * ', '
396:     end
drop_database(name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 328
328:     def drop_database(name)
329:       execute "DROP DATABASE IF EXISTS \"#{name}\""
330:     end
drop_schema(schema_name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 336
336:     def drop_schema(schema_name)
337:       execute("DROP SCHEMA \"#{schema_name}\"")
338:     end
escape_bytea(s) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 434
434:     def escape_bytea(s)
435:       if s
436:         result = ''
437:         s.each_byte { |c| result << sprintf('\\%03o', c) }
438:         result
439:       end
440:     end
indexes(table_name, name = nil) click to toggle source

From postgresql_adapter.rb

     # File lib/arjdbc/postgresql/adapter.rb, line 282
282:     def indexes(table_name, name = nil)
283:       result = select_rows(        SELECT i.relname, d.indisunique, a.attname          FROM pg_class t, pg_class i, pg_index d, pg_attribute a         WHERE i.relkind = 'i'           AND d.indexrelid = i.oid           AND d.indisprimary = 'f'           AND t.oid = d.indrelid           AND t.relname = '#{table_name}'           AND a.attrelid = t.oid           AND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum              OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum              OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum              OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum              OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum )        ORDER BY i.relname, name)
284: 
285:       current_index = nil
286:       indexes = []
287: 
288:       result.each do |row|
289:         if current_index != row[0]
290:           indexes << ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, row[0], row[1] == "t", [])
291:           current_index = row[0]
292:         end
293: 
294:         indexes.last.columns << row[2]
295:       end
296: 
297:       indexes
298:     end
insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 237
237:     def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
238:       # Extract the table from the insert sql. Yuck.
239:       table = sql.split(" ", 4)[2].gsub('"', '')
240: 
241:       # Try an insert with 'returning id' if available (PG >= 8.2)
242:       if supports_insert_with_returning? && id_value.nil?
243:         pk, sequence_name = *pk_and_sequence_for(table) unless pk
244:         if pk
245:           id_value = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
246:           clear_query_cache #FIXME: Why now?
247:           return id_value
248:         end
249:       end
250: 
251:       # Otherwise, plain insert
252:       execute(sql, name)
253: 
254:       # Don't need to look up id_value if we already have it.
255:       # (and can't in case of non-sequence PK)
256:       unless id_value
257:         # If neither pk nor sequence name is given, look them up.
258:         unless pk || sequence_name
259:           pk, sequence_name = *pk_and_sequence_for(table)
260:         end
261: 
262:         # If a pk is given, fallback to default sequence name.
263:         # Don't fetch last insert id for a table without a pk.
264:         if pk && sequence_name ||= default_sequence_name(table, pk)
265:           id_value = last_insert_id(table, sequence_name)
266:         end
267:       end
268:       id_value
269:     end
last_insert_id(table, sequence_name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 315
315:     def last_insert_id(table, sequence_name)
316:       Integer(select_value("SELECT currval('#{sequence_name}')"))
317:     end
modify_types(tp) click to toggle source
    # File lib/arjdbc/postgresql/adapter.rb, line 79
79:     def modify_types(tp)
80:       tp[:primary_key] = "serial primary key"
81:       tp[:string][:limit] = 255
82:       tp[:integer][:limit] = nil
83:       tp[:boolean] = { :name => "boolean" }
84:       tp[:float] = { :name => "float" }
85:       tp[:decimal] = { :name => "decimal" }
86:       tp
87:     end
postgresql_version() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 97
 97:     def postgresql_version
 98:       @postgresql_version ||=
 99:         begin
100:           value = select_value('SELECT version()')
101:           if value =~ /PostgreSQL (\d+)\.(\d+)\.(\d+)/
102:             ($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
103:           else
104:             0
105:           end
106:         end
107:     end
primary_key(table) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 344
344:     def primary_key(table)
345:       pk_and_sequence = pk_and_sequence_for(table)
346:       pk_and_sequence && pk_and_sequence.first
347:     end
quote_column_name(name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 453
453:     def quote_column_name(name)
454:       %("#{name}")
455:     end
quote_table_name(name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 442
442:     def quote_table_name(name)
443:       schema, name_part = extract_pg_identifier_from_name(name.to_s)
444: 
445:       unless name_part
446:         quote_column_name(schema)
447:       else
448:         table_name, name_part = extract_pg_identifier_from_name(name_part)
449:         "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
450:       end
451:     end
recreate_database(name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 319
319:     def recreate_database(name)
320:       drop_database(name)
321:       create_database(name)
322:     end
release_savepoint() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 154
154:     def release_savepoint
155:       execute("RELEASE SAVEPOINT #{current_savepoint_name}")
156:     end
rename_table(name, new_name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 472
472:     def rename_table(name, new_name)
473:       execute "ALTER TABLE #{name} RENAME TO #{new_name}"
474:     end
rollback_to_savepoint() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 150
150:     def rollback_to_savepoint
151:       execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
152:     end
structure_dump() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 349
349:     def structure_dump
350:       database = @config[:database]
351:       if database.nil?
352:         if @config[:url] =~ /\/([^\/]*)$/
353:           database = $1
354:         else
355:           raise "Could not figure out what database this url is for #{@config["url"]}"
356:         end
357:       end
358: 
359:       ENV['PGHOST']     = @config[:host] if @config[:host]
360:       ENV['PGPORT']     = @config[:port].to_s if @config[:port]
361:       ENV['PGPASSWORD'] = @config[:password].to_s if @config[:password]
362:       search_path = @config[:schema_search_path]
363:       search_path = "--schema=#{search_path}" if search_path
364: 
365:       @connection.connection.close
366:       begin
367:         definition = `pg_dump -i -U "#{@config[:username]}" -s -x -O #{search_path} #{database}`
368:         raise "Error dumping database" if $?.exitstatus == 1
369: 
370:         # need to patch away any references to SQL_ASCII as it breaks the JDBC driver
371:         definition.gsub(/SQL_ASCII/, 'UNICODE')
372:       ensure
373:         reconnect!
374:       end
375:     end
supports_ddl_transactions?() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 134
134:     def supports_ddl_transactions?
135:       true
136:     end
supports_insert_with_returning?() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 130
130:     def supports_insert_with_returning?
131:       postgresql_version >= 80200
132:     end
supports_migrations?() click to toggle source

Does PostgreSQL support migrations?

     # File lib/arjdbc/postgresql/adapter.rb, line 110
110:     def supports_migrations?
111:       true
112:     end
supports_savepoints?() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 138
138:     def supports_savepoints?
139:       true
140:     end
supports_standard_conforming_strings?() click to toggle source

Does PostgreSQL support standard conforming strings?

     # File lib/arjdbc/postgresql/adapter.rb, line 115
115:     def supports_standard_conforming_strings?
116:       # Temporarily set the client message level above error to prevent unintentional
117:       # error messages in the logs when working on a PostgreSQL database server that
118:       # does not support standard conforming strings.
119:       client_min_messages_old = client_min_messages
120:       self.client_min_messages = 'panic'
121: 
122:       # postgres-pr does not raise an exception when client_min_messages is set higher
123:       # than error and "SHOW standard_conforming_strings" fails, but returns an empty
124:       # PGresult instead.
125:       has_support = select('SHOW standard_conforming_strings').to_a[0][0] rescue false
126:       self.client_min_messages = client_min_messages_old
127:       has_support
128:     end
table_alias_length() click to toggle source

Returns the configured supported identifier length supported by PostgreSQL, or report the default of 63 on PostgreSQL 7.x.

     # File lib/arjdbc/postgresql/adapter.rb, line 160
160:     def table_alias_length
161:       @table_alias_length ||= (postgresql_version >= 80000 ? select_one('SHOW max_identifier_length')['max_identifier_length'].to_i : 63)
162:     end
tables() click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 531
531:     def tables
532:       @connection.tables(database_name, nil, nil, ["TABLE"])
533:     end

Private Instance Methods

extract_pg_identifier_from_name(name) click to toggle source
     # File lib/arjdbc/postgresql/adapter.rb, line 536
536:     def extract_pg_identifier_from_name(name)
537:       match_data = name[0,1] == '"' ? name.match(/\"([^\"]+)\"/) : name.match(/([^\.]+)/)
538: 
539:       if match_data
540:         rest = name[match_data[0].length..1]
541:         rest = rest[1..1] if rest[0,1] == "."
542:         [match_data[1], (rest.length > 0 ? rest : nil)]
543:       end
544:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.