Logger: Refactor get_jid_id()

- Cache jid_id so we save on DB querys
This commit is contained in:
Philipp Hörist 2017-10-22 01:11:42 +02:00
parent 9e39287d8e
commit 0aa07522fb
1 changed files with 44 additions and 37 deletions

View File

@ -108,6 +108,7 @@ class SubscriptionConstant(IntEnum):
class Logger: class Logger:
def __init__(self): def __init__(self):
self.jids_already_in = [] # holds jids that we already have in DB self.jids_already_in = [] # holds jids that we already have in DB
self._jid_ids = {}
self.con = None self.con = None
self.commit_timout_id = None self.commit_timout_id = None
@ -189,6 +190,7 @@ class Logger:
def init_vars(self): def init_vars(self):
self.open_db() self.open_db()
self.get_jids_already_in_db() self.get_jids_already_in_db()
self.get_jid_ids_from_db()
@staticmethod @staticmethod
def _get_timeout(): def _get_timeout():
@ -226,6 +228,15 @@ class Logger:
self.cur.execute(sql_to_commit) self.cur.execute(sql_to_commit)
self._timeout_commit() self._timeout_commit()
def get_jid_ids_from_db(self):
"""
Load all jid/jid_id tuples into a dict for faster access
"""
rows = self.con.execute(
'SELECT jid_id, jid, type FROM jids').fetchall()
for row in rows:
self._jid_ids[row.jid] = row
def get_jids_already_in_db(self): def get_jids_already_in_db(self):
try: try:
self.cur.execute('SELECT jid FROM jids') self.cur.execute('SELECT jid FROM jids')
@ -288,42 +299,38 @@ class Logger:
return [user['jid'] for user in family] return [user['jid'] for user in family]
return [jid] return [jid]
def get_jid_id(self, jid, typestr=None): def get_jid_id(self, jid, type_=None):
""" """
jids table has jid and jid_id logs table has log_id, jid_id, Get the jid id from a jid.
contact_name, time, kind, show, message so to ask logs we need jid_id In case the jid id is not found create a new one.
that matches our jid in jids table this method wants jid and returns the
jid_id for later sql-ing on logs typestr can be 'ROOM' or anything else :param jid: The JID
depending on the type of JID and is only needed to be specified when the
JID is new in DB :param type_: The JIDConstant type
return the jid id
""" """
if jid.find('/') != -1: # if it has a /
jid_is_from_pm = self.jid_is_from_pm(jid) result = self._jid_ids.get(jid, None)
if not jid_is_from_pm: # it's normal jid with resource if result is not None:
jid = jid.split('/', 1)[0] # remove the resource return result.jid_id
if jid in self.jids_already_in: # we already have jids in DB
self.cur.execute('SELECT jid_id FROM jids WHERE jid=?', [jid]) sql = 'SELECT jid_id, jid, type FROM jids WHERE jid = ?'
row = self.cur.fetchone() row = self.con.execute(sql, [jid]).fetchone()
if row: if row is not None:
self._jid_ids[jid] = row
return row.jid_id return row.jid_id
# oh! a new jid :), we add it now
if typestr == 'ROOM': if type_ is None:
typ = JIDConstant.ROOM_TYPE raise ValueError(
else: 'Unable to insert new JID because type is missing')
typ = JIDConstant.NORMAL_TYPE
try: sql = 'INSERT INTO jids (jid, type) VALUES (?, ?)'
self.cur.execute('INSERT INTO jids (jid, type) VALUES (?, ?)', (jid, lastrowid = self.con.execute(sql, (jid, type_)).lastrowid
typ)) Row = namedtuple('Row', 'jid_id jid type')
self.con.commit() self._jid_ids[jid] = Row(lastrowid, jid, type_)
except sqlite.IntegrityError: self._timeout_commit()
# Jid already in DB, maybe added by another instance. re-read DB return lastrowid
self.get_jids_already_in_db()
return self.get_jid_id(jid, typestr)
except sqlite.OperationalError as e:
raise exceptions.PysqliteOperationalError(str(e))
jid_id = self.cur.lastrowid
self.jids_already_in.append(jid)
return jid_id
def convert_kind_values_to_db_api_values(self, kind): def convert_kind_values_to_db_api_values(self, kind):
""" """
@ -961,7 +968,7 @@ class Logger:
try: try:
account_jid_id = self.get_jid_id(account_jid) account_jid_id = self.get_jid_id(account_jid)
jid_id = self.get_jid_id(jid) jid_id = self.get_jid_id(jid, type_=JIDConstant.NORMAL_TYPE)
except exceptions.PysqliteOperationalError as e: except exceptions.PysqliteOperationalError as e:
raise exceptions.PysqliteOperationalError(str(e)) raise exceptions.PysqliteOperationalError(str(e))
@ -993,7 +1000,7 @@ class Logger:
Return the accound_jid roster in NonBlockingRoster format Return the accound_jid roster in NonBlockingRoster format
""" """
data = {} data = {}
account_jid_id = self.get_jid_id(account_jid) account_jid_id = self.get_jid_id(account_jid, type_=JIDConstant.NORMAL_TYPE)
# First we fill data with roster_entry informations # First we fill data with roster_entry informations
self.cur.execute(''' self.cur.execute('''
@ -1149,7 +1156,7 @@ class Logger:
""" """
account_jid_id = self.get_jid_id(account_jid) account_jid_id = self.get_jid_id(account_jid)
jid_id = self.get_jid_id(jid) jid_id = self.get_jid_id(jid, type_=JIDConstant.NORMAL_TYPE)
sql = ''' sql = '''
UPDATE roster_entry SET avatar_sha = ? UPDATE roster_entry SET avatar_sha = ?