Class: Bitcoin::Storage::Backends::SequelStoreBase

Inherits:
StoreBase
  • Object
show all
Defined in:
lib/bitcoin/storage/storage.rb

Direct Known Subclasses

SequelStore, UtxoStore

Constant Summary collapse

DEFAULT_CONFIG =
{
  sqlite_pragmas: {
    # journal_mode pragma
    journal_mode: false,
    # synchronous pragma
    synchronous: false,
    # cache_size pragma
    # positive specifies number of cache pages to use,
    # negative specifies cache size in kilobytes.
    cache_size: -200_000,
  }
}
SEQUEL_ADAPTERS =
{ :sqlite => "sqlite3", :postgres => "pg", :mysql => "mysql" }

Constants inherited from StoreBase

Bitcoin::Storage::Backends::StoreBase::ADDRESS_TYPES, Bitcoin::Storage::Backends::StoreBase::MAIN, Bitcoin::Storage::Backends::StoreBase::ORPHAN, Bitcoin::Storage::Backends::StoreBase::SCRIPT_TYPES, Bitcoin::Storage::Backends::StoreBase::SIDE

Instance Attribute Summary

Attributes inherited from StoreBase

#config, #log

Instance Method Summary collapse

Methods inherited from StoreBase

#add_watched_address, #backend_name, #check_consistency, #get_balance, #get_block, #get_block_by_depth, #get_block_by_id, #get_block_by_prev_hash, #get_block_by_tx, #get_block_id_for_tx_id, #get_depth, #get_head, #get_idx_from_tx_hash, #get_locator, #get_tx, #get_tx_by_id, #get_txin_for_txout, #get_txins_for_txouts, #get_txouts_for_address, #get_txouts_for_pk_script, #get_txs, #get_unspent_txouts_for_address, #has_block, #has_tx, #import, #in_sync?, #initialize, #new_block, #new_tx, #parse_script, #persist_block, #push_notification, #rescan, #reset, #store_block, #store_tx, #subscribe, #update_block

Constructor Details

This class inherits a constructor from Bitcoin::Storage::Backends::StoreBase

Instance Method Details

#check_metadataObject

check that database network magic and backend match the ones we are using



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
# File 'lib/bitcoin/storage/storage.rb', line 486

def 
  version = @db[:schema_info].first
  unless version[:magic] == Bitcoin.network[:magic_head].hth
    name = Bitcoin::NETWORKS.find{|n,d| d[:magic_head].hth == version[:magic]}[0]
    raise "Error: DB #{@db.url} was created for '#{name}' network!"
  end
  unless version[:backend] == backend_name
    if version[:backend] == "sequel" && backend_name == "utxo"
      log.warn { "Note: The 'utxo' store is now the default backend.
      To keep using the full storage, change the configuration to use storage: 'sequel::#{@db.url}'.
      To use the new storage backend, delete or move #{@db.url}, or specify a different database path in the config." }
    end
    raise "Error: DB #{@db.url} was created for '#{version[:backend]}' backend!"
  end
end

#connectObject

connect to database



463
464
465
466
467
468
469
# File 'lib/bitcoin/storage/storage.rb', line 463

def connect
  Sequel.extension(:core_extensions, :sequel_3_dataset_methods)
  @db = Sequel.connect(@config[:db].sub("~", ENV["HOME"]))
  @db.extend_datasets(Sequel::Sequel3DatasetMethods)
  sqlite_pragmas; migrate; 
  log.info { "opened #{backend_name} store #{@db.uri}" }
end

#init_store_connectionObject

set the connection



453
454
455
456
457
458
459
460
# File 'lib/bitcoin/storage/storage.rb', line 453

def init_store_connection
  return  unless (self.is_a?(SequelStore) || self.is_a?(UtxoStore)) && @config[:db]
  @config[:db].sub!("~", ENV["HOME"])
  @config[:db].sub!("<network>", Bitcoin.network_name.to_s)
  adapter = SEQUEL_ADAPTERS[@config[:db].split(":").first] rescue nil
  Bitcoin.require_dependency(adapter, gem: adapter)  if adapter
  connect
end

#migrateObject

check if schema is up to date and migrate to current version if necessary



472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/bitcoin/storage/storage.rb', line 472

def migrate
  migrations_path = File.join(File.dirname(__FILE__), "#{backend_name}/migrations")
  Sequel.extension :migration
  unless Sequel::Migrator.is_current?(@db, migrations_path)
    store = self; log = @log; @db.instance_eval { @log = log; @store = store }
    Sequel::Migrator.run(@db, migrations_path)
    unless (v = @db[:schema_info].first) && v[:magic] && v[:backend]
      @db[:schema_info].update(
        magic: Bitcoin.network[:magic_head].hth, backend: backend_name)
    end
  end
end

#sqlite_pragmasObject

set pragma options for sqlite (if it is sqlite)



503
504
505
506
507
508
509
# File 'lib/bitcoin/storage/storage.rb', line 503

def sqlite_pragmas
  return  unless (@db.is_a?(Sequel::SQLite::Database) rescue false)
  @config[:sqlite_pragmas].each do |name, value|
    @db.pragma_set name, value
    log.debug { "set sqlite pragma #{name} to #{value}" }
  end
end