class SqlSkelton::TblIndex

class SqlSkelton::TblIndex

Summary

Class for mapping between the original and modified SQL tables

Description

This holds the information of old and new names for each table.

When you specify something, it is always the old table name.

Example

ci = SqlSkelton::TblIndex.new(tables)  # Columns are not set.
ci.update!(tables[0])
ci.update!(:all)

# Manually sets
ci.set_newtblval_with(oldtbl, new_value)
new_tbl_name = newtblval(oldtbl)

Constants

ReTblResvdSuffix

REgular expression for TaBLe for RESerVeD SUFFIXes.

Attributes

tblmaps[R]

Hash:

{ Old-Table-Name => New-Table-Name }

Public Class Methods

new(oldtbls=[]) click to toggle source

Constructor

Table list is NOT mandatory to specify.

@param oldtbls [Array,String] Old table name(s)

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 47
def initialize(oldtbls=[])
  @tblmaps = {}

  # [oldtbls].flatten.each do |ec|
  [oldtbls].flatten.map{|i| remove_sqlprefix(i)}.uniq.each do |ec|
    push(ec)
  end
end

Public Instance Methods

empty?() click to toggle source

Whether empty

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 58
def empty?()
  @tblmaps.empty?
end
mixtblnames(exclude: nil, compact: true) click to toggle source

Returns an Array of mixed table names == (new OR old)

@param (see oldtblnames)

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 215
def mixtblnames(exclude: nil, compact: true)
  newtbl = newtblnames(exclude: exclude, compact: compact).map{|i| remove_sqlprefix(i)}
  oldtbl = oldtblnames(exclude: exclude, compact: compact).map{|i| remove_sqlprefix(i)}

  mixtbl = []
  newtbl.each_with_index do |newc, i| 
    mixtbl[i] = (newc || oldtbl[i])
  end
  mixtbl
end
newtblnames(exclude: nil, compact: true) click to toggle source

Returns an Array of new table names.

@param (see oldtblnames)

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 207
def newtblnames(exclude: nil, compact: true)
  old_or_newtblnames(:new, exclude: exclude, compact: compact)
end
newtblval(oldtbl) click to toggle source

Gets a stored newtbl name

@param oldtbl [String] Old table name @return [String] Stored new table name

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 74
def newtblval(oldtbl)
  oldtbl = remove_sqlprefix(oldtbl)
  table_exist?(oldtbl) || (raise DbSuitRailsError, "ERROR: old-table (#{oldtbl}) is not registered.")
  @tblmaps[oldtbl]
end
oldtblnames(exclude: nil, compact: true) click to toggle source

Returns an Array of old table names.

@param exclude [String] Old table name, the corresponding value of which either becomes nil in, or if compact option is true, is excluded from, the result. @param compact [Boolean] Read only when exclude option is non-nil. If true (Def), the result is compacted; else the excluded value becomes nil. @return [Array]

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 199
def oldtblnames(exclude: nil, compact: true)
  old_or_newtblnames(:old, exclude: exclude, compact: compact)
end
push(oldtbl, newtbl=nil) click to toggle source

Push a new table

Make sure to use this method to add a record in @tblmaps . Or, alternatively, you can use {#update!}, which calls this method, and sets newtbl automatically.

If the record already exists, this raises an error.

@param oldtbl [String] Old table name @param newtbl [String] New table name @return [self]

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 101
def push(oldtbl, newtbl=nil)
  oldtbl = remove_sqlprefix(oldtbl)
  if table_exist?(oldtbl)
    raise DbSuitRailsError, "ERROR: Failed to push old-table (#{oldtbl}) as it already exists."
  else
    if (oldtbl == :all) || (newtbl == :all)
       raise DbSuitRailsError, "ERROR: :all is not allowed in push()."
    end
    @tblmaps[oldtbl] = remove_sqlprefix(newtbl)
  end

  self
end
set_newtblval_with(oldtbl, value) click to toggle source

Sets a newtbl name

@param oldtbl [String] Old table name @param value [String] new table name to set @return [String] Stored new table name

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 85
def set_newtblval_with(oldtbl, value)
  # @tblmaps[oldtbl] = value
  @tblmaps[remove_sqlprefix(oldtbl)] = remove_sqlprefix(value)
end
table_exist?(oldtbl) click to toggle source

Whether a old-name table is registered?

@param oldtbl [String] Old table name

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 65
def table_exist?(oldtbl)
  oldtbl = remove_sqlprefix(oldtbl)
  @tblmaps.has_key?(oldtbl)
end
update(oldtbl=:all, force: false) click to toggle source

Update a table entry (or all the table entries) according to the rule

If oldtbl is :all, all the tables are updated.

This updates a newtbl name only if the existing one is empty or nil.

If force: option is true, regardless of current newtbl name, newtbl is updated.

To manually set the new table name, use {#set_newtblval_with}

@param oldtbl [String, Symbol] Old table name or :all @param force forcibly updates. @return [self]

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 130
def update(oldtbl=:all, force: false)
  oldtbl = remove_sqlprefix(oldtbl)
  if :all == oldtbl
    oldtblnames().each do |ec_tbl|
      update(ec_tbl, force: force)
    end
    return self
  end

  table_exist?(oldtbl) || (raise DbSuitRailsError, "ERROR: Failed to update old-table (#{oldtbl}), which is not registered.")

  newtbl = newtblval(oldtbl)
  if !newtbl || newtbl.empty?
    set_newtblval_with(oldtbl, mk_newtblname(oldtbl))
  end

  ## If force, attempts to update newtbl name regardless the other conditions.
  force && set_newtblval_with(oldtbl, mk_newtblname(oldtbl))

  return self
end
update!(oldtbl=:all) click to toggle source

Updates a table or pushes it if it is not registered, yet.

Basically, this method is a wrapper for {#update} and {#push}

This updates a newtbl name regardless the conditions (force option is set).

If oldtbl is :all, all the table are updated, in which case fkey option is ignored.

@param oldtbl [String, Symbol] Old table name or :all @return [self]

@see SqlSkelton::TblIndex.update

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 166
def update!(oldtbl=:all)
  oldtbl = remove_sqlprefix(oldtbl)
  if defined? oldtbl.gsub
    table_exist?(oldtbl) || push(oldtbl)
  end
  return update(oldtbl, force: true)
end
updated_tbl!(oldtbl) click to toggle source

Wrapper of {#update!}

It returns the new tablename. Also, it does NOT update the record, if the new file is already registered.

@param oldtbl [String] Old table name @return [String]

@see SqlSkelton::TblIndex.update!

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 184
def updated_tbl!(oldtbl)
  oldtbl = remove_sqlprefix(oldtbl)
  if ! table_exist?(oldtbl)
    push(oldtbl)
    update(oldtbl, force: true)
  end
  newtblval(oldtbl)
end

Private Instance Methods

mk_newtblname(oldtbl, useprefix: false) click to toggle source

Gets a non-existing new table name

This is a low-level method, In practice, use {#update!} etc.

At the moment no potential name crush is resolved. If you want to implement it, refer to in col_index.rb

unique_colname()

where a sequential trial is implemented. Note in the case of tables, there may be more than one table name related to a table, like `XXX_id_seq`. Hence if you change one, you should change all the related table names at the same time.

@param oldtbl [String] Old table name @param useprefix [Boolean] If true, add a prefix as opposed to suffix. @return [String] Unique new table name

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 249
def mk_newtblname(oldtbl, useprefix: false)
  oldtbl = remove_sqlprefix(oldtbl)
  existing_tables = mixtblnames(exclude: oldtbl)

  matched = ReTblResvdSuffix.match(oldtbl)
  newtbl_root = (matched ? matched.pre_match : oldtbl)

  ## NOTE: The format *_[0-9]* for a table name is inconvenient.
  ##   Therefore, it is converted into '*_n[0-9]*'
  ## singularize defined in active_support/all library
  newtbl_root = ((/_\d/ =~ newtbl_root) ? newtbl_root.gsub(/_(\d)/, '_n\1') : newtbl_root).singularize
  
  begin 
    # Singularized table name should not coincides with any existing constant names,
    # be it Class name or existing Constant like Pi (if it does).
    # If it does, the following raises NameError
    # Note the table name "stdout" is OK, because the standard constant is STDOUT and is not Stdout.
    # Note: to judge if it agrees with an existinc class but other constants,
    #   (Class == newtbl_root.classify.constantize.class)
    newtbl_root.classify.constantize
    newtbl_root += SuffixId
  rescue NameError
  end

  # unique_name_cand defined in Utils module.
  newtbl_root = unique_name_cand(newtbl_root, useprefix: useprefix){ |cand|
    ! existing_tables.include?( cand.pluralize +  (matched ? matched[1] : '') )
  }

  if ! newtbl_root
    raise DbSuitRailsError, "ERROR: new table name (#{oldtbl}) already exists.  Consult the code developer."
  end

  newtbl_root.pluralize + (matched ? matched[1] : '')
end
old_or_newtblnames(old_or_new, exclude: nil, compact: true) click to toggle source

Core routine for {#oldtblnames} and {#newtblnames}

@param old_or_new [Symbol] :old or :new. @param (see oldtblnames) @return [Array]

# File lib/db_suit_rails/sql_skelton/tbl_index.rb, line 291
def old_or_newtblnames(old_or_new, exclude: nil, compact: true)
  arold = @tblmaps.keys
  case old_or_new
  when :old
    arret = arold
  when :new
    arret = @tblmaps.values
  else
    raise
  end

  exclude || (return arret)

  i = arold.find_index{ |val| exclude == val }
  compact ? arret.delete_at(i) : (arret[i] = nil)

  arret
end