mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-26 10:53:44 +03:00
Added unicode support to parse_dsn
Also added support for the argument as a keyword.
This commit is contained in:
parent
71d96293ab
commit
5afeee3613
|
@ -115,17 +115,21 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
#define psyco_parse_dsn_doc "parse_dsn(dsn) -> dict"
|
#define psyco_parse_dsn_doc "parse_dsn(dsn) -> dict"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_parse_dsn(PyObject *self, PyObject *args)
|
psyco_parse_dsn(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
char *dsn, *err = NULL;
|
char *err = NULL;
|
||||||
PQconninfoOption *options = NULL, *o;
|
PQconninfoOption *options = NULL, *o;
|
||||||
PyObject *res = NULL, *value;
|
PyObject *dict = NULL, *res = NULL, *dsn;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &dsn)) {
|
static char *kwlist[] = {"dsn", NULL};
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &dsn)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
options = PQconninfoParse(dsn, &err);
|
Py_INCREF(dsn); /* for ensure_bytes */
|
||||||
|
if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; }
|
||||||
|
|
||||||
|
options = PQconninfoParse(Bytes_AS_STRING(dsn), &err);
|
||||||
if (options == NULL) {
|
if (options == NULL) {
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
PyErr_Format(ProgrammingError, "error parsing the dsn: %s", err);
|
PyErr_Format(ProgrammingError, "error parsing the dsn: %s", err);
|
||||||
|
@ -133,31 +137,30 @@ psyco_parse_dsn(PyObject *self, PyObject *args)
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(OperationalError, "PQconninfoParse() failed");
|
PyErr_SetString(OperationalError, "PQconninfoParse() failed");
|
||||||
}
|
}
|
||||||
return NULL;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = PyDict_New();
|
if (!(dict = PyDict_New())) { goto exit; }
|
||||||
if (res != NULL) {
|
for (o = options; o->keyword != NULL; o++) {
|
||||||
for (o = options; o->keyword != NULL; o++) {
|
if (o->val != NULL) {
|
||||||
if (o->val != NULL) {
|
PyObject *value;
|
||||||
value = Text_FromUTF8(o->val);
|
if (!(value = Text_FromUTF8(o->val))) { goto exit; }
|
||||||
if (value == NULL) {
|
if (PyDict_SetItemString(dict, o->keyword, value) != 0) {
|
||||||
Py_DECREF(res);
|
|
||||||
res = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (PyDict_SetItemString(res, o->keyword, value) != 0) {
|
|
||||||
Py_DECREF(value);
|
|
||||||
Py_DECREF(res);
|
|
||||||
res = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
Py_DECREF(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PQconninfoFree(options);
|
/* success */
|
||||||
|
res = dict;
|
||||||
|
dict = NULL;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
PQconninfoFree(options); /* safe on null */
|
||||||
|
Py_XDECREF(dict);
|
||||||
|
Py_XDECREF(dsn);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -759,7 +762,7 @@ static PyMethodDef psycopgMethods[] = {
|
||||||
{"_connect", (PyCFunction)psyco_connect,
|
{"_connect", (PyCFunction)psyco_connect,
|
||||||
METH_VARARGS|METH_KEYWORDS, psyco_connect_doc},
|
METH_VARARGS|METH_KEYWORDS, psyco_connect_doc},
|
||||||
{"parse_dsn", (PyCFunction)psyco_parse_dsn,
|
{"parse_dsn", (PyCFunction)psyco_parse_dsn,
|
||||||
METH_VARARGS, psyco_parse_dsn_doc},
|
METH_VARARGS|METH_KEYWORDS, psyco_parse_dsn_doc},
|
||||||
{"adapt", (PyCFunction)psyco_microprotocols_adapt,
|
{"adapt", (PyCFunction)psyco_microprotocols_adapt,
|
||||||
METH_VARARGS, psyco_microprotocols_adapt_doc},
|
METH_VARARGS, psyco_microprotocols_adapt_doc},
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
# License for more details.
|
# License for more details.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
@ -341,7 +342,6 @@ class ParseDsnTestCase(ConnectingTestCase):
|
||||||
|
|
||||||
@skip_before_libpq(9, 2)
|
@skip_before_libpq(9, 2)
|
||||||
def test_parse_dsn_uri(self):
|
def test_parse_dsn_uri(self):
|
||||||
from psycopg2 import ProgrammingError
|
|
||||||
from psycopg2.extensions import parse_dsn
|
from psycopg2.extensions import parse_dsn
|
||||||
|
|
||||||
self.assertEqual(parse_dsn('postgresql://tester:secret@/test'),
|
self.assertEqual(parse_dsn('postgresql://tester:secret@/test'),
|
||||||
|
@ -351,8 +351,8 @@ class ParseDsnTestCase(ConnectingTestCase):
|
||||||
raised = False
|
raised = False
|
||||||
try:
|
try:
|
||||||
# extra '=' after port value
|
# extra '=' after port value
|
||||||
parse_dsn('postgresql://tester:secret@/test?port=1111=x')
|
parse_dsn(dsn='postgresql://tester:secret@/test?port=1111=x')
|
||||||
except ProgrammingError, e:
|
except psycopg2.ProgrammingError, e:
|
||||||
raised = True
|
raised = True
|
||||||
self.assertTrue(str(e).find('secret') < 0,
|
self.assertTrue(str(e).find('secret') < 0,
|
||||||
"URI was not exposed in error message")
|
"URI was not exposed in error message")
|
||||||
|
@ -360,6 +360,26 @@ class ParseDsnTestCase(ConnectingTestCase):
|
||||||
self.fail("unexpected error condition: " + repr(e))
|
self.fail("unexpected error condition: " + repr(e))
|
||||||
self.assertTrue(raised, "ProgrammingError raised due to invalid URI")
|
self.assertTrue(raised, "ProgrammingError raised due to invalid URI")
|
||||||
|
|
||||||
|
def test_unicode_value(self):
|
||||||
|
from psycopg2.extensions import parse_dsn
|
||||||
|
snowman = u"\u2603"
|
||||||
|
d = parse_dsn('dbname=' + snowman)
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
self.assertEqual(d['dbname'], snowman.encode('utf8'))
|
||||||
|
else:
|
||||||
|
self.assertEqual(d['dbname'], snowman)
|
||||||
|
|
||||||
|
def test_unicode_key(self):
|
||||||
|
from psycopg2.extensions import parse_dsn
|
||||||
|
snowman = u"\u2603"
|
||||||
|
self.assertRaises(psycopg2.ProgrammingError, parse_dsn,
|
||||||
|
snowman + '=' + snowman)
|
||||||
|
|
||||||
|
def test_bad_param(self):
|
||||||
|
from psycopg2.extensions import parse_dsn
|
||||||
|
self.assertRaises(TypeError, parse_dsn, None)
|
||||||
|
self.assertRaises(TypeError, parse_dsn, 42)
|
||||||
|
|
||||||
|
|
||||||
class IsolationLevelsTestCase(ConnectingTestCase):
|
class IsolationLevelsTestCase(ConnectingTestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user