#!/bin/bash

###########################################################
## Copyright (c) 2019-2025 Alexey Kuryakin daqgroup@mail.ru
###########################################################

###########################################################
## lsdbcl - list database client libraries.
###########################################################

###########################################################
source $(crwkit which crwlib_base.sh); # Use base library #
source $(crwkit which crwlib_file.sh); # Use file library #
###########################################################

let abort_notify_uses=0;

###############
# print version
###############
function print_vers(){
 local name="$1";
 echo "$name version 1.0";
};

###################
# print help screen
###################
function print_help(){
 local name="$1"; print_vers $name;
 echo "$name - list database client libraries.";
 echo "Copyright (c) 2019-2025 Alexey Kuryakin daqgroup@mail.ru";
 echo "Help on $name:";
 echo " ====================> Syntax:";
 echo "  $name [Options]";
 echo " ====================> Options:";
 echo "   -h,--help        => print this help screen and exit";
 echo "   --version        => print program version and exit";
 echo "   -p,--providers   => show supported Database Providers";
 echo "   -l,--libraries   => show Database Client Libraries";
 echo "   -o,--odbc        => show ODBC info (odbcinst reguired)";
 echo " ====================> Exit Code:";
 echo "  Return 0 on success, otherwise return error code";
 echo " ====================> Examples:";
 echo "  $name";
 echo "  $name --help";
 echo "  $name --version";
 echo "  $name --odbc";
 echo "  $name -p";
 echo "  $name -l";
};

readonly db_supported_engines="MSSQL Sybase PQ Oracle ODBC MySQL40 MySQL41 MySQL50 MySQL51 MySQL55 MySQL55 MySQL56 MySQL57 MySQL80 SQLite3 IB";
declare -i opt_odbcdrivers=0;
declare -i opt_providers=0;
declare -i opt_libraries=0;
declare db_lib_names="";

function show_db_info(){
 if [[ $# -gt 2 ]]; then
  if [[ $opt_providers -ne 0 ]]; then
   printf "%-7s = %-20s => " "$1" "\"$2\"";
   shift; shift;
   echo "$*";
  else
   shift; shift;
  fi;
  for lib in $*; do
   if word_is_in_list $lib $db_lib_names; then continue; fi;
   db_lib_names+=" $lib";
  done;
 fi;
};

function list_odbc_options(){
 odbcinst -j | sed -E 's/\.*:/ =/' | sed -E 's/^unixODBC/VERSION = unixODBC/';
};

function list_odbc_drivers(){
 odbcinst -q -d | grep -P '^\s*\[.*\]\s*$' | sed -E 's/^\s*\[//' | sed -E 's/]\s*$//';
};

function odbc_read_option(){
 local opt="$1"; if [[ -z $opt ]]; then return; fi;
 local ini="$(list_odbc_options | grep -P "^$opt\s*=" | sed -E "s/^$opt\s*=\s* //")";
 if [[ -n $opt ]]; then echo $ini; fi;
};

function odbc_option_drivers(){
 odbc_read_option "DRIVERS";
};

function odbc_option_system_data_sources(){
 odbc_read_option "SYSTEM DATA SOURCES";
};

function odbc_option_file_data_sources(){
 odbc_read_option "FILE DATA SOURCES";
};

function odbc_option_user_data_sources(){
 odbc_read_option "USER DATA SOURCES";
};

function cat_files(){
 for item in "$@"; do
  local ini="$(realpath $item)";
  if [[ -f $ini ]]; then
   echo "# $item";
   echo "";
   if [[ $(stat -c %s $ini) -gt 0 ]]; then
    cat $ini;
   else
    echo " (empty)";
   fi;
   echo "";
  fi;
 done;
};

function find_lib(){
 if [[ -n "$1" ]]; then
  find $(unix findlibso -d | grep '/' | sed 's/$/\//') -type f,l -name "$1" 2>/dev/null | sort -u;
 fi;
};

function find_odbc_driver(){
 local ini="$1"; local sec="$2";
 if [[ -e "$ini" ]] && [[ -n "$sec" ]]; then
  local driver="$(unix readcfg -f "$ini" -s "$sec" | grep -P '^Driver\s*=' | sed -E 's/^Driver\s*=\s*//')";
  if [[ -z "$driver" ]]; then return; fi;
  local lib="$(find_lib $driver)";
  if [[ -n "$lib" ]]; then driver="$lib"; fi;
  echo "$driver";
 fi;
};

function find_odbc_setup(){
 local ini="$1"; local sec="$2";
 if [[ -e "$ini" ]] && [[ -n "$sec" ]]; then
  local setup="$(unix readcfg -f "$ini" -s "$sec" | grep -P '^Setup\s*=' | sed -E 's/^Setup\s*=\s*//')";
  if [[ -z "$setup" ]]; then return; fi;
  local lib="$(find_lib $setup)";
  if [[ -n "$lib" ]]; then setup="$lib"; fi;
  echo "$setup";
 fi;
};

function list_db_client_libraries(){
 db_lib_names="";
 if [[ $opt_providers -ne 0 ]]; then echo "[Database Providers]"; fi;
 for db in $db_supported_engines; do
  case $db in
   MSSQL)   show_db_info $db "Microsoft SQL" libsybdb.so; ;;
   Sybase)  show_db_info $db "Sybase SQL" libsybdb.so; ;;
   PQ)      show_db_info $db "Postgre SQL" libpq.so; ;;
   Oracle)  show_db_info $db "Oracle" libociei.so libclntsh.so; ;;
   ODBC)    show_db_info $db "ODBC" libodbc.so; ;;
   MySQL40) show_db_info $db "MySQL 4.0" libmysqlclient.so libmysqlclient.so.12 libmysqld.so; ;;
   MySQL41) show_db_info $db "MySQL 4.1" libmysqlclient.so libmysqlclient.so.14 libmysqld.so; ;;
   MySQL50) show_db_info $db "MySQL 5.0" libmysqlclient.so libmysqlclient.so.15 libmysqld.so; ;;
   MySQL51) show_db_info $db "MySQL 5.1" libmysqlclient.so libmysqlclient.so.16 libmysqld.so; ;;
   MySQL55) show_db_info $db "MySQL 5.5" libmysqlclient.so libmysqlclient.so.18 libmysqld.so; ;;
   MySQL56) show_db_info $db "MySQL 5.6" libmysqlclient.so libmysqlclient.so.18 libmysqld.so; ;;
   MySQL57) show_db_info $db "MySQL 5.7" libmysqlclient.so libmysqlclient.so.20 libmysqld.so; ;;
   MySQL80) show_db_info $db "MySQL 8.0" libmysqlclient.so libmysqlclient.so.21 libmysqld.so; ;;
   SQLite3) show_db_info $db "SQLite3" libsqlite3.so; ;;
   IB)      show_db_info $db "Interbase/Firebird" libfbclient.so libgds.so libfbembed.so; ;;
   *)       ;;
  esac;
 done;
 if [[ $opt_providers -ne 0 ]]; then echo ""; fi;
 if [[ $opt_libraries -ne 0 ]] && [[ -n "$db_lib_names" ]]; then
  echo "[Database Client Libraries]";
  for lib in $db_lib_names; do
   unix findlibso -f $lib;
  done;
  echo "";
 fi;
 if [[ $opt_odbcdrivers -ne 0 ]] && which odbcinst > /dev/null 2>&1; then
  echo "[ODBC OPTIONS]";
  list_odbc_options;
  echo "";
  if [[ -n "$(odbcinst -q -d | xargs)" ]]; then
   echo "[ODBC DRIVERS]";
   list_odbc_drivers;
   echo "";
   local ini="$(odbc_option_drivers)";
   if [[ -e "$ini" ]]; then
    echo "[ODBC DRIVERS FILES]";
    for item in $(list_odbc_drivers | tr ' ' '~'); do
     local driver="$(echo "$item" | tr '~' ' ')";
     echo "$driver = $(find_odbc_driver $ini "$driver" | xargs)";
    done;
    echo "";
    echo "[ODBC SETUP FILES]";
    for item in $(list_odbc_drivers | tr ' ' '~'); do
     local setup="$(echo "$item" | tr '~' ' ')";
     echo "$setup = $(find_odbc_setup $ini "$setup" | xargs)";
    done;
    echo "";
    cat_files $ini;
   fi;
   local sds="$(odbc_option_system_data_sources)";
   if [[ -e $sds ]]; then
    echo "";
    cat_files $sds;
   fi;
   local fds="$(odbc_option_file_data_sources)";
   if [[ -d $fds ]] && [[ $(ls $fds | wc -l) -gt 0 ]]; then
    echo "";
    cat_files $fds/*;
   fi;
   local uds="$(odbc_option_user_data_sources)";
   if [[ -e $uds ]]; then
    echo "";
    cat_files $uds;
   fi;
  fi;
 fi;
};

################
# main processor
################
function main(){
 ######################
 # command line parsing
 ######################
 if [ $# -lt 1 ]; then
  let opt_providers=1;
  let opt_libraries=1;
  let opt_odbcdrivers=1;
  list_db_client_libraries $db_supported_engines;
  return;
 fi;
 for arg in $*; do
  case $arg in
   --version)                 print_vers $scriptname; return 0; ;;
   -h|-help|--help)           print_help $scriptname; return 0; ;;
   -p|-providers|--providers) let opt_providers=1; ;;
   -l|-libraries|--libraries) let opt_libraries=1; ;;
   -o|-odbc|--odbc)           let opt_odbcdrivers=1; ;;
   *) ;;
  esac;
 done;
 list_db_client_libraries $db_supported_engines;
};

main "$@";

##############
## END OF FILE
##############
