activerecord-nulldb-adapter-1.1.1/ 0000755 0000041 0000041 00000000000 14716761556 017132 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/.gitignore 0000644 0000041 0000041 00000000311 14716761556 021115 0 ustar www-data www-data # generated coverage
coverage
coverage.data
# docs
rdoc
doc
.yardoc
# bundler
.bundle
*.lock
vendor
# gem
pkg
*.gem
# mac os specific
.DS_Store
# vim
*.swp
# rvm
.rvmrc
.ruby-*
# ginger
.ginger
activerecord-nulldb-adapter-1.1.1/CHANGES.md 0000644 0000041 0000041 00000005455 14716761556 020535 0 ustar www-data www-data Unreleased
----------
1.1.1 (20214-11-14)
- Fix syntax error on 2.7 and 3.0.
1.1.0 (2024-11-14)
-----------
- Add support to Rails 8 #136
- *Breaking* Drop support to Ruby 2.5, 2.6
- *Breaking* Drop support to Rails 6.0 (keep 6.1)
1.0.1 (2023-10-16)
-----------
- Alias enum field #122
1.0.0 (2023-10-16)
-----------
- Add support to Rails 7.1 #124
0.9.0 (2023-03-10)
-----------
- Add support to BigSerial #119
- Add support to hstore #118
- Support Postgres type modifiers #117
0.8.0 (2022-10-28)
-----------
- Add support for Rails 7. #111 #112
0.7.0 (2021-01-18)
-----------
- Add support to Rails 6.1 #106
0.6.0 (2021-01-08)
-----------
- *Breaking* Finish dropping support to Rails <= 5.1 by removing custom code for these versions. #101
0.5.0 (2020-10-15)
-----------
- *Breaking* Drop support to Ruby 2.2, 2.3, 2.4
- *Breaking* Drop support to Rails 2.X, 3.X, 4.X, 5.0, 5.1
- Drop support to old versions of Ruby and Rails. #96
- Added support for postgres column types included jsonb and ability to delete columns #94
0.4.0 (2019-07-22)
-----------
- *Breaking* Drop support to Ruby 1.9
- Add support for ActiveRecord 6.0 #90
- Prevent ActiveRecord::Tasks::DatabaseNotSupported #88
0.3.9 (2018-07-07)
-----------
- Fix broken count
- Avoid monkey patching Schema.define
- Support ruby 2.4 (drop support for ruby 2.1 and rails 3.0/3.1)
- Support custom TableDefinition (useful for postgres)
0.3.8 (2018-02-06)
-----------
- Adds support for ActiveRecord Edge (6.0)
0.3.7 (2017-06-04)
-----------
- Adds support for ActiveRecord 5.1/5.2.
- Support limit and null
0.3.6 (2016-11-23)
-----------
- Adds support for ActiveRecord 5.0.
0.3.5 (2016-09-26)
-----------
- Adds support for #cast_values on EmptyResult instance.
0.3.4 (2016-08-10)
-----------
- Adds support for Postgres-specific 'enable_extension'
0.3.3 (2016-08-01)
-----------
- Adds support for ActiveRecord 4.2.
- Deprecates support for MRI 2.0.0.
0.3.2 (2016-01-25)
-----------
- Deprecates support for MRI 1.9.3 and adds support for 2.3.x.
- Fixes :string column type fetching for AR 4.1.
0.3.1 (2014-02-17)
-----------
- Removes accidental dependency on iconv. Fixing JRuby support.
0.3.0 (2014-01-31)
-----------
- Drops 1.8.7 support.
- Adds support for Ruby 2.0, 2.1 and ActiveRecord 4.
- Fixes ActiveRecord 2.3 support on Ruby 2 and up.
- Misc small fixes
0.2.1 (2010-09-01)
-----------
- Updated Rails 3 support so that nulldb works against AR 3.0.0.
- Add support for RSpec 2.
0.2.0 (2010-03-20)
-----------
- Rails 3 support. All specs pass against ActiveRecord 3.0.0.beta.
0.1.1 (2010-03-15)
-----------
- Released as activerecord-nulldb-adapter gem.
0.1.0 (2010-03-02)
-----------
- Released as nulldb gem, with some bug fixes.
0.0.2 (2007-05-31)
-----------
- Moved to Rubyforge
0.0.1 (2007-02-18)
-----------
- Initial Release
activerecord-nulldb-adapter-1.1.1/.github/ 0000755 0000041 0000041 00000000000 14716761556 020472 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/.github/workflows/ 0000755 0000041 0000041 00000000000 14716761556 022527 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/.github/workflows/ruby.yml 0000644 0000041 0000041 00000003417 14716761556 024240 0 ustar www-data www-data name: build
on: [push, pull_request]
jobs:
test:
strategy:
fail-fast: false
matrix:
gemfile:
[
activerecord_6.1,
activerecord_7.0,
activerecord_7.1,
activerecord_7.2,
activerecord_8.0,
activerecord_master,
]
ruby: ["2.7", "3.0", "3.1", "3.2", "3.3", "jruby-9.3.1.0"]
exclude:
- ruby: "jruby-9.3.1.0"
gemfile: "activerecord_7.0"
- ruby: "jruby-9.3.1.0"
gemfile: "activerecord_7.1"
- ruby: "2.7"
gemfile: "activerecord_7.2"
- ruby: "2.8"
gemfile: "activerecord_7.2"
- ruby: "3.0"
gemfile: "activerecord_7.2"
- ruby: "jruby-9.3.1.0"
gemfile: "activerecord_7.2"
- ruby: "2.7"
gemfile: "activerecord_8.0"
- ruby: "2.8"
gemfile: "activerecord_8.0"
- ruby: "3.0"
gemfile: "activerecord_8.0"
- ruby: "3.1"
gemfile: "activerecord_8.0"
- ruby: "jruby-9.3.1.0"
gemfile: "activerecord_8.0"
- ruby: "2.7"
gemfile: "activerecord_master"
- ruby: "2.8"
gemfile: "activerecord_master"
- ruby: "3.0"
gemfile: "activerecord_master"
- ruby: "3.1"
gemfile: "activerecord_master"
- ruby: "jruby-9.3.1.0"
gemfile: "activerecord_master"
runs-on: ubuntu-latest
env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- run: bundle exec rake
activerecord-nulldb-adapter-1.1.1/lib/ 0000755 0000041 0000041 00000000000 14716761556 017700 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/tasks/ 0000755 0000041 0000041 00000000000 14716761556 021025 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/tasks/database.rake 0000644 0000041 0000041 00000001454 14716761556 023441 0 ustar www-data www-data # Sadly, we have to monkeypatch Rake because all of the Rails database tasks are
# hardcoded for specific adapters, with no extension points (!)
Rake::TaskManager.class_eval do
def remove_task(task_name)
@tasks.delete(task_name.to_s)
end
end
def remove_task(task_name)
Rake.application.remove_task(task_name)
end
def wrap_task(task_name, &wrapper)
wrapped_task = Rake::Task[task_name]
remove_task(Rake::Task.scope_name(Rake.application.current_scope,
task_name))
task(task_name) do
wrapper.call(wrapped_task)
end
end
namespace :db do
namespace :test do
wrap_task :purge do |wrapped_task|
if ActiveRecord::Base.configurations["test"]["adapter"] == "nulldb"
# NO-OP
else
wrapped_task.invoke
end
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/nulldb_rspec.rb 0000644 0000041 0000041 00000004544 14716761556 022710 0 ustar www-data www-data require 'active_record/connection_adapters/nulldb_adapter'
module NullDB
module RSpec
end
end
module NullDB::RSpec::NullifiedDatabase
NullDBAdapter = ActiveRecord::ConnectionAdapters::NullDBAdapter
class HaveExecuted
def initialize(entry_point)
@entry_point = entry_point
end
def matches?(connection)
log = connection.execution_log_since_checkpoint
if @entry_point == :anything
not log.empty?
else
log.include?(NullDBAdapter::Statement.new(@entry_point))
end
end
def description
"connection should execute #{@entry_point} statement"
end
def failure_message
" did not execute #{@entry_point} statement when it should have"
end
def negative_failure_message
" executed #{@entry_point} statement when it should not have"
end
end
def self.globally_nullify_database
block = lambda { |config| nullify_database(config) }
if defined?(RSpec)
RSpec.configure(&block)
else
Spec::Runner.configure(&block)
end
end
def self.contextually_nullify_database(context)
nullify_database(context)
end
# A matcher for asserting that database statements have (or have not) been
# executed. Usage:
#
# ActiveRecord::Base.connection.should have_executed(:insert)
#
# The types of statement that can be matched mostly mirror the public
# operations available in
# ActiveRecord::ConnectionAdapters::DatabaseStatements:
# - :select_one
# - :select_all
# - :select_value
# - :insert
# - :update
# - :delete
# - :execute
#
# There is also a special :anything symbol that will match any operation.
def have_executed(entry_point)
HaveExecuted.new(entry_point)
end
private
def self.included(other)
if nullify_contextually?(other)
contextually_nullify_database(other)
else
globally_nullify_database
end
end
def self.nullify_contextually?(other)
if defined?(RSpec)
other < RSpec::Core::ExampleGroup
else
other.is_a? Spec::ExampleGroup
end
end
def self.nullify_database(receiver)
receiver.before :all do
ActiveRecord::Base.establish_connection(:adapter => :nulldb)
end
receiver.before :each do
ActiveRecord::Base.connection.checkpoint!
end
receiver.after :all do
ActiveRecord::Base.establish_connection(:test)
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/nulldb/ 0000755 0000041 0000041 00000000000 14716761556 021160 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/nulldb/arel_compiler.rb 0000644 0000041 0000041 00000000136 14716761556 024322 0 ustar www-data www-data module Arel
module SqlCompiler
class NullDBCompiler < GenericCompiler
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/nulldb/rails.rb 0000644 0000041 0000041 00000000454 14716761556 022622 0 ustar www-data www-data require 'nulldb/core'
# Need to defer calling Rails.root because when bundler loads, Rails.root is nil
NullDB.configure {|ndb| def ndb.project_root;Rails.root;end}
ActiveRecord::Tasks::DatabaseTasks.register_task(/nulldb/, ActiveRecord::Tasks::NullDBDatabaseTasks) if defined?(ActiveRecord::Tasks)
activerecord-nulldb-adapter-1.1.1/lib/nulldb/core.rb 0000644 0000041 0000041 00000001665 14716761556 022445 0 ustar www-data www-data require 'active_support'
require 'active_support/deprecation'
require 'active_record/connection_adapters/nulldb_adapter'
module NullDB
class Configuration < Struct.new(:project_root); end
class << self
def configure
@configuration = Configuration.new.tap {|c| yield c}
end
def configuration
if @configuration.nil?
raise "NullDB not configured. Require a framework, ex 'nulldb/rails'"
end
@configuration
end
def nullify(options={})
begin
@prev_connection = ActiveRecord::Base.connection_pool.try(:spec)
rescue ActiveRecord::ConnectionNotEstablished
end
ActiveRecord::Base.establish_connection(options.merge(:adapter => :nulldb))
end
def restore
if @prev_connection
ActiveRecord::Base.establish_connection(@prev_connection.config)
end
end
def checkpoint
ActiveRecord::Base.connection.checkpoint!
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/nulldb/version.rb 0000644 0000041 0000041 00000000046 14716761556 023172 0 ustar www-data www-data module NullDB
VERSION = "1.1.1"
end
activerecord-nulldb-adapter-1.1.1/lib/nulldb/extensions.rb 0000644 0000041 0000041 00000001034 14716761556 023702 0 ustar www-data www-data unless respond_to?(:tap)
class Object
def tap
yield self
self
end
end
end
unless respond_to?(:try)
class Object
def try(*a, &b)
if a.empty? && block_given?
yield self
else
__send__(*a, &b)
end
end
end
class NilClass
def try(*args); nil; end
end
end
class ActiveRecord::Base
# Instantiate a new NullDB connection. Used by ActiveRecord internally.
def self.nulldb_connection(config)
ActiveRecord::ConnectionAdapters::NullDBAdapter.new(config)
end
end activerecord-nulldb-adapter-1.1.1/lib/active_record/ 0000755 0000041 0000041 00000000000 14716761556 022511 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/active_record/tasks/ 0000755 0000041 0000041 00000000000 14716761556 023636 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/active_record/tasks/nulldb_database_tasks.rb 0000644 0000041 0000041 00000000646 14716761556 030502 0 ustar www-data www-data class ActiveRecord::Tasks::NullDBDatabaseTasks
def initialize(configuration)
@configuration = configuration
end
def create(master_established = false)
# NO-OP
end
def drop
# NO-OP
end
def purge
# NO-OP
end
def structure_dump(filename, extra_flags)
# NO-OP
end
def structure_load(filename, extra_flags)
# NO-OP
end
def clear_active_connections!
# NO-OP
end
end
activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/ 0000755 0000041 0000041 00000000000 14716761556 026533 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/quoting.rb 0000644 0000041 0000041 00000000362 14716761556 030547 0 ustar www-data www-data module ActiveRecord
module ConnectionAdapters
module Quoting
extend ActiveSupport::Concern
module ClassMethods
def quote_column_name(column_name)
"'#{column_name}'"
end
end
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter.rb 0000644 0000041 0000041 00000002317 14716761556 032043 0 ustar www-data www-data require 'logger'
require 'stringio'
require 'singleton'
require 'pathname'
require 'active_support'
require 'active_record/connection_adapters/abstract_adapter'
require 'nulldb/core'
require 'nulldb/extensions'
require 'active_record/connection_adapters/quoting'
require 'active_record/connection_adapters/nulldb_adapter/core'
require 'active_record/connection_adapters/nulldb_adapter/statement'
require 'active_record/connection_adapters/nulldb_adapter/checkpoint'
require 'active_record/connection_adapters/nulldb_adapter/column'
require 'active_record/connection_adapters/nulldb_adapter/configuration'
require 'active_record/connection_adapters/nulldb_adapter/empty_result'
require 'active_record/connection_adapters/nulldb_adapter/index_definition'
require 'active_record/connection_adapters/nulldb_adapter/null_object'
require 'active_record/connection_adapters/nulldb_adapter/table_definition'
require 'active_record/tasks/nulldb_database_tasks' if defined?(ActiveRecord::Tasks)
module ActiveRecord
module ConnectionAdapters
if ActiveRecord::VERSION::STRING >= '7.2'
register 'nulldb', 'ActiveRecord::ConnectionAdapters::NullDBAdapter', 'active_record/connection_adapters/nulldb_adapter'
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/ 0000755 0000041 0000041 00000000000 14716761556 031513 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/checkpoint.rb0000644 0000041 0000041 00000000324 14716761556 034166 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class Checkpoint < Statement
def initialize
super(:checkpoint, "")
end
def ==(other)
self.class == other.class
end
end
end
././@LongLink 0000644 0000000 0000000 00000000147 00000000000 011605 L ustar root root activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/empty_result.rb activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/empty_result.0000644 0000041 0000041 00000001243 14716761556 034250 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class EmptyResult < Array
attr_reader :column_types
def bind_column_meta(columns)
@columns = columns
return if columns.empty?
@column_types = columns.reduce({}) do |ctypes, col|
ctypes[col.name] = ActiveRecord::Type.lookup(col.type)
ctypes
end
end
def columns
@columns ||= []
end
def column_types
@column_types ||= {}
end
def cast_values(type_overrides = nil)
rows
end
def rows
[]
end
def >(num)
rows.size > num
end
def includes_column?(name)
false
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/statement.rb 0000644 0000041 0000041 00000000455 14716761556 034050 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class Statement
attr_reader :entry_point, :content
def initialize(entry_point, content = "")
@entry_point, @content = entry_point, content
end
def ==(other)
self.entry_point == other.entry_point
end
end
end
././@LongLink 0000644 0000000 0000000 00000000150 00000000000 011577 L ustar root root activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/configuration.rb activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/configuration0000644 0000041 0000041 00000000163 14716761556 034305 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class Configuration < Struct.new(:project_root); end
end
activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/column.rb 0000644 0000041 0000041 00000000174 14716761556 033337 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class Column < ::ActiveRecord::ConnectionAdapters::Column
end
end
././@LongLink 0000644 0000000 0000000 00000000146 00000000000 011604 L ustar root root activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/null_object.rb activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/null_object.r0000644 0000041 0000041 00000000254 14716761556 034177 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class NullObject
def method_missing(*args, &block)
nil
end
def to_a
[]
end
end
end
././@LongLink 0000644 0000000 0000000 00000000153 00000000000 011602 L ustar root root activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/table_definition.rb activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/table_definit0000644 0000041 0000041 00000001534 14716761556 034232 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
attr_accessor :name
alias_method :enum, :string
alias_method :uuid, :string
alias_method :citext, :text
alias_method :interval, :text
alias_method :geometry, :text
alias_method :serial, :integer
alias_method :bigserial, :integer
alias_method :inet, :string
alias_method :jsonb, :json if method_defined? :json
alias_method :hstore, :json
def unique_constraint(*args, **kwargs, &block); end
if ::ActiveRecord::VERSION::MAJOR >= 7 && ::ActiveRecord::VERSION::MINOR >= 1
# Avoid check for option validity
def create_column_definition(name, type, options)
ActiveRecord::ConnectionAdapters::ColumnDefinition.new(name, type, options)
end
end
end
end
activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/core.rb 0000644 0000041 0000041 00000026151 14716761556 032775 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
# A convenience method for integratinginto RSpec. See README for example of
# use.
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
# 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.
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
# A log of every statement that has been "executed" by this connection adapter
# instance.
def execution_log
(@execution_log ||= [])
end
# A log of every statement that has been "executed" since the last time
# #checkpoint! was called, or since the connection was created.
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
# Inserts a checkpoint in the log. See also #execution_log_since_checkpoint.
def checkpoint!
self.execution_log << Checkpoint.new
end
def adapter_name
"NullDB"
end
def supports_migrations?
true
end
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
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
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
# Rails 6.1+
if ActiveRecord::VERSION::MAJOR >= 7 || (ActiveRecord::VERSION::MAJOR >= 6 and ActiveRecord::VERSION::MINOR > 0)
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
else
def remove_index(table_name, options = {} )
index_name = index_name_for_remove(table_name, options)
index = @indexes[table_name].reject! { |index| index.name == index_name }
end
end
def add_fk_constraint(*args)
# NOOP
end
def add_pk_constraint(*args)
# NOOP
end
def enable_extension(*)
# NOOP
end
# Retrieve the table names defined by the schema
def tables
@tables.keys.map(&:to_s)
end
def views
[] # TODO: Implement properly if needed - This is new method in rails
end
# Retrieve table columns as defined by the schema
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
# Retrieve table indexes as defined by the schema
def indexes(table_name, name = nil)
@indexes[table_name]
end
def execute(statement, name = nil)
self.execution_log << Statement.new(entry_point, statement)
NullObject.new
end
def exec_query(statement, name = 'SQL', binds = [], options = {})
internal_exec_query(statement, name, binds, **options)
end
def internal_exec_query(statement, name = 'SQL', binds = [], prepare: false, async: false)
self.execution_log << Statement.new(entry_point, statement)
EmptyResult.new
end
def select_rows(statement, name = nil, binds = [], async: false)
[].tap do
self.execution_log << Statement.new(entry_point, statement)
end
end
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
alias :create :insert
def update(statement, name=nil, binds = [])
with_entry_point(:update) do
super(statement, name)
end
end
def delete(statement, name=nil, binds = [])
with_entry_point(:delete) do
super(statement, name)
end
end
def select_all(statement, name=nil, binds = [], options = {})
with_entry_point(:select_all) do
super(statement, name)
end
end
def select_one(statement, name=nil, binds = [])
with_entry_point(:select_one) do
super(statement, name)
end
end
def select_value(statement, name=nil, binds = [])
with_entry_point(:select_value) do
super(statement, name)
end
end
def select_values(statement, name=nil)
with_entry_point(:select_values) do
super(statement, name)
end
end
def primary_key(table_name)
columns(table_name).detect { |col| col.type == :primary_key }.try(:name)
end
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
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
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
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
### Rails 8.0+ ###
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
def affected_rows(raw_result)
0
end
def valid_column_definition_options
super + [:array, :using, :cast_as, :as, :type, :enum_type, :stored, :srid]
end
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
:close, :declare, :fetch, :move, :set, :show
) # :nodoc:
private_constant :READ_QUERY
def write_query?(sql) # :nodoc:
!READ_QUERY.match?(sql)
rescue ArgumentError # Invalid encoding
!READ_QUERY.match?(sql.b)
end
def reconnect
true
end
### Rails 8.0+ ###
protected
def select(statement, name = nil, binds = [], prepare: nil, async: nil, allow_retry: nil)
EmptyResult.new.tap do |r|
r.bind_column_meta(columns_for(name))
self.execution_log << Statement.new(entry_point, statement)
end
end
private
def columns_for(table_name)
table_meta = @tables[table_name]
return [] unless table_meta
table_meta.columns
end
def next_unique_id
@last_unique_id += 1
end
def with_entry_point(method)
if entry_point.nil?
with_thread_local_variable(:entry_point, method) do
yield
end
else
yield
end
end
def entry_point
Thread.current[:entry_point]
end
def with_thread_local_variable(name, value)
old_value = Thread.current[name]
Thread.current[name] = value
begin
yield
ensure
Thread.current[name] = old_value
end
end
def includes_column?
false
end
def new_table_definition(adapter = nil, table_name = nil, is_temporary = nil, options = {})
case ::ActiveRecord::VERSION::MAJOR
when 6, 7, 8
TableDefinition.new(self, table_name, temporary: is_temporary, options: options.except(:id))
when 5
TableDefinition.new(table_name, is_temporary, options.except(:id), nil)
else
raise "Unsupported ActiveRecord version #{::ActiveRecord::VERSION::STRING}"
end
end
def default_column_arguments(col_def)
[
col_def.name.to_s,
col_def.default.present? ? col_def.default.to_s : nil,
sql_type_definition(col_def),
col_def.null.nil? || col_def.null
]
end
def sql_type_definition(col_def)
ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(
type: col_def.type,
sql_type: col_def.type.to_s,
limit: col_def.limit
)
end
def initialize_args
[nil, @logger, @config]
end
# Register types only once to avoid ActiveRecord::TypeConflictError
# in ActiveRecord::Type::Registration#<=>
REGISTRATION_MUTEX = Mutex.new
def register_types
REGISTRATION_MUTEX.synchronize do
return if self.class.types_registered
self.class.types_registered = true
end
ActiveRecord::Type.register(
:primary_key,
ActiveModel::Type::Integer,
adapter: adapter_name,
override: true
)
ActiveRecord::Type.add_modifier({ array: true }, DummyOID, adapter: :nulldb)
ActiveRecord::Type.add_modifier({ range: true }, DummyOID, adapter: :nulldb)
end
class << self
attr_accessor :types_registered
end
class DummyOID < ActiveModel::Type::Value
attr_reader :subtype
def initialize(*args)
@subtype = args.first
end
end
end
././@LongLink 0000644 0000000 0000000 00000000153 00000000000 011602 L ustar root root activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/index_definition.rb activerecord-nulldb-adapter-1.1.1/lib/active_record/connection_adapters/nulldb_adapter/index_definit0000644 0000041 0000041 00000000233 14716761556 034245 0 ustar www-data www-data class ActiveRecord::ConnectionAdapters::NullDBAdapter
class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders); end
end
activerecord-nulldb-adapter-1.1.1/lib/nulldb.rb 0000644 0000041 0000041 00000000055 14716761556 021505 0 ustar www-data www-data require 'nulldb/core'
require 'nulldb/rails'
activerecord-nulldb-adapter-1.1.1/lib/activerecord-nulldb-adapter.rb 0000644 0000041 0000041 00000000021 14716761556 025564 0 ustar www-data www-data require 'nulldb'
activerecord-nulldb-adapter-1.1.1/Appraisals 0000644 0000041 0000041 00000001040 14716761556 021147 0 ustar www-data www-data appraise "activerecord-5.2" do
gem "activerecord", "~> 5.2.0"
end
appraise "activerecord-6.0" do
gem "activerecord", "~> 6.0.0"
end
appraise "activerecord-7.0" do
gem "activerecord", "~> 7.0.0"
end
appraise "activerecord-7.1" do
gem "activerecord", "~> 7.1.0"
end
appraise "activerecord-7.2" do
gem "activerecord", "~> 7.2.0"
end
appraise "activerecord-8.0" do
gem "activerecord", github: 'rails/rails', branch: "8-0-stable"
end
appraise "activerecord-master" do
gem "activerecord", github: 'rails/rails', branch: :main
end
activerecord-nulldb-adapter-1.1.1/spec/ 0000755 0000041 0000041 00000000000 14716761556 020064 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/spec/nulldb_spec.rb 0000644 0000041 0000041 00000041127 14716761556 022710 0 ustar www-data www-data require 'rubygems'
# Optional simplecov loading
begin
require 'simplecov'
SimpleCov.start
rescue LoadError
end
require 'active_record'
require 'active_record/version'
$: << File.join(File.dirname(__FILE__), "..", "lib")
require 'rspec'
require 'nulldb_rspec'
class Employee < ActiveRecord::Base
after_save :on_save_finished
def on_save_finished
end
end
class TablelessModel < ActiveRecord::Base
end
NullDB.configure {|ndb| ndb.project_root = 'Rails.root'}
describe "NullDB with no schema pre-loaded" do
before :each do
allow( Kernel ).to receive :load
allow( ActiveRecord::Migration ).to receive :verbose=
end
it "should load Rails.root/db/schema.rb if no alternate is specified" do
ActiveRecord::Base.establish_connection :adapter => :nulldb
expect( Kernel ).to receive(:load).with("Rails.root/db/schema.rb")
ActiveRecord::Base.connection.columns('schema_info')
end
it "should load the specified schema relative to Rails.root" do
expect( Kernel ).to receive(:load).with("Rails.root/foo/myschema.rb")
ActiveRecord::Base.establish_connection :adapter => :nulldb,
:schema => "foo/myschema.rb"
ActiveRecord::Base.connection.columns('schema_info')
end
it "should suppress migration output" do
expect( ActiveRecord::Migration).to receive(:verbose=).with(false)
ActiveRecord::Base.establish_connection :adapter => :nulldb,
:schema => "foo/myschema.rb"
ActiveRecord::Base.connection.columns('schema_info')
end
it "should allow creating a table without passing a block" do
ActiveRecord::Base.establish_connection :adapter => :nulldb
ActiveRecord::Schema.define do
create_table(:employees)
end
end
end
describe "NullDB" do
before :all do
ActiveRecord::Base.establish_connection :adapter => :nulldb
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table(:employees) do |t|
t.string :name, null: false, limit: 50
t.date :hire_date
t.integer :employee_number
t.decimal :salary
t.boolean :active, default: true
end
create_table(:employees_widgets, :id => false, :force => true) do |t|
t.integer :employee_id
t.integer :widget_id
end
add_index "employees", :name, :name => "index_employees_on_name"
add_index "employees", ["employee_number"], :name => "index_employees_on_employee_number", :unique => true
add_index "employees", :hire_date
remove_index "employees", :hire_date
add_index "employees_widgets", ["employee_id", "widget_id"], :name => "my_index"
add_fk_constraint "foo", "bar", "baz", "buz", "bungle"
add_pk_constraint "foo", "bar", {}, "baz", "buz"
end
end
before :each do
@employee = Employee.new(:name => "John Smith",
:hire_date => Date.civil(2000, 1, 1),
:employee_number => 42,
:salary => 56000.00)
end
it "should set the @config instance variable so plugins that assume its there can use it" do
expect( Employee.connection.instance_variable_get(:@config)[:adapter]).to eq :nulldb
end
it "should enable instantiation of AR objects without a database" do
expect( @employee ).to be_a_kind_of(ActiveRecord::Base)
end
it "should remember columns defined in migrations" do
should_have_column(Employee, :name, :string)
should_have_column(Employee, :hire_date, :date)
should_have_column(Employee, :employee_number, :integer)
should_have_column(Employee, :salary, :decimal)
should_have_column(Employee, :active, :boolean)
end
it 'should have limit on name' do
expect(Employee.columns_hash['name'].limit).to eq 50
end
it "should return true on nullable field" do
expect(Employee.columns_hash['salary'].null).to be true
end
it "should return false on non-nullable field" do
expect(Employee.columns_hash['name'].null).to be false
end
it "should stringify default values" do
expect(Employee.columns_hash['active'].default).to eq "true"
end
it "should have no default for employee_number" do
expect(Employee.columns_hash['employee_number'].default).to eq nil
end
it "should return the appropriate primary key" do
expect( ActiveRecord::Base.connection.primary_key('employees') ).to eq 'id'
end
it "should return a nil primary key on habtm" do
expect( ActiveRecord::Base.connection.primary_key('employees_widgets') ).to eq nil
end
it "should return an empty array of columns for a table-less model" do
expect( TablelessModel.columns).to eq []
end
it "should enable simulated saving of AR objects" do
expect{ @employee.save! }.to_not raise_error
end
it "should enable AR callbacks during simulated save" do
expect( @employee ).to receive :on_save_finished
@employee.save
end
it "should enable simulated deletes of AR objects" do
expect{ @employee.destroy }.to_not raise_error
end
it "should enable simulated creates of AR objects" do
emp = Employee.create(:name => "Bob Jones")
expect( emp.name ).to eq "Bob Jones"
end
it "should generate new IDs when inserting unsaved objects" do
cxn = Employee.connection
id1 = cxn.insert("some sql", "SomeClass Create", "id", nil, nil)
id2 = cxn.insert("some sql", "SomeClass Create", "id", nil, nil)
expect( id2 ).to eq (id1 + 1)
end
it "should re-use object ID when inserting saved objects" do
cxn = Employee.connection
id1 = cxn.insert("some sql", "SomeClass Create", "id", 23, nil)
expect( id1 ).to eq 23
end
it "should log executed SQL statements" do
cxn = Employee.connection
exec_count = cxn.execution_log.size
@employee.save!
expect( cxn.execution_log.size ).to eq (exec_count + 1)
end
it "should have the adapter name 'NullDB'" do
expect( Employee.connection.adapter_name ).to eq "NullDB"
end
it "should support migrations" do
expect( Employee.connection.supports_migrations? ).to eq true
end
it "should always have a schema_info table definition" do
expect( Employee.connection.tables ).to include "schema_info"
end
it "should return an empty array from #select" do
result = Employee.connection.select_all("who cares", "blah")
expect( result ).to eq []
end
it "should provide a way to set log checkpoints" do
cxn = Employee.connection
@employee.save!
expect( cxn.execution_log_since_checkpoint.size ).to be > 0
cxn.checkpoint!
expect( cxn.execution_log_since_checkpoint.size ).to eq 0
@employee.salary = @employee.salary + 1
@employee.save!
expect( cxn.execution_log_since_checkpoint.size ).to eq 1
end
def should_contain_statement(cxn, entry_point)
expect( cxn.execution_log_since_checkpoint).to \
include(ActiveRecord::ConnectionAdapters::NullDBAdapter::Statement.new(entry_point))
end
def should_not_contain_statement(cxn, entry_point)
expect( cxn.execution_log_since_checkpoint ).to_not \
include(ActiveRecord::ConnectionAdapters::NullDBAdapter::Statement.new(entry_point))
end
it "should tag logged statements with their entry point" do
cxn = Employee.connection
should_not_contain_statement(cxn, :insert)
@employee.save
should_contain_statement(cxn, :insert)
cxn.checkpoint!
should_not_contain_statement(cxn, :update)
@employee.salary = @employee.salary + 1
@employee.save
should_contain_statement(cxn, :update)
cxn.checkpoint!
should_not_contain_statement(cxn, :delete)
@employee.destroy
should_contain_statement(cxn, :delete)
cxn.checkpoint!
should_not_contain_statement(cxn, :select_all)
Employee.all.each do |emp|; end
should_contain_statement(cxn, :select_all)
cxn.checkpoint!
should_not_contain_statement(cxn, :select_value)
Employee.count_by_sql("frobozz")
should_contain_statement(cxn, :select_value)
cxn.checkpoint!
should_not_contain_statement(cxn, :select_values)
cxn.select_values("")
should_contain_statement(cxn, :select_values)
end
it "should allow #finish to be called on the result of #execute" do
Employee.connection.execute("blah").finish
end
it "should #to_a return empty array on the result of #execute" do
result = Employee.connection.execute("blah")
expect( result.to_a ).to be_a Array
expect( result.to_a ).to be_empty
end
def should_have_column(klass, col_name, col_type)
col = klass.columns_hash[col_name.to_s]
expect(col.sql_type.to_s.gsub(/\([0-9]+\)/, "").to_sym).to eq col_type
end
it "should support adding and removing indexes" do
expect( Employee.connection.indexes('employees').size ).to eq 2
expect( Employee.connection.indexes('employees_widgets').size ).to eq 1
end
it "should support unique indexes" do
expect( Employee.connection.indexes('employees').detect{|idx| idx.columns == ["name"]}.unique ).to eq false
expect( Employee.connection.indexes('employees').detect{|idx| idx.columns == ["employee_number"]}.unique ).to eq true
end
it "should support multi-column indexes" do
expect( Employee.connection.indexes('employees_widgets').first.columns).to eq ["employee_id", "widget_id"]
end
it "should support custom index names" do
expect( Employee.connection.indexes('employees_widgets').first.name ).to eq 'my_index'
end
it 'should handle ActiveRecord::ConnectionNotEstablished' do
expect( ActiveRecord::Base ).to receive(:connection_pool).and_raise(ActiveRecord::ConnectionNotEstablished)
expect { NullDB.nullify }.to_not raise_error
end
it 'should handle count queries' do
expect(Employee.count).to eql(0)
end
end
# need a fallback db for contextual nullification
if defined?(ActiveRecord::DatabaseConfigurations)
db_config = { 'test' => {'adapter' => 'nulldb'} }
ActiveRecord::Base.configurations = ActiveRecord::DatabaseConfigurations.new(db_config)
else
# Support ActiveRecord 5
ActiveRecord::Base.configurations['test'] = {'adapter' => 'nulldb'}
end
describe NullDB::RSpec::NullifiedDatabase do
describe 'have_executed rspec matcher' do
before(:all) do
ActiveRecord::Schema.define do
create_table(:employees)
end
end
include NullDB::RSpec::NullifiedDatabase
before { NullDB.checkpoint }
it 'passes if an execution was made' do
expect( Employee.connection ).to receive(:insert)
allow( Kernel ).to receive :load
Employee.create
end
end
describe '.globally_nullify_database' do
it 'nullifies the database' do
expect( NullDB::RSpec::NullifiedDatabase ).to respond_to(:nullify_database)
expect( NullDB::RSpec::NullifiedDatabase ).to receive(:nullify_database)
NullDB::RSpec::NullifiedDatabase.globally_nullify_database
end
end
end
describe 'table changes' do
before(:each) do
ActiveRecord::Base.establish_connection :adapter => :nulldb
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table(:employees) do |t|
t.string :name, null: false, limit: 50
t.date :hire_date
t.integer :employee_number
t.decimal :salary
end
end
end
def should_have_column(klass, col_name, col_type)
col = klass.columns_hash[col_name.to_s]
expect(col.sql_type.to_s.gsub(/\([0-9]+\)/, "").to_sym).to eq col_type
end
describe 'rename_table' do
it 'should rename a table' do
expect{
ActiveRecord::Schema.define do
rename_table :employees, :workers
end
}.to_not raise_error
class Worker < ActiveRecord::Base
after_save :on_save_finished
def on_save_finished
end
end
should_have_column(Worker, :name, :string)
should_have_column(Worker, :hire_date, :date)
should_have_column(Worker, :employee_number, :integer)
should_have_column(Worker, :salary, :decimal)
worker = Worker.create(:name => "Bob Jones")
expect(worker.name).to eq "Bob Jones"
end
end
describe 'add_column' do
it 'should add a column to an existing table' do
expect{
ActiveRecord::Schema.define do
add_column :employees, :title, :string
end
Employee.connection.schema_cache.clear!
Employee.reset_column_information
}.to_not raise_error
should_have_column(Employee, :name, :string)
should_have_column(Employee, :hire_date, :date)
should_have_column(Employee, :employee_number, :integer)
should_have_column(Employee, :salary, :decimal)
should_have_column(Employee, :title, :string)
end
end
describe 'change_column' do
it 'should change the column type' do
expect{
ActiveRecord::Schema.define do
change_column :employees, :name, :text
end
Employee.connection.schema_cache.clear!
Employee.reset_column_information
}.to_not raise_error
should_have_column(Employee, :name, :text)
should_have_column(Employee, :hire_date, :date)
should_have_column(Employee, :employee_number, :integer)
should_have_column(Employee, :salary, :decimal)
end
end
describe 'rename_column' do
it 'should rename a column' do
expect{
ActiveRecord::Schema.define do
rename_column :employees, :name, :full_name
end
Employee.connection.schema_cache.clear!
Employee.reset_column_information
}.to_not raise_error
should_have_column(Employee, :full_name, :string)
should_have_column(Employee, :hire_date, :date)
should_have_column(Employee, :employee_number, :integer)
should_have_column(Employee, :salary, :decimal)
end
end
describe 'change_column_default' do
it 'should change default value of a column' do
expect{
ActiveRecord::Schema.define do
change_column_default :employees, :name, 'Jon Doe'
end
Employee.connection.schema_cache.clear!
Employee.reset_column_information
}.to_not raise_error
columns = Employee.columns
expect(columns.second.default).to eq('Jon Doe')
end
it 'should change default value of a with has syntax' do
expect{
ActiveRecord::Schema.define do
change_column_default :employees, :name, from: nil, to: 'Jon Doe'
end
Employee.connection.schema_cache.clear!
Employee.reset_column_information
}.to_not raise_error
columns = Employee.columns
expect(columns.second.default).to eq('Jon Doe')
end
end
end
describe 'adapter-specific extensions' do
before(:all) do
ActiveRecord::Base.establish_connection :adapter => :nulldb
ActiveRecord::Migration.verbose = false
end
def should_have_column(klass, col_name, col_type)
col = klass.columns_hash[col_name.to_s]
expect(col.sql_type.to_s.gsub(/\([0-9]+\)/, "").to_sym).to eq col_type
end
it "supports 'enable_extension' in the schema definition" do
expect{
ActiveRecord::Schema.define do
enable_extension "plpgsql"
end
}.to_not raise_error
end
it 'supports postgres extension columns' do
expect {
ActiveRecord::Schema.define do
create_table :extended_models do |t|
t.citext :text
t.interval :time_interval
t.geometry :feature_geometry, srid: 4326, type: "multi_polygon"
t.jsonb :jsonb_column
t.hstore :hstore_column
end
end
}.to_not raise_error
class ExtendedModel < ActiveRecord::Base
end
should_have_column(ExtendedModel, :text, :text)
should_have_column(ExtendedModel, :time_interval, :text)
should_have_column(ExtendedModel, :feature_geometry, :text)
should_have_column(ExtendedModel, :jsonb_column, :json)
end
it 'supports ActiveModel attributes with postgres modifiers' do
class ExtendedModel < ActiveRecord::Base
attribute :strings, :string, array: true
attribute :size, :integer, range: true
end
expect(ExtendedModel.type_for_attribute(:strings))
.to be_a ActiveRecord::ConnectionAdapters::NullDBAdapter::DummyOID
expect(ExtendedModel.new(strings: %w[a b]).strings).to eq %w[a b]
expect(ExtendedModel.type_for_attribute(:size))
.to be_a ActiveRecord::ConnectionAdapters::NullDBAdapter::DummyOID
expect(ExtendedModel.new(size: 1..5).size).to eq 1..5
end
it 'registers a primary_key type' do
expect(ActiveRecord::Type.lookup(:primary_key, adapter: 'NullDB'))
.to be_a(ActiveModel::Type::Integer)
end
end
describe ActiveRecord::ConnectionAdapters::NullDBAdapter::EmptyResult do
it "should return an empty array from #cast_values" do
result = described_class.new
expect( result.cast_values ).to be_a Array
expect( result.cast_values ).to be_empty
end
end
activerecord-nulldb-adapter-1.1.1/spec/spec.opts 0000644 0000041 0000041 00000000017 14716761556 021723 0 ustar www-data www-data --format nested activerecord-nulldb-adapter-1.1.1/activerecord-nulldb-adapter.gemspec 0000644 0000041 0000041 00000002270 14716761556 026046 0 ustar www-data www-data # coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'nulldb/version'
Gem::Specification.new do |s|
s.name = "activerecord-nulldb-adapter"
s.version = NullDB::VERSION
s.require_paths = ["lib"]
s.authors = ["Avdi Grimm", "Myron Marston", "Danilo Cabello"]
s.summary = "The Null Object pattern as applied to ActiveRecord database adapters"
s.description = "A database backend that translates database interactions into no-ops. Using NullDB enables you to test your model business logic - including after_save hooks - without ever touching a real database."
s.email = "cabello@users.noreply.github.com"
s.extra_rdoc_files = [
"LICENSE",
"README.md"
]
s.files = `git ls-files`.split($/)
s.homepage = "https://github.com/nulldb/nulldb"
s.licenses = ["MIT"]
s.add_runtime_dependency 'activerecord', '>= 6.0', '< 8.1'
s.add_development_dependency 'spec'
s.add_development_dependency 'rdoc'
s.add_development_dependency 'rspec'
s.add_development_dependency 'rake'
s.add_development_dependency 'appraisal'
s.add_development_dependency 'simplecov'
s.add_development_dependency 'pry-byebug'
end
activerecord-nulldb-adapter-1.1.1/gemfiles/ 0000755 0000041 0000041 00000000000 14716761556 020725 5 ustar www-data www-data activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_7.0.gemfile 0000644 0000041 0000041 00000000430 14716761556 025312 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", "~> 7.0.0"
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_6.1.gemfile 0000644 0000041 0000041 00000000430 14716761556 025312 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", "~> 6.1.0"
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_master.gemfile 0000644 0000041 0000041 00000000462 14716761556 026306 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", github: "rails/rails", branch: :main
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_7.2.gemfile 0000644 0000041 0000041 00000000430 14716761556 025314 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", "~> 7.2.0"
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_6.0.gemfile 0000644 0000041 0000041 00000000430 14716761556 025311 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", "~> 6.0.0"
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_7.1.gemfile 0000644 0000041 0000041 00000000430 14716761556 025313 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", "~> 7.1.0"
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/gemfiles/activerecord_8.0.gemfile 0000644 0000041 0000041 00000000471 14716761556 025320 0 ustar www-data www-data # This file was generated by Appraisal
source "https://rubygems.org"
gem "activerecord", github: "rails/rails", branch: "8-0-stable"
group :development, :test do
gem "spec"
gem "rspec", ">= 1.2.9"
gem "rake"
gem "rdoc"
end
group :development do
gem "appraisal"
gem "simplecov", require: false
end
activerecord-nulldb-adapter-1.1.1/Rakefile 0000644 0000041 0000041 00000000442 14716761556 020577 0 ustar www-data www-data require 'rubygems'
require 'rake'
require 'rspec/core/rake_task'
require 'bundler/gem_tasks'
RSpec::Core::RakeTask.new(:spec)
task :default => :spec
require 'rdoc/task'
Rake::RDocTask.new do |rd|
rd.main = "README.md"
rd.rdoc_files.include("README.md", "LICENSE", "lib/**/*.rb")
end
activerecord-nulldb-adapter-1.1.1/Gemfile 0000644 0000041 0000041 00000000372 14716761556 020427 0 ustar www-data www-data source "https://rubygems.org"
gem 'activerecord', '>= 6.0', '< 8.1'
group :development, :test do
gem 'spec'
gem 'rspec', '>= 1.2.9'
gem 'rake'
gem 'rdoc'
end
group :development do
gem 'appraisal'
gem 'simplecov', :require => false
end
activerecord-nulldb-adapter-1.1.1/LICENSE 0000644 0000041 0000041 00000002057 14716761556 020143 0 ustar www-data www-data The MIT License
Copyright (c) 2008 Avdi Grimm
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
activerecord-nulldb-adapter-1.1.1/README.md 0000644 0000041 0000041 00000012333 14716761556 020413 0 ustar www-data www-data [
](http://badge.fury.io/rb/activerecord-nulldb-adapter) [
](https://codeclimate.com/github/nulldb/nulldb) [
](https://github.com/nulldb/nulldb/actions)
# The NullDB Connection Adapter Plugin
## What
NullDB is the Null Object pattern as applied to ActiveRecord database
adapters. It is a database backend that translates database interactions into
no-ops. Using NullDB enables you to test your model business logic -
including `after_save` hooks - without ever touching a real database.
## Compatibility
### Ruby
Currently supported Ruby versions: `2.7.X`, `3.X`.
Experimental support provided for: JRuby
### ActiveRecord
Any version of ActiveRecord `>= 6.1`
## Installation
```bash
gem install activerecord-nulldb-adapter
```
## How
Once installed, NullDB can be used much like any other ActiveRecord database
adapter:
```ruby
ActiveRecord::Base.establish_connection :adapter => :nulldb
```
NullDB needs to know where you keep your schema file in order to reflect table
metadata. By default it looks in RAILS_ROOT/db/schema.rb. You can override
that by setting the `schema` option:
```ruby
ActiveRecord::Base.establish_connection :adapter => :nulldb,
:schema => 'foo/myschema.rb'
```
NullDB comes with RSpec integration. To replace the database with NullDB in
all of your specs, put the following in your spec/rails_helper:
```ruby
require 'nulldb_rspec'
include NullDB::RSpec::NullifiedDatabase
```
after you load your rails environment
```ruby
require File.expand_path('../config/environment', __dir__)
```
otherwise you will encounter issues such as
([bug)](https://github.com/nulldb/nulldb/pull/90#issuecomment-496690958).
Or if you just want to use NullDB in a specific spec context, you can include
the same module inside a context:
```ruby
require 'nulldb_rspec'
describe Employee, "with access to the database" do
fixtures :employees
# ...
end
describe Employee, "with NullDB" do
include NullDB::RSpec::NullifiedDatabase
# ...
end
```
If you want to have NullDB enabled by default but disabled for particular
contexts then (see this
[post)](https://web.archive.org/web/20120419204019/http://andywaite.com/2011/5
/18/rspec-disable-nulldb)
NullDB::Rspec provides some custom matcher support for verifying expectations
about interactions with the database:
```ruby
describe Employee do
include NullDB::RSpec::NullifiedDatabase
it "should cause an insert statement to be executed" do
Employee.create!
Employee.connection.should have_executed(:insert)
end
end
```
UnitRecord-style verification that no database calls have been made at all can
be achieved by using the special `:anything` symbol:
```ruby
describe "stuff that shouldn't touch the database" do
after :each do
Employee.connection.should_not have_executed(:anything)
end
# ...
end
```
You can also experiment with putting NullDB in your database.yml:
```yaml
unit_test:
adapter: nulldb
```
However, due to the way Rails hard-codes specific database adapters into its
standard Rake tasks, you may find that this generates unexpected and
difficult-to-debug behavior. Workarounds for this are under development.
## Why
There are a number of advantages to writing unit tests that never touch the
database. The biggest is probably speed of execution - unit tests must be
fast for test-driven development to be practical. Another is separation of
concerns: unit tests should be exercising only the business logic contained in
your models, not ActiveRecord. For more on why testing-sans-database is a good
idea, see:
http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database.
NullDB is one way to separate your unit tests from the database. It was
inspired by the [ARBS](http://arbs.rubyforge.org/) and
[UnitRecord](http://unit-test-ar.rubyforge.org/) libraries. It differs from
them in that rather than modifying parts of ActiveRecord, it implements the
same [semi-]well-documented public interface that the other standard database
adapters, like MySQL and SQLServer, implement. This has enabled it to evolve
to support new ActiveRecord versions relatively easily.
One concrete advantage of this null-object pattern design is that it is
possible with NullDB to test `after_save` hooks. With NullDB, you can call
`#save` and all of the usual callbacks will be called - but nothing will be
saved.
## Limitations
* It is **not** an in-memory database. Finds will not work. Neither will
`reload`, currently. Test fixtures won't work either, for obvious
reasons.
* It has only the most rudimentery schema/migration support. Complex
migrations will probably break it.
* Lots of other things probably don't work. Patches welcome!
## Who
NullDB was originally written by Avdi Grimm . It is
currently maintained by [Danilo Cabello](https://github.com/cabello).
Previously maintained by: [Bram de Vries](https://github.com/blaet).
## Where
* Homepage: https://github.com/nulldb/nulldb
## License
See the LICENSE file for licensing information.