Class: ActiveRecord::ConnectionAdapters::NullDBAdapter

Inherits:
AbstractAdapter
  • Object
show all
Defined in:
lib/active_record/connection_adapters/nulldb_adapter/core.rb,
lib/active_record/connection_adapters/nulldb_adapter/column.rb,
lib/active_record/connection_adapters/nulldb_adapter/statement.rb,
lib/active_record/connection_adapters/nulldb_adapter/checkpoint.rb,
lib/active_record/connection_adapters/nulldb_adapter/null_object.rb,
lib/active_record/connection_adapters/nulldb_adapter/empty_result.rb,
lib/active_record/connection_adapters/nulldb_adapter/configuration.rb,
lib/active_record/connection_adapters/nulldb_adapter/index_definition.rb,
lib/active_record/connection_adapters/nulldb_adapter/table_definition.rb

Defined Under Namespace

Classes: Checkpoint, Column, Configuration, DummyOID, EmptyResult, IndexDefinition, NullObject, Statement, TableDefinition

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ NullDBAdapter

Recognized options:

:schema

path to the schema file, relative to Rails.root

:table_definition_class_name

table definition class

(e.g. ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition for Postgres) or nil.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 20

def initialize(config={})
  @log            = StringIO.new
  @logger         = Logger.new(@log)
  @last_unique_id = 0
  @tables         = {'schema_info' => new_table_definition(nil)}
  @indexes        = Hash.new { |hash, key| hash[key] = [] }
  @schema_path    = config.fetch(:schema){ "db/schema.rb" }
  @config         = config.merge(:adapter => :nulldb)
  super *initialize_args
  @visitor ||= Arel::Visitors::ToSql.new self if defined?(Arel::Visitors::ToSql)

  if config[:table_definition_class_name]
    ActiveRecord::ConnectionAdapters::NullDBAdapter.send(:remove_const, 'TableDefinition')
    ActiveRecord::ConnectionAdapters::NullDBAdapter.const_set('TableDefinition',
      self.class.const_get(config[:table_definition_class_name]))
  end

  register_types
end

Class Attribute Details

.types_registeredObject

Returns the value of attribute types_registered.



405
406
407
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 405

def types_registered
  @types_registered
end

Class Method Details

.insinuate_into_spec(config) ⇒ Object

A convenience method for integratinginto RSpec. See README for example of use.



5
6
7
8
9
10
11
12
13
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 5

def self.insinuate_into_spec(config)
  config.before :all do
    ActiveRecord::Base.establish_connection(:adapter => :nulldb)
  end

  config.after :all do
    ActiveRecord::Base.establish_connection(:test)
  end
end

Instance Method Details

#adapter_nameObject



59
60
61
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 59

def adapter_name
  "NullDB"
end

#add_column(table_name, column_name, type, **options) ⇒ Object



232
233
234
235
236
237
238
239
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 232

def add_column(table_name, column_name, type, **options)
  super

  table_meta = @tables[table_name.to_s]
  return unless table_meta

  table_meta.column column_name, type, **options
end

#add_fk_constraint(*args) ⇒ Object



113
114
115
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 113

def add_fk_constraint(*args)
  # NOOP
end

#add_index(table_name, column_names, **options) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 86

def add_index(table_name, column_names, **options)
  options[:unique] = false unless options.key?(:unique)
  column_names = Array.wrap(column_names).map(&:to_s)

  index, index_type, ignore = add_index_options(table_name, column_names, **options)

  if index.is_a?(ActiveRecord::ConnectionAdapters::IndexDefinition)
    @indexes[table_name] << index
  else
    # Rails < 6.1
    @indexes[table_name] << IndexDefinition.new(table_name, index, (index_type == 'UNIQUE'), column_names, [], [])
  end
end

#add_pk_constraint(*args) ⇒ Object



117
118
119
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 117

def add_pk_constraint(*args)
  # NOOP
end

#affected_rows(raw_result) ⇒ Object



277
278
279
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 277

def affected_rows(raw_result)
  0
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object



241
242
243
244
245
246
247
248
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 241

def change_column(table_name, column_name, type, options = {})
  table_meta = @tables[table_name.to_s]
  column = table_meta.columns.find { |column| column.name == column_name.to_s }
  return unless column

  column.type = type
  column.options = options if options
end

#change_column_default(table_name, column_name, default_or_changes) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 258

def change_column_default(table_name, column_name, default_or_changes)
  table_meta = @tables[table_name.to_s]
  column = table_meta.columns.find { |column| column.name == column_name.to_s }

  return unless column

  if default_or_changes.kind_of? Hash
    column.default = default_or_changes[:to]
  else
    column.default = default_or_changes
  end
end

#checkpoint!Object

Inserts a checkpoint in the log. See also #execution_log_since_checkpoint.



55
56
57
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 55

def checkpoint!
  self.execution_log << Checkpoint.new
end

#columns(table_name, name = nil) ⇒ Object

Retrieve table columns as defined by the schema



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 135

def columns(table_name, name = nil)
  if @tables.size <= 1
    ActiveRecord::Migration.verbose = false
    schema_path = if Pathname(@schema_path).absolute?
                    @schema_path
                  else
                    File.join(NullDB.configuration.project_root, @schema_path)
                  end
    Kernel.load(schema_path)
  end

  if table = @tables[table_name]
    table.columns.map do |col_def|
      col_args = default_column_arguments(col_def)
      ActiveRecord::ConnectionAdapters::NullDBAdapter::Column.new(*col_args)
    end
  else
    []
  end
end

#create_table(table_name, options = {}) {|table_definition| ... } ⇒ Object

Yields:

  • (table_definition)


67
68
69
70
71
72
73
74
75
76
77
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 67

def create_table(table_name, options = {})
  table_definition = new_table_definition(self, table_name, options.delete(:temporary), options)

  unless options[:id] == false
    table_definition.primary_key(options[:primary_key] || "id")
  end

  yield table_definition if block_given?

  @tables[table_name.to_s] = table_definition
end

#delete(statement, name = nil, binds = []) ⇒ Object



198
199
200
201
202
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 198

def delete(statement, name=nil, binds = [])
  with_entry_point(:delete) do
    super(statement, name)
  end
end

#enable_extensionObject



121
122
123
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 121

def enable_extension(*)
  # NOOP
end

#exec_query(statement, name = 'SQL', binds = [], options = {}) ⇒ Object



166
167
168
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 166

def exec_query(statement, name = 'SQL', binds = [], options = {})
  internal_exec_query(statement, name, binds, **options)
end

#execute(statement, name = nil) ⇒ Object



161
162
163
164
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 161

def execute(statement, name = nil)
  self.execution_log << Statement.new(entry_point, statement)
  NullObject.new
end

#execution_logObject

A log of every statement that has been “executed” by this connection adapter instance.



42
43
44
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 42

def execution_log
  (@execution_log ||= [])
end

#execution_log_since_checkpointObject

A log of every statement that has been “executed” since the last time #checkpoint! was called, or since the connection was created.



48
49
50
51
52
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 48

def execution_log_since_checkpoint
  checkpoint_index = @execution_log.rindex(Checkpoint.new)
  checkpoint_index = checkpoint_index ? checkpoint_index + 1 : 0
  @execution_log[(checkpoint_index..-1)]
end

#indexes(table_name, name = nil) ⇒ Object

Retrieve table indexes as defined by the schema



157
158
159
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 157

def indexes(table_name, name = nil)
  @indexes[table_name]
end

#insert(statement, name = nil, primary_key = nil, object_id = nil, sequence_name = nil, binds = [], returning: nil) ⇒ Object Also known as: create



181
182
183
184
185
186
187
188
189
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 181

def insert(statement, name = nil, primary_key = nil, object_id = nil, sequence_name = nil, binds = [], returning: nil)
  with_entry_point(:insert) do
    super(statement, name, primary_key, object_id, sequence_name)
  end

  result = object_id || next_unique_id

  returning ? [result] : result
end

#internal_exec_query(statement, name = 'SQL', binds = [], prepare: false, async: false) ⇒ Object



170
171
172
173
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 170

def internal_exec_query(statement, name = 'SQL', binds = [], prepare: false, async: false)
  self.execution_log << Statement.new(entry_point, statement)
  EmptyResult.new
end

#perform_query(raw_connection, statement, binds, type_casted_binds, prepare:, notification_payload:, batch:) ⇒ Object

Rails 8.0+ ###



272
273
274
275
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 272

def perform_query(raw_connection, statement, binds, type_casted_binds, prepare:, notification_payload:, batch:)
  self.execution_log << Statement.new(entry_point, statement)
  NullObject.new
end

#primary_key(table_name) ⇒ Object



228
229
230
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 228

def primary_key(table_name)
  columns(table_name).detect { |col| col.type == :primary_key }.try(:name)
end

#reconnectObject



296
297
298
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 296

def reconnect
  true
end

#remove_index(table_name, options = {}) ⇒ Object



102
103
104
105
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 102

def remove_index(table_name, column_name = nil, **options )
  index_name = index_name_for_remove(table_name, column_name, options)
  index = @indexes[table_name].reject! { |index| index.name == index_name }
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object



250
251
252
253
254
255
256
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 250

def rename_column(table_name, column_name, new_column_name)
  table_meta = @tables[table_name.to_s]
  column = table_meta.columns.find { |column| column.name == column_name.to_s }
  return unless column

  column.name = new_column_name
end

#rename_table(table_name, new_name) ⇒ Object



79
80
81
82
83
84
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 79

def rename_table(table_name, new_name)
  table_definition = @tables.delete(table_name.to_s)

  table_definition.name = new_name.to_s
  @tables[new_name.to_s] = table_definition
end

#select_all(statement, name = nil, binds = [], options = {}) ⇒ Object



204
205
206
207
208
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 204

def select_all(statement, name=nil, binds = [], options = {})
  with_entry_point(:select_all) do
    super(statement, name)
  end
end

#select_one(statement, name = nil, binds = []) ⇒ Object



210
211
212
213
214
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 210

def select_one(statement, name=nil, binds = [])
  with_entry_point(:select_one) do
    super(statement, name)
  end
end

#select_rows(statement, name = nil, binds = [], async: false) ⇒ Object



175
176
177
178
179
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 175

def select_rows(statement, name = nil, binds = [], async: false)
  [].tap do
    self.execution_log << Statement.new(entry_point, statement)
  end
end

#select_value(statement, name = nil, binds = []) ⇒ Object



216
217
218
219
220
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 216

def select_value(statement, name=nil, binds = [])
  with_entry_point(:select_value) do
    super(statement, name)
  end
end

#select_values(statement, name = nil) ⇒ Object



222
223
224
225
226
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 222

def select_values(statement, name=nil)
  with_entry_point(:select_values) do
    super(statement, name)
  end
end

#supports_migrations?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 63

def supports_migrations?
  true
end

#tablesObject

Retrieve the table names defined by the schema



126
127
128
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 126

def tables
  @tables.keys.map(&:to_s)
end

#update(statement, name = nil, binds = []) ⇒ Object



192
193
194
195
196
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 192

def update(statement, name=nil, binds = [])
  with_entry_point(:update) do
    super(statement, name)
  end
end

#valid_column_definition_optionsObject



281
282
283
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 281

def valid_column_definition_options
  super + [:array, :using, :cast_as, :as, :type, :enum_type, :stored, :srid]
end

#viewsObject



130
131
132
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 130

def views
  [] # TODO: Implement properly if needed - This is new method in rails
end

#write_query?(sql) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


290
291
292
293
294
# File 'lib/active_record/connection_adapters/nulldb_adapter/core.rb', line 290

def write_query?(sql) # :nodoc:
  !READ_QUERY.match?(sql)
rescue ArgumentError # Invalid encoding
  !READ_QUERY.match?(sql.b)
end