Jun
14
2011

Database.py

from datetime import date
import config
import logging
import cx_Oracle
from DataElements import Group
from DataElements import Member
from DataElements import Membership
from threading import Thread
import time
 
logger = logging.getLogger("LMSfeed.Database")
 
def getCols(rset,upper):
        cols={}
        count=0
        logger.debug(rset)
        for (name,type,display_size,internal_size,precision,scale,null_ok) in rset.description:
                if upper:
                        cols[name.upper()]=count
                else:
                        cols[name.lower()]=count
                count+=1
        return cols
 
class KeepAlive(Thread):
    """
        This keepalive thread should sit back and watch the DB connection and restart it if a DB error is encountered.
    """
    logger.debug("Starting Database KeepAlive Class")
    def __init__ (self,otherClass):
        """
            Init class. Pass in calling class so that this may call the conn object and the connection method.
 
        """
        Thread.__init__(self)
        self.otherClass = otherClass
 
    def run(self):
        """
 
        When executed it monitors the conn object in the object passed in by init. If a simple
        select count(*) from dual fails then restart the connection. If any error is encountered
        try to rebuild the connection via .connect
 
        """
        sql = "select 1 from dual"
        while True:
            logger.debug("Testing connection to " + self.otherClass.ezConStr)
            try:
                con = self.otherClass.pool.acquire()
                curs = con.cursor()
                rset = curs.execute(sql)
 
                rows = rset.fetchall()
 
                ## We just want to excersize the db connection. 
                ## If it did not fail in the fetchall then its not going to.
                ## http://www.oracle.com/technology/pub/articles/prez-python-queries.html
                curs.close()
 
                self.otherClass.pool.release(con)
                curs=None
                con=None
            except Exception, detail:
                logger.error("**** UNCAUGHT EXCEPTION ****")
                logger.error("Caught in EnterpriseDocument.py endElement name==group")
                logger.error(detail)  
                logger.debug("Connection to " + self.otherClass.ezConStr + " seems broken, trying to rebuild")
                self.otherClass.connect()
 
            time.sleep(config.dbPollingInterval)
 
 
class VistaDb:
    """
        class VistaDB
 
        This class handles access to the following Oracle tables
 
    """
    logger.debug("Starting Database VistaDB Class")
 
    def connect(self):
        """
 
        We will be using the connection pooling built into cx_Oracle
 
        """
        self.ezConStr = cx_Oracle.makedsn(config.dbVistaHost,config.dbVistaPort,config.dbVistaSid)
 
        self.pool = cx_Oracle.SessionPool(
                user=config.dbVistaUser,
                password=config.dbVistaPassword,
                dsn=self.ezConStr,
                min=0,
                max=20,
                increment=1,
                threaded=True)
        self.pool.timeout = 300
 
 
    def __init__(self,runKeepAlive=True):
                self.connect()
                if runKeepAlive:
                        keepAlive = KeepAlive(self)
                        keepAlive.start()
 
    ### GROUP LOGIC
 
    def getTypeLevelFromCode(self,code):
        """
 
        Translates a Vista English code into a IMS type level number.
 
        """
        if code == "Section":
            return 90
        if code == "Course":
            return 80
        if code == "Campus":
            return 30
        if code == "Division":
            return 25
        # Did not match any? 
        #TODO: Should I throw an error?
        return None
 
    def setAttrIfNotNull(self,group,attribute,value):
        """
 
        If the incoming value is not None and not some other value akin to None sent the attribute.
        If it is None, do nothing. Most of the time we don't set None's, we just don't set the attr.
        If a attr is set None somewhere else there is most likely an override.
 
        """
        if value != None:
                setattr(group,attribute,value)
 
    def getGroupBySourcedid(self,sourcedidid,sourcedidsource):
        """
 
        Return an EnterpriseDocument.Group object filled with info from Vista by passing sourcedid_id and sourcedid_source.
 
        """
        sql = """
                select * 
                from %s.learning_context 
                where 
                        source_id=:sourcedidid 
                        and source_name=:sourcedidsource 
                        and deleted_flag is null
        """%config.dbVistaSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("source_id=" + sourcedidid)
        logger.debug("source_name=" + sourcedidsource)
        rset = curs.execute(sql,sourcedidid=sourcedidid,sourcedidsource=sourcedidsource)
        logger.debug("Got rset")
        group = self.processRsetToGroup(rset)
 
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
        return group
 
    def hasContent(self,sid,sname):
            """
            If course has content return True, else return false
            """
            ret = True
            sql = """
                select 
                        (select count(*) from %(schema)s.co_lc_assignment where learning_context_id = lc.id) +
                        (select count(*) from %(schema)s.co_lc_association where learning_context_id = lc.id) 
                from %(schema)s.learning_context lc 
                where 
                        source_id = :sourcedidId 
                        AND source_name = :sourcedidSource
 
                """%{'schema':config.dbVistaSchema}
 
            con = self.pool.acquire()
            curs = con.cursor()
 
            logger.debug("About to execute the following SQL")
            logger.debug(sql)
            logger.debug("sourcedidId=%s"%sid)
            logger.debug("sourcedidSource=%s"%sname)
            rset = curs.execute(sql,sourcedidId=sid,sourcedidSource=sname)
            row = curs.fetchone()
            if row:
                    contentItems = row[0]
                    if int(contentItems) == 0:
                            ret = False
            curs.close()
            self.pool.release(con)
            curs=None
            con=None
 
            return ret
 
    def getGroupById(self,lcid):
        """
 
        Return an EnterpriseDocument.Group objected filled with info from Vista by passing a Vista Learning Context ID
 
        """
        sql = """
                select * 
                from %s.learning_context 
                where 
                        id = :id
        """%config.dbVistaSchema
        if str(lcid) == "None":
            logger.debug("Not processing a Null")
            return None
 
        con = self.pool.acquire()
        curs = con.cursor()
 
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("id=" + str(lcid))
        rset = curs.execute(sql,id=lcid)
        group = self.processRsetToGroup(rset)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None 
        return group  
 
    def getRollupParent(self,group):
        """
 
        Return the rollup parent as an EnterpriseDocument.Group object filled with info from Vista by passing in a child EnterpriseDocument.Group.
 
        """
        sql = """
                select master_lcid 
                from %s.XLIST_LC_MAPPING 
                where 
                        CHILD_SOURCE_ID=:child_source_id 
                        and CHILD_SOURCE_NAME=:child_source_name
        """%config.dbVistaSchema
 
        con = self.pool.acquire()
        curs = con.cursor()
 
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("childSourceId=" + group.sourcedidid)
        logger.debug("childSourceName=" + group.sourcedidsource)
        rset = curs.execute(sql,child_source_id=group.sourcedidid,child_source_name=group.sourcedidsource)
        masterLcid = None
        row = curs.fetchone()
        if row:
            group = self.getGroupById(row[0])
        else:
            group = None
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return group   
 
 
    def processRsetToGroup(self,rset):
        """
            processRsetToGroup(self,rset)
 
            Process a record set and return a new Group object
 
            We use a few SQL statments to get Group objects from VISTA_GROUP_INFO this code centralizes the the
            part that creates the group and populates it from the override DB
 
             This should be the ONLY place we get info from the override db to a group object because
             we make sure we handle overrides and make sure the object gets overrides applied. This func 
             acheves this by calling getGroupOverrides
        """
 
        group = None
 
        # Find where search col lives so we can map back
        cols = getCols(rset,True)
 
        row = rset.fetchone()
 
        logger.debug(row)
 
        if row:
            logger.debug("Got group")
            group = Group()
            self.setAttrIfNotNull(group,"sourcedidsource",row[cols["SOURCE_NAME"]])
            self.setAttrIfNotNull(group, "sourcedidid", row[cols["SOURCE_ID"]])
            if row[cols["DELIVERY_UNIT_TYPE"]] == "XLIST_MASTER":
                self.setAttrIfNotNull(group, "level", 85)
            else:   
                self.setAttrIfNotNull(group, "level", self.getTypeLevelFromCode(row[cols["TYPE_CODE"]]))
            self.setAttrIfNotNull(group, "descriptionshort", row[cols["NAME"]])
            self.setAttrIfNotNull(group, "descriptionlong", row[cols["DESCRIPTION"]].read())
            self.setAttrIfNotNull(group, "descriptionfull", row[cols["FULLDESCRIPTION"]].read())
            self.setAttrIfNotNull(group, "orgorgname", row[cols["ORGNAME"]])
            self.setAttrIfNotNull(group, "orgid", row[cols["ORGID"]])
 
            startDateEpoch = -1
            startDateEpoch = row[cols["STARTDATE_TIME"]]
 
            if startDateEpoch > 1:
                startDateEpoch = startDateEpoch/1000
                startDateTime = date.fromtimestamp(startDateEpoch)
                group.timeframebeginepoch = startDateEpoch
                group.timeframebegin = startDateTime.isoformat()
 
            self.setAttrIfNotNull(group, "timeframebeginrestrict", "1")
 
            endDateEpoch = -1
            endDateEpoch = row[cols["ENDDATE_TIME"]]
            if endDateEpoch > 1:
                endDateEpoch = endDateEpoch/1000
                endDateTime = date.fromtimestamp(endDateEpoch)
                group.timeframeendepoch = endDateEpoch
                group.timeframeend = endDateTime.isoformat()
 
            self.setAttrIfNotNull(group, "timeframeendrestrict", "1")
            self.setAttrIfNotNull(group, "timeframeadminperiod", row[cols["ADMINPERIOD"]])
            self.setAttrIfNotNull(group, "url", row[cols["URL"]])
            self.setAttrIfNotNull(group, "datasource", row[cols["DATASOURCE"]])
            self.setAttrIfNotNull(group, "vistadbid", row[cols["ID"]])
 
            # Get LC Parent
            lc_parent_id = row[cols["PARENT_ID"]]
            if lc_parent_id is not None and hasattr(group,"level"):
                logger.debug("lc_parent_id=%d and level=%s"%(lc_parent_id,group.level))
                lc_parent = self.getGroupById(lc_parent_id)
                group.lcparent=lc_parent
                group.lcparentid=lc_parent.sourcedidid
                group.lcparentsource=lc_parent.sourcedidsource
 
            rollupparent = self.getRollupParent(group)
            if rollupparent is not None:
                logger.debug("In Vista lcid = " + str(group.vistadbid) + "(" + group.sourcedidid + ":" + group.sourcedidsource + ") Rolls to lcid=" + str(rollupparent.vistadbid) + "(" + rollupparent.sourcedidid + ":" + rollupparent.sourcedidsource + ")")
                group.rollupparent=rollupparent
                group.rollupid=rollupparent.sourcedidid
                group.rollupsource=rollupparent.sourcedidsource
 
            return group
 
        else:
            logger.debug("Group not found")    
            return None
 
    ### ENROLLMENT LOGIC
 
    def getRoleSubrole(self, vistaRole):
        """
 
        Maps the string from the Vista DB into a EnterpriseDocument.Member.role which is an ordered list of role and subrole.
 
        """
        logger.debug("Starting getRoleSubrole with vistaRole =" + vistaRole)
        if vistaRole == "SINS":
            logger.debug("Returning 2,None")
            return (2,None)
        elif vistaRole == "SSTU":
            logger.debug("Returning 1,None")
            return (1,None)
        elif vistaRole == "SDES":
            logger.debug("Returning 3,None")
            return (3,None)
        elif vistaRole == "SAUD":
            logger.debug("Returning 1,AUD")
            return (1,"AUD")
        elif vistaRole == "STEA":
            logger.debug("Returning 2,TA")
            return (2,"TA")
 
        logger.error("Could not find match for vistaRole == " + vistaRole)
        return (None, None)
 
 
    def getMembershipBySourcedid(self,sourcedidid,sourcedidsource):
        """
 
        Gets enrollment for a section specified by sourcedidid, sourcedidsource from vista and maps that to
        a new EnterpriseDocument.Membership object.
 
        """
        sql = """
            select 
              p.remote_userid, p.sourcedid_source, p.webct_id_lowercase,
              rd.name, r.role_status, r.delete_status
            from %(schema)s.role r, %(schema)s.member m, %(schema)s.person p, %(schema)s.learning_context l, %(schema)s.role_definition rd
            where
              (r.member_id = m.id and m.person_id = p.id and m.learning_context_id = l.id and r.role_definition_id = rd.id)
            and p.demouser = 0
            and l.source_id = :source_id
            and l.source_name = :source_name
            """%{'schema':config.dbVistaSchema} ## This uses a different mapping schema
                                                ## so it can mark all the schema's with only one passed
 
        con = self.pool.acquire()
        curs = con.cursor()
 
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("source_id=" + sourcedidid)
        logger.debug("source_name=" + sourcedidsource)
        rset=curs.execute(sql,source_id=sourcedidid,source_name=sourcedidsource)
 
        cols = getCols(rset,False)
 
        membership = Membership()
        membership.sourcedidid = sourcedidid
        membership.sourcedidsource = sourcedidsource
        rows = rset.fetchall()
 
        for row in rows:
            member = Member()
            self.setAttrIfNotNull(member,"sourcedidid",row[cols["remote_userid"]])
            self.setAttrIfNotNull(member,"sourcedidsource",row[cols["sourcedid_source"]])
            self.setAttrIfNotNull(member,"userid",row[cols["webct_id_lowercase"]])
 
            (roletype, subrole) = self.getRoleSubrole(row[cols["name"]])
            self.setAttrIfNotNull(member,"roletype",roletype)
            self.setAttrIfNotNull(member,"subrole",subrole)
 
            if row[cols["delete_status"]] == 1:
                member.status = '0'
                member.restrict = '0'
            else:
                member.status = '1'
                if row[cols["role_status"]] == 1:
                    member.restrict='0'
                else:
                    member.restrict='1'
 
            membership.addMember(member)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return membership  
 
class OverrideDb:
    """
        class OverrideDb
 
        This class handles access to the following Oracle tables:
            vista_ims_adm.vista_group_info            	Group objects are created
            vista_ims_adm.vista_enrollment_info       	Role objects are created
            vista_ims_adm.vista_member_info           	Used to find role records
            vista_ims_adm.vista_override_info         	Override records are applied to both Group and Role records    
	    vista_ims_adm.vista_group_destination_info  Where do these records feed to?  
 
    """
    logger.debug("Starting Database ODB Class")
 
    ## Overridable fields and their DB fields
    groupOverride = {
                  "LC_PARENT_ID":"lcparentdbid",
                  "ROLLUP_ID":"rollupdbid",
                  "TYPE_LEVEL":"level",
                  "SHORT_DESCRIPTION":"descriptionshort",
                  "LONG_DESCRIPTION":"descriptionlong",
                  "FULL_DESCRIPTION":"descriptionfull",
                  "ORG_ID":"orgid",
                  "ORG_NAME":"orgorgname",
                  "BKHIERARCHY":"extensionbkhierarchy",
                  "DIVISION":"extensiondivision",
                  "BEGIN_DATE":"timeframebegin",
                  "BEGIN_RESTRICT":"dbbeginrestrict",
                  "END_DATE":"timeframeend",
                  "END_RESTRICT":"dbbeginrestrict",
                  "ADMIN_PERIOD":"timeframeadminperiod",
                  "EMAIL":"email",
                  "URL":"url",
                  "WEBCT_TEMPLATE":"extensionwebcttemplate",
                  "CREATOR":"creator",
                  "EXPIRE_TS":"expirets",
                  "VISTA_DATA_SOURCE_ID":"datasource",
                  }
 
    roleOverride = {
                  "ROLE":"roletype",
                  "SUBROLE":"subrole",
                  "STATUS":"status",
                  "COMMENTS":"comments",
                  "RESTRICT":"restrict",
                  "EXPIRE_TS":"roleexpirets"
                  }
 
    memberOverride = {
                      "USERID":"userid",
                      "EXPIRE_TS":"memberexpirets"
                      }
 
    def connect(self):
        """
 
        We will be using the connection pooling built into cx_Oracle
 
        """
        self.ezConStr = cx_Oracle.makedsn(config.dbOverrideHost,config.dbOverridePort,config.dbOverrideSid)
        self.pool = cx_Oracle.SessionPool(
                user=config.dbOverrideUser,
                password=config.dbOverridePassword,
                dsn=self.ezConStr,
                min=0,
                max=20,
                increment=1,
                threaded=True)
        self.pool.timeout=300
 
    def __init__(self,runKeepAlive=True):
            self.connect()
            if runKeepAlive:
                    keepAlive = KeepAlive(self)
                    keepAlive.start()
            self.removeNonOverridable()
    def getAllEnrollmentsOfAllPeers(self,sourcedidId,sourcedidSource):
        sql = """
            select m.sourcedid_id,m.sourcedid_source,e.role,e.subrole from 
                %(schema)s.override_vista_member_info m
                inner join %(schema)s.override_vista_enrollment_info e on m.vista_member_id=e.vista_member_id
                  inner join %(schema)s.override_rollup_group_info g on e.vista_group_id = g.vista_group_id
                    where g.rollup_id in (
                        select rollup_id from  %(schema)s.override_rollup_group_info gg
                          where gg.sourcedid_id='%(sourcedidId)s' and gg.sourcedid_source='%(sourcedidSource)s'
                      )
                  and e.status='1'
        """%{'schema':config.dbOverrideSchema,'sourcedidId':sourcedidId,'sourcedidSource':sourcedidSource}
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
 
        rset = curs.execute(str(sql))
 
        rows = rset.fetchall()
        ret = []
        for row in rows:
            ret.append(str(row[0])+'.'+str(row[1])+'.'+str(row[2])+'.'+str(row[3])) 
 
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
        return ret 
 
    def removeNonOverridable(self):
        sql = """
                select table_name, field
                        from %s.lms_or_fields_info
                  """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
 
        rset = curs.execute(sql)
 
        # Find where search col lives so we can map back
        cols = getCols(rset,True)
 
        rows = rset.fetchall()
        validOverrides = []
        for row in rows:
            validOverrides.append((row[cols["TABLE_NAME"]],row[cols["FIELD"]])) 
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        logger.debug("validOverrides="+str(validOverrides))
 
        for groupO in self.groupOverride.keys():
                if ("VISTA_GROUP_INFO",groupO) not in validOverrides:
                        del self.groupOverride[groupO]
        for memberO in self.memberOverride.keys():
                if ("VISTA_MEMBER_INFO",memberO) not in validOverrides:
                        del self.memberOverride[memberO]
        for roleO in self.roleOverride.keys():
                if("VISTA_ENROLLMENT_INFO",roleO) not in validOverrides:
                        del self.roleOverride[roleO]
 
        logger.debug("groupOverrideAfterRemoval="+str(self.groupOverride))
        logger.debug("memberOverrideAfterRemoval="+str(self.memberOverride))
        logger.debug("roleOverrideAfterRemoval="+str(self.roleOverride))
 
 
    ### HELPER FUNCTION
    def getListGroups(self,sql):
        """
            Helper function to execute SQL and get a list of groups back, A list of tuples are
            returned of sourcedid_id,sourcedid_source
        """
        ret = []
        logger.debug("started getListGroups with sql=" + sql)
        con = self.pool.acquire()
        curs = con.cursor()
        rset = curs.execute(sql)
        cols = getCols(rset,False) 
 
        rows = rset.fetchall()
 
        for row in rows:
            sourceid = row[cols["sourcedid_id"]]
            sourcename = row[cols["sourcedid_source"]]
            ret.append((sourceid,sourcename))
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return ret
 
    def setAttrIfNotNull(self,group,attribute,value):
        logger.debug("Trying to set " + str(attribute) + " to " + str(value))
        logger.debug("Will only set if this is null == " + str(getattr(group,attribute,None)))
        if value != None:
            if str(value) != "Null":
                logger.debug("Yup... Its null... Setting Attribute")
                setattr(group,attribute,value)
 
    ### GROUP LOGIC    
    def insertGroup(self,group):
        logger.debug("started insertGroup with sourcedidid=" + group.sourcedidid + " sourcedidsource=" + group.sourcedidsource)
        con = self.pool.acquire()
        curs = con.cursor()
        if hasattr(group,"lcparentid"):
            lcGroup = self.getGroup(group.get("lcparentid"),group.get("lcparentsource"))
            logger.debug("Assigning LC Parent = " + group.get("lcparentid") + ":" + group.get("lcparentsource"))
            group.lcdbid = lcGroup.dbid
 
        if group.get("rollupid"):
            rollupGroup = self.getGroup(group.get("rollupid"), group.get("rollupsource"))
            logger.debug("Assigning Rollup = " + group.get("rollupid") + ":" + group.get("rollupsource"))
            group.rollupdbid=rollupGroup.dbid
 
        sql = """
            insert into %s.VISTA_GROUP_INFO (
                SOURCEDID_ID, 
                SOURCEDID_SOURCE,
                LC_PARENT_ID,
                ROLLUP_ID,
                TYPE_LEVEL,
                SHORT_DESCRIPTION,
                LONG_DESCRIPTION,
                FULL_DESCRIPTION,
                ORG_ID,
                ORG_NAME,
                BKHIERARCHY,
                DIVISION,
                BEGIN_DATE,
                BEGIN_RESTRICT,
                END_DATE,
                END_RESTRICT,
                ADMIN_PERIOD,
                EMAIL,
                URL,
                WEBCT_TEMPLATE,
                CREATOR,
                EXPIRE_TS,
                VISTA_DATA_SOURCE_ID
            ) values (
            :sourcedid_id, 
            :sourcedid_source,
            :lc_parent_id,
            :rollup_id,
            :type_level,
            :short_description,
            :long_description,
            :full_description,
            :org_id,
            :org_name,
            :bkhierarchy,
            :division,
            :begin_date,
            :begin_restrict,
            :end_date,
            :end_restrict,
            :admin_period,
            :email,
            :url,
            :webct_template,
            :creator,
            :expire_ts,
            :vista_data_source_id
            )
        """%config.dbOverrideSchema
        logger.debug("Going to run sql=" + sql)
        param = {} 
        param["sourcedid_id"]=group.sourcedidid
        param["sourcedid_source"]=group.sourcedidsource
 
        param["lc_parent_id"]=group.get("lcdbid")
 
        param["rollup_id"]=group.get("rollupdbid")
 
        param["type_level"]= group.get("level")
        param["short_description"]= group.get("descriptionshort")
        param["long_description"]= group.get("descriptionlong")
        param["full_description"]= group.get("descriptionfull")
 
        param["org_id"]= group.get("orgid")
 
        param["org_name"]= group.get("orgorgname")
 
        param["bkhierarchy"]= group.get("extensionbkhierarchy")
 
        param["division"]= group.get("extensiondivision")
 
        param["begin_date"]= group.get("timeframebegin")
 
        param["begin_restrict"]= group.get("timeframebeginrestrict")
 
        param["end_date"]= group.get("timeframeend")
 
        param["end_restrict"]= group.get("timeframeendrestrict")
 
        param["admin_period"]= group.get("timeframeadminperiod")
 
        param["email"]= group.get("email")
 
        param["url"]= group.get("url")
 
        param["webct_template"]= group.get("extensionwebcttemplate")
 
        param["creator"]= config.feedName
 
        param["expire_ts"]= group.get("expirets")
 
        param["vista_data_source_id"]= group.get("datasource")
 
        for (key,value) in param.iteritems():
                logger.debug("%s=%s"%(key,value))
 
        curs.execute(sql,param)
        curs.close()
 
        con.commit()
        self.pool.release(con)
        curs=None
        con=None
 
 
    def updateGroup(self,group):
        if str(group) == "None":
            logger.debug("Not processing a None groupe ")
            return None
 
        # The Divisions and Content Seciotns don't have a LCParent
        if group.get("level")=="25" or group.get("level")=="85":
            lcGroup = None
        else:
            lcGroup = self.getGroup(group.get("lcparentid"),group.get("lcparentsource"))
 
        if group.get("rollupdbid") is not None:
            rollupGroup = self.getGroupFromId(group.get("rollupdbid"))
        elif group.get("rollupid") is not None and group.get("rollupsource") is not None:
            rollupGroup = self.getGroup(group.get("rollupid"), group.get("rollupsource"))
        else:
            rollupGroup = None
 
        sql = """
                update %s.VISTA_GROUP_INFO set
                LC_PARENT_ID=:lc_parent_id,
                ROLLUP_ID=:rollup_id,
                TYPE_LEVEL=:type_leve,
                SHORT_DESCRIPTION=:short_description,
                LONG_DESCRIPTION=:long_description,
                FULL_DESCRIPTIOn=:full_description,
                ORG_ID=:org_id,
                ORG_NAME=:org_name,
                BKHIERARCHY=:bkhierarchy,
                DIVISION=:division,
                BEGIN_DATE=:begin_date,
                BEGIN_RESTRICT=:begin_restrict,
                END_DATE=:end_date,
                END_RESTRICT=:end_restrict,
                ADMIN_PERIOD=:admin_period,
                EMAIL=:email,
                URL=:url,
                WEBCT_TEMPLATE=:webct_template,
                EXPIRE_TS=:expire_ts
 
                    where SOURCEDID_ID=:sourcedid_id and SOURCEDID_SOURCE=:sourcedid_source
                    """%config.dbOverrideSchema
        logger.debug("About to execute the following sql")
        logger.debug(sql)
 
        params = {}
 
        if lcGroup is not None:
            params["lc_parent_id"]= lcGroup.dbid
        else:
            params["lc_parent_id"]= None
 
        if rollupGroup is not None:
            params["rollup_id"]= rollupGroup.dbid
        else:
            params["rollup_id"]= None
 
 
        params["type_leve"]= group.get("level")
        params["short_description"]= group.get("descriptionshort")
        params["long_description"]= group.get("descriptionlong")
        params["full_description"]= group.get("descriptionfull")
 
        params["org_id"]= group.get("orgid")
 
        params["org_name"]= group.get("orgorgname")
 
        params["bkhierarchy"]= group.get("extensionbkhierarchy")
 
        params["division"]= group.get("extensiondivision")
 
        params["begin_date"]= group.get("timeframebegin")
 
        params["begin_restrict"]= group.get("timeframebeginrestrict")
 
        params["end_date"]= group.get("timeframeend")
 
        params["end_restrict"]= group.get("timeframeendrestrict")
 
        params["admin_period"]= group.get("timeframeadminperiod")
 
        params["email"]= group.get("email")
 
        params["url"]= group.get("url")
 
        params["webct_template"]= group.get("extensionwebcttemplate")
 
        params["expire_ts"]= group.get("expirets")
 
        params["sourcedid_id"]= group.sourcedidid
        params["sourcedid_source"]= group.sourcedidsource
 
        for (key,value) in params.iteritems():
                logger.debug("%s=%s"%(key,value))
 
        con = self.pool.acquire()
        curs = con.cursor()
        curs.execute(sql,params)
        curs.close()
 
        con.commit()
        self.pool.release(con)
        curs=None
        con=None
 
 
 
    def getGroupOverrides(self,group):
        """
            getGroupOverrides(self,group)
 
            Get override records from VISTA_OVERRIDE_INFO and save the values to a group object.
 
            The original value will be saved as orig_fieldname. This will allow access to the underlying 
            value and allow the func that send the object to the override DB to ignore the update. If you
            ever want to test for the existence of an override record see if there is an orig_field.
 
            Group object after this func:
                For every override record:
                group.field = value from vista_override_info
                group.orig_field = value from vista_group_info
        """
        logger.debug("Starting getGroupOverrides for " + group.sourcedidid)
 
        sql = """
                select VALUE,FIELD 
                from %s.vista_override_info 
                where 
                        table_name='VISTA_GROUP_INFO' 
                        and table_id=:table_id
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("table_id=" + group.dbid)
        rset = curs.execute(sql,table_id=group.dbid)
 
        # Find where search col lives so we can map back
        cols = getCols(rset,True)
 
        rows = rset.fetchall()
 
        for row in rows:
            objectFieldName = self.groupOverride[row[cols["FIELD"]]]
            overrideValue = row[cols["VALUE"]]
            # If there is no object set at this instance then save orig_field ="" to signify a null is underlying
            origValue = getattr(group,objectFieldName,"")
            logger.debug("Setting " +  str(objectFieldName) + "=" + str(overrideValue))
            # Set the override values in the object
            setattr(group,"orig_" + objectFieldName, origValue)
            setattr(group,objectFieldName,overrideValue)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
 
        # Get some details on overriden rollup and lc parents
        if hasattr(group,"orig_lcparentdbid"):
            if group.lcparentdbid != None:
                orig_parent = self.getGroupFromId(group.orig_lcparentdbid)
                logger.debug("Setting orig_lcparent,orig_lcparentid,orig_lcparentsource from " +group.orig_lcparentdbid)
                group.orig_lcparent=orig_parent
                if orig_parent == None:
                    group.orig_lcparentid=None
                    group.orig_lcparentsource=None
                else:
                    group.orig_lcparentid=orig_parent.sourcedidid
                    group.orig_lcparentsource=orig_parent.sourcedidsource
            else:
                logger.debug("Setting orig_lcparent,orig_lcparentid,orig_lcparentsource to None")
                group.orig_lcparent=None
                group.orig_lcparentid=None
                group.orig_lcparentsource=None
 
            parent = self.getGroupFromId(group.lcparentdbid)
            logger.debug("Setting lcparent,lcparentid,lcparentsource from " +group.lcparentdbid)
            group.lcparent=parent
            group.lcparentid=parent.sourcedidid
            group.lcparentsource=parent.sourcedidsource
 
        if hasattr(group,"orig_rollupdbid"):
            if group.orig_rollupdbid != None:
                orig_rollup = self.getGroupFromId(group.orig_rollupdbid)
                logger.debug("Setting orig_rollupparent,orig_rollupid,orig_rollupsource from " +group.orig_rollupdbid)
                group.orig_rollupparent=orig_rollup
                if orig_rollup == None:
                    group.orig_rollupid=None
                    group.orig_rollupsource=None
                else:
                    group.orig_rollupid=orig_rollup.sourcedidid
                    group.orig_rollupsource=orig_rollup.sourcedidsource
            else:
                logger.debug("Setting orig_rollupparent,orig_rollupid,orig_rollupsource to None")
                group.orig_rollupparent=None
                group.orig_rollupid=None
                group.orig_rollupsource=None
 
            if getattr(group,"rollupdbid",None) != None and getattr(group,"rollupdbid",None)!="": 
                rollup = self.getGroupFromId(group.rollupdbid)
                logger.debug("Setting rollupparent,rollupid,rollupsource from " +str(group.rollupdbid))
                group.rollupparent=rollup
                group.rollupid=rollup.sourcedidid
                group.rollupsource=rollup.sourcedidsource
            else:
                group.rollupparent=None
                group.rollupid=None
                group.rollupsource=None
 
    def processRsetToGroup(self,rset):
        """
            processRsetToGroup(self,rset)
 
            Process a record set and return a new Group object
 
            We use a few SQL statments to get Group objects from VISTA_GROUP_INFO this code centralizes the the
            part that creates the group and populates it from the override DB
 
             This should be the ONLY place we get info from the override db to a group object because
             we make sure we handle overrides and make sure the object gets overrides applied. This func 
             acheves this by calling getGroupOverrides
        """
 
        group = None
 
        # Find where search col lives so we can map back
        cols = getCols(rset,True)
 
        row = rset.fetchone()
 
        logger.debug(row)
 
        if row:
            logger.debug("Got group")
            group = Group()
 
            self.setAttrIfNotNull(group,"sourcedidsource",row[cols["SOURCEDID_SOURCE"]])
            self.setAttrIfNotNull(group, "sourcedidid", row[cols["SOURCEDID_ID"]])
            self.setAttrIfNotNull(group, "level", row[cols["TYPE_LEVEL"]])
            self.setAttrIfNotNull(group, "descriptionshort", row[cols["SHORT_DESCRIPTION"]])
            self.setAttrIfNotNull(group, "descriptionlong", row[cols["LONG_DESCRIPTION"]])
            self.setAttrIfNotNull(group, "descriptionfull", row[cols["FULL_DESCRIPTION"]])
            self.setAttrIfNotNull(group, "orgorgname", row[cols["ORG_NAME"]])
            self.setAttrIfNotNull(group, "orgid", row[cols["ORG_ID"]])
            self.setAttrIfNotNull(group, "timeframebegin", row[cols["BEGIN_DATE"]])
            self.setAttrIfNotNull(group, "timeframebeginrestrict", row[cols["BEGIN_RESTRICT"]])
            self.setAttrIfNotNull(group, "timeframeend", row[cols["END_DATE"]])
            self.setAttrIfNotNull(group, "timeframeendrestrict", row[cols["END_RESTRICT"]])
            self.setAttrIfNotNull(group, "timeframeadminperiod", row[cols["ADMIN_PERIOD"]])
            self.setAttrIfNotNull(group, "url", row[cols["URL"]])
            self.setAttrIfNotNull(group, "datasource", row[cols["VISTA_DATA_SOURCE_ID"]])
            self.setAttrIfNotNull(group, "extensionbkhierarchy", row[cols["BKHIERARCHY"]])
            self.setAttrIfNotNull(group, "extensiondivision", row[cols["DIVISION"]])
            self.setAttrIfNotNull(group, "dbid", row[cols["VISTA_GROUP_ID"]])
            self.setAttrIfNotNull(group, "lcparentdbid", row[cols["LC_PARENT_ID"]])
            self.setAttrIfNotNull(group, "rollupdbid", row[cols["ROLLUP_ID"]])
            self.setAttrIfNotNull(group, "creator", row[cols["CREATOR"]])
            self.setAttrIfNotNull(group, "expirets", row[cols["EXPIRE_TS"]])
            self.setAttrIfNotNull(group, "createts", row[cols["CREATE_TS"]])
            self.setAttrIfNotNull(group, "modifyts", row[cols["MODIFY_TS"]])
 
            # Save override data to the dataobject
            self.getGroupOverrides(group)
 
            # Get some details about Rollup and LCParents
            if hasattr(group,"lcparentdbid"):
                logger.debug("Trying to set lcparent for vista_Group_id=" + str(group.lcparentdbid))
                lcparent = self.getGroupFromId(group.lcparentdbid)
                group.lcparent=lcparent
                group.lcparentid=lcparent.sourcedidid
                group.lcparentsource=lcparent.sourcedidsource
 
            if getattr(group,"rollupdbid",None)!=None and getattr(group,"rollupdbid",None)!="":
                logger.debug("Trying to set rollup for vista_Group_id=" + str(group.rollupdbid))
                rollupparent = self.getGroupFromId(group.rollupdbid)
                group.rollupparent=rollupparent
                group.rollupid=rollupparent.sourcedidid
                group.rollupsource=rollupparent.sourcedidsource
 
            return group
 
        else:
            logger.debug("Group not found")    
            return None
 
 
    def getGroupDestinations(self,sourcedidid,sourcedidsource):
        """
		Returns a list of destinations for this group.
		This will return a tuple of groupid,primary,active
		"""
        if sourcedidid==None or sourcedidsource==None:
            logger.debug("Not processing a Null")
            return None
 
        sql = """
    		select g.LMS_DESTINATION_ID, g.PRIMARY, g.ACTIVE, d.URL 
    		from %(schema)s.LMS_GROUP_DESTINATION_INFO g, %(schema)s.LMS_DESTINATION_INFO d, %(schema)s.VISTA_GROUP_INFO gg
    		where
    		    (d.LMS_DESTINATION_ID=g.LMS_DESTINATION_ID and gg.VISTA_GROUP_ID=g.LMS_GROUP_ID)
    		    and
    			gg.sourcedid_id = :sourceid
    			and gg.sourcedid_source = :source
    	      """%{'schema':config.dbOverrideSchema}
        con=self.pool.acquire()
        curs=con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("sourcedid_id=%s"%sourcedidid)
        logger.debug("sourcedid_source=%s"%sourcedidsource)
        rset=curs.execute(sql,sourceid=sourcedidid, source=sourcedidsource)
        rows = rset.fetchall()
        retList=[]
        for row in rows: 
            retList.append((str(row[0]),str(row[1]),str(row[2]),str(row[3])))
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return retList
 
 
 
    def getGroupFromId(self,vistaGroupId):
        """
            getGroupFromId(self,vistaGroupId)
 
            Executes SQL to get a group from vista_group_info using the PK vista_group_id
 
        """
        if str(vistaGroupId) == "None":
            logger.debug("Not processing a Null")
            return None
 
        sql = """
                select * 
                from %s.vista_group_info 
                where 
                        vista_group_id=:vista_group_id
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("vistaGroupId=" + vistaGroupId)
        rset=curs.execute(sql,vista_group_id=vistaGroupId)
 
        group = self.processRsetToGroup(rset)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return group                        
 
    def getGroup(self, sourcedidid, sourcedidsource):
        """
            getGroup(self, sourcedidid, sourcedidsource)
 
            getGroup executes SQL to get a group using sourcedid_id and sourcedid_source from vista_group_info
 
        """
        logger.debug("Searching for sorucedidid=" + str(sourcedidid) + " sourcedidsource=" + str(sourcedidsource))
        if str(sourcedidid) == "None" or str(sourcedidsource) == "None":
            logger.debug("Not processing a None sourcedid or sourcedidsource ")
            return None
 
        sql = """
                select * 
                from %s.vista_group_info 
                where 
                        sourcedid_id=:sourcedid_id 
                        and sourcedid_source=:sourcedid_source
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("sourcedidid=" + sourcedidid)
        logger.debug("sourcedidsource=" + sourcedidsource)
        rset = curs.execute(sql,sourcedid_id=sourcedidid,sourcedid_source=sourcedidsource) 
        group = self.processRsetToGroup(rset)
 
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return group
 
    def getGroupDbId(self,sourcedidid,sourcedidsource):
        """
            getGroupDbId(self,sourcedidid,sourcedidsource)
 
            Gets vista_group_id from vista_group_info.sourcedid_id and vista_group_info.sourcedid_source
 
            You can't or at least should never (And this codes does not care about) override sourcedid* values 
            so not checking for overrides is just fine!
        """
 
        logger.debug("Searching for group with sorucedidid=" + str(sourcedidid) + " sourcedidsource=" + str(sourcedidsource))
        if str(sourcedidid) == "None" or str(sourcedidsource) == "None":
            logger.debug("Not processing a None sourcedid or sourcedidsource ")
            return None
 
        sql = """
                select vista_group_id 
                from %s.vista_group_info 
                where 
                        sourcedid_id=:sourcedid_id 
                        and sourcedid_source=:sourcedid_source
        """%config.dbOverrideSchema
 
        con = self.pool.acquire()
        curs = con.cursor()
 
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("sourcedidid=" + sourcedidid)
        logger.debug("sourcedidsource=" + sourcedidsource)
        rset = curs.execute(sql,sourcedid_id=sourcedidid,sourcedid_source=sourcedidsource)
 
        row = rset.fetchone()
        if row:
            groupDbId = row[0]
        else:
            groupDbId=None
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return groupDbId
 
    def getSourcedidid(self,termCode,classNumber,sourcedidsource):
        """
            getSourcedidid(self,termCode,classNumber)
 
            Gets sourcedid_id from vista_group_info using the term code and the class number
 
            This returns type level 90 only, no content sections
        """
 
        logger.debug("Searching for group with term code=" + str(termCode) + " class number=" + str(classNumber))
        if str(termCode) == "None" or str(classNumber) == "None":
            logger.debug("Not processing a None termCode or classNumber ")
            return None
 
        sql = """
                select sourcedid_id 
                from %s.vista_group_info 
                where 
                        sourcedid_id like :sourcedid_id 
                        and sourcedid_source = :sourcedid_source 
                        and TYPE_LEVEL = 90
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("termCode=" + termCode)
        logger.debug("classNumber=" + classNumber)
        rset = curs.execute(sql,sourcedid_id="%s-%-%s"%(termCode,classNumber),sourcedid_source=sourcedidsource)
 
        row = rset.fetchone()
        if row:
            groupDbId = row[0]
        else:
            groupDbId=None
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return groupDbId
 
    def isGroupDeleted(self,sourcedidid,sourcedidsource):
        sql = """
            select count(*) 
            from %s.lms_group_event_log_info 
            where
                sourcedid_id = :sourcedid_id
                and sourcedid_source = :sourcedid_source
                and lms_group_event_id = 'DELETE-VISTA-SECTION'
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("sourcedidid=" + sourcedidid)
        logger.debug("sourcedidsource=" + sourcedidsource)
        rset = curs.execute(sql,sourcedid_id=sourcedidid,sourcedid_source=sourcedidsource)
        ret = False
        row = curs.fetchone()
        logger.debug(row)
        if row:
            if row[0] > 0:
                ret = True
 
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return ret
 
    ### ENROLLMENT LOGIC
    def getPersonIds(self,emplidOrRegid):
        emplid = None
        regid = None
 
        if len(emplidOrRegid) < 10 :
            emplid = str(int(emplidOrRegid))
        else:
            regid = emplidOrRegid
 
        if emplid != None:
            return self.getPersonIdsByEmplid(emplid)
 
        return self.getPersonIdsByRegid(regid)
 
    def getPersonIdsByRegid(self,regid):
        sql = """
                select userid, emplid, sourcedid_id , sourcedid_source 
                from %s.vista_member_info m 
                where 
                        m.sourcedid_id=:sourcedid_id
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("regid=" + regid)
        rset = curs.execute(sql,sourcedid_id=regid)
 
        ret = None
        row = rset.fetchone()
        if row:
            emplid = row[1]
            uid = row[0]
            sourceid = row[2]
            sourcename = row[3]
            ret = (emplid,uid,sourceid,sourcename)
            logger.debug(ret)
 
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return ret
 
    def getPersonIdsByEmplid(self,emplid):
        sql = """
                select userid, emplid, sourcedid_id , sourcedid_source 
                from %s.vista_member_info m
                where
                        m.emplid=:eid
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("emplid=" + emplid)
        rset = curs.execute(sql,eid=emplid)
        ret = None
        row = rset.fetchone()
        if row:
            emplid = row[1]
            uid = row[0]
            sourceid = row[2]
            sourcename = row[3]
            ret = (emplid,uid,sourceid,sourcename)
            logger.debug(ret)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return ret
 
    def getMemberDbId(self,sourcedidid,sourcedidsource):
        sql = """
                select vista_member_id 
                from %s.vista_member_info
                where
                        sourcedid_id = :sourcedid_id
                        and sourcedid_source = :sourcedid_source
        """%config.dbOverrideSchema
 
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("sourcedid_id=" + sourcedidid)
        logger.debug("sourcedid_name=" + sourcedidsource)
        rset=curs.execute(sql,sourcedid_id=sourcedidid,sourcedid_source=sourcedidsource)
 
        row = rset.fetchone()
 
        ret = None
        if row:
            ret = row[0]
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return ret
 
    def getRoleOverrides(self,member):
        """
            getRoleOverrides(self,membership)
 
            Get override records from VISTA_OVERRIDE_INFO and save the values to a membership object.
 
            The original value will be saved as orig_fieldname. This will allow access to the underlying 
            value and allow the func that send the object to the override DB to ignore the update. If you
            ever want to test for the existence of an override record see if there is an orig_field.
 
            Member object after this func:
                For every override record:
                member.field = value from vista_override_info
                member.orig_field = value from vista_enrollment_info
        """
        logger.debug("Starting getRoleOverrides for " + member.sourcedidid)
 
        sql = """
                select field,value 
                from %s.vista_override_info 
                where 
                        table_name='VISTA_ENROLLMENT_INFO' 
                        and table_id=:table_id
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("table_id=" + member.dbroleid)
        rset = curs.execute(sql,table_id=member.dbroleid)
        rows = rset.fetchall()
        for row in rows:
            objectFieldName = self.roleOverride[row[0]]
            overrideValue = row[1]
            # If there is no object set at this instance then save orig_field ="" to signify a null is underlying
            origValue = getattr(member,objectFieldName,"")
            logger.debug("Setting role override " +  str(objectFieldName) + "=" + str(overrideValue))
            # Set the override values in the object
            setattr(member,"orig_" + objectFieldName, origValue)
            setattr(member,objectFieldName,overrideValue)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
 
    def getMemberOverrides(self,member):
        """
            getMemberOverrides(self,membership)
 
            Get override records from VISTA_OVERRIDE_INFO and save the values to a membership object.
 
            The original value will be saved as orig_fieldname. This will allow access to the underlying 
            value and allow the func that send the object to the override DB to ignore the update. If you
            ever want to test for the existence of an override record see if there is an orig_field.
 
            Member object after this func:
                For every override record:
                member.field = value from vista_override_info
                member.orig_field = value from vista_enrollment_info
        """
        logger.debug("Starting getMemberOverrides for " + member.sourcedidid)
 
        sql = """
                select field,value 
                from %s.vista_override_info 
                where
                        table_name='VISTA_MEMBER_INFO'
                        and table_id=:table_id
        """%config.dbOverrideSchema
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("table_id=" + member.dbmemberid)
        rset = curs.execute(sql,table_id=member.dbmemberid)
        rows = rset.fetchall()
        for row in rows:
            objectFieldName = self.memberOverride[row[0]]
            overrideValue = row[1]
            # If there is no object set at this instance then save orig_field ="" to signify a null is underlying
            origValue = getattr(member,objectFieldName,"")
            logger.debug("Setting member override" +  str(objectFieldName) + "=" + str(overrideValue))
            # Set the override values in the object
            setattr(member,"orig_" + objectFieldName, origValue)
            setattr(member,objectFieldName,overrideValue)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
 
    def getMembership(self, sourcedidid,sourcedidsource):
        logger.debug("Starting getMembership")
 
        sql = """select 
                    g.vista_group_id, e.vista_enrollment_id, m.vista_member_id, m.sourcedid_id, m.sourcedid_source, m.userid, 
                    m.expire_ts as memberexpirets, e.expire_ts as roleexpirets, e.vista_data_source_id roledatasource, m.vista_Data_source_id memberdatasource,
                    e.role, e.subrole, e.status, e.comments, e.restrict, e.vista_data_source_id roledatasource, m.emplid,
                    g.sourcedid_id groupsourcedidid, g.sourcedid_source groupsourcedidsource
            from %(s)s.vista_enrollment_info e, %(s)s.vista_group_info g, %(s)s.vista_member_info m 
            where
                (g.vista_group_id = e.vista_group_id and e.vista_member_id = m.vista_member_id)
                and g.sourcedid_id = :sourcedid_id
                and g.sourcedid_source = :sourcedid_source
           """%{'s':config.dbOverrideSchema}
        con = self.pool.acquire()
        curs = con.cursor()
 
        logger.debug("About to execute the following SQL")
 
        logger.debug(sql)
        logger.debug("sourcedid_id=" + sourcedidid)
        logger.debug("sourcedid_name=" + sourcedidsource)
        rset = curs.execute(sql,sourcedid_id=sourcedidid,sourcedid_source=sourcedidsource)
        logger.debug(rset)
        membership = Membership()
        membership.db = True
        membership.datasource = config.datasource
        membership.sourcedidid = sourcedidid
        membership.sourcedidsource = sourcedidsource
 
        logger.debug("About to start loop")
        rows = rset.fetchall()
        cols = getCols(rset,False)
        logger.debug(cols)
        for row in rows:
            logger.debug("In loop")
            member = Member()
            logger.debug("memberexpirets=>" + str(row[cols["memberexpirets"]]))
            logger.debug("roleexpirets=>" + str(row[cols["roleexpirets"]]))
 
            self.setAttrIfNotNull(member, "dbmemberid", row[cols["vista_member_id"]])
            self.setAttrIfNotNull(member, "sourcedidid", row[cols["sourcedid_id"]])
            self.setAttrIfNotNull(member, "sourcedidsource", row[cols["sourcedid_source"]])
            self.setAttrIfNotNull(member, "userid", row[cols["userid"]])
            self.setAttrIfNotNull(member, "memberexpirets", row[cols["memberexpirets"]])
            self.setAttrIfNotNull(member, "roleexpirets", row[cols["roleexpirets"]])
            self.setAttrIfNotNull(member, "roledatasource", row[cols["roledatasource"]])
            self.setAttrIfNotNull(member, "memberdatasource", row[cols["memberdatasource"]])
            self.setAttrIfNotNull(member, "datasource", row[cols["roledatasource"]])
            self.setAttrIfNotNull(member, "dbroleid", row[cols["vista_enrollment_id"]])
            self.setAttrIfNotNull(member, "dbgroupid", row[cols["vista_group_id"]])
            self.setAttrIfNotNull(member, "roletype", row[cols["role"]])
            self.setAttrIfNotNull(member, "subrole", row[cols["subrole"]])
            self.setAttrIfNotNull(member, "status", row[cols["status"]])
            self.setAttrIfNotNull(member, "comments", row[cols["comments"]])
            self.setAttrIfNotNull(member, "restrict", row[cols["restrict"]])
            self.setAttrIfNotNull(member, "emplid", row[cols["emplid"]])
            self.setAttrIfNotNull(member, "groupsourcedidid", row[cols["groupsourcedidid"]])
            self.setAttrIfNotNull(member, "groupsourcedidsource", row[cols["groupsourcedidsource"]])
            member.db=True
            self.getMemberOverrides(member)
            self.getRoleOverrides(member)
 
            logger.debug(str(member))
 
            membership.addMember(member)
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return membership
 
    def updateMember(self,member):
        if not hasattr(member,"dbgroupid"):
                member.dbgroupid = self.getGroupDbId(member.groupsourcedidid, member.groupsourcedidsource)
 
        if not hasattr(member,"dbmemberid"):
                member.dbmemberid = self.getMemberDbId(member.sourcedidid, member.sourcedidsource)
 
        logger.debug("Started updateMember with dbgroupid=" + member.dbgroupid + " dbmemberid=" + member.dbmemberid)
 
        sql = """
                update %s.vista_enrollment_info set 
                status = :status,
                comments = :comments,
                expire_ts = :expire_ts
                where
                        vista_member_id= :vista_member_id
                        and vista_group_id=:vista_group_id
                        and role = :role
                        and subrole = :subrole
        """%config.dbOverrideSchema
        sqlNullSubrole = """
                update %s.vista_enrollment_info set 
                status = :status,
                comments = :comments,
                expire_ts = :expire_ts
                where
                        vista_member_id= :vista_member_id
                        and vista_group_id=:vista_group_id
                        and role = :role
                        and subrole is null
        """%config.dbOverrideSchema
 
        con = self.pool.acquire()
        curs = con.cursor()
 
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
 
        logger.debug("status=" + str(member.get("status")))
        logger.debug("comments=" + str(member.get("comments")))
        logger.debug("expire_Ts=" +str( member.get("expirets")))
        logger.debug("vista_member_id=" + str(member.get("dbmemberid")))
        logger.debug("vista_group_id=" + str(member.get("dbgroupid")))
        logger.debug("role=" + str(member.get("roletype")))
        logger.debug("subrole=" + str(member.get("subrole")))
 
        params = {}
        params["status"] = member.get("status")
        params["comments"] = member.get("comments")
        params["expire_ts"] = member.get("expirets")
        params["vista_member_id"] = member.get("dbmemberid")
        params["vista_group_id"] = member.get("dbgroupid")
        params["role"] = member.get("roletype")
        if member.get("subrole") != None:
                params["subrole"] = member.get("subrole")
                curs.execute(sql,params)
        else:
                curs.execute(sqlNullSubrole,params)
        curs.close()
 
        con.commit()
        self.pool.release(con)
        curs=None
        con=None
 
 
 
    def insertMember(self,member):
        if not hasattr(member,"dbgroupid"):
            member.dbgroupid = self.getGroupDbId(member.groupsourcedidid, member.groupsourcedidsource)
 
        if not hasattr(member,"dbmemberid"):
            member.dbmemberid = self.getMemberDbId(member.sourcedidid, member.sourcedidsource)
 
        logger.debug("started insertRole with dbgroupid=" + str(member.dbgroupid) + " dbmemberid=" + str(member.dbmemberid))
        sql = """
            insert into %s.VISTA_ENROLLMENT_INFO (
            VISTA_MEMBER_ID,
            VISTA_GROUP_ID,
            ROLE,
            SUBROLE,
            STATUS,
            COMMENTS,
            CREATOR,
            VISTA_DATA_SOURCE_ID
            )values(
            :vista_member_id,
            :vista_group_id,
            :role,
            :subrole,
            :status,
            :comments,
            :creator,
            :vista_data_source_id
            )
 
        """%config.dbOverrideSchema
 
        con = self.pool.acquire()
        curs = con.cursor()
 
        params={}
        params["vista_member_id"]=member.get("dbmemberid")
        params["vista_group_id"]=member.get("dbgroupid")
        params["role"]=member.get("roletype")
        params["subrole"]=member.get("subrole")
        params["status"]=member.get("status")
        params["comments"]=member.get("comments")
        params["creator"]=config.feedName
        params["vista_data_source_id"]=config.datasource
 
        curs.execute(sql,params)
        curs.close()
 
        con.commit()
        self.pool.release(con)
        curs=None
        con=None
 
    def getMemberExpire(self,sourcedidid,sourcedidsource):
        logger.debug("Starting getMemberExpire")
 
        sql = """
                select expire_ts
                from %s.vista_member_info m 
                where
                        m.sourcedid_id =  :sourcedid_id
                        and m.sourcedid_source = :sourcedid_source
        """%config.dbOverrideSchema
 
        con = self.pool.acquire()
        curs = con.cursor()
        logger.debug("About to execute the following SQL")
        logger.debug(sql)
        logger.debug("sourcedid_id=" + sourcedidid)
        logger.debug("sourcedid_name=" + sourcedidsource)
        rset = curs.execute(sql,sourcedid_id=sourcedidid,sourcedid_source=sourcedidsource)
        row = rset.fetchone()
        ret = None
        if row:
            ret = row[0]
        curs.close()
 
        self.pool.release(con)
        curs=None
        con=None
 
        return ret
VN:F [1.9.17_1161]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.17_1161]
Rating: 0 (from 0 votes)
Written by admin in: |

No Comments »

RSS feed for comments on this post.

Leave a comment

You must be logged in to post a comment.

Powered by WordPress | Aeros Theme | TheBuckmaker.com WordPress Themes