#!/bin/bash
# *******************************************************************
# **  @file eisman_query.sh - query package database
# **
# **  Creation:     2013-01-13 dv
# **  Last update:  $Id: eisman_query.sh 42121 2016-07-06 18:13:43Z dv $
# **
# **  Copyright (c) 2013-@@YEARE@@ the eisfair team, team(at)eisfair(dot)org
# **
# **  This program is free software; you can redistribute it and/or modify
# **  it under the terms of the GNU General Public License as published by
# **  the Free Software Foundation; either version 2 of the License, or
# **  (at your option) any later version.
# *******************************************************************

. /var/install/include/eislib
. /var/install/include/eismanlib

PACKSTATE='s'
DATABASE="${EISMAN_PATH}/packages.db"


# *******************************************************************
# **  show help on arguments and possible options
# **  @param  n/a
# **  @return n/a
# *******************************************************************

show_help()
{
cat <<EOF

Query package database

usage: eisman query [OPTIONS] [PACKAGE] [VERSION]

options:
   --help                      show this help screen
   --excl-sections <sec-list>  comma separated list of sections
   --sections      <sec-list>  comma separated list of sections
   --fields        <fld-list>  comma separated list of fields
   --unstable                  show unstable packages too
   --installed                 query installed packages database
   --outdated                  query outdated packages database
   --url           <url>       only search packages from this source

possible values for fields:
   name     package name
   version  package version
   short    short package description
   date     date of creation
   author   author of the package
   section  section of the package
   space    disk space needed in MB
   url      URL of the package
   status   status of the package
   require  required packages (multiple results possible)
   link     linked packages (that need update if installed)
   text     descriptive text (multiple results possible)

PACKAGE  a package name that may contain wildcards like
         * -> matches multiple characters
         ? -> matches exactly one character
         example:  *sql  matches postgresql, mysql,...
                   ??sql matches mysql, ...

VERSION  a version that may contain wildcards too

EOF

}


# *******************************************************************
# **  use grep to perform a query upon the package.db file. Note that
# **  the global variable $PACKSTATE is used to decide if the search
# **  covers only stable or all packages.
# **  @param  $1  section
# **  @param  $2  package
# **  @param  $3  version (can be an empty string!)
# **  @param  $4  the info fields to be returned (separated by '|' )
# **  @return (on stdout) data found in packages.db meeting the
# **          search criteria
# *******************************************************************

query_package_db()
{
    local sections="${1}"
    local package="${2}"
    local version="${3}"
    local fields="${4}"
    local result
    local resline

    if [ -z "${version}" ]
    then
        version='.*'
    fi

    if [ "${DATABASE}" = "${EISMAN_PATH}/installed.db" ] || \
       [ "${DATABASE}" = "${EISMAN_PATH}/outdated.db" ]
    then
        # when query operates on the installed packages database, the
        # query result must be sorted in an alphabetical order, since
        # the installed packages database is unsorted.
        if [ -z "${exclsections}" ]
        then
            grep -E "^\[(${sections})\]\[${package}\]\[${version}\]\[${PACKSTATE}\]\[${filterurl}\]($fields)" "${DATABASE}" |
            cut  -d ']' -f 6                      |
            sed ':a;N;$!ba;s/\n/||/g;s/-||/-\n/g' |
            sort                                  |
            sed 's/||/\n/g'
        else
            grep -E "^\[(${sections})\]\[${package}\]\[${version}\]\[${PACKSTATE}\]\[${filterurl}\]($fields)" "${DATABASE}" |
            grep -v -E "^\[(${exclsections})\]"   |
            cut  -d ']' -f 6                      |
            sed ':a;N;$!ba;s/\n/||/g;s/-||/-\n/g' |
            sort                                  |
            sed 's/||/\n/g'
        fi
    else
        # when query operates on the available packages database, the
        # query result must not be sorted! It is already organised
        # according to the sort order in the index file supplied by
        # 'get-index'
        if [ -z "${exclsections}" ]
        then
            grep -E "^\[(${sections})\]\[${package}\]\[${version}\]\[${PACKSTATE}\]\[${filterurl}\]($fields)" "${DATABASE}" |
            cut  -d ']' -f 6
        else
            grep -E "^\[(${sections})\]\[${package}\]\[${version}\]\[${PACKSTATE}\]\[${filterurl}\]($fields)" "${DATABASE}" |
            grep -v -E "^\[(${exclsections})\]"   |
            cut  -d ']' -f 6
        fi
    fi
}


# *******************************************************************
# **  main program
# *******************************************************************
main()
{
    # initialize defaults
    sections=".*"
    exclsections=""
    fields="name|short|status|version|url|------"
    package=".*"
    version=".*"
    filterurl=".*"

    # read option switches
    while [ "${1:0:2}" = "--" ]
    do
        case ${1} in
        --help)
            shift
            show_help
            exit 0
            ;;
        --sections)
            shift
            if [ "${1}" != "" -a "${1:0:2}" != "--" ]
            then
                sections="${1}"
                sections="${sections//,/|}"
                shift
            else
                echo 'error: missing argument for --sections!' >&2
                show_help
                exit 1
            fi
            ;;
        --sections=*)
            sections="${1:11}"
            sections="${sections//,/|}"
            shift
            ;;
        --excl-sections)
            shift
            if [ "${1}" != "" -a "${1:0:2}" != "--" ]
            then
                exclsections="${1}"
                exclsections="${exclsections//,/|}"
                shift
            else
                echo 'error: missing argument for --excl-sections!' >&2
                show_help
                exit 1
            fi
            ;;
        --excl-sections=*)
            exclsections="${1:16}"
            exclsections="${exclsections//,/|}"
            shift
            ;;
        --fields)
            shift
            if [ "${1}" != "" -a "${1:0:2}" != "--" ]
            then
                fields="${1}"
                fields="${fields//,/|}|------"
                shift
            else
                echo 'error: missing argument for --fields!' >&2
                show_help
                exit 1
            fi
            ;;
        --fields=*)
            fields="${1:9}"
            fields="${fields//,/|}|------"
            shift
            ;;
        --unstable)
            PACKSTATE=".*"
            shift
            ;;
        --url)
            shift
            filterurl="${1}.*"
            shift
            ;;
        --url=*)
            filterurl="${1:6}.*"
            shift
            ;;
        --installed)
            DATABASE="${EISMAN_PATH}/installed.db"
            shift
            ;;
        --outdated)
            DATABASE="${EISMAN_PATH}/outdated.db"
            shift
            ;;
        *)
            echo "error: invalid switch \"$1\"!" >&2
            show_help
            exit 1
            ;;
        esac
    done

    if [ -n "${1}" ]
    then
        package="${1}"
        package="${package//\*/.*}"
        package="${package//\?/.}"
        shift
    fi

    if [ -n "${1}" ]
    then
        version="${1}"
        version="${version//\*/.*}"
        version="${version//\?/.}"
        shift
    fi

    # perform query
    query_package_db "${sections}" "${package}" "${version}.*" "${fields}"

    exit 0
}

main "${@}"
