Skip to content

Commit 2808682

Browse files
uckogouriano
authored andcommitted
python_ncbi_dbapi.connect: Make usage more flexible. JIRA: CXX-13698.
- Allow all arguments to be passed via keywords, using PEP 249 names where applicable. -- Take the server specification via dsn rather than host; that's a bit of a stretch, but PEP 249 prioritizes accepting the former name, and its value can at least include a port number suffix or at this point even be a configuration-file-defined alias. -- Leave all historically mandatory arguments mandatory for now, including in particular our driver and type extensions. - Belatedly allow specifying both support_standard_interface and extra, which must appear in that order when passing both positionally. (Otherwise, the seventh positional argument will continue to do double duty based on its type.) git-svn-id: https://anonsvn.ncbi.nlm.nih.gov/repos/v1/trunk/c++@103028 78c7ea69-d796-4a43-9a09-de51944f1b03
1 parent 930a4ea commit 2808682

File tree

2 files changed

+76
-50
lines changed

2 files changed

+76
-50
lines changed

src/dbapi/lang_bind/python/python_ncbi_dbapi.cpp

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,14 +1210,15 @@ CConnection::CConnection(
12101210
const string& db_name,
12111211
const string& user_name,
12121212
const string& user_pswd,
1213-
const pythonpp::CObject& extra_params
1213+
bool support_standard_interface,
1214+
const pythonpp::CDict& extra_params
12141215
)
12151216
: m_DefParams(server_name, user_name, user_pswd)
12161217
, m_Params(m_DefParams)
12171218
, m_DM(CDriverManager::GetInstance())
12181219
, m_DS(NULL)
12191220
, m_DefTransaction( NULL )
1220-
, m_ConnectionMode(eSimpleMode)
1221+
, m_ConnectionMode(support_standard_interface ? eStandardMode : eSimpleMode)
12211222
{
12221223
try {
12231224
m_DefParams.SetDriverName(driver_name);
@@ -1239,30 +1240,19 @@ CConnection::CConnection(
12391240
m_DefParams.SetEncoding(eEncoding_UTF8);
12401241
}
12411242

1242-
1243-
// Handle extra-parameters ...
1244-
if (!pythonpp::CNone::HasSameType(extra_params)) {
1245-
if (pythonpp::CDict::HasSameType(extra_params)) {
1246-
const pythonpp::CDict dict = extra_params;
1247-
1248-
// Iterate over a dict.
1249-
pythonpp::py_ssize_t i = 0;
1250-
PyObject* key;
1251-
PyObject* value;
1252-
while ( PyDict_Next(dict, &i, &key, &value) ) {
1253-
// Refer to borrowed references in key and value.
1254-
const string param_name = pythonpp::CString(key);
1255-
const string param_value = pythonpp::CString(value);
1256-
1257-
m_DefParams.SetParam(param_name, param_value);
1258-
}
1259-
} else if (pythonpp::CBool::HasSameType(extra_params)) {
1260-
bool support_standard_interface = pythonpp::CBool(extra_params);
1261-
m_ConnectionMode = (support_standard_interface ? eStandardMode : eSimpleMode);
1262-
} else {
1263-
throw CNotSupportedError("Expected dictionary as an argument.");
1243+
{{
1244+
// Iterate over a dict.
1245+
pythonpp::py_ssize_t i = 0;
1246+
PyObject* key;
1247+
PyObject* value;
1248+
while ( PyDict_Next(extra_params, &i, &key, &value) ) {
1249+
// Refer to borrowed references in key and value.
1250+
const string param_name = pythonpp::CString(key);
1251+
const string param_value = pythonpp::CString(value);
1252+
1253+
m_DefParams.SetParam(param_name, param_value);
12641254
}
1265-
}
1255+
}}
12661256

12671257
pythonpp::CThreadingGuard ALLOW_OTHER_THREADS;
12681258
// Make a datasource ...
@@ -3862,37 +3852,70 @@ ReleaseGlobalLock(PyObject *self, PyObject *args)
38623852
}
38633853

38643854
//////////////////////////////////////////////////////////////////////////////
3865-
// connect(driver_name, db_type, db_name, user_name, user_pswd)
3855+
// connect(driver_name, db_type, server_name, db_name, user_name, user_pswd)
38663856
static
38673857
PyObject*
3868-
Connect(PyObject *self, PyObject *args)
3858+
Connect(PyObject *self, PyObject *args, PyObject *kwargs)
38693859
{
38703860
CConnection* conn = NULL;
38713861

38723862
try {
38733863
// Debugging ...
38743864
// throw python::CDatabaseError("oops ...");
38753865
// throw python::CDatabaseError("oops ...", 200, "Blah-blah-blah");
3876-
3877-
string driver_name;
3878-
string db_type;
3879-
string server_name;
3880-
string db_name;
3881-
string user_name;
3882-
string user_pswd;
3883-
pythonpp::CObject extra_params = pythonpp::CNone();
3866+
pythonpp::CString driver_name;
3867+
pythonpp::CString db_type;
3868+
pythonpp::CString server_name;
3869+
pythonpp::CString db_name;
3870+
pythonpp::CString user_name;
3871+
pythonpp::CString user_pswd;
3872+
pythonpp::CBool support_standard_interface(false);
3873+
pythonpp::CDict extra_params;
38843874

38853875
try {
3886-
const pythonpp::CTuple func_args(args);
3876+
static const char * const kwnames[] = {
3877+
"driver", "type", "dsn", "database", "user", "password",
3878+
"support_standard_interface", "extra"
3879+
};
3880+
PyObject *py_driver_name;
3881+
PyObject *py_db_type;
3882+
PyObject *py_server_name;
3883+
PyObject *py_db_name;
3884+
PyObject *py_user_name;
3885+
PyObject *py_user_pswd;
3886+
PyObject *py_support_standard_interface = nullptr;
3887+
PyObject *py_extra_params = nullptr;
3888+
3889+
int status = PyArg_ParseTupleAndKeywords
3890+
(args, kwargs, "UUUUUU|OO:connect", (char**) kwnames,
3891+
&py_driver_name, &py_db_type, &py_server_name, &py_db_name,
3892+
&py_user_name, &py_user_pswd, &py_support_standard_interface,
3893+
&py_extra_params);
3894+
if ( !status ) {
3895+
pythonpp::CError::Check();
3896+
}
38873897

3888-
driver_name = pythonpp::CString(func_args[0]);
3889-
db_type = pythonpp::CString(func_args[1]);
3890-
server_name = pythonpp::CString(func_args[2]);
3891-
db_name = pythonpp::CString(func_args[3]);
3892-
user_name = pythonpp::CString(func_args[4]);
3893-
user_pswd = pythonpp::CString(func_args[5]);
3894-
if ( func_args.size() > 6 ) {
3895-
extra_params = func_args[6];
3898+
driver_name = py_driver_name;
3899+
db_type = py_db_type;
3900+
server_name = py_server_name;
3901+
db_name = py_db_name;
3902+
user_name = py_user_name;
3903+
user_pswd = py_user_pswd;
3904+
if (py_extra_params != nullptr) {
3905+
extra_params = py_extra_params;
3906+
if (py_support_standard_interface != nullptr) {
3907+
support_standard_interface = py_support_standard_interface;
3908+
}
3909+
} else if (py_support_standard_interface != nullptr) {
3910+
// For historical reasons, does double duty, but only
3911+
// when passed positionally.
3912+
const pythonpp::CTuple func_args(args);
3913+
if (func_args.size() > 6
3914+
&& pythonpp::CDict::HasSameType(py_support_standard_interface)) {
3915+
extra_params = py_support_standard_interface;
3916+
} else {
3917+
support_standard_interface = py_support_standard_interface;
3918+
}
38963919
}
38973920
} catch (const pythonpp::CError&) {
38983921
throw CProgrammingError("Invalid parameters within 'connect' function");
@@ -3905,6 +3928,7 @@ Connect(PyObject *self, PyObject *args)
39053928
db_name,
39063929
user_name,
39073930
user_pswd,
3931+
support_standard_interface,
39083932
extra_params
39093933
);
39103934
}
@@ -4247,11 +4271,12 @@ static struct PyMethodDef python_ncbi_dbapi_methods[] = {
42474271
"NOTE: This is not a part of the Python Database API Specification "
42484272
"v2.0."
42494273
},
4250-
{(char*)"connect", (PyCFunction) python::Connect, METH_VARARGS, (char*)
4251-
"connect(driver_name, db_type, server_name, database_name, userid, password,"
4252-
"[extra/use_std_interface]) "
4253-
"-- connect to the "
4254-
"driver_name; db_type; server_name; database_name; userid; password;"
4274+
{(char*)"connect", (PyCFunction) python::Connect,
4275+
METH_VARARGS | METH_KEYWORDS, (char*)
4276+
"connect([driver=]driver_name, [type=]db_type, [dsn=]server_name,"
4277+
" [database=]database_name, [user=]userid, [password=]password,"
4278+
" [[support_standard_interface=]support_standard_interface],"
4279+
" [[extra=]extra]) -- connect with the specified parameters"
42554280
},
42564281
{(char*)"set_logger", (PyCFunction) python::SetLogger, METH_VARARGS,
42574282
(char*)"set_logger(logger) "

src/dbapi/lang_bind/python/python_ncbi_dbapi.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ class CConnection : public pythonpp::CExtObject<CConnection>
678678
const string& db_name,
679679
const string& user_name,
680680
const string& user_pswd,
681-
const pythonpp::CObject& extra_params
681+
bool support_standard_interface,
682+
const pythonpp::CDict& extra_params
682683
);
683684
~CConnection(void);
684685

0 commit comments

Comments
 (0)