Skip to content

Commit

Permalink
Merge branch 'release/0.1.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
prawn-cake committed Sep 19, 2015
2 parents 503b6e7 + 9d60bd3 commit 9368e0b
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 94 deletions.
4 changes: 2 additions & 2 deletions .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[bumpversion]
current_version = 0.1.0
tag = True
current_version = 0.1.1
tag = False
tag_name = {new_version}
commit = True

Expand Down
5 changes: 2 additions & 3 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ exclude_lines =

# Don't complain about missing debug-only code:
def __repr__
def __unicode__
if self\.debug

# Don't complain if tests don't hit defensive assertion code:
Expand All @@ -23,9 +22,9 @@ exclude_lines =
include =
pgclient/*
omit =
pgclient/tests.py
pgclient/system_test/*

ignore_errors = True

[html]
directory = coverage_html_report
directory = coverage_html_report
2 changes: 1 addition & 1 deletion pgclient/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-

__version__ = '0.1.0'
__version__ = '0.1.1'
26 changes: 18 additions & 8 deletions pgclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,48 @@ def __init__(self, dsn=None, database=None, user=None, password=None,
self.dsn = dsn

# Pass connection params as is
conn_params = dict(dsn=dsn, database=database, user=user,
password=password, host=host, port=port)
conn_params = dict(dsn=dsn,
database=database,
user=user,
password=password,
host=host,
port=port)
if pool_size < 1:
raise ValueError('Wrong pool_size value. Must be >= 1. '
'Current: {}'.format(pool_size))
# Init thread-safe connection pool
self._pool = pgpool.ThreadedConnectionPool(
minconn=1, maxconn=pool_size, **conn_params)

@property
def _connection(self):
"""Acquire pool connection property
def acquire_conn(self):
"""Get new pool connection
:return: postgresql connection instance
:return: psycopg2 connection object
"""
return self._pool.getconn()

def release_conn(self, conn):
"""Release connection to a pool
:param conn: psycopg2 connection object
"""
self._pool.putconn(conn)

@contextmanager
def _get_cursor(self, cursor_factory=None):
"""Get connection cursor context manager
:param cursor_factory: pg_extras.* cursor factory class
"""
conn = self._connection
conn = self.acquire_conn()
try:
yield conn.cursor(cursor_factory=cursor_factory)
conn.commit()
except psycopg2.DatabaseError as err:
conn.rollback()
raise psycopg2.DatabaseError(err.message)
finally:
self._pool.putconn(conn)
self.release_conn(conn)

@property
def cursor(self):
Expand Down
43 changes: 35 additions & 8 deletions pgclient/system_test/system_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import os.path as op
import psycopg2
from psycopg2.pool import PoolError

sys.path.append(
op.abspath(op.dirname(__file__)) + '/../'
Expand All @@ -24,12 +25,14 @@ class PostgresClientSystemTest(unittest.TestCase):
DB_NAME = 'test'
DB_PORT = os.environ.get('POSTGRES_PORT', 5432)
TABLE_NAME = 'users'
POOL_SIZE = 3

def setUp(self):
dsn = 'user={} password={} dbname={} host=localhost port={}'.format(
self.DB_USER, self.DB_PASSWORD, self.DB_NAME, self.DB_PORT)
self.dsn = 'user={} password={} dbname={} host=localhost port={}'\
.format(self.DB_USER, self.DB_PASSWORD, self.DB_NAME, self.DB_PORT)
try:
self.pg_client = PostgresClient(dsn=dsn, pool_size=10)
self.pg_client = PostgresClient(dsn=self.dsn,
pool_size=self.POOL_SIZE)
except psycopg2.OperationalError as err:
print('Check that postgres docker container is started. '
'Check README for more information')
Expand Down Expand Up @@ -65,6 +68,12 @@ def _drop_table(self):
def tearDown(self):
self._drop_table()

def test_create_with_wrong_pool_value(self):
with self.assertRaises(ValueError) as err:
pg_client = PostgresClient(dsn=self.dsn, pool_size=0)
self.assertIsNone(pg_client)
self.assertIn('Wrong pool_size value', err)

def test_cursor(self):
with self.pg_client.cursor as cursor:
cursor.execute('SELECT * FROM users')
Expand Down Expand Up @@ -98,10 +107,28 @@ def test_success_transaction(self):
self.assertEqual(len(result_set), 101)

def test_rollback_transaction(self):
# Insert null username must cause an error
with self.pg_client.cursor as transaction:
with self.assertRaises(psycopg2.DatabaseError) as err:
# Inserting null username value must raise an error
with self.assertRaises(psycopg2.DatabaseError) as err:
with self.pg_client.cursor as transaction:
transaction.execute(
"INSERT INTO {} (username) VALUES (%s)".format(self.TABLE_NAME),
"INSERT INTO {} (username) VALUES (%s)".format(
self.TABLE_NAME),
(None, ))
self.assertIn('null value in column', err.exception.message)
print('abc')
self.assertIn('null value in column', err.exception.message)
print('transaction finished')

def test_connection_pool_overflow(self):
# Consume all connection to check overflow case
connections = []
for i in range(self.POOL_SIZE):
connections.append(self.pg_client.acquire_conn())

with self.assertRaises(PoolError) as err:
with self.pg_client.cursor as cursor:
self.assertIsNone(cursor)
self.assertIn('connection pool exhausted', err)

# Release all connections back to pool
for conn in connections:
self.pg_client.release_conn(conn)
5 changes: 0 additions & 5 deletions pgclient/tests/__init__.py

This file was deleted.

66 changes: 0 additions & 66 deletions pgclient/tests/test_client.py

This file was deleted.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='pgclient',
version='0.1.0',
version='0.1.1',
packages=['pgclient'],
url='https://github.com/prawn-cake/pgclient',
license='MIT',
Expand Down

0 comments on commit 9368e0b

Please sign in to comment.