The Oracle adapter. This adapter communicates with an Oracle rdbms. For extra documentation see lib/og/adapter.rb
Connects to Oracle by config[:user], config[:password], config[:database], config[:privilege]. If you need DBA privilege, please set privilege as :SYSDBA or :SYSOPER.
- close
- close
- commit
- commit
- create_db
- create_db
- create_table
- create_table
- drop_db
- drop_db
- drop_table
- drop_table
- enchant
- enchant
- exec_statement
- exec_statement
- insert_sql
- insert_sql
- last_insert_id
- last_insert_id
- new
- new
- primary_key_type
- primary_key_type
- query_statement
- query_statement
- read_attr
- read_attr
- resolve_limit_options
- rollback
- rollback
- sql_update
- sql_update
- start
- start
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 20
20: def initialize
21: super
22:
23: @typemap.update(
24: Integer => 'number',
25: Fixnum => 'number',
26: String => 'varchar2(1024)', # max might be 4000 (Oracle 8)
27: TrueClass => 'char(1)',
28: Numeric => 'number',
29: Object => 'varchar2(1024)',
30: Array => 'varchar2(1024)',
31: Hash => 'varchar2(1024)'
32: )
33:
34: # TODO: how to pass address etc?
35: @store = Oracle.new(config[:user], config[:password], config[:database])
36: # gmosx: better use this???
37: # @store = Oracle.new(config[:tns])
38:
39: # gmosx: does this work?
40: @store.autocommit = true
41: rescue Exception => ex
42: # mcb:
43: # Oracle will raise a ORA-01017 if username, password, or
44: # SID aren't valid. I verified this for all three.
45: # irb(main):002:0> conn = Oracle.new('keebler', 'dfdfd', 'kbsid')
46: # /usr/local/lib/ruby/site_ruby/1.8/oracle.rb:27:in `logon': ORA-01017: invalid username/password; logon denied (OCIError)
47: if database_does_not_exist_exception? ex
48: Logger.info "Database '#{options[:name]}' not found!"
49: create_db(options)
50: retry
51: end
52: raise
53: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 55
55: def close
56: @store.logoff
57: super
58: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 70
70: def create_db(database, user = nil, password = nil)
71: # FIXME: what is appropriate for oracle?
72: # `createdb #{database} -U #{user}`
73: super
74: raise NotImplementedError, "Oracle Database/Schema creation n/a"
75: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 77
77: def drop_db(database, user = nil, password = nil)
78: # FIXME: what is appropriate for oracle?
79: # `dropdb #{database} -U #{user}`
80: super
81: raise NotImplementedError, "Oracle Database/Schema dropping n/a"
82: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 90
90: def enchant(klass, manager)
91: pk = klass.primary_key
92:
93: seq = if klass.schema_inheritance_child?
94: "#{table(klass.schema_inheritance_root_class)}_#{pk}_seq"
95: else
96: "#{table(klass)}_#{pk}_seq"
97: end
98:
99: pkann = klass.ann[pk]
100:
101: pkann[:sequence] = seq unless pkann[:sequence] == false
102:
103: super
104: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 110
110: def exec_statement(sql)
111: @conn.exec(sql).clear
112: end
The insert sql statements.
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 136
136: def insert_sql(sql, klass)
137: str = ''
138:
139: if klass.ann[klass.primary_key][:sequence]
140: str << "@#{klass.primary_key} = store.last_insert_id(#{klass})\n"
141: end
142:
143: str << "store.exec \"#{sql}\""
144:
145: return str
146: end
Return the last inserted row id.
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 124
124: def last_insert_id(klass)
125: seq = klass.ann[klass.primary_key][:sequence]
126:
127: res = query_statement("SELECT #{seq}.nextval FROM DUAL")
128: lid = Integer(res.first_value)
129: res.close
130:
131: return lid
132: end
The type used for default primary keys.
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 86
86: def primary_key_type
87: 'integer PRIMARY KEY'
88: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 106
106: def query_statement(sql)
107: return @conn.exec(sql)
108: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 114
114: def sql_update(sql)
115: Logger.debug sql if $DBG
116: res = @conn.exec(sql)
117: changed = res.cmdtuples
118: res.clear
119: return changed
120: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 20
20: def initialize(config)
21: super
22:
23: @typemap.update(
24: Integer => 'number',
25: Fixnum => 'number',
26: String => 'varchar2(1024)', # max might be 4000 (Oracle 8)
27: TrueClass => 'char(1)',
28: Numeric => 'number',
29: Object => 'varchar2(1024)',
30: Array => 'varchar2(1024)',
31: Hash => 'varchar2(1024)',
32: Time => 'TIMESTAMP',
33: Date => 'DATE',
34: DateTime => 'TIMESTAMP'
35: )
36:
37: # TODO: how to pass address etc?
38: @conn = OCI8.new(
39: config[:user],
40: config[:password],
41: config[:name],
42: config[:privilege]
43: )
44:
45: # gmosx: does this work?
46: @conn.autocommit = true
47: rescue OCIException => ex
48: #---
49: # mcb:
50: # Oracle will raise a ORA-01017 if username, password, or
51: # SID aren't valid. I verified this for all three.
52: # irb(main):002:0> conn = Oracle.new('keebler', 'dfdfd', 'kbsid')
53: # /usr/local/lib/ruby/site_ruby/1.8/oracle.rb:27:in `logon': ORA-01017:
54: # invalid username/password; logon denied (OCIError)
55: #+++
56: if database_does_not_exist_exception? ex
57: Logger.info "Database '#{options[:name]}' not found!"
58: create_db(options)
59: retry
60: end
61: raise
62: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 64
64: def close
65: @conn.logoff
66: super
67: end
Commit a transaction.
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 160
160: def commit
161: @transaction_nesting -= 1
162: @store.commit if @transaction_nesting < 1
163: ensure
164: @store.autocommit = true
165: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 79
79: def create_db(database, user = nil, password = nil)
80: # FIXME: what is appropriate for oracle?
81: # `createdb #{database} -U #{user}`
82: super
83: raise NotImplementedError, "Oracle Database/Schema creation n/a"
84: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 177
177: def create_table(klass)
178: super
179:
180: seq = klass.ann[klass.primary_key][:sequence]
181: # Create the sequence for this table.
182: begin
183: exec_statement("CREATE SEQUENCE #{seq}")
184: Logger.info "Created sequence '#{seq}'."
185: rescue Exception => ex
186: # gmosx: any idea how to better test this?
187: if table_already_exists_exception?(ex)
188: Logger.debug "Sequence #{seq} already exists" if $DBG
189: else
190: raise
191: end
192: end
193:
194: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 86
86: def drop_db(database, user = nil, password = nil)
87: # FIXME: what is appropriate for oracle?
88: # `dropdb #{database} -U #{user}`
89: super
90: raise NotImplementedError, "Oracle Database/Schema dropping n/a"
91: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 196
196: def drop_table(klass)
197: super
198: exec_statement("DROP SEQUENCE #{klass.ann[klass.primary_key][:sequence]}")
199: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 99
99: def enchant(klass, manager)
100: pk = klass.primary_key
101:
102: seq = if klass.schema_inheritance_child?
103: "#{table(klass.schema_inheritance_root_class)}_#{pk}_seq"
104: else
105: "#{table(klass)}_#{pk}_seq"
106: end
107:
108: pkann = klass.ann(pk)
109:
110: pkann[:sequence] = OracleUtils.shorten_string(seq) unless pkann[:sequence] == false
111:
112: super
113: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 119
119: def exec_statement(sql)
120: Logger.debug "ORACLE "+sql
121: @conn.exec(sql)
122: end
The insert sql statements.
[ show source ]
# File lib/og/adapter/oracle.rb, line 144
144: def insert_sql(sql, klass)
145: str = ''
146:
147: if klass.ann(klass.primary_key, :sequence)
148: str << "@#{klass.primary_key} = store.last_insert_id(#{klass})\n"
149: end
150:
151: str << "store.exec \"#{sql}\""
152:
153: return str
154: end
Return the last inserted row id.
[ show source ]
# File lib/og/adapter/oracle.rb, line 132
132: def last_insert_id(klass)
133: seq = klass.ann(klass.primary_key, :sequence)
134:
135: res = query_statement("SELECT #{seq}.nextval FROM DUAL")
136: lid = Integer(res.first_value)
137: res.close
138:
139: return lid
140: end
The type used for default primary keys.
[ show source ]
# File lib/og/adapter/oracle.rb, line 95
95: def primary_key_type
96: 'integer PRIMARY KEY'
97: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 115
115: def query_statement(sql)
116: @conn.exec(sql)
117: end
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 201
201: def read_attr(s, a, col)
202: store = self.class
203: {
204: String => nil,
205: Integer => :parse_int,
206: Float => :parse_float,
207: Time => :parse_timestamp,
208: Date => :parse_date,
209: TrueClass => :parse_boolean,
210: Og::Blob => :parse_blob
211: }.each do |klass, meth|
212: if a.class.ancestor? klass
213: return meth ?
214: "#{store}.#{meth}(res[#{col} + offset])" : "res[#{col} + offset]"
215: end
216: end
217:
218: # else try to load it via YAML
219: "YAML::load(res[#{col} + offset])"
220: end
Rollback a transaction.
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 169
169: def rollback
170: @transaction_nesting -= 1
171: @store.rollbackif @transaction_nesting < 1
172: ensure
173: @store.autocommit = true
174: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 124
124: def sql_update(sql)
125: Logger.debug sql if $DBG
126: res = @conn.exec(sql)
127: return res.to_i
128: end
Start a new transaction.
[ show source ]
# File lib/og/adapter/oracle/old.rb, line 152
152: def start
153: @store.autocommit = false
154:
155: @transaction_nesting += 1
156: end
Commit a transaction.
[ show source ]
# File lib/og/adapter/oracle.rb, line 168
168: def commit
169: @transaction_nesting -= 1
170: @conn.commit if @transaction_nesting < 1
171: ensure
172: @conn.autocommit = true
173: end
Rollback a transaction.
[ show source ]
# File lib/og/adapter/oracle.rb, line 177
177: def rollback
178: @transaction_nesting -= 1
179: @conn.rollbackif @transaction_nesting < 1
180: ensure
181: @conn.autocommit = true
182: end
Start a new transaction.
[ show source ]
# File lib/og/adapter/oracle.rb, line 160
160: def start
161: @conn.autocommit = false
162:
163: @transaction_nesting += 1
164: end
Create the SQL table where instances of the given class will be serialized.
[ show source ]
# File lib/og/adapter/oracle.rb, line 189
189: def create_table(klass)
190: fields = fields_for_class(klass)
191:
192: # Oracle hard limit
193: OracleUtils.shorten_table_name(klass) if klass.table.size > 30
194: raise "ORACLE TOO LONG! #{klass.table.size}" if klass.table.size > 30
195:
196: sql = "CREATE TABLE #{klass.table} (#{fields.join(', ')}"
197:
198: # Create table constraints.
199:
200: if constraints = klass.ann(:self, :sql_constraint)
201: sql << ", #{constraints.join(', ')}"
202: end
203:
204: sql << ")"
205:
206: begin
207: exec(sql, false)
208: Logger.info "Created table '#{klass.table}'."
209: rescue Object => ex
210: if table_already_exists_exception? ex
211: # Don't return yet. Fall trough to also check for the
212: # join table.
213: else
214: handle_sql_exception(ex, sql)
215: end
216: end
217:
218: seq = klass.ann[klass.primary_key][:sequence]
219: # Create the sequence for this table.
220: begin
221: exec_statement("CREATE SEQUENCE #{seq} INCREMENT BY 1 START WITH 1 NOMAXVALUE NOMINVALUE NOCYCLE")
222: Logger.info "Created sequence '#{seq}'."
223: rescue OCIError => ex
224: if table_already_exists_exception?(ex)
225: Logger.debug "Sequence #{seq} already exists" if $DBG
226: else
227: raise
228: end
229: end
230:
231: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 233
233: def drop_table(klass)
234: super
235:
236: seq = klass.ann[klass.primary_key][:sequence]
237: # Create the sequence for this table.
238: begin
239: exec_statement("DROP SEQUENCE #{seq}")
240: Logger.info "Dropped sequence '#{seq}'."
241: rescue OCIError => ex
242: if sequence_does_not_exist_exception?(ex)
243: Logger.debug "Sequence #{seq} didn't exist" if $DBG
244: else
245: raise
246: end
247: end
248:
249: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 264
264: def read_attr(s, a, col)
265: store = self.class
266: {
267: String => nil,
268: Integer => :parse_int,
269: Float => :parse_float,
270: Time => :parse_timestamp,
271: Date => :parse_date,
272: TrueClass => :parse_boolean,
273: Og::Blob => :parse_blob
274: }.each do |klass, meth|
275: if a.class.ancestor? klass
276: return meth ?
277: "#{store}.#{meth}(res[#{col} + offset])" : "res[#{col} + offset]"
278: end
279: end
280:
281: # else try to load it via YAML
282: "YAML::load(res[#{col} + offset])"
283: end
[ show source ]
# File lib/og/adapter/oracle.rb, line 251
251: def resolve_limit_options(options, sql)
252: from = options[:offset] || 1
253: to = from + options[:limit] if options[:limit]
254: sql.replace "SELECT * FROM (#{sql}) WHERE ROWNUM "
255: if to && from
256: sql << "BETWEEN #{from} AND #{to}"
257: elsif to
258: sql << "<= #{options[:limit]}"
259: elsif from
260: sql << ">= #{from}"
261: end
262: end