Permalink
Browse files

Fix the problem that query will be ignored after an invalid query

  • Loading branch information...
naoina committed Feb 7, 2012
1 parent e224ecd commit 5b4a6b738b9bbe77b460d2aacedb889f01ac2a88
Showing with 109 additions and 21 deletions.
  1. +1 −1 _groonga.c
  2. +35 −11 pyroonga/groonga.py
  3. +5 −1 pyroonga/tests/__init__.py
  4. +59 −7 pyroonga/tests/test_groonga.py
  5. +9 −1 setup.py
View
@@ -318,7 +318,7 @@ static PyTypeObject GroongaContextType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"groonga context objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
View
@@ -49,23 +49,28 @@
}
-def raise_if_notsuccess(rc):
- if rc != _groonga.SUCCESS:
- raise GroongaError(rc)
+class Context(_groonga.Context):
+ def __init__(self, encoding):
+ """Construct a Context of groonga
+
+ :param encoding: Encoding of groonga. Supported value is 'utf-8',
+ 'euc-jp', 'sjis', 'latin1', and 'koi8-r'.
+ """
+ super(Context, self).__init__(flags=0)
+ encodename = encoding.replace('_', '-')
+ enc = encodings.get(encodename, DEFAULT_ENCODING)
+ self.set_encoding(enc)
class Groonga(object):
def __init__(self, encoding='utf-8'):
"""Construct a Groonga.
- :param encoding: Encoding of groonga. Suppoted value is 'utf-8',
+ :param encoding: Encoding of groonga. Supported value is 'utf-8',
'euc-jp', 'sjis', 'latin1' and 'koi8-r'. Default is 'utf-8'.
"""
- ctx = _groonga.Context(flags=0)
- encodename = encoding.replace('_', '-')
- enc = encodings.get(encodename, DEFAULT_ENCODING)
- ctx.set_encoding(enc)
- self._ctx = ctx
+ self._ctx = Context(encoding)
+ self.encoding = encoding
self.connected = False
self.host = self.port = None
@@ -76,11 +81,21 @@ def connect(self, host, port):
:param port: Integer of server port number.
"""
rc = self._ctx.connect(host, port, flags=0)
- raise_if_notsuccess(rc)
+ self._raise_if_notsuccess(rc)
self.connected = True
self.host = host
self.port = port
+ def reconnect(self):
+ """Reconnect to the groonga server
+ """
+ if self.host is None or self.port is None:
+ raise GroongaError(_groonga.SOCKET_IS_NOT_CONNECTED)
+ del self._ctx
+ self._ctx = Context(self.encoding)
+ self.connect(self.host, self.port)
+ self.connected = True
+
def query(self, qstr):
"""Send and receive the query string to the groonga server
@@ -91,5 +106,14 @@ def query(self, qstr):
raise GroongaError(_groonga.SOCKET_IS_NOT_CONNECTED)
self._ctx.send(qstr, flags=0)
rc, result, flags = self._ctx.recv()
- raise_if_notsuccess(rc)
+ try:
+ self._raise_if_notsuccess(rc)
+ except GroongaError:
+ self.reconnect()
+ raise
return result
+
+ def _raise_if_notsuccess(self, rc):
+ if rc != _groonga.SUCCESS:
+ self.connected = False
+ raise GroongaError(rc)
@@ -32,7 +32,11 @@
import os
import shutil
-import unittest
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
from subprocess import Popen, PIPE
from signal import SIGTERM
@@ -30,7 +30,10 @@
__all__ = [
]
-import unittest
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
import _groonga
@@ -43,25 +46,37 @@ class TestGroongaWithNotConnected(unittest.TestCase):
def test___init__(self):
# test with default encoding
grn = Groonga()
- self.assertEqual(grn._ctx.get_encoding(), _groonga.ENC_UTF8)
+ self.assertEqual(grn.encoding, 'utf-8')
self.assertFalse(grn.connected)
+ self.assertIsNone(grn.host)
+ self.assertIsNone(grn.port)
# test with all encodings
grn = Groonga(encoding='utf-8')
- self.assertEqual(grn._ctx.get_encoding(), _groonga.ENC_UTF8)
+ self.assertEqual(grn.encoding, 'utf-8')
self.assertFalse(grn.connected)
+ self.assertIsNone(grn.host)
+ self.assertIsNone(grn.port)
grn = Groonga(encoding='euc-jp')
- self.assertEqual(grn._ctx.get_encoding(), _groonga.ENC_EUC_JP)
+ self.assertEqual(grn.encoding, 'euc-jp')
self.assertFalse(grn.connected)
+ self.assertIsNone(grn.host)
+ self.assertIsNone(grn.port)
grn = Groonga(encoding='sjis')
- self.assertEqual(grn._ctx.get_encoding(), _groonga.ENC_SJIS)
+ self.assertEqual(grn.encoding, 'sjis')
self.assertFalse(grn.connected)
+ self.assertIsNone(grn.host)
+ self.assertIsNone(grn.port)
grn = Groonga(encoding='latin1')
- self.assertEqual(grn._ctx.get_encoding(), _groonga.ENC_LATIN1)
+ self.assertEqual(grn.encoding, 'latin1')
self.assertFalse(grn.connected)
+ self.assertIsNone(grn.host)
+ self.assertIsNone(grn.port)
grn = Groonga(encoding='koi8-r')
- self.assertEqual(grn._ctx.get_encoding(), _groonga.ENC_KOI8R)
+ self.assertEqual(grn.encoding, 'koi8-r')
self.assertFalse(grn.connected)
+ self.assertIsNone(grn.host)
+ self.assertIsNone(grn.port)
def test_connect_not_running_server(self):
grn = Groonga()
@@ -70,12 +85,30 @@ def test_connect_not_running_server(self):
class TestGroonga(GroongaTestBase):
def test_connect(self):
+ # test the connect
grn = Groonga()
grn.connect(host='localhost', port=10041)
self.assertTrue(grn.connected)
self.assertEqual(grn.host, 'localhost')
self.assertEqual(grn.port, 10041)
+ def test_reconnect(self):
+ # test the reconnect with not connected
+ grn = Groonga()
+ ctx = grn._ctx
+ self.assertRaises(GroongaError, grn.reconnect)
+ self.assertIs(grn._ctx, ctx)
+ self.assertFalse(grn.connected)
+
+ # test the reconnect
+ grn = Groonga()
+ ctx = grn._ctx
+ grn.host = 'localhost'
+ grn.port = 10041
+ grn.reconnect()
+ self.assertIsNot(grn._ctx, ctx)
+ self.assertTrue(grn.connected)
+
def test_query(self):
# test with not connected
grn = Groonga()
@@ -94,6 +127,25 @@ def test_query(self):
["path","ShortText"],["flags","ShortText"],["domain","ShortText"],\
["range","ShortText"]]]''')
+ # test the query with after the query of invalid command
+ grn = Groonga()
+ grn.connect('localhost', 10041)
+ self.assertRaises(GroongaError, grn.query, 'unknown command')
+ result = grn.query('table_list')
+ self.assertEqual(result, '''[[["id","UInt32"],["name","ShortText"],\
+["path","ShortText"],["flags","ShortText"],["domain","ShortText"],\
+["range","ShortText"]]]''')
+
+ def test__raise_if_notsuccess(self):
+ grn = Groonga()
+ try:
+ grn._raise_if_notsuccess(_groonga.SUCCESS)
+ except GroongaError:
+ self.fail("GroongaError has not been raised")
+ from pyroonga.exceptions import error_messages
+ for rc in [rc for rc in error_messages if rc != _groonga.SUCCESS]:
+ self.assertRaises(GroongaError, grn._raise_if_notsuccess, rc)
+
def main():
unittest.main()
View
@@ -1,3 +1,5 @@
+import sys
+
from setuptools import setup, find_packages, Extension
from subprocess import Popen, PIPE
@@ -14,6 +16,12 @@ def pkgconfig(*packages, **kw):
version = '0.1'
+setup_requires = [
+ 'nose',
+ ]
+if sys.version_info[:2] < (2, 7):
+ setup_requires.append('unittest2')
+
setup(name='pyroonga',
version=version,
description="Python interface for groonga",
@@ -37,7 +45,7 @@ def pkgconfig(*packages, **kw):
install_requires=[
# -*- Extra requirements: -*-
],
- setup_requires=['nose'],
+ setup_requires=setup_requires,
test_suite='nose.collector',
ext_modules=[Extension(
'_groonga',

0 comments on commit 5b4a6b7

Please sign in to comment.