54 const std::string& name,
55 const cool::StorageType::TypeId typeId,
56 cool::FieldSelection::Relation relation,
59 #define MAKE_FS(type, converter) \
60 if (typeId == cool::StorageType::type) \
61 return new cool::FieldSelection(name, typeId, relation, \
62 static_cast<cool::type>(converter(refValue)));
65 MAKE_FS(Float, PyFloat_AsDouble)
66 MAKE_FS(Double, PyFloat_AsDouble)
68 MAKE_FS(UChar, PyLong_AsUnsignedLong)
70 MAKE_FS(UInt16, PyLong_AsUnsignedLong)
72 MAKE_FS(UInt32, PyLong_AsUnsignedLong)
73 MAKE_FS(Int64, PyLong_AsLongLong)
74 MAKE_FS(UInt63, PyLong_AsUnsignedLongLong)
76 MAKE_FS(String255, _PyUnicode_AsString)
77 MAKE_FS(String4k, _PyUnicode_AsString)
78 MAKE_FS(String64k, _PyUnicode_AsString)
79 MAKE_FS(String16M, _PyUnicode_AsString)
83 throw (std::runtime_error(
"Unsupported cool type encountered in python conversion"));
134 const string& type_name,
135 bool string_to_unicode =
false)
139 #define MAKE_FETCHER(type, converter) \
140 if (type_name == #type) \
141 return bind(payload_fetcher<cool::type, decltype(converter)>, \
142 _1, name, &converter);
159 if (string_to_unicode)
175 PyErr_Format(PyExc_RuntimeError,
176 "Type '%s' is not in type conversion table. "
177 "Please add it to quick_retrieve.cxx. "
178 "Can't convert field '%s'.",
222 const long max_records = -1,
223 const bool with_channel =
true,
224 const bool loud =
false,
226 PyObject *channel_name_mapping = NULL,
227 const bool with_time =
false,
228 const bool as_unicode =
false)
234 const long long records = objects->size();
235 const Py_ssize_t
count = to_fetch ? PySequence_Size(to_fetch) : 0;
236 const unsigned int fetch_start = 2 + with_channel + with_time;
241 vector<payload_fetcher_t> payload_fetchers;
243 while (objects->goToNext())
245 const IObject&
object = objects->currentRef();
252 for (Py_ssize_t i = 0; i <
count; i++)
254 PyObject *py_name = PySequence_GetItem(to_fetch, i);
255 const char *name = _PyUnicode_AsString(py_name);
256 const string type = (
object.payload()
257 .specification()[name]
263 auto pff = pf.target<
PyObject* (*)(
const IObject&)>();
266 payload_fetchers.push_back(std::move(pf));
272 PyObject *py_datetime_module = PyImport_ImportModule(
"datetime");
273 if (!py_datetime_module)
274 throw (std::runtime_error(
"Could not import python datetime_module"));
276 py_datetime_class = PyObject_GetAttrString(py_datetime_module,
279 Py_DECREF(py_datetime_module);
287 PyTuple_SET_ITEM(one, 0,
make_iov_key(iovkey_wrapper,
object.since()));
288 PyTuple_SET_ITEM(one, 1,
make_iov_key(iovkey_wrapper,
object.until()));
292 const ITime& t =
object.insertionTime();
293 static const char *
const argtypes =
const_cast<char *
>(
"iiiiiil");
296 PyObject_CallFunction(py_datetime_class, argtypes,
297 t.year(), t.month(), t.day(),
298 t.hour(), t.minute(), t.second(), t.nanosecond() / 1000);
300 PyTuple_SetItem(one, 2, py_record_time);
305 if (channel_name_mapping)
309 PyObject *channelId = PyLong_FromUnsignedLong(
object.channelId());
310 PyObject *channelName = PyDict_GetItem(channel_name_mapping,
314 Py_INCREF(channelName);
315 Py_DECREF(channelId);
316 PyTuple_SET_ITEM(one, 2+with_time, channelName);
318 PyTuple_SET_ITEM(one, 2+with_time, channelId);
321 PyTuple_SET_ITEM(one, 2+with_time,
322 PyLong_FromLong(
object.channelId()));
326 for (Py_ssize_t i = 0; i <
count; i++)
327 PyTuple_SET_ITEM(one, fetch_start + i, payload_fetchers[i](
object));
339 PyList_Append(
result, one);
343 if (
unlikely(loud && ((++j) % 1000 == 0)))
345 cout <<
"Progress: " << j <<
" / " << records <<
"\r";
349 if (
unlikely(max_records > 0 && j >= max_records))
354 cout <<
"Done fetching " << j <<
" records.\x1B[K" << endl;
356 if (py_datetime_class)
358 Py_DECREF(py_datetime_class);
PyObject * quick_retrieve(const IObjectIteratorPtr &objects, PyObject *object_converter, PyObject *to_fetch=NULL, const long max_records=-1, const bool with_channel=true, const bool loud=false, PyObject *iovkey_wrapper=NULL, PyObject *channel_name_mapping=NULL, const bool with_time=false, const bool as_unicode=false)