def update_db(config, options = {})

      begin
        options ||= {}

        runtime_user = config[:username]

        Conn.remove_connection
        Conn.establish_connection config

        if have_db_control?
          warn "WARNING: Runtime user '#{runtime_user}' has full access to the database. (this is not recommended)" unless Rails.env.test?
        else
          raise NeedFullAccess, 'please provide update_username and update_password for a user with full access to the database' unless config[:update_username]

          use_config = config.dup
          use_config[:username] = config[:update_username]
          use_config[:password] = config[:update_password]

          Conn.remove_connection
          Conn.establish_connection use_config

          raise NeedFullAccess, 'provided update user does not have full access to the database' unless have_db_control?
        end

        unless Conn.object_exists?(VERSION_TABLE_NAME)
          debug 'Creating version tracking table...'
          db_connection.execute <<-EOSQL
CREATE TABLE [#{VERSION_TABLE_NAME}] (
  [object_name] VARCHAR(120) NOT NULL PRIMARY KEY,
  [object_type] VARCHAR(40) NOT NULL,
  [object_version] VARCHAR(40) NOT NULL,
  [created] DATETIME NOT NULL,
  [updated] DATETIME NOT NULL,
  [created_by] VARCHAR(120),
  [updated_by] VARCHAR(120)
)
          EOSQL
        end

        if (proc = (options[:before_update] || options[:pre_update] || @pre_update))
          if proc.is_a?(String)
            code = proc
            proc = Proc.new { |db_conn, user| eval code }
          end
          if proc.respond_to?(:call)
            debug 'Running pre-update code...'
            proc.call db_connection, runtime_user
          end
        end

        debug 'Processing source list...'
        sources.each do |src|
          src.name_prefix = table_prefix

          cur_ver = get_version src.prefixed_name

          if cur_ver
            raise ObjectTypeMismatch, "object type mismatch for #{src.prefixed_name}" unless src.type.upcase == cur_ver['object_type'].upcase
            if cur_ver['object_version'].to_i >= src.version.to_i
              debug " > Preserving #{src.prefixed_name}..."
              next  # source
            else
              debug " > Updating #{src.prefixed_name}..."
              if src.is_create?
                db_connection.execute src.drop_sql
              end
            end
          else
            debug " > Creating #{src.prefixed_name}..."
          end

          db_connection.execute src.update_sql
          db_connection.execute src.grant_sql(runtime_user)
          set_version src.prefixed_name, src.type, src.version

          src.name_prefix = ''
        end

        if (proc = (options[:after_update] || options[:post_update] || @post_update))
          if proc.is_a?(String)
            code = proc
            proc = Proc.new { |db_conn, user| eval code }
          end
          if proc.respond_to?(:call)
            debug 'Running post-update code...'
            proc.call db_connection, runtime_user
          end
        end

        yield db_connection, runtime_user if block_given?

      ensure
        Conn.remove_connection
      end

      true
    end
def update_db(config, options = {})

      begin
        options ||= {}

        runtime_user = config[:username]

        Conn.remove_connection
        Conn.establish_connection config

        if have_db_control?
          warn "WARNING: Runtime user '#{runtime_user}' has full access to the database. (this is not recommended)" unless Rails.env.test?
        else
          raise NeedFullAccess, 'please provide update_username and update_password for a user with full access to the database' unless config[:update_username]

          use_config = config.dup
          use_config[:username] = config[:update_username]
          use_config[:password] = config[:update_password]

          Conn.remove_connection
          Conn.establish_connection use_config

          raise NeedFullAccess, 'provided update user does not have full access to the database' unless have_db_control?
        end

        unless Conn.object_exists?(VERSION_TABLE_NAME)
          debug 'Creating version tracking table...'
          db_connection.execute <<-EOSQL
CREATE TABLE [#{VERSION_TABLE_NAME}] (
  [object_name] VARCHAR(120) NOT NULL PRIMARY KEY,
  [object_type] VARCHAR(40) NOT NULL,
  [object_version] VARCHAR(40) NOT NULL,
  [created] DATETIME NOT NULL,
  [updated] DATETIME NOT NULL,
  [created_by] VARCHAR(120),
  [updated_by] VARCHAR(120)
)
          EOSQL
        end

        if (proc = (options[:before_update] || options[:pre_update] || @pre_update))
          if proc.is_a?(String)
            code = proc
            proc = Proc.new { |db_conn, user| eval code }
          end
          if proc.respond_to?(:call)
            debug 'Running pre-update code...'
            proc.call db_connection, runtime_user
          end
        end

        debug 'Processing source list...'
        sources.each do |src|
          src.name_prefix = table_prefix

          cur_ver = get_version src.prefixed_name

          if cur_ver
            raise ObjectTypeMismatch, "object type mismatch for #{src.prefixed_name}" unless src.type.upcase == cur_ver['object_type'].upcase
            if cur_ver['object_version'].to_i >= src.version.to_i
              debug " > Preserving #{src.prefixed_name}..."
              next  # source
            else
              debug " > Updating #{src.prefixed_name}..."
              if src.is_create?
                db_connection.execute src.drop_sql
              end
            end
          else
            debug " > Creating #{src.prefixed_name}..."
          end

          db_connection.execute src.update_sql
          db_connection.execute src.grant_sql(runtime_user)
          set_version src.prefixed_name, src.type, src.version

          src.name_prefix = ''
        end

        if (proc = (options[:after_update] || options[:post_update] || @post_update))
          if proc.is_a?(String)
            code = proc
            proc = Proc.new { |db_conn, user| eval code }
          end
          if proc.respond_to?(:call)
            debug 'Running post-update code...'
            proc.call db_connection, runtime_user
          end
        end

        yield db_connection, runtime_user if block_given?

      ensure
        Conn.remove_connection
      end

      true
    end
Performs the database update using the specified configuration.

 A warning will be logged if the runtime user has full access to the database.

 An error will be raised if there is the runtime user does not have full access and no update_user is provided,
 or if an update_user is provided who also does not have full access to the database.