summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-08-07 15:23:11 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-08-07 15:23:11 -0400
commit819ec8e13f03297a7af2fb5d7db5f742a5a1357d (patch)
treece28705537cd3ad1a8125d2557a383c26cee63ac /lib/sqlalchemy
parentc13d4f613faa0590db713c4491781012163bc5f0 (diff)
downloadsqlalchemy-819ec8e13f03297a7af2fb5d7db5f742a5a1357d.tar.gz
- add new C extension "utils", so far includes distill_params
- repair test_processors which wasn't hitting the python functions - add another suite to test_processors that does distill_params
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/cextension/processors.c1
-rw-r--r--lib/sqlalchemy/cextension/resultproxy.c1
-rw-r--r--lib/sqlalchemy/cextension/utils.c189
-rw-r--r--lib/sqlalchemy/engine/util.py88
-rw-r--r--lib/sqlalchemy/processors.py5
5 files changed, 242 insertions, 42 deletions
diff --git a/lib/sqlalchemy/cextension/processors.c b/lib/sqlalchemy/cextension/processors.c
index 427db5d8e..c261142a7 100644
--- a/lib/sqlalchemy/cextension/processors.c
+++ b/lib/sqlalchemy/cextension/processors.c
@@ -1,5 +1,6 @@
/*
processors.c
+Copyright (C) 2010-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com
This module is part of SQLAlchemy and is released under
diff --git a/lib/sqlalchemy/cextension/resultproxy.c b/lib/sqlalchemy/cextension/resultproxy.c
index ca3a8f40b..8c89baa25 100644
--- a/lib/sqlalchemy/cextension/resultproxy.c
+++ b/lib/sqlalchemy/cextension/resultproxy.c
@@ -1,5 +1,6 @@
/*
resultproxy.c
+Copyright (C) 2010-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com
This module is part of SQLAlchemy and is released under
diff --git a/lib/sqlalchemy/cextension/utils.c b/lib/sqlalchemy/cextension/utils.c
new file mode 100644
index 000000000..8edd5d66c
--- /dev/null
+++ b/lib/sqlalchemy/cextension/utils.c
@@ -0,0 +1,189 @@
+/*
+utils.c
+Copyright (C) 2012 the SQLAlchemy authors and contributors <see AUTHORS file>
+
+This module is part of SQLAlchemy and is released under
+the MIT License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+#include <Python.h>
+
+/*
+ Given arguments from the calling form *multiparams, **params,
+ return a list of bind parameter structures, usually a list of
+ dictionaries.
+
+ In the case of 'raw' execution which accepts positional parameters,
+ it may be a list of tuples or lists.
+
+ */
+static PyObject *
+distill_params(PyObject *self, PyObject *args)
+{
+ PyObject *multiparams, *params;
+ PyObject *enclosing_list, *double_enclosing_list;
+ PyObject *zero_element, *zero_element_item;
+ Py_ssize_t multiparam_size, zero_element_length;
+
+ if (!PyArg_UnpackTuple(args, "_distill_params", 2, 2, &multiparams, &params)) {
+ return NULL;
+ }
+
+ if (multiparams != Py_None) {
+ multiparam_size = PyTuple_Size(multiparams);
+ if (multiparam_size < 0) {
+ return NULL;
+ }
+ }
+
+ if (multiparams == Py_None || multiparam_size == 0) {
+ if (params != Py_None && PyDict_Size(params) != 0) {
+ enclosing_list = PyList_New(1);
+ if (enclosing_list == NULL) {
+ return NULL;
+ }
+ Py_INCREF(params);
+ if (PyList_SetItem(enclosing_list, 0, params) == -1) {
+ Py_DECREF(params);
+ Py_DECREF(enclosing_list);
+ return NULL;
+ }
+ }
+ else {
+ enclosing_list = PyList_New(0);
+ if (enclosing_list == NULL) {
+ return NULL;
+ }
+ }
+ return enclosing_list;
+ }
+ else if (multiparam_size == 1) {
+ zero_element = PyTuple_GetItem(multiparams, 0);
+ if (PyTuple_Check(zero_element) || PyList_Check(zero_element)) {
+ zero_element_length = PySequence_Length(zero_element);
+
+ if (zero_element_length != 0) {
+ zero_element_item = PySequence_GetItem(zero_element, 0);
+ if (zero_element_item == NULL) {
+ return NULL;
+ }
+ }
+
+ if (zero_element_length == 0 ||
+ PyObject_HasAttrString(zero_element_item, "__iter__") &&
+ !PyObject_HasAttrString(zero_element_item, "strip")
+ ) {
+ /*
+ * execute(stmt, [{}, {}, {}, ...])
+ * execute(stmt, [(), (), (), ...])
+ */
+ Py_XDECREF(zero_element_item);
+ Py_INCREF(zero_element);
+ return zero_element;
+ }
+ else {
+ /*
+ * execute(stmt, ("value", "value"))
+ */
+ Py_XDECREF(zero_element_item);
+ enclosing_list = PyList_New(1);
+ if (enclosing_list == NULL) {
+ return NULL;
+ }
+ Py_INCREF(zero_element);
+ if (PyList_SetItem(enclosing_list, 0, zero_element) == -1) {
+ Py_DECREF(zero_element);
+ Py_DECREF(enclosing_list);
+ return NULL;
+ }
+ return enclosing_list;
+ }
+ }
+ else if (PyObject_HasAttrString(zero_element, "keys")) {
+ /*
+ * execute(stmt, {"key":"value"})
+ */
+ enclosing_list = PyList_New(1);
+ if (enclosing_list == NULL) {
+ return NULL;
+ }
+ Py_INCREF(zero_element);
+ if (PyList_SetItem(enclosing_list, 0, zero_element) == -1) {
+ Py_DECREF(zero_element);
+ Py_DECREF(enclosing_list);
+ return NULL;
+ }
+ return enclosing_list;
+ } else {
+ enclosing_list = PyList_New(1);
+ if (enclosing_list == NULL) {
+ return NULL;
+ }
+ double_enclosing_list = PyList_New(1);
+ if (double_enclosing_list == NULL) {
+ Py_DECREF(enclosing_list);
+ return NULL;
+ }
+ Py_INCREF(zero_element);
+ if (PyList_SetItem(enclosing_list, 0, zero_element) == -1) {
+ Py_DECREF(zero_element);
+ Py_DECREF(enclosing_list);
+ Py_DECREF(double_enclosing_list);
+ return NULL;
+ }
+ if (PyList_SetItem(double_enclosing_list, 0, enclosing_list) == -1) {
+ Py_DECREF(zero_element);
+ Py_DECREF(enclosing_list);
+ Py_DECREF(double_enclosing_list);
+ return NULL;
+ }
+ return double_enclosing_list;
+ }
+ }
+ else {
+ zero_element = PyTuple_GetItem(multiparams, 0);
+ if (PyObject_HasAttrString(zero_element, "__iter__") &&
+ !PyObject_HasAttrString(zero_element, "strip")
+ ) {
+ Py_INCREF(multiparams);
+ return multiparams;
+ }
+ else {
+ enclosing_list = PyList_New(1);
+ if (enclosing_list == NULL) {
+ return NULL;
+ }
+ Py_INCREF(multiparams);
+ if (PyList_SetItem(enclosing_list, 0, multiparams) == -1) {
+ Py_DECREF(multiparams);
+ Py_DECREF(enclosing_list);
+ return NULL;
+ }
+ return enclosing_list;
+ }
+ }
+}
+
+#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+
+
+static PyMethodDef module_methods[] = {
+ {"_distill_params", distill_params, METH_VARARGS,
+ "Distill an execute() parameter structure."},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+PyMODINIT_FUNC
+initcutils(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule3("cutils", module_methods,
+ "Internal utility functions.");
+ if (m == NULL)
+ return;
+
+}
+
diff --git a/lib/sqlalchemy/engine/util.py b/lib/sqlalchemy/engine/util.py
index bbbfe3cff..6bf8f2d3f 100644
--- a/lib/sqlalchemy/engine/util.py
+++ b/lib/sqlalchemy/engine/util.py
@@ -26,46 +26,6 @@ def _coerce_config(configuration, prefix):
util.coerce_kw_type(options, option, type_)
return options
-
-def _distill_params(multiparams, params):
- """Given arguments from the calling form *multiparams, **params,
- return a list of bind parameter structures, usually a list of
- dictionaries.
-
- In the case of 'raw' execution which accepts positional parameters,
- it may be a list of tuples or lists.
-
- """
-
- if not multiparams:
- if params:
- return [params]
- else:
- return []
- elif len(multiparams) == 1:
- zero = multiparams[0]
- if isinstance(zero, (list, tuple)):
- if not zero or hasattr(zero[0], '__iter__') and \
- not hasattr(zero[0], 'strip'):
- # execute(stmt, [{}, {}, {}, ...])
- # execute(stmt, [(), (), (), ...])
- return zero
- else:
- # execute(stmt, ("value", "value"))
- return [zero]
- elif hasattr(zero, 'keys'):
- # execute(stmt, {"key":"value"})
- return [zero]
- else:
- # execute(stmt, "value")
- return [[zero]]
- else:
- if hasattr(multiparams[0], '__iter__') and \
- not hasattr(multiparams[0], 'strip'):
- return multiparams
- else:
- return [multiparams]
-
def connection_memoize(key):
"""Decorator, memoize a function in a connection.info stash.
@@ -83,3 +43,51 @@ def connection_memoize(key):
return val
return decorated
+
+def py_fallback():
+ def _distill_params(multiparams, params):
+ """Given arguments from the calling form *multiparams, **params,
+ return a list of bind parameter structures, usually a list of
+ dictionaries.
+
+ In the case of 'raw' execution which accepts positional parameters,
+ it may be a list of tuples or lists.
+
+ """
+
+ if not multiparams:
+ if params:
+ return [params]
+ else:
+ return []
+ elif len(multiparams) == 1:
+ zero = multiparams[0]
+ if isinstance(zero, (list, tuple)):
+ if not zero or hasattr(zero[0], '__iter__') and \
+ not hasattr(zero[0], 'strip'):
+ # execute(stmt, [{}, {}, {}, ...])
+ # execute(stmt, [(), (), (), ...])
+ return zero
+ else:
+ # execute(stmt, ("value", "value"))
+ return [zero]
+ elif hasattr(zero, 'keys'):
+ # execute(stmt, {"key":"value"})
+ return [zero]
+ else:
+ # execute(stmt, "value")
+ return [[zero]]
+ else:
+ if hasattr(multiparams[0], '__iter__') and \
+ not hasattr(multiparams[0], 'strip'):
+ return multiparams
+ else:
+ return [multiparams]
+
+ return locals()
+try:
+ from sqlalchemy.cutils import _distill_params
+except ImportError:
+ globals().update(py_fallback())
+
+
diff --git a/lib/sqlalchemy/processors.py b/lib/sqlalchemy/processors.py
index 240263feb..ddca43a6c 100644
--- a/lib/sqlalchemy/processors.py
+++ b/lib/sqlalchemy/processors.py
@@ -29,10 +29,11 @@ def str_to_datetime_processor_factory(regexp, type_):
m = rmatch(value)
except TypeError:
raise ValueError("Couldn't parse %s string '%r' "
- "- value is not a string." % (type_.__name__ , value))
+ "- value is not a string." %
+ (type_.__name__, value))
if m is None:
raise ValueError("Couldn't parse %s string: "
- "'%s'" % (type_.__name__ , value))
+ "'%s'" % (type_.__name__, value))
if has_named_groups:
groups = m.groupdict(0)
return type_(**dict(zip(groups.iterkeys(),