Module: BlackStack::Deployer::DB

Defined in:
lib/blackstack-deployer.rb

Overview

def

Constant Summary collapse

@@checkpoint =
nil
@@superhuser =
nil
@@ndb =
nil
@@folder =
nil

Class Method Summary collapse

Class Method Details

.connect(s) ⇒ Object



536
537
538
# File 'lib/blackstack-deployer.rb', line 536

def self.connect(s)
  @@db = Sequel::connect(s)
end

.deployObject

Run a series of .sql files with updates to the database.



614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
# File 'lib/blackstack-deployer.rb', line 614

def self.deploy()
  tlogger = BlackStack::Deployer::logger
  # get list of `.sql` files in the directory `sql_path`, with a name higher than `last_filename`, sorted by name.

  Dir.entries(@@folder).select { 
    |filename| filename =~ /\.sql$/ && filename > @@checkpoint.to_s
  }.uniq.sort.each { |filename|
    fullfilename = "#{@@folder}/#{filename}"

    tlogger.logs "#{fullfilename}... "
    BlackStack::Deployer::DB::execute_sentences( File.open(fullfilename).read )
    tlogger.done

    tlogger.logs "Updating checkpoint... "
    @@checkpoint = filename
    tlogger.done
  }
end

.execute_sentences(sql, chunk_size = 200) ⇒ Object

Method to process an .sql file with one sql sentence by line. Reference: stackoverflow.com/questions/64066344/import-large-sql-files-with-ruby-sequel-gem This method is called by BlackStack::Deployer::db_execute_file if the filename matches with ‘/.sentences./`. This method should not be called directly by user code.



571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'lib/blackstack-deployer.rb', line 571

def self.execute_sentences(sql, chunk_size=200)      
  tlogger = BlackStack::Deployer::logger

  # Fix issue: Ruby `split': invalid byte sequence in UTF-8 (ArgumentError)

  # Reference: https://stackoverflow.com/questions/11065962/ruby-split-invalid-byte-sequence-in-utf-8-argumenterror

  #

  # Fix issue: `PG::SyntaxError: ERROR:  at or near "��truncate": syntax error`

  #

  sql.encode!('UTF-8', :invalid => :replace, :replace => '')

  # Remove null bytes to avoid error: `String contains null byte`

  # Reference: https://stackoverflow.com/questions/29320369/coping-with-string-contains-null-byte-sent-from-users

  sql.gsub!("\u0000", "")

  # Get the array of sentences

  tlogger.logs "Splitting the sql sentences... "
  sentences = sql.split(/;/i) 
  tlogger.logf "done (#{sentences.size})"

  # Chunk the array into parts of chunk_size elements

  # Reference: https://stackoverflow.com/questions/2699584/how-to-split-chunk-a-ruby-array-into-parts-of-x-elements

  tlogger.logs "Bunlding the array of sentences into chunks of #{chunk_size} each... "
  chunks = sentences.each_slice(chunk_size).to_a
  tlogger.logf "done (#{chunks.size})"

  chunk_number = -1
  chunks.each { |chunk|
    chunk_number += 1
    statement = chunk.join(";\n").to_s.strip
    tlogger.logs "lines #{chunk_size*chunk_number+1} to #{chunk_size*chunk_number+chunk.size} of #{sentences.size}... "
    begin
      @@db.execute(statement) #if statement.to_s.strip.size > 0

      tlogger.done
    rescue => e
      tlogger.logf e.to_s 
      raise "Error executing statement: #{statement}\n#{e.message}"
    end
  }
  tlogger.done
end

.execute_transactions(sql) ⇒ Object

Method to process an .sql file with transactions code, separated by BEGIN; and COMMIT; statements. Reference: stackoverflow.com/questions/64066344/import-large-sql-files-with-ruby-sequel-gem This method is called by BlackStack::Deployer::db_execute_file if the filename matches with ‘/.tsql./`. This method should not be called directly by user code.



563
564
565
# File 'lib/blackstack-deployer.rb', line 563

def self.execute_transactions(sql)  
  # TODO: Code Me!

end

.is_sentences_file?(filename) ⇒ Boolean

Return true if the name of the file matches with ‘/.sentences./`, and it doesn’t match with ‘/.transactions./`, and the matches with `/.sentences./` are no more than one. Otherwise({, return false. This method should not be called directly by user code.



555
556
557
# File 'lib/blackstack-deployer.rb', line 555

def self.is_sentences_file?(filename)
  filename =~ /\.sentences\./ && filename !~ /\.transactions\./ && filename.scan(/\.sentences\./).size == 1
end

.is_transactions_file?(filename) ⇒ Boolean

Return true if the name of the file matches with ‘/.transactions./`, and it doesn’t match with ‘/.sentences./`, and the matches with `/.transactions./` are no more than one. Otherwise, return false. This method should not be called directly by user code.



548
549
550
# File 'lib/blackstack-deployer.rb', line 548

def self.is_transactions_file?(filename)
  filename =~ /\.transactions\./ && filename !~ /\.sentences\./ && filename.scan(/\.transactions\./).size == 1
end

.set_checkpoint(s) ⇒ Object



532
533
534
# File 'lib/blackstack-deployer.rb', line 532

def self.set_checkpoint(s)
  @@checkpoint = s
end

.set_folder(s) ⇒ Object

def



540
541
542
# File 'lib/blackstack-deployer.rb', line 540

def self.set_folder(s)
  @@folder = s
end