Kitlist  1.1.0
kitlistpgsqldao.cpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of Kitlist, a program to maintain a simple list
4  of items and assign items to one or more categories.
5 
6  Copyright (C) 2008,2009 Frank Dean
7 
8  Kitlist is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  Kitlist is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Kitlist. If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #include <cassert>
24 #include <iostream>
25 #include <sstream>
26 #include "kitlistpgsqldao.hpp"
27 
28 #ifdef HAVE_LIBPQXX
29 
30 using namespace std;
31 using namespace PGSTD;
32 using namespace pqxx;
33 
34 
36 class AddItem : public transactor<> {
37  Item* m_item;
38  long m_new_id;
39 public:
40  AddItem(Item* item) : transactor<>("AddItem"), m_item(item) {}
41 
42  void operator()(argument_type &T) {
43  T.exec("INSERT INTO item (description, checked) values('" +
44  T.esc(m_item->get_description()) + "', " +
45  (m_item->get_checked() ? "true" : "false") + ")");
46  result R(T.exec("SELECT lastval()"));
47  R.front()[0].to(m_new_id);
48  }
49 
50  void on_commit() {
51  m_item->set_id(m_new_id);
52  }
53 
54 };
55 
56 
58 class AssociateItemWithCategory : public transactor<> {
59  long m_id;
60  long m_cat_id;
61 public:
62  AssociateItemWithCategory(long id, long cat_id) :
63  transactor<>("AssociateItemWithCategory"), m_id(id), m_cat_id(cat_id) {}
64 
65  void operator()(argument_type &T) {
66  ostringstream os;
67  os << "INSERT INTO category_item (item, category) VALUES('" << m_id << "', '" << m_cat_id << "')";
68  T.exec(os.str());
69  }
70 
71 };
72 
73 
75 class DeleteItem : public transactor<> {
76  long m_id;
77 public:
78  DeleteItem(long id) : transactor<>("DeleteItem"), m_id(id) {}
79 
80  void operator()(argument_type &T) {
81  ostringstream os;
82  os << "DELETE FROM item WHERE id='" << m_id << '\'';
83  T.exec(os.str());
84  }
85 
86 };
87 
88 
90 class UpdateItemCheckedState : public transactor<> {
91  ItemContainer& m_items;
92 public:
93  UpdateItemCheckedState(ItemContainer& items)
94  : transactor<>("UpdateItemCheckedState"), m_items(items) {}
95 
96  void operator()(argument_type &T) {
97  for (ItemIter i = m_items.begin(); i != m_items.end(); ++i) {
98  ostringstream os;
99  os << "UPDATE item SET checked="
100  << ((*i)->get_checked() ? "true" : "false")
101  << " WHERE id=" << (*i)->get_id();
102  T.exec(os.str());
103  }
104  }
105 
106 };
107 
108 
110 class RemoveItemFromCategory : public transactor<> {
111  long m_id;
112  long m_cat_id;
113 public:
114  RemoveItemFromCategory(long id, long cat_id) :
115  transactor<>("RemoveItemFromCategory"), m_id(id), m_cat_id(cat_id) {}
116 
117  void operator()(argument_type &T) {
118  ostringstream os;
119  os << "DELETE FROM category_item WHERE item='"
120  << m_id << "' AND category='" << m_cat_id << '\'';
121  T.exec(os.str());
122  }
123 
124 };
125 
126 
128 class SetItemFlag : public transactor<> {
129  long m_id;
130  bool m_flag;
131 public:
132  SetItemFlag(long id, bool flag) : transactor<>("SetItemFlag"), m_id(id), m_flag(flag) {}
133 
134  void operator()(argument_type &T) {
135  ostringstream os;
136  os << "UPDATE item SET checked=" << (m_flag ? "true" : "false") << " WHERE id='" << m_id << '\'';
137  T.exec(os.str());
138  }
139 
140 };
141 
142 
144 class SetCategoryFlag : public transactor<> {
145  long m_cat_id;
146  bool m_flag;
147 public:
148  SetCategoryFlag(long cat_id, bool flag) : transactor<>("SetCategoryFlag"), m_cat_id(cat_id), m_flag(flag) {}
149 
150  void operator()(argument_type &T) {
151  ostringstream os;
152  os << "UPDATE item SET checked=" << (m_flag ? "true" : "false") << " FROM category_item AS c WHERE item.id=c.item AND c.category='" << m_cat_id << "'";
153  T.exec(os.str());
154  }
155 
156 };
157 
158 
160 class SetAllFlags : public transactor<> {
161  bool m_flag;
162 public:
163  SetAllFlags(bool flag) : transactor<>("SetAllFlags"), m_flag(flag) {}
164 
165  void operator()(argument_type &T) {
166  ostringstream os;
167  os << "UPDATE item SET checked=" << (m_flag ? "true" : "false");
168  T.exec(os.str());
169  }
170 
171 };
172 
173 
175 class DeleteCategory : public transactor<> {
176  long m_id;
177 public:
178  DeleteCategory(long id) : transactor<>("DeleteCategory"), m_id(id) {}
179 
180  void operator()(argument_type &T) {
181  ostringstream os;
182  os << "DELETE FROM category WHERE id='" << m_id << '\'';
183  T.exec(os.str());
184  }
185 
186 };
187 
188 
190 class NewCategory : public transactor<> {
191  string m_name;
192  long* m_new_id;
193  result R;
194 public:
195  NewCategory(string name, long* id) : transactor<>("NewCategory"), m_name(name), m_new_id(id) {}
196 
197  void operator()(argument_type &T) {
198  T.exec("INSERT INTO category (NAME) values('" + T.esc(m_name) + "')");
199  R = T.exec("SELECT lastval()");
200  }
201 
202  void on_commit() {
203  R.front()[0].to(*m_new_id);
204  }
205 
206 };
207 
208 
210 class AddCategoryItem : public transactor<> {
211  Item* m_item;
212  long m_cat_id;
213  long m_new_id;
214 public:
215  AddCategoryItem(Item* item, long cat_id)
216  : transactor<>("AddCategoryItem"), m_item(item), m_cat_id(cat_id) {}
217 
218  void operator()(argument_type &T) {
219  T.exec("INSERT INTO item (description, checked) values('" +
220  T.esc(m_item->get_description()) + "', " +
221  (m_item->get_checked() ? "true" : "false") + ")");
222  result R(T.exec("SELECT lastval()"));
223  result::reference ref = R.front();
224  m_new_id =ref[0].as(long());
225  ostringstream os;
226  os << "INSERT INTO category_item (category, item) VALUES('"
227  << m_cat_id << "', '" << m_new_id << "')";
228  T.exec(os.str());
229  }
230 
231  void on_commit() {
232  m_item->set_id(m_new_id);
233  }
234 
235 };
236 
237 
239 
241 class CopyItemsToCategory : public transactor<> {
242  long m_from_cat_id;
243  long m_to_cat_id;
244  item_choice m_item_choice;
245 public:
246  CopyItemsToCategory(long from_cat_id, long to_cat_id, item_choice choice)
247  : transactor<>("CopyItemsToCategory"),
248  m_from_cat_id(from_cat_id),
249  m_to_cat_id(to_cat_id),
250  m_item_choice(choice) {}
251 
252  void operator()(argument_type &T) {
253  ostringstream os;
254  // Insert element
255  os << "INSERT INTO category_item (item, category) ";
256 
257  // Selection statement for list of items
258  if (m_from_cat_id >= 0) {
259  switch (m_item_choice) {
260  case CHECKED_ITEMS:
261  case UNCHECKED_ITEMS:
262  os << "SELECT ci.item AS item, '" << m_to_cat_id << "' AS category FROM category_item AS ci "
263  << "JOIN item i ON ci.item=i.id ";
264  break;
265  default:
266  os << "SELECT ci.item AS item, '" << m_to_cat_id << "' AS category FROM category_item AS ci ";
267  }
268  os << "WHERE ci.category='" << m_from_cat_id << "' ";
269 
270  switch (m_item_choice) {
271  case CHECKED_ITEMS:
272  os << "AND i.checked=true ";
273  break;
274  case UNCHECKED_ITEMS:
275  os << "AND i.checked=false ";
276  break;
277  }
278  os << "AND ci.item NOT IN ";
279  } else {
280  os << "SELECT i.id AS item, '" << m_to_cat_id << "' FROM item AS i WHERE ";
281  switch (m_item_choice) {
282  case CHECKED_ITEMS:
283  os << "i.checked=true AND ";
284  break;
285  case UNCHECKED_ITEMS:
286  os << "i.checked=false AND ";
287  break;
288  }
289  os << "i.id NOT IN ";
290  }
291 
292  // Inner select, avoid items already in the list
293  os << "(SELECT c2.item FROM category_item AS c2 WHERE c2.category='" << m_to_cat_id << "')";
294 
295  T.exec(os.str());
296  }
297 
298 };
299 
300 
302 class GetNextItemId : public transactor<> {
303  long* m_id;
304  result R;
305 public:
306  GetNextItemId(long* id) : transactor<>("GetNextItemId"), m_id(id) {}
307 
308  void operator()(argument_type &T) {
309  R = T.exec("SELECT nextval('item_sequence')");
310  }
311 
312  void on_commit() {
313  R.front()[0].to(*m_id);
314  }
315 
316 };
317 
318 
320 class GetNextCategoryId : public transactor<> {
321  long* m_cat_id;
322  result R;
323 public:
324  GetNextCategoryId(long* cat_id) : transactor<>("GetNextCategoryId"), m_cat_id(cat_id) {}
325 
326  void operator()(argument_type &T) {
327  R = T.exec("SELECT nextval('category_sequence')");
328  }
329 
330  void on_commit() {
331  R.front()[0].to(*m_cat_id);
332  }
333 
334 };
335 
336 
337 
339 
341 class GetAllItems : public transactor<nontransaction> {
342  ItemContainer* m_items;
343  item_choice m_item_choice;
344  result R;
345 public:
346  GetAllItems(ItemContainer* items, item_choice choice)
347  : transactor<nontransaction>("GetAllItems"), m_items(items), m_item_choice(choice) {}
348 
349  void operator()(argument_type &T) {
350  // Perform a query on the database, storing result tuples in R.
351  ostringstream os;
352  os << "SELECT id, description, checked FROM item";
353  switch (m_item_choice) {
354  case CHECKED_ITEMS:
355  os << " WHERE checked=true";
356  break;
357  case UNCHECKED_ITEMS:
358  os << " WHERE checked=false";
359  break;
360  }
361  os << " ORDER BY id";
362  R = T.exec(os.str());
363  }
364 
365  void on_commit() {
366  // Process each successive result tuple
367  for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
368  Item* item = new Item;
369  item->set_id(c[0].as(long()));
370  item->set_description(c[1].as(string()));
371  item->set_checked(c[2].as(bool()));
372  m_items->push_back(item);
373  }
374  }
375 
376 };
377 
378 
380 class LoadModel : public pqxx::transactor<pqxx::nontransaction> {
381  KitModel& m_kitmodel;
382  CategoryMap* m_categories;
383  pqxx::result R;
384 public:
385  LoadModel(KitModel& kitmodel) : pqxx::transactor<pqxx::nontransaction>("LoadModel"), m_kitmodel(kitmodel) {}
386 
387  void operator()(argument_type &T) {
388  R = T.exec("SELECT i.id AS item_id, c.id AS category_id, i.description, c.name AS category, i.checked FROM item AS i FULL OUTER JOIN category_item AS ci ON i.id=ci.item FULL OUTER JOIN category AS c ON c.id=ci.category");
389  }
390 
391  void on_commit() {
392  for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
393  // item id will be null where there is an empty category
394  ModelItem* item = 0;
395  if (!c[0].is_null()) {
396  long item_id = c[0].as(long());
397  // Create a new item if we do not already have it
398  item = m_kitmodel.find_item(item_id);
399  if (!item) {
400  item = new ModelItem;
401  item->set_id(item_id);
402  item->set_description(c[2].as(string()));
403  item->set_checked(c[4].as(bool()));
404  m_kitmodel.add_item(item);
405  }
406  }
407 
408  // Do we have a category?
409  if (!c[1].is_null()) {
410  long cat_id = c[1].as(long());
411  // Create a new category if we do not already have one
412  ModelCategory* category = 0;
413  category = m_kitmodel.find_category(cat_id);
414  if (!category) {
415  category = new ModelCategory;
416  category->set_id(cat_id);
417  category->set_name(c[3].as(string()));
418  m_kitmodel.add_category(category);
419  }
420  if (item)
421  category->add_item(item);
422  }
423 
424  } // for
425  m_kitmodel.reset();
426  }
427 
428 };
429 
430 
432 class SaveModel : public transactor<> {
433 private:
434  ModelItemContainer m_items;
435  ModelCategoryContainer m_categories;
436 protected:
437  KitModel* m_model;
438 public:
439  SaveModel(KitModel* model) : transactor<>("SaveModel"), m_model(model), m_items(0) {}
440 
441 
442  bool on_foreach_item(ModelItem& item) {
443  m_items.push_back(&item);
444  return false;
445  }
446 
447 
448  bool on_foreach_category(ModelCategory& category) {
449  m_categories.push_back(&category);
450  return false;
451  }
452 
453 
454  void operator()(argument_type &T) {
455 
456  // Extract the list of items from the model
457  m_model->foreach_item( sigc::mem_fun(*this, &SaveModel::on_foreach_item) );
458 
459  // Insert/Update/Delete items
460  for (ModelItemIter i = m_items.begin(); i != m_items.end(); ++i) {
461  ModelItem* item = (*i);
462  if (item->is_dirty()) {
463  ostringstream os;
464  if (item->is_new()) {
465  os << "INSERT INTO item (id, description, checked) values("
466  << item->get_id() << ", '"
467  << T.esc(item->get_description()) << "', "
468  << (item->get_checked() ? "true" : "false") << ")";
469  } else if (item->is_deleted()) {
470  os << "DELETE FROM item WHERE id="
471  << item->get_id();
472  } else {
473  os << "UPDATE item SET description='"
474  << T.esc(item->get_description()) << "', checked="
475  << (item->get_checked() ? "true" : "false")
476  << " WHERE id=" << item->get_id();
477  }
478  cout << "Query: " << os.str() << endl;
479  T.exec(os.str());
480  }
481  }
482 
483  // Extract a list of categories from the model
484  m_model->foreach_category( sigc::mem_fun(*this, &SaveModel::on_foreach_category) );
485 
486  // Insert/Update/Delete categories
487  for (ModelCategoryIter i = m_categories.begin(); i != m_categories.end(); ++i) {
488  ModelCategory* cat = (*i);
489  if (cat->is_dirty()) {
490  ostringstream os;
491  if (cat->is_new()) {
492  os << "INSERT INTO category (id, name) values("
493  << cat->get_id() << ", '"
494  << T.esc(cat->get_name()) << "')";
495  } else if (cat->is_deleted()) {
496  os << "DELETE FROM category WHERE id="
497  << cat->get_id();
498  } else {
499  os << "UPDATE category SET name='"
500  << T.esc(cat->get_name())
501  << "' WHERE id=" << cat->get_id();
502  }
503  cout << "Query: " << os.str() << endl;
504  T.exec(os.str());
505  }
506  // Any item or category deletes will have cascaded to the
507  // relationship table, category_item, so just need to deal
508  // with potential items added to the category
509  if (!cat->is_deleted()) {
510  ItemMap* items = cat->get_removed_children();
511  for (ItemMapIter i2 = items->begin(); i2 != items->end(); i2++) {
512  ModelItem* item = (*i2).second;
513  ostringstream os;
514  os << "DELETE FROM category_item WHERE item="
515  << item->get_id()
516  << " AND category="
517  << cat->get_id();
518  cout << "Query: " << os.str() << endl;
519  T.exec(os.str());
520  }
521  items = cat->get_added_children();
522  for (ItemMapIter i2 = items->begin(); i2 != items->end(); i2++) {
523  ModelItem* item = (*i2).second;
524  if (!item->is_deleted()) {
525  ostringstream os;
526  os << "INSERT INTO category_item (item, category) values ("
527  << item->get_id() << ", "
528  << cat->get_id() << ")";
529  cout << "Query: " << os.str() << endl;
530  T.exec(os.str());
531  }
532  }
533  }
534  }// for
535 
536  }
537 
538 
539  void on_commit() {
540  // Remove deleted items from categories etc.
541  m_model->purge();
542  // Clear the dirty, deleted and new flags etc.
543  m_model->reset();
544  }
545 
546 };
547 
548 
550 
552 class LoadCategory : public transactor<nontransaction> {
553  Category *m_category;
554  item_choice m_item_choice;
555  result R;
556 public:
557  LoadCategory(Category *category, item_choice choice)
558  : transactor<nontransaction>("LoadCategory"), m_category(category), m_item_choice(choice) {}
559 
560  void operator()(argument_type &T) {
561  // Perform a query on the database, storing result tuples in R.
562  ostringstream os;
563  os << "SELECT id, description, checked FROM item AS i "
564  << "JOIN category_item AS ci ON i.id=ci.item "
565  << "WHERE ci.category = '" << m_category->get_id() << "'";
566 
567  switch (m_item_choice) {
568  case CHECKED_ITEMS:
569  os << " AND i.checked=true";
570  break;
571  case UNCHECKED_ITEMS:
572  os << " AND i.checked=false";
573  break;
574  }
575 
576  os << " ORDER BY i.id";
577  R = T.exec(os.str());
578  }
579 
580  void on_commit() {
581  // Process each successive result tuple
582  for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
583  Item* i = new Item;
584  i->set_id(c[0].as(long()));
585  i->set_description(c[1].as(string()));
586  i->set_checked(c[2].as(bool()));
587  m_category->add_item(i);
588  }
589  }
590 
591 };
592 
593 
595 
597 class GetCategories : public transactor<nontransaction> {
598  result m_result;
599  CategoryContainer* m_categories;
600 public:
601  GetCategories(CategoryContainer* categories)
602  : transactor<nontransaction>("GetCategories"), m_categories(categories) {}
603 
604  void operator()(argument_type &T) {
605  m_result = T.exec("SELECT id, name FROM category ORDER BY id");
606  }
607 
608  void on_commit() {
609  if (!m_result.empty()) {
610  for (result::const_iterator c = m_result.begin(); c != m_result.end(); ++c) {
611  Category* cat = new Category;
612  cat->set_id(c[0].as(long()));
613  cat->set_name(c[1].as(string()));
614  m_categories->push_back(cat);
615  }
616  }
617  }
618 
619 };
620 
621 
630 KitListPgsqlDao::KitListPgsqlDao(int verbose) : KitListDao(verbose) {
631  connect();
632 }
633 
647 KitListPgsqlDao::KitListPgsqlDao(string dbname, int verbose) : KitListDao(verbose), m_dbname(dbname) {
648  connect();
649 }
650 
666 KitListPgsqlDao::KitListPgsqlDao(string dbname, string user, string port, int verbose)
667  : KitListDao(verbose), m_dbname(dbname), m_user(user), m_port(port) {
668  connect();
669 }
670 
671 KitListPgsqlDao::~KitListPgsqlDao() {
672  delete m_db_connection;
673  if (is_verbose())
674  cout << "Connection closed" << endl;
675 }
676 
680 void KitListPgsqlDao::connect() {
681  // Set up a connection to the backend.
682  string cs;
683  if (m_dbname.size() > 0) cs += "dbname=" + m_dbname;
684  if (m_user.size() > 0) cs += " user=" + m_user;
685  if (m_port.size() > 0) cs += " port=" + m_port;
686  if (is_verbose()) {
687  cout << "Connect string: \"" << cs << '"' << endl;
688  }
689  m_db_connection = new connection(cs);
690  if (is_verbose()) {
691  cout << "Connected to database: " << m_db_connection->dbname() << endl
692  << "Username: " << m_db_connection->username() << endl
693  << "Hostname: " << (m_db_connection->hostname() ? m_db_connection->hostname() : "(null)") << endl
694  << "Socket: " << m_db_connection->sock() << endl
695  << "Backend PID: " << m_db_connection->backendpid() << endl
696  << "Port: " << m_db_connection->port() << endl
697  << "Backend version: " << m_db_connection->server_version() << endl
698  << "Protocol version: " << m_db_connection->protocol_version() << endl << endl;
699  }
700 }
701 
702 
708 Category* KitListPgsqlDao::get_category(long cat_id, item_choice choice) {
709  Category* retval = new Category;
710  retval->set_id(cat_id);
711  m_db_connection->perform(LoadCategory(retval, choice));
712  return retval;
713 }
714 
715 
723 ItemContainer* KitListPgsqlDao::get_all_items(item_choice choice) {
724  ItemContainer* retval = new ItemContainer;
725  GetAllItems g = GetAllItems(retval, choice);
726  m_db_connection->perform(g);
727  return retval;
728 }
729 
730 
735 long KitListPgsqlDao::add_item(const std::string name) {
736  Item item;
737  item.set_description(name);
738  m_db_connection->perform(AddItem(&item));
739  return item.get_id();
740 }
741 
742 
747 long KitListPgsqlDao::add_item(const std::string name, long cat_id) {
748  Item item;
749  item.set_description(name);
750  m_db_connection->perform(AddCategoryItem(&item, cat_id));
751  return item.get_id();
752 }
753 
754 
763 void KitListPgsqlDao::append_items_to_category(long to_cat_id, long from_cat_id, item_choice choice) {
764  m_db_connection->perform(CopyItemsToCategory(from_cat_id, to_cat_id, choice));
765 }
766 
767 
774 void KitListPgsqlDao::associate_item_with_category(long id, long cat_id) {
775  m_db_connection->perform(AssociateItemWithCategory(id, cat_id));
776 }
777 
778 
782 CategoryContainer KitListPgsqlDao::get_categories() {
783  CategoryContainer retval;
784  m_db_connection->perform(GetCategories(&retval));
785  return retval;
786 }
787 
788 
793 long KitListPgsqlDao::new_category(const std::string name) {
794  long retval;
795  m_db_connection->perform(NewCategory(name, &retval));
796  return retval;
797 }
798 
799 
804 void KitListPgsqlDao::delete_item(long id) {
805  m_db_connection->perform(DeleteItem(id));
806 }
807 
808 
812 void KitListPgsqlDao::update_item_checked_state(ItemContainer& items) {
813  m_db_connection->perform(UpdateItemCheckedState(items));
814 }
815 
816 
823 void KitListPgsqlDao::remove_item_from_category(long id, long cat_id) {
824  m_db_connection->perform(RemoveItemFromCategory(id, cat_id));
825 }
826 
827 
831 long KitListPgsqlDao::get_next_item_id() {
832  long retval;
833  m_db_connection->perform(GetNextItemId(&retval));
834  return retval;
835 }
836 
837 
841 long KitListPgsqlDao::get_next_category_id() {
842  long retval;
843  m_db_connection->perform(GetNextCategoryId(&retval));
844  return retval;
845 }
846 
847 
851 void KitListPgsqlDao::delete_category(long id) {
852  m_db_connection->perform(DeleteCategory(id));
853 }
854 
855 
860 void KitListPgsqlDao::set_item_flag(long id) {
861  m_db_connection->perform(SetItemFlag(id, true));
862 }
863 
864 
868 void KitListPgsqlDao::unset_item_flag(long id) {
869  m_db_connection->perform(SetItemFlag(id, false));
870 }
871 
872 
876 void KitListPgsqlDao::set_category_flag(long id) {
877  m_db_connection->perform(SetCategoryFlag(id, true));
878 }
879 
880 
884 void KitListPgsqlDao::unset_category_flag(long id) {
885  m_db_connection->perform(SetCategoryFlag(id, false));
886 }
887 
888 
892 void KitListPgsqlDao::set_all_flags() {
893  m_db_connection->perform(SetAllFlags(true));
894 }
895 
896 
900 void KitListPgsqlDao::unset_all_flags() {
901  m_db_connection->perform(SetAllFlags(false));
902 }
903 
904 
912 KitModel* KitListPgsqlDao::get_model() {
913  KitModel* retval = new KitModel();
914  m_db_connection->perform(LoadModel(*retval));
915  return retval;
916 }
917 
918 
926 void KitListPgsqlDao::save_model(KitModel* model) {
927  m_db_connection->perform(SaveModel(model));
928 }
929 
930 #endif //HAVE_LIBPQXX
long get_id()
Definition: item.hpp:46
ModelItemContainer::iterator ModelItemIter
Definition: kitmodel.hpp:82
std::string get_name()
Definition: category.hpp:47
Represents a Category combined with GuiState attributes.
Definition: kitmodel.hpp:94
ItemContainer::iterator ItemIter
Definition: item.hpp:92
virtual void add_item(Item *item)
Associates the passed item with this Category.
Definition: category.cpp:29
void foreach_category(const SlotForeachCategory &slot)
Calls the provided slot for each category in the map.
Definition: kitmodel.cpp:254
STL namespace.
ItemMap::iterator ItemMapIter
Definition: kitmodel.hpp:85
bool is_dirty()
Definition: kitmodel.hpp:45
virtual void add_category(ModelCategory *category)
Add a category to the model.
Definition: kitmodel.cpp:361
virtual ModelItem * find_item(long id)
Finds an item by it&#39;s unique ID.
Definition: kitmodel.cpp:278
std::vector< Item * > ItemContainer
Definition: item.hpp:91
virtual ModelCategory * find_category(long id)
Finds a Category by it&#39;s unique ID.
Definition: kitmodel.cpp:265
virtual void set_checked(bool checked)
Definition: item.hpp:49
void set_name(const std::string name)
Definition: category.hpp:46
bool is_new()
Definition: kitmodel.hpp:50
std::vector< ModelItem * > ModelItemContainer
Definition: kitmodel.hpp:81
Defines the methods that an implementation of this class must implement.
Definition: kitlistdao.hpp:46
void set_id(long id)
Definition: category.hpp:44
Represents an Item.
Definition: item.hpp:37
bool is_deleted()
Definition: kitmodel.hpp:47
Represents a Category.
Definition: category.hpp:37
void set_id(long id)
Definition: item.hpp:45
std::string get_description()
Definition: item.hpp:48
Represents an Item combined with GuiState attributes.
Definition: kitmodel.hpp:60
std::vector< ModelCategory * > ModelCategoryContainer
Definition: kitmodel.hpp:119
Holds a rich graph of objects representing the application&#39;s data model.
Definition: kitmodel.hpp:135
bool get_checked()
Definition: item.hpp:50
virtual ItemMap * get_removed_children()
Returns a list of items that have been removed from the Category.
Definition: kitmodel.hpp:107
long get_id()
Definition: category.hpp:45
void foreach_item(const SlotForeachModelItem &slot)
Calls the provided slot for each item in the map.
Definition: kitmodel.cpp:230
virtual void set_checked(bool checked)
Definition: kitmodel.hpp:64
ModelCategoryContainer::iterator ModelCategoryIter
Definition: kitmodel.hpp:120
virtual void add_item(Item *)
Adds the passed item to this ModelCategory.
Definition: kitmodel.cpp:88
std::vector< Category * > CategoryContainer
Definition: category.hpp:84
virtual void add_item(ModelItem *item)
Adds an item to the model.
Definition: kitmodel.cpp:371
virtual void purge()
Purges deleted categories and items from the model.
Definition: kitmodel.cpp:486
item_choice
Definition: kitlistdao.hpp:36
virtual void reset()
Resets all contained objects to their default states.
Definition: kitmodel.cpp:466
std::map< long, ModelCategory * > CategoryMap
Definition: kitmodel.hpp:122
void set_description(const std::string description)
Definition: item.hpp:47
std::map< long, ModelItem * > ItemMap
Definition: kitmodel.hpp:84
virtual ItemMap * get_added_children()
Returns a list of items that have been added to the Category.
Definition: kitmodel.hpp:109

Copyright 2008-2021 Frank Dean