Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated sqla to handle conflicting keys when inserting.

  • Loading branch information...
commit e98075aa42f10a9f8c3959e878cbeffea2a8da19 1 parent c9eba8b
@mmerickel authored
View
11 anykeystore/backends/sqla.py
@@ -81,14 +81,21 @@ def retrieve(self, key):
c.close()
raise KeyError
+ def _insert_or_replace(self, c, key, value, expires):
+ try:
+ c.execute(
+ self.table.insert(), key=key, value=value, expires=expires)
+ except self.backend_api.exc.IntegrityError:
+ c.execute(
+ self.table.update(), key=key, value=value, expires=expires)
+
def store(self, key, value, expires=None):
expiration = None
if expires is not None:
expiration = datetime.utcnow() + coerce_timedelta(expires)
c = self._get_conn()
try:
- c.execute(
- self.table.insert(), key=key, value=value, expires=expiration)
+ self._insert_or_replace(c, key, value, expiration)
finally:
c.close()
View
66 anykeystore/tests/test_backends/test_sqla.py
@@ -1,5 +1,5 @@
import unittest2 as unittest
-from mock import MagicMock
+from mock import MagicMock, patch
class TestSQLStore(unittest.TestCase):
@@ -7,28 +7,70 @@ def _getTargetClass(self):
from anykeystore.backends.sqla import SQLStore
return SQLStore
+ def _makeApi(self):
+ api = MagicMock(spec=[
+ 'engine_from_config', 'MetaData',
+ 'select', 'insert', 'delete'])
+ return api
+
def test_init_with_table(self):
cls = self._getTargetClass()
- api = MagicMock(spec=['engine_from_config'])
+ api = self._makeApi()
result = cls('myurl', table='foo', backend_api=api)
self.assertEqual(result.table, 'foo')
def test_init_with_table_name(self):
cls = self._getTargetClass()
- cls._make_table = MagicMock(return_value='some_table')
- api = MagicMock(spec=['engine_from_config', 'MetaData'])
+ api = self._makeApi()
api.MetaData.return_value = 'a_meta'
- result = cls(
- 'myurl', table_name='foo', backend_api=api)
+ with patch.object(cls, '_make_table') as _make_table:
+ _make_table.return_value = 'some_table'
+ result = cls(
+ 'myurl', table_name='foo', backend_api=api)
self.assertEqual(result.table, 'some_table')
- cls._make_table.assert_called_with('foo', 'a_meta')
+ _make_table.assert_called_with('foo', 'a_meta')
def test_init_with_table_name_and_metadata(self):
cls = self._getTargetClass()
- cls._make_table = MagicMock(return_value='some_table')
- api = MagicMock(spec=['engine_from_config', 'MetaData'])
+ api = self._makeApi()
api.MetaData.return_value = 'a_meta'
- result = cls(
- 'myurl', table_name='foo', metadata='b_meta', backend_api=api)
+ with patch.object(cls, '_make_table') as _make_table:
+ _make_table.return_value = 'some_table'
+ result = cls(
+ 'myurl', table_name='foo', metadata='b_meta', backend_api=api)
self.assertEqual(result.table, 'some_table')
- cls._make_table.assert_called_with('foo', 'b_meta')
+ _make_table.assert_called_with('foo', 'b_meta')
+
+ def test__get_conn(self):
+ cls = self._getTargetClass()
+ api = self._makeApi()
+ engine = MagicMock()
+ engine.connect.return_value = 'myconn'
+ api.engine_from_config.return_value = engine
+ table = MagicMock()
+ store = cls('myurl', table=table, backend_api=api)
+ result = store._get_conn()
+ self.assertEqual(result, 'myconn')
+ self.assertTrue(store._created)
+ self.assertEqual(table.create.call_count, 1)
+ self.assertEqual(engine.connect.call_count, 1)
+
+ result = store._get_conn()
+ self.assertEqual(result, 'myconn')
+ self.assertEqual(table.create.call_count, 1)
+ self.assertEqual(engine.connect.call_count, 2)
+
+ def test_retrieve(self):
+ cls = self._getTargetClass()
+ api = self._makeApi()
+ table = MagicMock()
+ store = cls('myurl', table=table, backend_api=api)
+ with patch.object(store, '_get_conn') as get_conn:
+ get_conn.return_value = conn = MagicMock()
+
+ conn.execute.return_value.fetchone.return_value = ('bar', None)
+ result = store.retrieve('foo')
+ self.assertEqual(result, 'bar')
+
+ conn.execute.return_value.fetchone.return_value = None
+ self.assertRaises(KeyError, store.retrieve, 'foo')
Please sign in to comment.
Something went wrong with that request. Please try again.