A Store that persists objects into a PostgreSQL database. To read documentation about the methods, consult the documentation for SqlStore and Store.
This is the reference Og store.
- commit
- create_db
- create_table
- destroy_db
- enchant
- exec_statement
- insert
- last_insert_id
- new
- primary_key_type
- query_statement
- read_row
- rollback
- sql_update
- start
- table_info
[ show source ]
# File lib/og/adapter/postgresql.rb, line 23
23: def initialize(options)
24: super
25:
26: @typemap.update(Og::Blob => 'bytea')
27:
28: @conn = PGconn.connect(
29: options[:address] || options[:host],
30: options[:port],
31: "--client_min_messages=WARNING", nil,
32: options[:name],
33: options[:user].to_s,
34: options[:password].to_s
35: )
36: schema_order = options[:schema_order]
37: encoding = options[:encoding]
38: min_messages = options[:min_messages]
39:
40: @conn.exec("SET search_path TO #{schema_order}") if schema_order
41: @conn.exec("SET client_encoding TO '#{encoding}'") if encoding
42: @conn.exec("SET client_min_messages TO '#{min_messages}'") if min_messages
43: rescue PGError => ex
44: if database_does_not_exist_exception? ex
45: Logger.info "Database '#{options[:name]}' not found!"
46: create_db(options)
47: retry
48: end
49: raise
50: end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 52
52: def create_db(options)
53: # gmosx: system is used to avoid shell expansion.
54: system "createdb", options[:name], '-U', options[:user], '-q'
55: super
56: end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 58
58: def destroy_db(options)
59: system "dropdb", options[:name], '-U', options[:user], '-q'
60: super
61: end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 69
69: def enchant(klass, manager)
70: super
71:
72: pk = klass.primary_key
73:
74: seq = if klass.schema_inheritance_child?
75: "#{table(klass.schema_inheritance_root_class)}_#{pk}_seq"
76: else
77: "#{table(klass)}_#{pk}_seq"
78: end
79:
80: pkann = klass.ann(pk)
81:
82: unless pkann[:sequence]
83: if pkann[:sql] =~ /SERIAL/i
84: klass.ann(pk, {:sequence => seq})
85: else
86: klass.ann(pk, {:sequence => false})
87: end
88: end
89: end
The type used for default primary keys.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 65
65: def primary_key_type
66: "serial PRIMARY KEY"
67: end
Create the SQL table where instances of the given class will be serialized.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 96
96: def create_table(klass)
97: fields = fields_for_class(klass)
98:
99: sql = "CREATE TABLE #{klass.table} (#{fields.join(', ')}"
100:
101: # Create table constraints.
102:
103: if constraints = klass.ann(:self, :sql_constraint)
104: sql << ", #{constraints.join(', ')}"
105: end
106:
107: sql << ") WITHOUT OIDS"
108:
109: begin
110: exec(sql, false)
111: Logger.info "Created table '#{klass.table}'."
112: rescue Object => ex
113: if table_already_exists_exception? ex
114: # Don't return yet. Fall trough to also check for the
115: # join table.
116: else
117: handle_sql_exception(ex, sql)
118: end
119: end
120: end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 126
126: def exec_statement(sql)
127: @conn.exec(sql).clear
128: end
The insert sql statements.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 151
151: def insert(klass, inserts)
152: next_oid = nil
153: if klass.ann(klass.primary_key, :sequence)
154: seq = klass.ann(klass.primary_key, :sequence)
155: next_oid = Integer(query("SELECT nextval('#{seq}')").first_value)
156: inserts[klass.primary_key]=write_attr(next_oid, {:class => Integer})
157: elsif not inserts[klass.primary_key].nil?
158: next_oid = inserts[klass.primary_key]
159: end
160: if next_oid.nil?
161: raise StoreException, "Postgres stores need a sequence annotation for primary keys"
162: end
163: super
164: return next_oid
165: end
Return the last inserted row id.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 140
140: def last_insert_id(klass)
141: seq = klass.ann(klass.primary_key, :sequence)
142:
143: res = query("SELECT currval('#{seq}')")
144: lid = Integer(res.first_value)
145:
146: return lid
147: end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 122
122: def query_statement(sql)
123: return @conn.exec(sql)
124: end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 130
130: def sql_update(sql)
131: Logger.debug sql if $DBG
132: res = @conn.exec(sql)
133: changed = res.cmdtuples
134: res.clear
135: return changed
136: end
Commit a transaction.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 184
184: def commit
185: @transaction_nesting -= 1
186: exec('COMMIT') if @transaction_nesting < 1
187:
188: if @transaction_nesting >= 1 && @conn.server_version > 80000
189: exec("RELEASE SAVEPOINT SP#{@transaction_nesting}")
190: end
191: end
def read_attr(s, anno, col)
store = self.class
{
String => nil,
Integer => :parse_int,
Float => :parse_float,
Time => :parse_timestamp,
Date => :parse_date,
TrueClass => :parse_boolean,
Og::Blob => :parse_blob
}.each do |klass, meth|
if anno[:class].ancestor? klass
return meth ?
"#{store}.#{meth}(res[#{col} + offset])" : "res[#{col} + offset]"
end
end
# else try to load it via YAML
"YAML::load(res[#{col} + offset])"
end
[ show source ]
# File lib/og/adapter/postgresql.rb, line 225
225: def read_row(obj, res, res_row, row)
226: res.fields.each_with_index do |field, idx|
227: obj.instance_variable_set "@#{field}", res.getvalue(row, idx)
228: end
229: end
Rollback a transaction.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 195
195: def rollback
196: @transaction_nesting -= 1
197: exec('ROLLBACK') if @transaction_nesting < 1
198:
199: if @transaction_nesting >= 1 && @conn.server_version > 80000
200: exec("ROLLBACK TO SAVEPOINT SP#{@transaction_nesting}")
201: end
202: end
Start a new transaction.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 171
171: def start
172: # neumann: works with earlier PSQL databases too.
173: exec('BEGIN TRANSACTION') if @transaction_nesting < 1
174:
175: if @transaction_nesting >= 1 && @conn.server_version > 80000
176: exec("SAVEPOINT SP#{@transaction_nesting}")
177: end
178:
179: @transaction_nesting += 1
180: end
Returns the PostgreSQL information of a table within the database or nil if it doesn’t exist. Mostly for internal usage.
[ show source ]
# File lib/og/adapter/postgresql.rb, line 234
234: def table_info(table)
235: r = query_statement("SELECT c.* FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND pg_catalog.pg_table_is_visible(c.oid) AND c.relname = '#{self.class.escape(table.to_s)}'")
236: return r && r.blank? ? nil : r.next
237: end