5 #define likely(x) __builtin_expect((x),1)
6 #define unlikely(x) __builtin_expect((x),0)
10 #include <CoolKernel/ChannelSelection.h>
11 #include <CoolKernel/ITime.h>
12 #include <CoolKernel/IField.h>
13 #include <CoolKernel/FieldSelection.h>
14 #include <CoolKernel/CompositeSelection.h>
15 #include <CoolKernel/IObject.h>
16 #include <CoolKernel/IObjectIterator.h>
17 #include <CoolKernel/IFolder.h>
18 #include <CoolKernel/IDatabase.h>
19 #include <CoolKernel/IDatabaseSvc.h>
21 #include <CoolApplication/DatabaseSvcFactory.h>
23 #include <boost/typeof/typeof.hpp>
24 #include <boost/bind/bind.hpp>
25 #include <boost/function.hpp>
41 using boost::placeholders::_1;
43 using cool::DatabaseSvcFactory;
44 using cool::IDatabasePtr;
48 using cool::IFolderPtr;
49 using cool::ChannelSelection;
50 using cool::IObjectIteratorPtr;
51 using cool::IObjectVectorPtr;
52 using cool::ValidityKey;
56 const std::string&
name,
58 cool::FieldSelection::Relation relation,
61 #define MAKE_FS(type, converter) \
62 if (typeId == cool::StorageType::type) \
63 return new cool::FieldSelection(name, typeId, relation, \
64 static_cast<cool::type>(converter(refValue)));
67 MAKE_FS(Float, PyFloat_AsDouble)
68 MAKE_FS(Double, PyFloat_AsDouble)
70 MAKE_FS(UChar, PyLong_AsUnsignedLong)
72 MAKE_FS(UInt16, PyLong_AsUnsignedLong)
74 MAKE_FS(UInt32, PyLong_AsUnsignedLong)
75 MAKE_FS(Int64, PyLong_AsLongLong)
76 MAKE_FS(UInt63, PyLong_AsUnsignedLongLong)
78 #if PY_VERSION_HEX < 0x03000000
79 MAKE_FS(String255, PyString_AsString)
80 MAKE_FS(String4k, PyString_AsString)
81 MAKE_FS(String64k, PyString_AsString)
82 MAKE_FS(String16M, PyString_AsString)
84 MAKE_FS(String255, _PyUnicode_AsString)
85 MAKE_FS(String4k, _PyUnicode_AsString)
86 MAKE_FS(String64k, _PyUnicode_AsString)
87 MAKE_FS(String16M, _PyUnicode_AsString)
92 throw (std::runtime_error(
"Unsupported cool type encountered in python conversion"));
97 return vector<const cool::IRecordSelection*>();
110 const char*
data =
reinterpret_cast<const char*
>(
blob.startingAddress());
111 #if PY_VERSION_HEX < 0x03000000
112 return PyString_FromStringAndSize(
data,
blob.size());
114 return PyBytes_FromStringAndSize(
data,
blob.size());
120 #if PY_VERSION_HEX < 0x03000000
121 return PyString_FromStringAndSize(
str.c_str(),
str.size());
123 return PyUnicode_FromStringAndSize(
str.c_str(),
str.size());
129 return PyUnicode_DecodeUTF8(
str.c_str(),
str.size(),
"backslashreplace");
135 template<
typename T,
typename FUNC_TYPE>
137 FUNC_TYPE* converter_function)
145 return converter_function(
field.data<
T>());
151 const string& type_name,
152 bool string_to_unicode =
false)
156 #define MAKE_FETCHER(type, converter) \
157 if (type_name == #type) \
158 return bind(payload_fetcher<cool::type, BOOST_TYPEOF(converter)>, \
159 _1, name, &converter);
176 if (string_to_unicode)
192 PyErr_Format(PyExc_RuntimeError,
193 "Type '%s' is not in type conversion table. "
194 "Please add it to quick_retrieve.cxx. "
195 "Can't convert field '%s'.",
212 unsigned long long value)
214 static const char *
const argtypes =
const_cast<char *
>(
"K");
215 if (iovkey_wrapper && iovkey_wrapper != Py_None)
216 return PyObject_CallFunction(iovkey_wrapper,
argtypes,
value);
217 return PyLong_FromUnsignedLongLong(
value);
224 if (!
function ||
function == Py_None)
return object;
226 PyObject *new_object = PyObject_CallObject(
function,
object);
227 Py_DECREF(old_object);
239 const long max_records = -1,
240 const bool with_channel =
true,
241 const bool loud =
false,
243 PyObject *channel_name_mapping = NULL,
244 const bool with_time =
false,
245 const bool as_unicode =
false)
251 const long long records =
objects->size();
252 const Py_ssize_t
count = to_fetch ? PySequence_Size(to_fetch) : 0;
253 const unsigned int fetch_start = 2 + with_channel + with_time;
258 vector<payload_fetcher_t> payload_fetchers;
262 const IObject&
object =
objects->currentRef();
269 for (Py_ssize_t
i = 0;
i <
count;
i++)
271 PyObject *py_name = PySequence_GetItem(to_fetch,
i);
272 #if PY_VERSION_HEX < 0x03000000
273 const char *
name = PyString_AsString(py_name);
275 const char *
name = _PyUnicode_AsString(py_name);
277 const string type = (
object.payload()
278 .specification()[
name]
286 payload_fetchers.push_back(
pf);
292 PyObject *py_datetime_module = PyImport_ImportModule(
"datetime");
293 if (!py_datetime_module)
294 throw (std::runtime_error(
"Could not import python datetime_module"));
296 py_datetime_class = PyObject_GetAttrString(py_datetime_module,
299 Py_DECREF(py_datetime_module);
312 const ITime&
t =
object.insertionTime();
313 static const char *
const argtypes =
const_cast<char *
>(
"iiiiiil");
316 PyObject_CallFunction(py_datetime_class,
argtypes,
317 t.year(),
t.month(),
t.day(),
318 t.hour(),
t.minute(),
t.second(),
t.nanosecond() / 1000);
320 PyTuple_SetItem(
one, 2, py_record_time);
325 if (channel_name_mapping)
330 PyObject *channelName = PyDict_GetItem(channel_name_mapping,
334 Py_INCREF(channelName);
336 PyTuple_SET_ITEM(
one, 2+with_time, channelName);
341 PyTuple_SET_ITEM(
one, 2+with_time,
346 for (Py_ssize_t
i = 0;
i <
count;
i++)
347 PyTuple_SET_ITEM(
one, fetch_start +
i, payload_fetchers[
i](
object));
363 if (
unlikely(loud && ((++j) % 1000 == 0)))
365 cout <<
"Progress: " << j <<
" / " << records <<
"\r";
369 if (
unlikely(max_records > 0 && j >= max_records))
374 cout <<
"Done fetching " << j <<
" records.\x1B[K" << endl;
376 if (py_datetime_class)
378 Py_DECREF(py_datetime_class);