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> 
   39 using std::placeholders::_1;
 
   41 using cool::DatabaseSvcFactory;
 
   42 using cool::IDatabasePtr;
 
   46 using cool::IFolderPtr;
 
   47 using cool::ChannelSelection;
 
   48 using cool::IObjectIteratorPtr;
 
   49 using cool::IObjectVectorPtr;
 
   50 using cool::ValidityKey;
 
   54     const std::string& 
name, 
 
   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))); 
   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"));
 
   88     return vector<const cool::IRecordSelection*>();
 
  101     const char* 
data = 
reinterpret_cast<const char*
>(
blob.startingAddress());
 
  102     return PyBytes_FromStringAndSize(
data, 
blob.size());
 
  107     return PyUnicode_FromStringAndSize(
str.c_str(), 
str.size());
 
  112     return PyUnicode_DecodeUTF8(
str.c_str(), 
str.size(), 
"backslashreplace");
 
  118 template<
typename T, 
typename FUNC_TYPE>
 
  120                                  FUNC_TYPE* converter_function)
 
  128     return converter_function(
field.data<
T>());
 
  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'.",
 
  195                               unsigned long long value)
 
  197     static const char * 
const argtypes = 
const_cast<char *
>(
"K");
 
  198     if (iovkey_wrapper && iovkey_wrapper != Py_None)
 
  199         return PyObject_CallFunction(iovkey_wrapper, 
argtypes, 
value);
 
  200     return PyLong_FromUnsignedLongLong(
value);
 
  207     if (!
function || 
function == Py_None) 
return object;
 
  209     PyObject *new_object = PyObject_CallObject(
function, 
object);
 
  210     Py_DECREF(old_object);
 
  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;
 
  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(
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);
 
  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)
 
  310                 PyObject *channelName = PyDict_GetItem(channel_name_mapping,    
 
  314                     Py_INCREF(channelName);
 
  316                     PyTuple_SET_ITEM(
one, 2+with_time, channelName);
 
  321                 PyTuple_SET_ITEM(
one, 2+with_time, 
 
  326         for (Py_ssize_t 
i = 0; 
i < 
count; 
i++)
 
  327             PyTuple_SET_ITEM(
one, fetch_start + 
i, payload_fetchers[
i](
object));
 
  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);