activerecord-oracle_enhanced-adapter 1.7.11 → 1.8.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Gemfile +20 -11
  4. data/History.md +123 -4
  5. data/RUNNING_TESTS.md +79 -55
  6. data/Rakefile +13 -19
  7. data/VERSION +1 -1
  8. data/activerecord-oracle_enhanced-adapter.gemspec +16 -17
  9. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
  10. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +7 -59
  11. data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +6 -50
  12. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +11 -11
  13. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +117 -117
  14. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +30 -23
  15. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +10 -10
  16. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +48 -70
  17. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +1 -4
  18. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +51 -69
  19. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +4 -4
  20. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +76 -76
  21. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +13 -42
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +60 -64
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +33 -47
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +146 -159
  25. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +94 -132
  26. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +3 -3
  27. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +65 -100
  28. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -1
  29. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +250 -487
  30. data/lib/active_record/oracle_enhanced/type/boolean.rb +7 -10
  31. data/lib/active_record/oracle_enhanced/type/integer.rb +3 -4
  32. data/lib/active_record/oracle_enhanced/type/national_character_string.rb +1 -1
  33. data/lib/active_record/oracle_enhanced/type/raw.rb +2 -3
  34. data/lib/active_record/oracle_enhanced/type/string.rb +2 -2
  35. data/lib/active_record/oracle_enhanced/type/text.rb +2 -2
  36. data/lib/activerecord-oracle_enhanced-adapter.rb +2 -2
  37. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +57 -131
  38. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +32 -34
  39. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +40 -42
  40. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +83 -85
  41. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +205 -286
  42. data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +14 -6
  43. data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +3 -5
  44. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +42 -49
  45. data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +1 -3
  46. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +68 -71
  47. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +51 -92
  48. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +221 -327
  49. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +16 -18
  50. data/spec/spec_helper.rb +59 -57
  51. metadata +10 -10
@@ -1,5 +1,5 @@
1
1
  class ActiveRecord::ConnectionAdapters::OracleAdapter < ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter #:nodoc:
2
2
  def adapter_name
3
- 'Oracle'
3
+ "Oracle"
4
4
  end
5
5
  end
@@ -4,7 +4,6 @@ module ActiveRecord
4
4
  attr_reader :table_name, :nchar, :virtual_column_data_default, :returning_id #:nodoc:
5
5
 
6
6
  def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, virtual = false, returning_id = nil, comment = nil) #:nodoc:
7
-
8
7
  @virtual = virtual
9
8
  @virtual_column_data_default = default.inspect if virtual
10
9
  @returning_id = returning_id
@@ -17,7 +16,7 @@ module ActiveRecord
17
16
  # Is column NCHAR or NVARCHAR2 (will need to use N'...' value quoting for these data types)?
18
17
  # Define only when needed as adapter "quote" method will check at first if instance variable is defined.
19
18
  if sql_type_metadata
20
- @object_type = sql_type_metadata.sql_type.include? '.'
19
+ @object_type = sql_type_metadata.sql_type.include? "."
21
20
  end
22
21
  # TODO: Need to investigate when `sql_type` becomes nil
23
22
  end
@@ -62,72 +61,21 @@ module ActiveRecord
62
61
  super
63
62
  end
64
63
 
65
- # Get column comment from schema definition.
66
- # Will work only if using default ActiveRecord connection.
67
- # def comment
68
- # #TODO: may be deprecated due to conflict with variable
69
- # ActiveRecord::Base.connection.column_comment(@table_name, name)
70
- # end
71
-
72
64
  private
73
65
 
74
- def self.extract_value_from_default(default)
75
- case default
66
+ def self.extract_value_from_default(default)
67
+ case default
76
68
  when String
77
69
  default.gsub(/''/, "'")
78
- else
70
+ else
79
71
  default
80
- end
81
- end
82
-
83
- def guess_date_or_time(value)
84
- value.respond_to?(:hour) && (value.hour == 0 and value.min == 0 and value.sec == 0) ?
85
- Date.new(value.year, value.month, value.day) : value
86
- end
87
-
88
- class << self
89
- protected
90
-
91
- def fallback_string_to_date(string) #:nodoc:
92
- if OracleEnhancedAdapter.string_to_date_format || OracleEnhancedAdapter.string_to_time_format
93
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
94
- `fallback_string_to_date` has been deprecated.
95
- It will be removed from next version of Oracle enhanced adapter.
96
- Users are unlikely to see this message since this method has gone
97
- from ActiveRecord::ConnectionAdapters::Column in Rails 4.2.
98
- MSG
99
- return (string_to_date_or_time_using_format(string).to_date rescue super)
100
- end
101
- super
102
- end
103
-
104
- def fallback_string_to_time(string) #:nodoc:
105
- if OracleEnhancedAdapter.string_to_time_format || OracleEnhancedAdapter.string_to_date_format
106
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
107
- `fallback_string_to_time` has been deprecated.
108
- It will be removed from next version of Oracle enhanced adapter.
109
- Users are unlikely to see this message since this method has gone
110
- from ActiveRecord::ConnectionAdapters::Column in Rails 4.2.
111
- MSG
112
- return (string_to_date_or_time_using_format(string).to_time rescue super)
113
72
  end
114
- super
115
73
  end
116
74
 
117
- def string_to_date_or_time_using_format(string) #:nodoc:
118
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
119
- `string_to_date_or_time_using_format` has been deprecated.
120
- It will be removed from next version of Oracle enhanced adapter.
121
- Users are unlikely to see this message since `fallback_string_to_date`
122
- and `fallback_string_to_time` have gone
123
- from ActiveRecord::ConnectionAdapters::Column in Rails 4.2.
124
- MSG
125
- if OracleEnhancedAdapter.string_to_time_format && dt=Date._strptime(string, OracleEnhancedAdapter.string_to_time_format)
126
- return Time.parse("#{dt[:year]}-#{dt[:mon]}-#{dt[:mday]} #{dt[:hour]}:#{dt[:min]}:#{dt[:sec]}#{dt[:zone]}")
127
- end
128
- DateTime.strptime(string, OracleEnhancedAdapter.string_to_date_format).to_date
75
+ def guess_date_or_time(value)
76
+ value.respond_to?(:hour) && ((value.hour == 0) && (value.min == 0) && (value.sec == 0)) ?
77
+ Date.new(value.year, value.month, value.day) : value
129
78
  end
130
- end
131
79
  end
132
80
  end
133
81
  end
@@ -2,66 +2,22 @@ module ActiveRecord #:nodoc:
2
2
  module ConnectionAdapters #:nodoc:
3
3
  module OracleEnhanced #:nodoc:
4
4
  module ColumnDumper #:nodoc:
5
- def column_spec(column)
6
- spec = Hash[prepare_column_options(column).map { |k, v| [k, "#{k}: #{v}"] }]
7
- spec[:name] = column.name.inspect
8
- if column.virtual?
9
- spec[:type] = "virtual"
10
- else
11
- spec[:type] = schema_type(column).to_s
12
- end
13
- spec
14
- end
15
-
16
5
  def prepare_column_options(column)
17
- spec = {}
18
-
19
- if limit = schema_limit(column)
20
- spec[:limit] = limit
21
- end
22
-
23
- if precision = schema_precision(column)
24
- spec[:precision] = precision
25
- end
26
-
27
- if scale = schema_scale(column)
28
- spec[:scale] = scale
29
- end
6
+ spec = super
30
7
 
31
- if virtual_as = schema_virtual_as(column)
32
- spec[:as] = virtual_as
8
+ if supports_virtual_columns? && column.virtual?
9
+ spec[:as] = column.virtual_column_data_default
10
+ spec = { type: schema_type(column).inspect }.merge!(spec) unless column.type == :decimal
33
11
  end
34
12
 
35
- if virtual_type = schema_virtual_type(column)
36
- spec[:virtual_type] = virtual_type
37
- end
38
-
39
- default = schema_default(column) if column.has_default?
40
- spec[:default] = default unless default.nil?
41
-
42
- spec[:null] = 'false' unless column.null
43
-
44
- spec[:comment] = column.comment.inspect if column.comment.present?
45
-
46
13
  spec
47
14
  end
48
15
 
49
- def migration_keys
50
- # TODO `& column_specs.map(&:keys).flatten` should be exetuted here
51
- [:name, :limit, :precision, :scale, :default, :null, :as, :virtual_type, :comment]
52
- end
53
-
54
16
  private
55
17
 
56
- def schema_virtual_as(column)
57
- column.virtual_column_data_default if column.virtual?
58
- end
59
-
60
- def schema_virtual_type(column)
61
- unless column.type == :decimal
62
- column.type.inspect if column.virtual?
18
+ def default_primary_key?(column)
19
+ schema_type(column) == :integer
63
20
  end
64
- end
65
21
  end
66
22
  end
67
23
  end
@@ -29,8 +29,8 @@ module ActiveRecord
29
29
  # Used always by JDBC connection as well by OCI connection when describing tables over database link
30
30
  def describe(name)
31
31
  name = name.to_s
32
- if name.include?('@')
33
- name, db_link = name.split('@')
32
+ if name.include?("@")
33
+ name, db_link = name.split("@")
34
34
  default_owner = select_value("SELECT username FROM all_db_links WHERE db_link = '#{db_link.upcase}'")
35
35
  db_link = "@#{db_link}"
36
36
  else
@@ -38,8 +38,8 @@ module ActiveRecord
38
38
  default_owner = @owner
39
39
  end
40
40
  real_name = ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.valid_table_name?(name) ? name.upcase : name
41
- if real_name.include?('.')
42
- table_owner, table_name = real_name.split('.')
41
+ if real_name.include?(".")
42
+ table_owner, table_name = real_name.split(".")
43
43
  else
44
44
  table_owner, table_name = default_owner, real_name
45
45
  end
@@ -65,11 +65,11 @@ module ActiveRecord
65
65
  AND synonym_name = '#{real_name}'
66
66
  SQL
67
67
  if result = select_one(sql)
68
- case result['name_type']
69
- when 'SYNONYM'
68
+ case result["name_type"]
69
+ when "SYNONYM"
70
70
  describe("#{result['owner'] && "#{result['owner']}."}#{result['table_name']}#{db_link}")
71
71
  else
72
- db_link ? [result['owner'], result['table_name'], db_link] : [result['owner'], result['table_name']]
72
+ db_link ? [result["owner"], result["table_name"], db_link] : [result["owner"], result["table_name"]]
73
73
  end
74
74
  else
75
75
  raise OracleEnhancedConnectionException, %Q{"DESC #{name}" failed; does it exist?}
@@ -109,13 +109,13 @@ module ActiveRecord
109
109
  end
110
110
 
111
111
  # if MRI or YARV
112
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
112
+ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
113
113
  ORACLE_ENHANCED_CONNECTION = :oci
114
- require 'active_record/connection_adapters/oracle_enhanced/oci_connection'
114
+ require "active_record/connection_adapters/oracle_enhanced/oci_connection"
115
115
  # if JRuby
116
- elsif RUBY_ENGINE == 'jruby'
116
+ elsif RUBY_ENGINE == "jruby"
117
117
  ORACLE_ENHANCED_CONNECTION = :jdbc
118
- require 'active_record/connection_adapters/oracle_enhanced/jdbc_connection'
118
+ require "active_record/connection_adapters/oracle_enhanced/jdbc_connection"
119
119
  else
120
120
  raise "Unsupported Ruby engine #{RUBY_ENGINE}"
121
121
  end
@@ -74,9 +74,9 @@ module ActiveRecord
74
74
  def add_context_index(table_name, column_name, options = {})
75
75
  self.all_schema_indexes = nil
76
76
  column_names = Array(column_name)
77
- index_name = options[:name] || index_name(table_name, :column => options[:index_column] || column_names,
77
+ index_name = options[:name] || index_name(table_name, column: options[:index_column] || column_names,
78
78
  # CONEXT index name max length is 25
79
- :identifier_max_length => 25)
79
+ identifier_max_length: 25)
80
80
 
81
81
  quoted_column_name = quote_column_name(options[:index_column] || column_names.first)
82
82
  if options[:index_column_trigger_on]
@@ -129,10 +129,10 @@ module ActiveRecord
129
129
  def remove_context_index(table_name, options = {})
130
130
  self.all_schema_indexes = nil
131
131
  unless Hash === options # if column names passed as argument
132
- options = {:column => Array(options)}
132
+ options = { column: Array(options) }
133
133
  end
134
134
  index_name = options[:name] || index_name(table_name,
135
- :column => options[:index_column] || options[:column], :identifier_max_length => 25)
135
+ column: options[:index_column] || options[:column], identifier_max_length: 25)
136
136
  execute "DROP INDEX #{index_name}"
137
137
  drop_ctx_preference(default_datastore_name(index_name))
138
138
  drop_ctx_preference(default_storage_name(index_name))
@@ -143,17 +143,17 @@ module ActiveRecord
143
143
 
144
144
  private
145
145
 
146
- def create_datastore_procedure(table_name, procedure_name, column_names, options)
147
- quoted_table_name = quote_table_name(table_name)
148
- select_queries, column_names = column_names.partition { |c| c.to_s =~ /^\s*SELECT\s+/i }
149
- select_queries = select_queries.map { |s| s.strip.gsub(/\s+/, ' ') }
150
- keys, selected_columns = parse_select_queries(select_queries)
151
- quoted_column_names = (column_names+keys).map{|col| quote_column_name(col)}
152
- execute compress_lines(<<-SQL)
146
+ def create_datastore_procedure(table_name, procedure_name, column_names, options)
147
+ quoted_table_name = quote_table_name(table_name)
148
+ select_queries, column_names = column_names.partition { |c| c.to_s =~ /^\s*SELECT\s+/i }
149
+ select_queries = select_queries.map { |s| s.strip.gsub(/\s+/, " ") }
150
+ keys, selected_columns = parse_select_queries(select_queries)
151
+ quoted_column_names = (column_names + keys).map { |col| quote_column_name(col) }
152
+ execute compress_lines(<<-SQL)
153
153
  CREATE OR REPLACE PROCEDURE #{quote_table_name(procedure_name)}
154
154
  (p_rowid IN ROWID,
155
155
  p_clob IN OUT NOCOPY CLOB) IS
156
- -- add_context_index_parameters #{(column_names+select_queries).inspect}#{!options.empty? ? ', ' << options.inspect[1..-2] : ''}
156
+ -- add_context_index_parameters #{(column_names + select_queries).inspect}#{!options.empty? ? ', ' << options.inspect[1..-2] : ''}
157
157
  #{
158
158
  selected_columns.map do |cols|
159
159
  cols.map do |col|
@@ -170,171 +170,171 @@ module ActiveRecord
170
170
  #{
171
171
  (column_names.map do |col|
172
172
  col = col.to_s
173
- "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+2}, '<#{col}>');\n" <<
173
+ "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 2}, '<#{col}>');\n" <<
174
174
  "IF LENGTH(r1.#{col}) > 0 THEN\n" <<
175
175
  "DBMS_LOB.WRITEAPPEND(p_clob, LENGTH(r1.#{col}), r1.#{col});\n" <<
176
176
  "END IF;\n" <<
177
- "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+3}, '</#{col}>');\n"
177
+ "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 3}, '</#{col}>');\n"
178
178
  end.join) <<
179
179
  (selected_columns.zip(select_queries).map do |cols, query|
180
180
  (cols.map do |col|
181
181
  "l_#{col} := '';\n"
182
182
  end.join) <<
183
183
  "FOR r2 IN (\n" <<
184
- query.gsub(/:(\w+)/,"r1.\\1") << "\n) LOOP\n" <<
184
+ query.gsub(/:(\w+)/, "r1.\\1") << "\n) LOOP\n" <<
185
185
  (cols.map do |col|
186
186
  "l_#{col} := l_#{col} || r2.#{col} || CHR(10);\n"
187
187
  end.join) <<
188
188
  "END LOOP;\n" <<
189
189
  (cols.map do |col|
190
190
  col = col.to_s
191
- "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+2}, '<#{col}>');\n" <<
191
+ "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 2}, '<#{col}>');\n" <<
192
192
  "IF LENGTH(l_#{col}) > 0 THEN\n" <<
193
193
  "DBMS_LOB.WRITEAPPEND(p_clob, LENGTH(l_#{col}), l_#{col});\n" <<
194
194
  "END IF;\n" <<
195
- "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+3}, '</#{col}>');\n"
195
+ "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 3}, '</#{col}>');\n"
196
196
  end.join)
197
197
  end.join)
198
198
  }
199
199
  END LOOP;
200
200
  END;
201
201
  SQL
202
- end
202
+ end
203
203
 
204
- def parse_select_queries(select_queries)
205
- keys = []
206
- selected_columns = []
207
- select_queries.each do |query|
208
- # get primary or foreign keys like :id or :something_id
209
- keys << (query.scan(/:\w+/).map{|k| k[1..-1].downcase.to_sym})
210
- select_part = query.scan(/^select\s.*\sfrom/i).first
211
- selected_columns << select_part.scan(/\sas\s+(\w+)/i).map{|c| c.first}
204
+ def parse_select_queries(select_queries)
205
+ keys = []
206
+ selected_columns = []
207
+ select_queries.each do |query|
208
+ # get primary or foreign keys like :id or :something_id
209
+ keys << (query.scan(/:\w+/).map { |k| k[1..-1].downcase.to_sym })
210
+ select_part = query.scan(/^select\s.*\sfrom/i).first
211
+ selected_columns << select_part.scan(/\sas\s+(\w+)/i).map { |c| c.first }
212
+ end
213
+ [keys.flatten.uniq, selected_columns]
212
214
  end
213
- [keys.flatten.uniq, selected_columns]
214
- end
215
215
 
216
- def create_datastore_preference(datastore_name, procedure_name)
217
- drop_ctx_preference(datastore_name)
218
- execute <<-SQL
216
+ def create_datastore_preference(datastore_name, procedure_name)
217
+ drop_ctx_preference(datastore_name)
218
+ execute <<-SQL
219
219
  BEGIN
220
220
  CTX_DDL.CREATE_PREFERENCE('#{datastore_name}', 'USER_DATASTORE');
221
221
  CTX_DDL.SET_ATTRIBUTE('#{datastore_name}', 'PROCEDURE', '#{procedure_name}');
222
222
  END;
223
223
  SQL
224
- end
224
+ end
225
225
 
226
- def create_storage_preference(storage_name, tablespace)
227
- drop_ctx_preference(storage_name)
228
- sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{storage_name}', 'BASIC_STORAGE');\n"
229
- ['I_TABLE_CLAUSE', 'K_TABLE_CLAUSE', 'R_TABLE_CLAUSE',
230
- 'N_TABLE_CLAUSE', 'I_INDEX_CLAUSE', 'P_TABLE_CLAUSE'].each do |clause|
231
- default_clause = case clause
232
- when 'R_TABLE_CLAUSE'; 'LOB(DATA) STORE AS (CACHE) '
233
- when 'I_INDEX_CLAUSE'; 'COMPRESS 2 '
234
- else ''
226
+ def create_storage_preference(storage_name, tablespace)
227
+ drop_ctx_preference(storage_name)
228
+ sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{storage_name}', 'BASIC_STORAGE');\n"
229
+ ["I_TABLE_CLAUSE", "K_TABLE_CLAUSE", "R_TABLE_CLAUSE",
230
+ "N_TABLE_CLAUSE", "I_INDEX_CLAUSE", "P_TABLE_CLAUSE"].each do |clause|
231
+ default_clause = case clause
232
+ when "R_TABLE_CLAUSE"; "LOB(DATA) STORE AS (CACHE) "
233
+ when "I_INDEX_CLAUSE"; "COMPRESS 2 "
234
+ else ""
235
+ end
236
+ sql << "CTX_DDL.SET_ATTRIBUTE('#{storage_name}', '#{clause}', '#{default_clause}TABLESPACE #{tablespace}');\n"
235
237
  end
236
- sql << "CTX_DDL.SET_ATTRIBUTE('#{storage_name}', '#{clause}', '#{default_clause}TABLESPACE #{tablespace}');\n"
238
+ sql << "END;\n"
239
+ execute sql
237
240
  end
238
- sql << "END;\n"
239
- execute sql
240
- end
241
241
 
242
- def create_lexer_preference(lexer_name, lexer_type, options)
243
- drop_ctx_preference(lexer_name)
244
- sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{lexer_name}', '#{lexer_type}');\n"
245
- options.each do |key, value|
246
- plsql_value = case value
247
- when String; "'#{value}'"
248
- when true; "'YES'"
249
- when false; "'NO'"
250
- when nil; 'NULL'
251
- else value
242
+ def create_lexer_preference(lexer_name, lexer_type, options)
243
+ drop_ctx_preference(lexer_name)
244
+ sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{lexer_name}', '#{lexer_type}');\n"
245
+ options.each do |key, value|
246
+ plsql_value = case value
247
+ when String; "'#{value}'"
248
+ when true; "'YES'"
249
+ when false; "'NO'"
250
+ when nil; "NULL"
251
+ else value
252
+ end
253
+ sql << "CTX_DDL.SET_ATTRIBUTE('#{lexer_name}', '#{key}', #{plsql_value});\n"
252
254
  end
253
- sql << "CTX_DDL.SET_ATTRIBUTE('#{lexer_name}', '#{key}', #{plsql_value});\n"
255
+ sql << "END;\n"
256
+ execute sql
254
257
  end
255
- sql << "END;\n"
256
- execute sql
257
- end
258
258
 
259
- def create_wordlist_preference(wordlist_name, wordlist_type, options)
260
- drop_ctx_preference(wordlist_name)
261
- sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{wordlist_name}', '#{wordlist_type}');\n"
262
- options.each do |key, value|
263
- plsql_value = case value
264
- when String; "'#{value}'"
265
- when true; "'YES'"
266
- when false; "'NO'"
267
- when nil; 'NULL'
268
- else value
259
+ def create_wordlist_preference(wordlist_name, wordlist_type, options)
260
+ drop_ctx_preference(wordlist_name)
261
+ sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{wordlist_name}', '#{wordlist_type}');\n"
262
+ options.each do |key, value|
263
+ plsql_value = case value
264
+ when String; "'#{value}'"
265
+ when true; "'YES'"
266
+ when false; "'NO'"
267
+ when nil; "NULL"
268
+ else value
269
+ end
270
+ sql << "CTX_DDL.SET_ATTRIBUTE('#{wordlist_name}', '#{key}', #{plsql_value});\n"
269
271
  end
270
- sql << "CTX_DDL.SET_ATTRIBUTE('#{wordlist_name}', '#{key}', #{plsql_value});\n"
272
+ sql << "END;\n"
273
+ execute sql
271
274
  end
272
- sql << "END;\n"
273
- execute sql
274
- end
275
275
 
276
- def drop_ctx_preference(preference_name)
277
- execute "BEGIN CTX_DDL.DROP_PREFERENCE('#{preference_name}'); END;" rescue nil
278
- end
276
+ def drop_ctx_preference(preference_name)
277
+ execute "BEGIN CTX_DDL.DROP_PREFERENCE('#{preference_name}'); END;" rescue nil
278
+ end
279
279
 
280
- def create_index_column_trigger(table_name, index_name, index_column, index_column_source)
281
- trigger_name = default_index_column_trigger_name(index_name)
282
- columns = Array(index_column_source)
283
- quoted_column_names = columns.map{|col| quote_column_name(col)}.join(', ')
284
- execute compress_lines(<<-SQL)
280
+ def create_index_column_trigger(table_name, index_name, index_column, index_column_source)
281
+ trigger_name = default_index_column_trigger_name(index_name)
282
+ columns = Array(index_column_source)
283
+ quoted_column_names = columns.map { |col| quote_column_name(col) }.join(", ")
284
+ execute compress_lines(<<-SQL)
285
285
  CREATE OR REPLACE TRIGGER #{quote_table_name(trigger_name)}
286
286
  BEFORE UPDATE OF #{quoted_column_names} ON #{quote_table_name(table_name)} FOR EACH ROW
287
287
  BEGIN
288
288
  :new.#{quote_column_name(index_column)} := '1';
289
289
  END;
290
290
  SQL
291
- end
291
+ end
292
292
 
293
- def drop_index_column_trigger(index_name)
294
- trigger_name = default_index_column_trigger_name(index_name)
295
- execute "DROP TRIGGER #{quote_table_name(trigger_name)}" rescue nil
296
- end
293
+ def drop_index_column_trigger(index_name)
294
+ trigger_name = default_index_column_trigger_name(index_name)
295
+ execute "DROP TRIGGER #{quote_table_name(trigger_name)}" rescue nil
296
+ end
297
297
 
298
- def default_datastore_procedure(index_name)
299
- "#{index_name}_prc"
300
- end
298
+ def default_datastore_procedure(index_name)
299
+ "#{index_name}_prc"
300
+ end
301
301
 
302
- def default_datastore_name(index_name)
303
- "#{index_name}_dst"
304
- end
302
+ def default_datastore_name(index_name)
303
+ "#{index_name}_dst"
304
+ end
305
305
 
306
- def default_storage_name(index_name)
307
- "#{index_name}_sto"
308
- end
306
+ def default_storage_name(index_name)
307
+ "#{index_name}_sto"
308
+ end
309
309
 
310
- def default_index_column_trigger_name(index_name)
311
- "#{index_name}_trg"
312
- end
310
+ def default_index_column_trigger_name(index_name)
311
+ "#{index_name}_trg"
312
+ end
313
313
 
314
- def default_lexer_name(index_name)
315
- "#{index_name}_lex"
316
- end
314
+ def default_lexer_name(index_name)
315
+ "#{index_name}_lex"
316
+ end
317
317
 
318
- def default_wordlist_name(index_name)
319
- "#{index_name}_wl"
320
- end
318
+ def default_wordlist_name(index_name)
319
+ "#{index_name}_wl"
320
+ end
321
321
 
322
- module BaseClassMethods
323
- # Declare that model table has context index defined.
324
- # As a result <tt>contains</tt> class scope method is defined.
325
- def has_context_index
326
- extend ContextIndexClassMethods
322
+ module BaseClassMethods
323
+ # Declare that model table has context index defined.
324
+ # As a result <tt>contains</tt> class scope method is defined.
325
+ def has_context_index
326
+ extend ContextIndexClassMethods
327
+ end
327
328
  end
328
- end
329
329
 
330
- module ContextIndexClassMethods
331
- # Add context index condition.
332
- def contains(column, query, options ={})
333
- score_label = options[:label].to_i || 1
334
- where("CONTAINS(#{connection.quote_table_name(column)}, ?, #{score_label}) > 0", query).
335
- order("SCORE(#{score_label}) DESC")
330
+ module ContextIndexClassMethods
331
+ # Add context index condition.
332
+ def contains(column, query, options = {})
333
+ score_label = options[:label].to_i || 1
334
+ where("CONTAINS(#{connection.quote_table_name(column)}, ?, #{score_label}) > 0", query).
335
+ order("SCORE(#{score_label}) DESC")
336
+ end
336
337
  end
337
- end
338
338
  end
339
339
  end
340
340
  end