summaryrefslogtreecommitdiff
path: root/psycopg/psycopgmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'psycopg/psycopgmodule.c')
-rw-r--r--psycopg/psycopgmodule.c176
1 files changed, 21 insertions, 155 deletions
diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c
index 2c7e3fb..3b2b060 100644
--- a/psycopg/psycopgmodule.c
+++ b/psycopg/psycopgmodule.c
@@ -75,177 +75,43 @@ HIDDEN PyObject *psyco_DescriptionType = NULL;
/** connect module-level function **/
#define psyco_connect_doc \
-"connect(dsn, ...) -- Create a new database connection.\n\n" \
-"This function supports two different but equivalent sets of arguments.\n" \
-"A single data source name or ``dsn`` string can be used to specify the\n" \
-"connection parameters, as follows::\n\n" \
-" psycopg2.connect(\"dbname=xxx user=xxx ...\")\n\n" \
-"If ``dsn`` is not provided it is possible to pass the parameters as\n" \
-"keyword arguments; e.g.::\n\n" \
-" psycopg2.connect(database='xxx', user='xxx', ...)\n\n" \
-"The full list of available parameters is:\n\n" \
-"- ``dbname`` -- database name (only in 'dsn')\n" \
-"- ``database`` -- database name (only as keyword argument)\n" \
-"- ``host`` -- host address (defaults to UNIX socket if not provided)\n" \
-"- ``port`` -- port number (defaults to 5432 if not provided)\n" \
-"- ``user`` -- user name used to authenticate\n" \
-"- ``password`` -- password used to authenticate\n" \
-"- ``sslmode`` -- SSL mode (see PostgreSQL documentation)\n\n" \
-"- ``async`` -- if the connection should provide asynchronous API\n\n" \
-"If the ``connection_factory`` keyword argument is not provided this\n" \
-"function always return an instance of the `connection` class.\n" \
-"Else the given sub-class of `extensions.connection` will be used to\n" \
-"instantiate the connection object.\n\n" \
-":return: New database connection\n" \
-":rtype: `extensions.connection`"
-
-static size_t
-_psyco_connect_fill_dsn(char *dsn, const char *kw, const char *v, size_t i)
-{
- strcpy(&dsn[i], kw); i += strlen(kw);
- strcpy(&dsn[i], v); i += strlen(v);
- return i;
-}
+"_connect(dsn, [connection_factory], [async]) -- New database connection.\n\n"
static PyObject *
psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
{
- PyObject *conn = NULL, *factory = NULL;
- PyObject *pyport = NULL;
-
- size_t idsn=-1;
- int iport=-1;
- const char *dsn_static = NULL;
- char *dsn_dynamic=NULL;
- const char *database=NULL, *user=NULL, *password=NULL;
- const char *host=NULL, *sslmode=NULL;
- char port[16];
+ PyObject *conn = NULL;
+ PyObject *factory = NULL;
+ const char *dsn = NULL;
int async = 0;
- static char *kwlist[] = {"dsn", "database", "host", "port",
- "user", "password", "sslmode",
- "connection_factory", "async", NULL};
+ static char *kwlist[] = {"dsn", "connection_factory", "async", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssOsssOi", kwlist,
- &dsn_static, &database, &host, &pyport,
- &user, &password, &sslmode,
- &factory, &async)) {
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|Oi", kwlist,
+ &dsn, &factory, &async)) {
return NULL;
}
-#if PY_MAJOR_VERSION < 3
- if (pyport && PyString_Check(pyport)) {
- PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10);
- if (!pyint) goto fail;
- /* Must use PyInt_AsLong rather than PyInt_AS_LONG, because
- * PyInt_FromString can return a PyLongObject: */
- iport = PyInt_AsLong(pyint);
- Py_DECREF(pyint);
- if (iport == -1 && PyErr_Occurred())
- goto fail;
- }
- else if (pyport && PyInt_Check(pyport)) {
- iport = PyInt_AsLong(pyport);
- if (iport == -1 && PyErr_Occurred())
- goto fail;
- }
-#else
- if (pyport && PyUnicode_Check(pyport)) {
- PyObject *pyint = PyObject_CallFunction((PyObject*)&PyLong_Type,
- "Oi", pyport, 10);
- if (!pyint) goto fail;
- iport = PyLong_AsLong(pyint);
- Py_DECREF(pyint);
- if (iport == -1 && PyErr_Occurred())
- goto fail;
- }
- else if (pyport && PyLong_Check(pyport)) {
- iport = PyLong_AsLong(pyport);
- if (iport == -1 && PyErr_Occurred())
- goto fail;
- }
-#endif
- else if (pyport != NULL) {
- PyErr_SetString(PyExc_TypeError, "port must be a string or int");
- goto fail;
- }
+ Dprintf("psyco_connect: dsn = '%s', async = %d", dsn, async);
- if (iport > 0)
- PyOS_snprintf(port, 16, "%d", iport);
-
- if (dsn_static == NULL) {
- size_t l = 46; /* len(" dbname= user= password= host= port= sslmode=\0") */
-
- if (database) l += strlen(database);
- if (host) l += strlen(host);
- if (iport > 0) l += strlen(port);
- if (user) l += strlen(user);
- if (password) l += strlen(password);
- if (sslmode) l += strlen(sslmode);
-
- dsn_dynamic = malloc(l*sizeof(char));
- if (dsn_dynamic == NULL) {
- PyErr_SetString(InterfaceError, "dynamic dsn allocation failed");
- goto fail;
- }
-
- idsn = 0;
- if (database)
- idsn = _psyco_connect_fill_dsn(dsn_dynamic, " dbname=", database, idsn);
- if (host)
- idsn = _psyco_connect_fill_dsn(dsn_dynamic, " host=", host, idsn);
- if (iport > 0)
- idsn = _psyco_connect_fill_dsn(dsn_dynamic, " port=", port, idsn);
- if (user)
- idsn = _psyco_connect_fill_dsn(dsn_dynamic, " user=", user, idsn);
- if (password)
- idsn = _psyco_connect_fill_dsn(dsn_dynamic, " password=", password, idsn);
- if (sslmode)
- idsn = _psyco_connect_fill_dsn(dsn_dynamic, " sslmode=", sslmode, idsn);
-
- if (idsn > 0) {
- dsn_dynamic[idsn] = '\0';
- memmove(dsn_dynamic, &dsn_dynamic[1], idsn);
- }
- else {
- PyErr_SetString(InterfaceError, "missing dsn and no parameters");
- goto fail;
- }
+ /* allocate connection, fill with errors and return it */
+ if (factory == NULL || factory == Py_None) {
+ factory = (PyObject *)&connectionType;
}
- {
- const char *dsn = (dsn_static != NULL ? dsn_static : dsn_dynamic);
- Dprintf("psyco_connect: dsn = '%s', async = %d", dsn, async);
-
- /* allocate connection, fill with errors and return it */
- if (factory == NULL) factory = (PyObject *)&connectionType;
- /* Here we are breaking the connection.__init__ interface defined
- * by psycopg2. So, if not requiring an async conn, avoid passing
- * the async parameter. */
- /* TODO: would it be possible to avoid an additional parameter
- * to the conn constructor? A subclass? (but it would require mixins
- * to further subclass) Another dsn parameter (but is not really
- * a connection parameter that can be configured) */
- if (!async) {
+ /* Here we are breaking the connection.__init__ interface defined
+ * by psycopg2. So, if not requiring an async conn, avoid passing
+ * the async parameter. */
+ /* TODO: would it be possible to avoid an additional parameter
+ * to the conn constructor? A subclass? (but it would require mixins
+ * to further subclass) Another dsn parameter (but is not really
+ * a connection parameter that can be configured) */
+ if (!async) {
conn = PyObject_CallFunction(factory, "s", dsn);
- } else {
+ } else {
conn = PyObject_CallFunction(factory, "si", dsn, async);
- }
}
- goto cleanup;
- fail:
- assert (PyErr_Occurred());
- if (conn != NULL) {
- Py_DECREF(conn);
- conn = NULL;
- }
- /* Fall through to cleanup: */
- cleanup:
- if (dsn_dynamic != NULL) {
- free(dsn_dynamic);
- }
-
return conn;
}
@@ -754,7 +620,7 @@ exit:
/** method table and module initialization **/
static PyMethodDef psycopgMethods[] = {
- {"connect", (PyCFunction)psyco_connect,
+ {"_connect", (PyCFunction)psyco_connect,
METH_VARARGS|METH_KEYWORDS, psyco_connect_doc},
{"adapt", (PyCFunction)psyco_microprotocols_adapt,
METH_VARARGS, psyco_microprotocols_adapt_doc},