Tidy up _simple_... methods

This commit is contained in:
Erik Johnston 2015-03-20 14:59:48 +00:00
parent 87db64b839
commit 7e282a53a5
4 changed files with 63 additions and 43 deletions

View file

@ -399,7 +399,7 @@ class SQLBaseStore(object):
txn.execute(sql, allvalues.values()) txn.execute(sql, allvalues.values())
def _simple_select_one(self, table, keyvalues, retcols, def _simple_select_one(self, table, keyvalues, retcols,
allow_none=False): allow_none=False, desc="_simple_select_one"):
"""Executes a SELECT query on the named table, which is expected to """Executes a SELECT query on the named table, which is expected to
return a single row, returning a single column from it. return a single row, returning a single column from it.
@ -411,8 +411,10 @@ class SQLBaseStore(object):
allow_none : If true, return None instead of failing if the SELECT allow_none : If true, return None instead of failing if the SELECT
statement returns no rows statement returns no rows
""" """
return self._simple_selectupdate_one( return self.runInteraction(
table, keyvalues, retcols=retcols, allow_none=allow_none desc,
self._simple_select_one_txn,
table, keyvalues, retcols, allow_none,
) )
def _simple_select_one_onecol(self, table, keyvalues, retcol, def _simple_select_one_onecol(self, table, keyvalues, retcol,
@ -523,7 +525,7 @@ class SQLBaseStore(object):
return self.cursor_to_dict(txn) return self.cursor_to_dict(txn)
def _simple_update_one(self, table, keyvalues, updatevalues, def _simple_update_one(self, table, keyvalues, updatevalues,
retcols=None): desc="_simple_update_one"):
"""Executes an UPDATE query on the named table, setting new values for """Executes an UPDATE query on the named table, setting new values for
columns in a row matching the key values. columns in a row matching the key values.
@ -541,51 +543,70 @@ class SQLBaseStore(object):
get-and-set. This can be used to implement compare-and-set by putting get-and-set. This can be used to implement compare-and-set by putting
the update column in the 'keyvalues' dict as well. the update column in the 'keyvalues' dict as well.
""" """
return self._simple_selectupdate_one(table, keyvalues, updatevalues, return self.runInteraction(
retcols=retcols) desc,
self._simple_update_one_txn,
table, keyvalues, updatevalues,
)
def _simple_update_one_txn(self, txn, table, keyvalues, updatevalues):
update_sql = "UPDATE %s SET %s WHERE %s" % (
table,
", ".join("%s = ?" % (k,) for k in updatevalues),
" AND ".join("%s = ?" % (k,) for k in keyvalues)
)
txn.execute(
update_sql,
updatevalues.values() + keyvalues.values()
)
if txn.rowcount == 0:
raise StoreError(404, "No row found")
if txn.rowcount > 1:
raise StoreError(500, "More than one row matched")
def _simple_select_one_txn(self, txn, table, keyvalues, retcols,
allow_none=False):
select_sql = "SELECT %s FROM %s WHERE %s ORDER BY rowid asc" % (
", ".join(retcols),
table,
" AND ".join("%s = ?" % (k) for k in keyvalues)
)
txn.execute(select_sql, keyvalues.values())
row = txn.fetchone()
if not row:
if allow_none:
return None
raise StoreError(404, "No row found")
if txn.rowcount > 1:
raise StoreError(500, "More than one row matched")
return dict(zip(retcols, row))
def _simple_selectupdate_one(self, table, keyvalues, updatevalues=None, def _simple_selectupdate_one(self, table, keyvalues, updatevalues=None,
retcols=None, allow_none=False): retcols=None, allow_none=False):
""" Combined SELECT then UPDATE.""" """ Combined SELECT then UPDATE."""
if retcols:
select_sql = "SELECT %s FROM %s WHERE %s ORDER BY rowid asc" % (
", ".join(retcols),
table,
" AND ".join("%s = ?" % (k) for k in keyvalues)
)
if updatevalues:
update_sql = "UPDATE %s SET %s WHERE %s" % (
table,
", ".join("%s = ?" % (k,) for k in updatevalues),
" AND ".join("%s = ?" % (k,) for k in keyvalues)
)
def func(txn): def func(txn):
ret = None ret = None
if retcols: if retcols:
txn.execute(select_sql, keyvalues.values()) ret = self._simple_select_one_txn(
txn,
row = txn.fetchone() table=table,
if not row: keyvalues=keyvalues,
if allow_none: retcols=retcols,
return None allow_none=allow_none,
raise StoreError(404, "No row found")
if txn.rowcount > 1:
raise StoreError(500, "More than one row matched")
ret = dict(zip(retcols, row))
if updatevalues:
txn.execute(
update_sql,
updatevalues.values() + keyvalues.values()
) )
if txn.rowcount == 0: if updatevalues:
raise StoreError(404, "No row found") self._simple_update_one_txn(
if txn.rowcount > 1: txn,
raise StoreError(500, "More than one row matched") table=table,
keyvalues=keyvalues,
updatevalues=updatevalues,
)
return ret return ret
return self.runInteraction("_simple_selectupdate_one", func) return self.runInteraction("_simple_selectupdate_one", func)

View file

@ -45,7 +45,6 @@ class PresenceStore(SQLBaseStore):
updatevalues={"state": new_state["state"], updatevalues={"state": new_state["state"],
"status_msg": new_state["status_msg"], "status_msg": new_state["status_msg"],
"mtime": self._clock.time_msec()}, "mtime": self._clock.time_msec()},
retcols=["state"],
) )
def allow_presence_visible(self, observed_localpart, observer_userid): def allow_presence_visible(self, observed_localpart, observer_userid):

View file

@ -180,7 +180,7 @@ class SQLBaseStoreTestCase(unittest.TestCase):
self.mock_txn.rowcount = 1 self.mock_txn.rowcount = 1
self.mock_txn.fetchone.return_value = ("Old Value",) self.mock_txn.fetchone.return_value = ("Old Value",)
ret = yield self.datastore._simple_update_one( ret = yield self.datastore._simple_selectupdate_one(
table="tablename", table="tablename",
keyvalues={"keycol": "TheKey"}, keyvalues={"keycol": "TheKey"},
updatevalues={"columname": "New Value"}, updatevalues={"columname": "New Value"},

View file

@ -44,7 +44,7 @@ class RoomStoreTestCase(unittest.TestCase):
@defer.inlineCallbacks @defer.inlineCallbacks
def test_get_room(self): def test_get_room(self):
self.assertObjectHasAttributes( self.assertDictContainsSubset(
{"room_id": self.room.to_string(), {"room_id": self.room.to_string(),
"creator": self.u_creator.to_string(), "creator": self.u_creator.to_string(),
"is_public": True}, "is_public": True},