Archive of

Two practical ORACLE procedures for adding/dropping fields

DECLARE
    -- Procedure to add a column if it does not exist
    PROCEDURE add_column_if_not_exists (
        p_owner       VARCHAR2,
        p_table_name  VARCHAR2,
        p_column_name VARCHAR2,
        p_column_type VARCHAR2
    ) IS
        l_sql    VARCHAR2(1024);
        l_count  NUMBER;
    BEGIN
        -- Check if column exists
        SELECT COUNT(*)
        INTO l_count
        FROM ALL_TAB_COLUMNS
        WHERE OWNER = p_owner
          AND TABLE_NAME = p_table_name
          AND COLUMN_NAME = p_column_name;

        -- Add column if it does not exist
        IF l_count = 0 THEN
            l_sql := 'ALTER TABLE ' || p_owner || '.' || p_table_name || ' ADD (' || p_column_name || ' ' || p_column_type || ')';
            DBMS_OUTPUT.PUT_LINE(l_sql);
            EXECUTE IMMEDIATE l_sql;
        END IF;
    END;

    -- Procedure to drop a column if it does exist
    PROCEDURE drop_column_if_exists (
        p_owner       VARCHAR2,
        p_table_name  VARCHAR2,
        p_column_name VARCHAR2
    ) IS
        l_sql    VARCHAR2(1024);
        l_count  NUMBER;
    BEGIN
        -- Check if column exists
        SELECT COUNT(*)
        INTO l_count
        FROM ALL_TAB_COLUMNS
        WHERE OWNER = p_owner
          AND TABLE_NAME = p_table_name
          AND COLUMN_NAME = p_column_name;

        -- drop column if it does exist
        IF l_count = 1 THEN
            l_sql := 'ALTER TABLE ' || p_owner || '.' || p_table_name || ' DROP COLUMN ' || p_column_name;
            DBMS_OUTPUT.PUT_LINE(l_sql);
            EXECUTE IMMEDIATE l_sql;
        END IF;
    END;
BEGIN
...
END;
/

A tip to ease the process creating new feature branch

We use feature/ticket-number-team-abbr as feature branch name, such as feature/mt-1234-axo at work.

If you mainly work with a huge repository. Everytime, you switch to the integration/main branch and run git pull before you create a feature branch, it would take a while as it needs to update your work directory and normally there are a lot of files changed.

I use a different way which is a little bit speedy. Whatever which branch you are now in, run

git fetch && git checkout -b feature/mt-xxxx-axo origin/integration 

It helps but I still need to type the above, which is still a lot of letters! So, I create a bash script to help me more,

see the following command nbi 38546

nbi 38546
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 22 (delta 17), reused 22 (delta 17), pack-reused 0
Unpacking objects: 100% (22/22), 4.43 KiB | 5.00 KiB/s, done.
From github.com:Euronet-XE/DFX
   941796a8a..11f76bff7  feature/mt-38183-fugu -> origin/feature/mt-38183-fugu
 * [new branch]          feature/mt-39492-ice  -> origin/feature/mt-39492-ice
 * [new branch]          feature/mt-39744-ice-card -> origin/feature/mt-39744-ice-card
branch 'feature/mt-38546-axo' set up to track 'origin/integration'.
David.Wei @ /d/git/xemt-core/dfx - [feature/mt-38546-axo] $

what’s in this nbi script? here it is

cat ~/bin/nbi
#!/bin/bash

# Check if the current directory is a git repository
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
    echo "Error: Current directory is not a git repository."
    exit 1
fi

# Run git fetch to get the latest changes from the remote repository
git fetch

# Determine the action based on the script name
case "$(basename "$0")" in
    nbi)
        # Check if an argument is provided
        if [[ $# -eq 1 ]]; then
            # Run git checkout to create and switch to a new branch based on the integration branch
            git checkout -b "feature/mt-$1-axo" "origin/integration"
            exit $?
        else
            echo "Usage: $0 <anumber>"
            exit 1
        fi
        ;;
    nbm)
        # Check if an argument is provided
        if [[ $# -eq 1 ]]; then
            # Run git checkout to create and switch to a new branch based on the main branch
            git checkout -b "feature/mt-$1-axo" "origin/main"
            exit $?
        else
            echo "Usage: $0 <anumber>"
            exit 1
        fi
        ;;
    *)
        echo "Error: Unsupported script name."
        exit 1
        ;;
esac

why do I call it nbi ? haha, it is a ABBR from new branch from integration

Wait, why did I mention nbm in the script? Yes, you can copy this nbi script with name nbm , then using the nbm command it will work the same way with the repositories that use main as the integration branch.

Did you see? How lazy I am!

2024-07-22 Update: I also wrote another script sw to ease the switching branches operation:

#!/bin/bash

# Check if the user provided a number
if [ -z "$1" ]; then
  echo "Usage: sw <number>"
  exit 1
fi

# Construct the branch name
branch_name="feature/mt-$1-axo"

# Switch to the branch
git switch "$branch_name"

# Check if the switch was successful
if [ $? -eq 0 ]; then
  echo "Switched to branch '$branch_name'"
else
  echo "Failed to switch to branch '$branch_name'"
fi

Sharing pre-request script among Postman collections

I tried a few ways to write a script that can be reused among a few of postman request collections and finally I got a solution I like.

  1. Using const or let keywords to define internal used objects or utility containers. For example
const stpCommon = {
  randomCharacters: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split(''),
  nonUsdCurrencies: 'GBP,AUD,NZD,CAD,JPY,EUR'.split(','),
  getCurrencyPair: (currency) => `${currency}/USD`,
  getRandomRate: () => (Math.random() * 0.9 + 0.8).toFixed(5),
  getRandomElement: (array) => {
    if (array.length === 0) {
      throw new Error('Cannot get a random element from an empty array');
    }
    const randomIndex = Math.floor(Math.random() * array.length);
    return array[randomIndex];
  },
  getNextWeekday: function (date) {
    const clonedDate = new Date(date);
    const day = clonedDate.getDay();
    if (day === 6) {
      clonedDate.setDate(clonedDate.getDate() + 2);
    } else if (day === 0) {
      clonedDate.setDate(clonedDate.getDate() + 1);
    }
  },
  getBasicRequest: () => {
    const fixedAmountCurrency = stpCommon.getFixedAmountCurrency()
    return {
      currencyPair: stpCommon.getCurrencyPair(fixedAmountCurrency),
      rate: stpCommon.getRandomRate(),
      side: "2",
      fixedAmount: stpCommon.getFixedAmount(),
      ...
    }
...
  1. Using object name itself in its member methods. don't use this keyword, see the last method in above example.
  2. At the end of your script, using a conditional block to expose the object you want in Postman environment, normally one object is enough. For instance:
// the only way to expose an object in postman, is to define a object without any declaration keywords like var/let/const
// the following is a hack to expose the object in postman without troubling Node.js as in Node.js, we are not allowed to
// define a variable without any declaration keywords like var/let/const
if (typeof(pm) !== 'undefined') {
  stpUtils = _stpUtils
}
  1. At the end of your script, utilize conditional exports the objects that you want to use in Node.js environment, this step enables writing test cases for it. For example
const utilsA = {...}
const utilsB = {...}
const _utilsC = {something using utilsA & utilsB}
// provided you want to use utilsC in postman
if (typeof(pm) !== 'undefined') {
  utilsC = _utilsC
}
// and you want to expose all objects in your test cases
if (typeof (module) !== 'undefined') {
  module.exports = {
    utilsA, utilsB, _utilsC
  }
}

This way, you can paste all the script body into the postman scripts tab without trouble, while in Node.js env, you can freely use Jest or other unit test framework to write test cases for your shard library. What a great solution!

Outputing human friendly JSON string with JSON.stringify

method 1:

JSON.stringify(obj, null, '\t');

This "pretty-prints" your JSON string, using a tab for indentation.

method 2:

If you prefer to use spaces instead of tabs, you could also use a number for the number of spaces you'd like :

JSON.stringify(obj, null, 2);

Reference