Fairport  v1.0.38
fairport/pst/folder.h
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 #ifndef FAIRPORT_PST_FOLDER_H
00013 #define FAIRPORT_PST_FOLDER_H
00014 
00015 #include <algorithm>
00016 #include <boost/iterator/filter_iterator.hpp>
00017 #include <boost/iterator/transform_iterator.hpp>
00018 
00019 #include "fairport/util/primitives.h"
00020 #include "fairport/util/errors.h"
00021 
00022 #include "fairport/ndb/database_iface.h"
00023 
00024 #include "fairport/ltp/propbag.h"
00025 #include "fairport/ltp/table.h"
00026 
00027 #include "fairport/pst/message.h"
00028 #include "fairport/pst/contact.h"
00029 #include "fairport/pst/task.h"
00030 #include "fairport/pst/pstutil.h"
00031 
00032 namespace fairport
00033 {
00034 
00037 
00047 class search_folder : public detail::itembase
00048 {
00049     typedef boost::filter_iterator<detail::is_item_type, const_table_row_iter> row_filter_iterator;
00050 public:
00052     typedef boost::transform_iterator<message_transform_row, const_table_row_iter> message_iterator;
00054     typedef boost::transform_iterator<contact_transform_row, row_filter_iterator> contact_iterator;
00056     typedef boost::transform_iterator<task_transform_row, row_filter_iterator> task_iterator;
00057 
00060     search_folder(const node& n)
00061         : detail::itembase(n) { }
00062 
00063     // subobject discovery/enumeration
00066     message_iterator message_begin() const
00067         { return boost::make_transform_iterator(get_contents_table().begin(), message_transform_row(get_db())); }
00070     message_iterator message_end() const
00071         { return boost::make_transform_iterator(get_contents_table().end(), message_transform_row(get_db())); }
00072 
00075     contact_iterator contact_begin() const
00076         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(contact_class), get_contents_table().begin(), get_contents_table().end()), contact_transform_row(get_db())); }
00079     contact_iterator contact_end() const
00080         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(contact_class), get_contents_table().end(), get_contents_table().end()), contact_transform_row(get_db())); }
00081 
00084     task_iterator task_begin() const
00085         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(task_class), get_contents_table().begin(), get_contents_table().end()), task_transform_row(get_db())); }
00088     task_iterator task_end() const
00089         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(task_class), get_contents_table().end(), get_contents_table().end()), task_transform_row(get_db())); }
00090 
00091     // property access
00094     std::wstring get_name() const
00095         { return get_property_bag().read_prop<std::wstring>(0x3001); }
00098     size_t get_unread_message_count() const
00099         { return get_property_bag().read_prop<slong>(0x3603); }
00102     size_t get_message_count() const
00103         { return get_property_bag().read_prop<slong>(0x3602); }
00104 
00105     // lower layer access
00106 
00109     table& get_contents_table();
00111     const table& get_contents_table() const;
00112 
00113 private:
00114     mutable std::tr1::shared_ptr<table> m_contents_table;
00115 };
00116 
00117 class folder;
00118 typedef detail::item_transform_row<folder> folder_transform_row;
00119 typedef detail::item_transform_row<search_folder> search_folder_transform_row;
00120 
00133 class folder : public detail::itembase
00134 {
00135     typedef boost::filter_iterator<detail::is_item_type, const_table_row_iter> row_filter_iterator;
00136     typedef boost::filter_iterator<detail::is_nid_type<nid_type_search_folder>, const_table_row_iter> search_folder_filter_iterator;
00137     typedef boost::filter_iterator<detail::is_nid_type<nid_type_folder>, const_table_row_iter> folder_filter_iterator;
00138 
00139 public:
00141     typedef boost::transform_iterator<message_transform_row, const_table_row_iter> message_iterator;
00143     typedef boost::transform_iterator<folder_transform_row, folder_filter_iterator> folder_iterator;
00145     typedef boost::transform_iterator<search_folder_transform_row, search_folder_filter_iterator> search_folder_iterator;
00147     typedef boost::transform_iterator<contact_transform_row, row_filter_iterator> contact_iterator;
00149     typedef boost::transform_iterator<task_transform_row, row_filter_iterator> task_iterator;
00150 
00153     folder(const node& n)
00154         : detail::itembase(n) { }
00155 
00156     // subobject discovery/enumeration
00159     folder_iterator sub_folder_begin() const
00160         { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_folder> >(get_hierarchy_table().begin(), get_hierarchy_table().end()), folder_transform_row(get_db())); }
00163     folder_iterator sub_folder_end() const
00164         { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_folder> >(get_hierarchy_table().end(), get_hierarchy_table().end()), folder_transform_row(get_db())); }
00165 
00168     search_folder_iterator sub_search_folder_begin() const
00169         { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_search_folder> >(get_hierarchy_table().begin(), get_hierarchy_table().end()), search_folder_transform_row(get_db())); }
00172     search_folder_iterator sub_search_folder_end() const
00173         { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_search_folder> >(get_hierarchy_table().end(), get_hierarchy_table().end()), search_folder_transform_row(get_db())); }
00174 
00179     folder open_sub_folder(const std::wstring& name);
00180 
00182     message_iterator message_begin() const
00183         { return boost::make_transform_iterator(get_contents_table().begin(), message_transform_row(get_db())); }
00185     message_iterator message_end() const
00186         { return boost::make_transform_iterator(get_contents_table().end(), message_transform_row(get_db())); }
00187     
00189     contact_iterator contact_begin() const
00190         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(contact_class), get_contents_table().begin(), get_contents_table().end()), contact_transform_row(get_db())); }
00192     contact_iterator contact_end() const
00193         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(contact_class), get_contents_table().end(), get_contents_table().end()), contact_transform_row(get_db())); }
00194 
00196     task_iterator task_begin() const
00197         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(task_class), get_contents_table().begin(), get_contents_table().end()), task_transform_row(get_db())); }
00199     task_iterator task_end() const
00200         { return boost::make_transform_iterator(boost::make_filter_iterator(detail::is_item_type(task_class), get_contents_table().end(), get_contents_table().end()), task_transform_row(get_db())); }
00201 
00204     message_iterator associated_message_begin() const
00205         { return boost::make_transform_iterator(get_associated_contents_table().begin(), message_transform_row(get_db())); }
00208     message_iterator associated_message_end() const
00209         { return boost::make_transform_iterator(get_associated_contents_table().end(), message_transform_row(get_db())); }
00210 
00211     // property access
00213     std::wstring get_name() const
00214         { return get_property_bag().read_prop<std::wstring>(0x3001); }
00217     size_t get_subfolder_count() const
00218         { return get_hierarchy_table().size(); } 
00220     size_t get_unread_message_count() const
00221         { return get_property_bag().read_prop<slong>(0x3603); }
00223     size_t get_message_count() const
00224         { return get_property_bag().read_prop<slong>(0x3602); }
00227     size_t get_associated_message_count() const
00228         { return get_property_bag().read_prop<slong>(0x3617); }
00229 
00230     // lower layer access
00231 
00234     table& get_hierarchy_table();
00236     table& get_contents_table();
00239     table& get_associated_contents_table();
00241     const table& get_hierarchy_table() const;
00243     const table& get_contents_table() const;
00245     const table& get_associated_contents_table() const;
00246 
00247 private:
00248     mutable std::tr1::shared_ptr<table> m_contents_table;
00249     mutable std::tr1::shared_ptr<table> m_associated_contents_table;
00250     mutable std::tr1::shared_ptr<table> m_hierarchy_table;
00251 };
00252 
00253 typedef detail::item_transform_info<folder> folder_transform_info;
00254 
00255 } // end namespace fairport
00256 
00257 inline const fairport::table& fairport::search_folder::get_contents_table() const
00258 {
00259     if(!m_contents_table)
00260         m_contents_table.reset(new table(get_db()->lookup_node(make_nid(nid_type_search_contents_table, get_nid_index(get_property_bag().get_node().get_id())))));
00261 
00262     return *m_contents_table;
00263 }
00264 
00265 inline fairport::table& fairport::search_folder::get_contents_table()
00266 {
00267     return const_cast<table&>(const_cast<const search_folder*>(this)->get_contents_table());
00268 }
00269 
00270 
00271 namespace internal
00272 {
00273 
00274 struct folder_name_equal : public std::unary_function<bool, const fairport::folder&>
00275 {
00276     folder_name_equal(const std::wstring& name) : m_name(name) { }
00277     bool operator()(const fairport::folder& f) const { return f.get_name() == m_name; }
00278     std::wstring m_name;
00279 };
00280 
00281 } // end namespace internal
00282 
00283 inline fairport::folder fairport::folder::open_sub_folder(const std::wstring& name)
00284 {
00285     folder_iterator iter = std::find_if(sub_folder_begin(), sub_folder_end(), internal::folder_name_equal(name));
00286 
00287     if(iter != sub_folder_end())
00288         return *iter;
00289 
00290     throw key_not_found<std::wstring>(name);
00291 }
00292 
00293 inline const fairport::table& fairport::folder::get_contents_table() const
00294 {
00295     if(!m_contents_table)
00296         m_contents_table.reset(new table(get_db()->lookup_node(make_nid(nid_type_contents_table, get_nid_index(get_property_bag().get_node().get_id())))));
00297 
00298     return *m_contents_table;
00299 }
00300 
00301 inline fairport::table& fairport::folder::get_contents_table()
00302 {
00303     return const_cast<table&>(const_cast<const folder*>(this)->get_contents_table());
00304 }
00305 
00306 inline const fairport::table& fairport::folder::get_hierarchy_table() const
00307 {
00308     if(!m_hierarchy_table)
00309         m_hierarchy_table.reset(new table(get_db()->lookup_node(make_nid(nid_type_hierarchy_table, get_nid_index(get_property_bag().get_node().get_id())))));
00310 
00311     return *m_hierarchy_table;
00312 }
00313 
00314 inline fairport::table& fairport::folder::get_hierarchy_table()
00315 {
00316     return const_cast<table&>(const_cast<const folder*>(this)->get_hierarchy_table());
00317 }
00318 
00319 inline const fairport::table& fairport::folder::get_associated_contents_table() const
00320 {
00321     if(!m_associated_contents_table)
00322         m_associated_contents_table.reset(new table(get_db()->lookup_node(make_nid(nid_type_associated_contents_table, get_nid_index(get_property_bag().get_node().get_id())))));
00323 
00324     return *m_associated_contents_table;
00325 }
00326 
00327 inline fairport::table& fairport::folder::get_associated_contents_table()
00328 {
00329     return const_cast<table&>(const_cast<const folder*>(this)->get_associated_contents_table());
00330 }
00331 
00332 #endif