## @file
# This file is used to create/update/query/erase a common table
#
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

##
# Import Modules
#
import Common.EdkLogger as EdkLogger

## TableFile
#
# This class defined a common table
#
# @param object:     Inherited from object class
#
# @param Cursor:     Cursor of the database
# @param TableName:  Name of the table
#
class Table(object):
    def __init__(self, Cursor):
        self.Cur = Cursor
        self.Table = ''
        self.ID = 0

    ## Create table
    #
    # Create a table
    #
    def Create(self, SqlCommand):
        self.Cur.execute(SqlCommand)
        self.ID = 0
        EdkLogger.verbose(SqlCommand + " ... DONE!")

    ## Insert table
    #
    # Insert a record into a table
    #
    def Insert(self, SqlCommand):
        self.Exec(SqlCommand)

    ## Query table
    #
    # Query all records of the table
    #
    def Query(self):
        EdkLogger.verbose("\nQuery table %s started ..." % self.Table)
        SqlCommand = """select * from %s""" % self.Table
        self.Cur.execute(SqlCommand)
        for Rs in self.Cur:
            EdkLogger.verbose(str(Rs))

        TotalCount = self.GetCount()
        EdkLogger.verbose("*** Total %s records in table %s ***" % (TotalCount, self.Table) )
        EdkLogger.verbose("Query tabel %s DONE!" % self.Table)

    ## Drop a table
    #
    # Drop the table
    #
    def Drop(self):
        SqlCommand = """drop table IF EXISTS %s""" % self.Table
        self.Cur.execute(SqlCommand)
        EdkLogger.verbose("Drop tabel %s ... DONE!" % self.Table)

    ## Get count
    #
    # Get a count of all records of the table
    #
    # @retval Count:  Total count of all records
    #
    def GetCount(self):
        SqlCommand = """select count(ID) from %s""" % self.Table
        self.Cur.execute(SqlCommand)
        for Item in self.Cur:
            return Item[0]

    ## Generate ID
    #
    # Generate an ID if input ID is -1
    #
    # @param ID:   Input ID
    #
    # @retval ID:  New generated ID
    #
    def GenerateID(self, ID):
        if ID == -1:
            self.ID = self.ID + 1

        return self.ID

    ## Init the ID of the table
    #
    # Init the ID of the table
    #
    def InitID(self):
        self.ID = self.GetCount()

    ## Exec
    #
    # Exec Sql Command, return result
    #
    # @param SqlCommand:  The SqlCommand to be executed
    #
    # @retval RecordSet:  The result after executed
    #
    def Exec(self, SqlCommand):
        EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand)
        self.Cur.execute(SqlCommand)
        RecordSet = self.Cur.fetchall()
        EdkLogger.debug(4, "RecordSet: %s" % RecordSet)
        return RecordSet
