Skip to content

Commit

Permalink
[ADD] Support for get and create of sequences
Browse files Browse the repository at this point in the history
* Add `get_next_sequence` method to run stored proc on CP for next
  • Loading branch information
lasley committed Sep 12, 2016
1 parent 9b879f4 commit 24fc5ef
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
31 changes: 31 additions & 0 deletions carepoint/db/carepoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import imp
import operator
import urllib2
from sqlalchemy import text, bindparam
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.inspection import inspect
Expand Down Expand Up @@ -321,6 +322,36 @@ def get_pks(self, model_obj):
"""
return tuple(k.name for k in inspect(model_obj).primary_key)

def get_next_sequence(self, sequence_name):
""" It generates and returns the next int in sequence
Params:
sequence_name: ``str`` Name of the sequence in Carepoint DB
Return:
Integer to use as pk
"""
conn = self.dbs['cph'].connect()
trans = conn.begin()
try:
res = conn.execute(
text(
"SET NOCOUNT ON;"
"DECLARE @out int = 0;"
"EXEC CsGenerateIntId :seq_name, @out output;"
"SELECT @out;"
"SET NOCOUNT OFF;",
bindparams=[bindparam('seq_name')],
),
seq_name=sequence_name,
)
id_int = res.fetchall()[0][0]
trans.commit()
except:
trans.rollback()
raise
finally:
conn.close()
return id_int

def __getattr__(self, key):
""" Re-implement __getattr__ to use __getitem__ if attr not found """
try:
Expand Down
63 changes: 63 additions & 0 deletions carepoint/tests/db/test_carepoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
from carepoint import Carepoint


class EndTestException(Exception):
pass


class CarepointTest(unittest.TestCase):

MODEL_DIR = os.path.join(os.path.dirname(__file__), 'test_models')
Expand Down Expand Up @@ -223,6 +227,65 @@ def test_search_returns_response(self):
response = self.carepoint.read(model_obj, filters)
self.assertEqual(response, expect)

# Get Next Sequence
def test_get_next_sequence_connect(self):
""" It should establish connection to underlying DB """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
self.carepoint.get_next_sequence(None)
dbs['cph'].connect.assert_called_once_with()

def test_get_next_sequence_transaction(self):
""" It should create a new transaction """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
self.carepoint.get_next_sequence(None)
dbs['cph'].connect().begin.assert_called_once_with()

@mock.patch('carepoint.db.carepoint.text')
def test_get_next_sequence_execute(self, text):
""" It should execute stored procedure on connection """
expect = 'expect'
with mock.patch.object(self.carepoint, 'dbs') as dbs:
self.carepoint.get_next_sequence(expect)
dbs['cph'].connect().execute.assert_called_once_with(
text(), seq_name=expect,
)

def test_get_next_sequence_fetch(self):
""" It should return result of fetch """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
res = self.carepoint.get_next_sequence(None)
expect = dbs['cph'].connect().execute().fetchall()[0][0]
self.assertEqual(
expect, res,
)

def test_get_next_sequence_commit(self):
""" It should commit the transaction """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
self.carepoint.get_next_sequence(None)
dbs['cph'].connect().begin().commit.assert_called_once_with()

def test_get_next_sequence_transaction(self):
""" It should create a new transaction """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
self.carepoint.get_next_sequence(None)
dbs['cph'].connect().begin.assert_called_once_with()

def test_get_next_sequence_rollback(self):
""" It should rollback transaction and raise on error """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
conn = dbs['cph'].connect()
conn.execute.side_effect = EndTestException
with self.assertRaises(EndTestException):
self.carepoint.get_next_sequence(None)
conn.begin().rollback.assert_called_once_with()

def test_get_next_sequence_close(self):
""" It should close the connection """
with mock.patch.object(self.carepoint, 'dbs') as dbs:
self.carepoint.get_next_sequence(None)
dbs['cph'].connect().close.assert_called_once_with()

# Create
def test_create_calls__get_session_with_model_obj(self):
model_obj = self.__get_model_obj()
Expand Down

0 comments on commit 24fc5ef

Please sign in to comment.