diff options
Diffstat (limited to 'src/py_journal.cc')
-rw-r--r-- | src/py_journal.cc | 143 |
1 files changed, 102 insertions, 41 deletions
diff --git a/src/py_journal.cc b/src/py_journal.cc index 88447b92..bea14d66 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -33,9 +33,14 @@ #include "pyinterp.h" #include "pyutils.h" -#include "hooks.h" #include "journal.h" #include "xact.h" +#include "post.h" +#include "chain.h" +#include "filters.h" +#include "iterators.h" +#include "scope.h" +#include "report.h" namespace ledger { @@ -130,51 +135,113 @@ namespace { return journal.find_account(name, auto_create); } - struct py_xact_finalizer_t : public xact_finalizer_t { - object pyobj; - py_xact_finalizer_t() {} - py_xact_finalizer_t(object obj) : pyobj(obj) {} - py_xact_finalizer_t(const py_xact_finalizer_t& other) - : pyobj(other.pyobj) {} - virtual bool operator()(xact_t& xact) { - return call<bool>(pyobj.ptr(), xact); - } - }; - - std::list<py_xact_finalizer_t> py_finalizers; - - void py_add_xact_finalizer(journal_t& journal, object x) + std::size_t py_read(journal_t& journal, const string& pathname) { - py_finalizers.push_back(py_xact_finalizer_t(x)); - journal.add_xact_finalizer(&py_finalizers.back()); + return journal.read(pathname); } - void py_remove_xact_finalizer(journal_t& journal, object x) + struct collector_wrapper { - for (std::list<py_xact_finalizer_t>::iterator i = py_finalizers.begin(); - i != py_finalizers.end(); - i++) - if ((*i).pyobj == x) { - journal.remove_xact_finalizer(&(*i)); - py_finalizers.erase(i); - return; - } - } + journal_t& journal; + report_t report; + collect_posts * posts_collector; + post_handler_ptr chain; + + collector_wrapper(journal_t& _journal, report_t& base) + : journal(_journal), report(base), + posts_collector(new collect_posts) {} + ~collector_wrapper() { + journal.clear_xdata(); + } - void py_run_xact_finalizers(journal_t& journal, xact_t& xact) + std::size_t length() const { + return posts_collector->length(); + } + + std::vector<post_t *>::iterator begin() { + return posts_collector->begin(); + } + std::vector<post_t *>::iterator end() { + return posts_collector->end(); + } + }; + + shared_ptr<collector_wrapper> + py_collect(journal_t& journal, const string& query) { - journal.xact_finalize_hooks.run_hooks(xact); + if (journal.has_xdata()) { + PyErr_SetString(PyExc_RuntimeError, + _("Cannot have multiple journal collections open at once")); + throw_error_already_set(); + } + + report_t& current_report(downcast<report_t>(*scope_t::default_scope)); + shared_ptr<collector_wrapper> coll(new collector_wrapper(journal, + current_report)); + std::auto_ptr<journal_t> save_journal + (current_report.session.journal.release()); + current_report.session.journal.reset(&journal); + + try { + strings_list remaining = + process_arguments(split_arguments(query.c_str()), coll->report); + coll->report.normalize_options("register"); + + value_t args; + foreach (const string& arg, remaining) + args.push_back(string_value(arg)); + coll->report.parse_query_args(args, "@Journal.collect"); + + journal_posts_iterator walker(coll->journal); + coll->chain = + chain_post_handlers(coll->report, + post_handler_ptr(coll->posts_collector)); + pass_down_posts(coll->chain, walker); + } + catch (...) { + current_report.session.journal.release(); + current_report.session.journal.reset(save_journal.release()); + throw; + } + current_report.session.journal.release(); + current_report.session.journal.reset(save_journal.release()); + + return coll; } - std::size_t py_read(journal_t& journal, const string& pathname) + post_t * posts_getitem(collector_wrapper& collector, long i) { - return journal.read(pathname); + post_t * post = collector.posts_collector->posts[i]; + std::cerr << typeid(post).name() << std::endl; + std::cerr << typeid(*post).name() << std::endl; + std::cerr << typeid(post->account).name() << std::endl; + std::cerr << typeid(*post->account).name() << std::endl; + return post; } } // unnamed namespace void export_journal() { + class_< item_handler<post_t>, shared_ptr<item_handler<post_t> >, + boost::noncopyable >("PostHandler") + ; + + class_< collect_posts, bases<item_handler<post_t> >, + shared_ptr<collect_posts>, boost::noncopyable >("PostCollector") + .def("__len__", &collect_posts::length) + .def("__iter__", range<return_internal_reference<> > + (&collect_posts::begin, &collect_posts::end)) + ; + + class_< collector_wrapper, shared_ptr<collector_wrapper>, + boost::noncopyable >("PostCollectorWrapper", no_init) + .def("__len__", &collector_wrapper::length) + .def("__getitem__", posts_getitem, return_internal_reference<>()) + .def("__iter__", range<return_internal_reference<> > + (&collector_wrapper::begin, &collector_wrapper::end)) + ; + class_< journal_t::fileinfo_t > ("FileInfo") .def(init<path>()) @@ -206,11 +273,6 @@ void export_journal() .add_property("commodity_pool", make_getter(&journal_t::commodity_pool, return_internal_reference<>())) -#if 0 - .add_property("xact_finalize_hooks", - make_getter(&journal_t::xact_finalize_hooks), - make_setter(&journal_t::xact_finalize_hooks)) -#endif .def("add_account", &journal_t::add_account) .def("remove_account", &journal_t::remove_account) @@ -223,12 +285,8 @@ void export_journal() .def("add_xact", &journal_t::add_xact) .def("remove_xact", &journal_t::remove_xact) - .def("add_xact_finalizer", py_add_xact_finalizer) - .def("remove_xact_finalizer", py_remove_xact_finalizer) - .def("run_xact_finalizers", py_run_xact_finalizers) - .def("__len__", xacts_len) - .def("__getitem__", xacts_getitem, return_internal_reference<1>()) + .def("__getitem__", xacts_getitem, return_internal_reference<>()) .def("__iter__", range<return_internal_reference<> > (&journal_t::xacts_begin, &journal_t::xacts_end)) @@ -243,8 +301,11 @@ void export_journal() .def("read", py_read) + .def("has_xdata", &journal_t::has_xdata) .def("clear_xdata", &journal_t::clear_xdata) + .def("collect", py_collect) + .def("valid", &journal_t::valid) ; } |