00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cassert>
00024 #include <iostream>
00025 #include <sstream>
00026 #include "kitlistpgsqldao.hpp"
00027
00028 #ifdef HAVE_LIBPQXX
00029
00030 using namespace std;
00031 using namespace PGSTD;
00032 using namespace pqxx;
00033
00034
00036 class AddItem : public transactor<> {
00037 Item* m_item;
00038 long m_new_id;
00039 public:
00040 AddItem(Item* item) : transactor<>("AddItem"), m_item(item) {}
00041
00042 void operator()(argument_type &T) {
00043 T.exec("INSERT INTO item (description, checked) values('" +
00044 T.esc(m_item->get_description()) + "', " +
00045 (m_item->get_checked() ? "true" : "false") + ")");
00046 result R(T.exec("SELECT lastval()"));
00047 R.front()[0].to(m_new_id);
00048 }
00049
00050 void on_commit() {
00051 m_item->set_id(m_new_id);
00052 }
00053
00054 };
00055
00056
00058 class AssociateItemWithCategory : public transactor<> {
00059 long m_id;
00060 long m_cat_id;
00061 public:
00062 AssociateItemWithCategory(long id, long cat_id) :
00063 transactor<>("AssociateItemWithCategory"), m_id(id), m_cat_id(cat_id) {}
00064
00065 void operator()(argument_type &T) {
00066 ostringstream os;
00067 os << "INSERT INTO category_item (item, category) VALUES('" << m_id << "', '" << m_cat_id << "')";
00068 T.exec(os.str());
00069 }
00070
00071 };
00072
00073
00075 class DeleteItem : public transactor<> {
00076 long m_id;
00077 public:
00078 DeleteItem(long id) : transactor<>("DeleteItem"), m_id(id) {}
00079
00080 void operator()(argument_type &T) {
00081 ostringstream os;
00082 os << "DELETE FROM item WHERE id='" << m_id << '\'';
00083 T.exec(os.str());
00084 }
00085
00086 };
00087
00088
00090 class UpdateItemCheckedState : public transactor<> {
00091 ItemContainer& m_items;
00092 public:
00093 UpdateItemCheckedState(ItemContainer& items)
00094 : transactor<>("UpdateItemCheckedState"), m_items(items) {}
00095
00096 void operator()(argument_type &T) {
00097 for (ItemIter i = m_items.begin(); i != m_items.end(); ++i) {
00098 ostringstream os;
00099 os << "UPDATE item SET checked="
00100 << ((*i)->get_checked() ? "true" : "false")
00101 << " WHERE id=" << (*i)->get_id();
00102 T.exec(os.str());
00103 }
00104 }
00105
00106 };
00107
00108
00110 class RemoveItemFromCategory : public transactor<> {
00111 long m_id;
00112 long m_cat_id;
00113 public:
00114 RemoveItemFromCategory(long id, long cat_id) :
00115 transactor<>("RemoveItemFromCategory"), m_id(id), m_cat_id(cat_id) {}
00116
00117 void operator()(argument_type &T) {
00118 ostringstream os;
00119 os << "DELETE FROM category_item WHERE item='"
00120 << m_id << "' AND category='" << m_cat_id << '\'';
00121 T.exec(os.str());
00122 }
00123
00124 };
00125
00126
00128 class SetItemFlag : public transactor<> {
00129 long m_id;
00130 bool m_flag;
00131 public:
00132 SetItemFlag(long id, bool flag) : transactor<>("SetItemFlag"), m_id(id), m_flag(flag) {}
00133
00134 void operator()(argument_type &T) {
00135 ostringstream os;
00136 os << "UPDATE item SET checked=" << (m_flag ? "true" : "false") << " WHERE id='" << m_id << '\'';
00137 T.exec(os.str());
00138 }
00139
00140 };
00141
00142
00144 class SetCategoryFlag : public transactor<> {
00145 long m_cat_id;
00146 bool m_flag;
00147 public:
00148 SetCategoryFlag(long cat_id, bool flag) : transactor<>("SetCategoryFlag"), m_cat_id(cat_id), m_flag(flag) {}
00149
00150 void operator()(argument_type &T) {
00151 ostringstream os;
00152 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 << "'";
00153 T.exec(os.str());
00154 }
00155
00156 };
00157
00158
00160 class SetAllFlags : public transactor<> {
00161 bool m_flag;
00162 public:
00163 SetAllFlags(bool flag) : transactor<>("SetAllFlags"), m_flag(flag) {}
00164
00165 void operator()(argument_type &T) {
00166 ostringstream os;
00167 os << "UPDATE item SET checked=" << (m_flag ? "true" : "false");
00168 T.exec(os.str());
00169 }
00170
00171 };
00172
00173
00175 class DeleteCategory : public transactor<> {
00176 long m_id;
00177 public:
00178 DeleteCategory(long id) : transactor<>("DeleteCategory"), m_id(id) {}
00179
00180 void operator()(argument_type &T) {
00181 ostringstream os;
00182 os << "DELETE FROM category WHERE id='" << m_id << '\'';
00183 T.exec(os.str());
00184 }
00185
00186 };
00187
00188
00190 class NewCategory : public transactor<> {
00191 string m_name;
00192 long* m_new_id;
00193 result R;
00194 public:
00195 NewCategory(string name, long* id) : transactor<>("NewCategory"), m_name(name), m_new_id(id) {}
00196
00197 void operator()(argument_type &T) {
00198 T.exec("INSERT INTO category (NAME) values('" + T.esc(m_name) + "')");
00199 R = T.exec("SELECT lastval()");
00200 }
00201
00202 void on_commit() {
00203 R.front()[0].to(*m_new_id);
00204 }
00205
00206 };
00207
00208
00210 class AddCategoryItem : public transactor<> {
00211 Item* m_item;
00212 long m_cat_id;
00213 long m_new_id;
00214 public:
00215 AddCategoryItem(Item* item, long cat_id)
00216 : transactor<>("AddCategoryItem"), m_item(item), m_cat_id(cat_id) {}
00217
00218 void operator()(argument_type &T) {
00219 T.exec("INSERT INTO item (description, checked) values('" +
00220 T.esc(m_item->get_description()) + "', " +
00221 (m_item->get_checked() ? "true" : "false") + ")");
00222 result R(T.exec("SELECT lastval()"));
00223 result::reference ref = R.front();
00224 m_new_id =ref[0].as(long());
00225 ostringstream os;
00226 os << "INSERT INTO category_item (category, item) VALUES('"
00227 << m_cat_id << "', '" << m_new_id << "')";
00228 T.exec(os.str());
00229 }
00230
00231 void on_commit() {
00232 m_item->set_id(m_new_id);
00233 }
00234
00235 };
00236
00237
00239
00241 class CopyItemsToCategory : public transactor<> {
00242 long m_from_cat_id;
00243 long m_to_cat_id;
00244 item_choice m_item_choice;
00245 public:
00246 CopyItemsToCategory(long from_cat_id, long to_cat_id, item_choice choice)
00247 : transactor<>("CopyItemsToCategory"),
00248 m_from_cat_id(from_cat_id),
00249 m_to_cat_id(to_cat_id),
00250 m_item_choice(choice) {}
00251
00252 void operator()(argument_type &T) {
00253 ostringstream os;
00254
00255 os << "INSERT INTO category_item (item, category) ";
00256
00257
00258 if (m_from_cat_id >= 0) {
00259 switch (m_item_choice) {
00260 case CHECKED_ITEMS:
00261 case UNCHECKED_ITEMS:
00262 os << "SELECT ci.item AS item, '" << m_to_cat_id << "' AS category FROM category_item AS ci "
00263 << "JOIN item i ON ci.item=i.id ";
00264 break;
00265 default:
00266 os << "SELECT ci.item AS item, '" << m_to_cat_id << "' AS category FROM category_item AS ci ";
00267 }
00268 os << "WHERE ci.category='" << m_from_cat_id << "' ";
00269
00270 switch (m_item_choice) {
00271 case CHECKED_ITEMS:
00272 os << "AND i.checked=true ";
00273 break;
00274 case UNCHECKED_ITEMS:
00275 os << "AND i.checked=false ";
00276 break;
00277 }
00278 os << "AND ci.item NOT IN ";
00279 } else {
00280 os << "SELECT i.id AS item, '" << m_to_cat_id << "' FROM item AS i WHERE ";
00281 switch (m_item_choice) {
00282 case CHECKED_ITEMS:
00283 os << "i.checked=true AND ";
00284 break;
00285 case UNCHECKED_ITEMS:
00286 os << "i.checked=false AND ";
00287 break;
00288 }
00289 os << "i.id NOT IN ";
00290 }
00291
00292
00293 os << "(SELECT c2.item FROM category_item AS c2 WHERE c2.category='" << m_to_cat_id << "')";
00294
00295 T.exec(os.str());
00296 }
00297
00298 };
00299
00300
00302 class GetNextItemId : public transactor<> {
00303 long* m_id;
00304 result R;
00305 public:
00306 GetNextItemId(long* id) : transactor<>("GetNextItemId"), m_id(id) {}
00307
00308 void operator()(argument_type &T) {
00309 R = T.exec("SELECT nextval('item_sequence')");
00310 }
00311
00312 void on_commit() {
00313 R.front()[0].to(*m_id);
00314 }
00315
00316 };
00317
00318
00320 class GetNextCategoryId : public transactor<> {
00321 long* m_cat_id;
00322 result R;
00323 public:
00324 GetNextCategoryId(long* cat_id) : transactor<>("GetNextCategoryId"), m_cat_id(cat_id) {}
00325
00326 void operator()(argument_type &T) {
00327 R = T.exec("SELECT nextval('category_sequence')");
00328 }
00329
00330 void on_commit() {
00331 R.front()[0].to(*m_cat_id);
00332 }
00333
00334 };
00335
00336
00337
00339
00341 class GetAllItems : public transactor<nontransaction> {
00342 ItemContainer* m_items;
00343 item_choice m_item_choice;
00344 result R;
00345 public:
00346 GetAllItems(ItemContainer* items, item_choice choice)
00347 : transactor<nontransaction>("GetAllItems"), m_items(items), m_item_choice(choice) {}
00348
00349 void operator()(argument_type &T) {
00350
00351 ostringstream os;
00352 os << "SELECT id, description, checked FROM item";
00353 switch (m_item_choice) {
00354 case CHECKED_ITEMS:
00355 os << " WHERE checked=true";
00356 break;
00357 case UNCHECKED_ITEMS:
00358 os << " WHERE checked=false";
00359 break;
00360 }
00361 os << " ORDER BY id";
00362 R = T.exec(os.str());
00363 }
00364
00365 void on_commit() {
00366
00367 for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
00368 Item* item = new Item;
00369 item->set_id(c[0].as(long()));
00370 item->set_description(c[1].as(string()));
00371 item->set_checked(c[2].as(bool()));
00372 m_items->push_back(item);
00373 }
00374 }
00375
00376 };
00377
00378
00380 class LoadModel : public pqxx::transactor<pqxx::nontransaction> {
00381 KitModel& m_kitmodel;
00382 CategoryMap* m_categories;
00383 pqxx::result R;
00384 public:
00385 LoadModel(KitModel& kitmodel) : pqxx::transactor<pqxx::nontransaction>("LoadModel"), m_kitmodel(kitmodel) {}
00386
00387 void operator()(argument_type &T) {
00388 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");
00389 }
00390
00391 void on_commit() {
00392 for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
00393
00394 ModelItem* item = 0;
00395 if (!c[0].is_null()) {
00396 long item_id = c[0].as(long());
00397
00398 item = m_kitmodel.find_item(item_id);
00399 if (!item) {
00400 item = new ModelItem;
00401 item->set_id(item_id);
00402 item->set_description(c[2].as(string()));
00403 item->set_checked(c[4].as(bool()));
00404 m_kitmodel.add_item(item);
00405 }
00406 }
00407
00408
00409 if (!c[1].is_null()) {
00410 long cat_id = c[1].as(long());
00411
00412 ModelCategory* category = 0;
00413 category = m_kitmodel.find_category(cat_id);
00414 if (!category) {
00415 category = new ModelCategory;
00416 category->set_id(cat_id);
00417 category->set_name(c[3].as(string()));
00418 m_kitmodel.add_category(category);
00419 }
00420 if (item)
00421 category->add_item(item);
00422 }
00423
00424 }
00425 m_kitmodel.reset();
00426 }
00427
00428 };
00429
00430
00432 class SaveModel : public transactor<> {
00433 private:
00434 ModelItemContainer m_items;
00435 ModelCategoryContainer m_categories;
00436 protected:
00437 KitModel* m_model;
00438 public:
00439 SaveModel(KitModel* model) : transactor<>("SaveModel"), m_model(model), m_items(0) {}
00440
00441
00442 bool on_foreach_item(ModelItem& item) {
00443 m_items.push_back(&item);
00444 return false;
00445 }
00446
00447
00448 bool on_foreach_category(ModelCategory& category) {
00449 m_categories.push_back(&category);
00450 return false;
00451 }
00452
00453
00454 void operator()(argument_type &T) {
00455
00456
00457 m_model->foreach_item( sigc::mem_fun(*this, &SaveModel::on_foreach_item) );
00458
00459
00460 for (ModelItemIter i = m_items.begin(); i != m_items.end(); ++i) {
00461 ModelItem* item = (*i);
00462 if (item->is_dirty()) {
00463 ostringstream os;
00464 if (item->is_new()) {
00465 os << "INSERT INTO item (id, description, checked) values("
00466 << item->get_id() << ", '"
00467 << T.esc(item->get_description()) << "', "
00468 << (item->get_checked() ? "true" : "false") << ")";
00469 } else if (item->is_deleted()) {
00470 os << "DELETE FROM item WHERE id="
00471 << item->get_id();
00472 } else {
00473 os << "UPDATE item SET description='"
00474 << T.esc(item->get_description()) << "', checked="
00475 << (item->get_checked() ? "true" : "false")
00476 << " WHERE id=" << item->get_id();
00477 }
00478 cout << "Query: " << os.str() << endl;
00479 T.exec(os.str());
00480 }
00481 }
00482
00483
00484 m_model->foreach_category( sigc::mem_fun(*this, &SaveModel::on_foreach_category) );
00485
00486
00487 for (ModelCategoryIter i = m_categories.begin(); i != m_categories.end(); ++i) {
00488 ModelCategory* cat = (*i);
00489 if (cat->is_dirty()) {
00490 ostringstream os;
00491 if (cat->is_new()) {
00492 os << "INSERT INTO category (id, name) values("
00493 << cat->get_id() << ", '"
00494 << T.esc(cat->get_name()) << "')";
00495 } else if (cat->is_deleted()) {
00496 os << "DELETE FROM category WHERE id="
00497 << cat->get_id();
00498 } else {
00499 os << "UPDATE category SET name='"
00500 << T.esc(cat->get_name())
00501 << "' WHERE id=" << cat->get_id();
00502 }
00503 cout << "Query: " << os.str() << endl;
00504 T.exec(os.str());
00505 }
00506
00507
00508
00509 if (!cat->is_deleted()) {
00510 ItemMap* items = cat->get_removed_children();
00511 for (ItemMapIter i2 = items->begin(); i2 != items->end(); i2++) {
00512 ModelItem* item = (*i2).second;
00513 ostringstream os;
00514 os << "DELETE FROM category_item WHERE item="
00515 << item->get_id()
00516 << " AND category="
00517 << cat->get_id();
00518 cout << "Query: " << os.str() << endl;
00519 T.exec(os.str());
00520 }
00521 items = cat->get_added_children();
00522 for (ItemMapIter i2 = items->begin(); i2 != items->end(); i2++) {
00523 ModelItem* item = (*i2).second;
00524 if (!item->is_deleted()) {
00525 ostringstream os;
00526 os << "INSERT INTO category_item (item, category) values ("
00527 << item->get_id() << ", "
00528 << cat->get_id() << ")";
00529 cout << "Query: " << os.str() << endl;
00530 T.exec(os.str());
00531 }
00532 }
00533 }
00534 }
00535
00536 }
00537
00538
00539 void on_commit() {
00540
00541 m_model->purge();
00542
00543 m_model->reset();
00544 }
00545
00546 };
00547
00548
00550
00552 class LoadCategory : public transactor<nontransaction> {
00553 Category *m_category;
00554 item_choice m_item_choice;
00555 result R;
00556 public:
00557 LoadCategory(Category *category, item_choice choice)
00558 : transactor<nontransaction>("LoadCategory"), m_category(category), m_item_choice(choice) {}
00559
00560 void operator()(argument_type &T) {
00561
00562 ostringstream os;
00563 os << "SELECT id, description, checked FROM item AS i "
00564 << "JOIN category_item AS ci ON i.id=ci.item "
00565 << "WHERE ci.category = '" << m_category->get_id() << "'";
00566
00567 switch (m_item_choice) {
00568 case CHECKED_ITEMS:
00569 os << " AND i.checked=true";
00570 break;
00571 case UNCHECKED_ITEMS:
00572 os << " AND i.checked=false";
00573 break;
00574 }
00575
00576 os << " ORDER BY i.id";
00577 R = T.exec(os.str());
00578 }
00579
00580 void on_commit() {
00581
00582 for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
00583 Item* i = new Item;
00584 i->set_id(c[0].as(long()));
00585 i->set_description(c[1].as(string()));
00586 i->set_checked(c[2].as(bool()));
00587 m_category->add_item(i);
00588 }
00589 }
00590
00591 };
00592
00593
00595
00597 class GetCategories : public transactor<nontransaction> {
00598 result m_result;
00599 CategoryContainer* m_categories;
00600 public:
00601 GetCategories(CategoryContainer* categories)
00602 : transactor<nontransaction>("GetCategories"), m_categories(categories) {}
00603
00604 void operator()(argument_type &T) {
00605 m_result = T.exec("SELECT id, name FROM category ORDER BY id");
00606 }
00607
00608 void on_commit() {
00609 if (!m_result.empty()) {
00610 for (result::const_iterator c = m_result.begin(); c != m_result.end(); ++c) {
00611 Category* cat = new Category;
00612 cat->set_id(c[0].as(long()));
00613 cat->set_name(c[1].as(string()));
00614 m_categories->push_back(cat);
00615 }
00616 }
00617 }
00618
00619 };
00620
00621
00630 KitListPgsqlDao::KitListPgsqlDao(int verbose) : KitListDao(verbose) {
00631 connect();
00632 }
00633
00647 KitListPgsqlDao::KitListPgsqlDao(string dbname, int verbose) : KitListDao(verbose), m_dbname(dbname) {
00648 connect();
00649 }
00650
00666 KitListPgsqlDao::KitListPgsqlDao(string dbname, string user, string port, int verbose)
00667 : KitListDao(verbose), m_dbname(dbname), m_user(user), m_port(port) {
00668 connect();
00669 }
00670
00671 KitListPgsqlDao::~KitListPgsqlDao() {
00672 delete m_db_connection;
00673 if (is_verbose())
00674 cout << "Connection closed" << endl;
00675 }
00676
00680 void KitListPgsqlDao::connect() {
00681
00682 string cs;
00683 if (m_dbname.size() > 0) cs += "dbname=" + m_dbname;
00684 if (m_user.size() > 0) cs += " user=" + m_user;
00685 if (m_port.size() > 0) cs += " port=" + m_port;
00686 if (is_verbose()) {
00687 cout << "Connect string: \"" << cs << '"' << endl;
00688 }
00689 m_db_connection = new connection(cs);
00690 if (is_verbose()) {
00691 cout << "Connected to database: " << m_db_connection->dbname() << endl
00692 << "Username: " << m_db_connection->username() << endl
00693 << "Hostname: " << (m_db_connection->hostname() ? m_db_connection->hostname() : "(null)") << endl
00694 << "Socket: " << m_db_connection->sock() << endl
00695 << "Backend PID: " << m_db_connection->backendpid() << endl
00696 << "Port: " << m_db_connection->port() << endl
00697 << "Backend version: " << m_db_connection->server_version() << endl
00698 << "Protocol version: " << m_db_connection->protocol_version() << endl << endl;
00699 }
00700 }
00701
00702
00708 Category* KitListPgsqlDao::get_category(long cat_id, item_choice choice) {
00709 Category* retval = new Category;
00710 retval->set_id(cat_id);
00711 m_db_connection->perform(LoadCategory(retval, choice));
00712 return retval;
00713 }
00714
00715
00723 ItemContainer* KitListPgsqlDao::get_all_items(item_choice choice) {
00724 ItemContainer* retval = new ItemContainer;
00725 GetAllItems g = GetAllItems(retval, choice);
00726 m_db_connection->perform(g);
00727 return retval;
00728 }
00729
00730
00735 long KitListPgsqlDao::add_item(const std::string name) {
00736 Item item;
00737 item.set_description(name);
00738 m_db_connection->perform(AddItem(&item));
00739 return item.get_id();
00740 }
00741
00742
00747 long KitListPgsqlDao::add_item(const std::string name, long cat_id) {
00748 Item item;
00749 item.set_description(name);
00750 m_db_connection->perform(AddCategoryItem(&item, cat_id));
00751 return item.get_id();
00752 }
00753
00754
00763 void KitListPgsqlDao::append_items_to_category(long to_cat_id, long from_cat_id, item_choice choice) {
00764 m_db_connection->perform(CopyItemsToCategory(from_cat_id, to_cat_id, choice));
00765 }
00766
00767
00774 void KitListPgsqlDao::associate_item_with_category(long id, long cat_id) {
00775 m_db_connection->perform(AssociateItemWithCategory(id, cat_id));
00776 }
00777
00778
00782 CategoryContainer KitListPgsqlDao::get_categories() {
00783 CategoryContainer retval;
00784 m_db_connection->perform(GetCategories(&retval));
00785 return retval;
00786 }
00787
00788
00793 long KitListPgsqlDao::new_category(const std::string name) {
00794 long retval;
00795 m_db_connection->perform(NewCategory(name, &retval));
00796 return retval;
00797 }
00798
00799
00804 void KitListPgsqlDao::delete_item(long id) {
00805 m_db_connection->perform(DeleteItem(id));
00806 }
00807
00808
00812 void KitListPgsqlDao::update_item_checked_state(ItemContainer& items) {
00813 m_db_connection->perform(UpdateItemCheckedState(items));
00814 }
00815
00816
00823 void KitListPgsqlDao::remove_item_from_category(long id, long cat_id) {
00824 m_db_connection->perform(RemoveItemFromCategory(id, cat_id));
00825 }
00826
00827
00831 long KitListPgsqlDao::get_next_item_id() {
00832 long retval;
00833 m_db_connection->perform(GetNextItemId(&retval));
00834 return retval;
00835 }
00836
00837
00841 long KitListPgsqlDao::get_next_category_id() {
00842 long retval;
00843 m_db_connection->perform(GetNextCategoryId(&retval));
00844 return retval;
00845 }
00846
00847
00851 void KitListPgsqlDao::delete_category(long id) {
00852 m_db_connection->perform(DeleteCategory(id));
00853 }
00854
00855
00860 void KitListPgsqlDao::set_item_flag(long id) {
00861 m_db_connection->perform(SetItemFlag(id, true));
00862 }
00863
00864
00868 void KitListPgsqlDao::unset_item_flag(long id) {
00869 m_db_connection->perform(SetItemFlag(id, false));
00870 }
00871
00872
00876 void KitListPgsqlDao::set_category_flag(long id) {
00877 m_db_connection->perform(SetCategoryFlag(id, true));
00878 }
00879
00880
00884 void KitListPgsqlDao::unset_category_flag(long id) {
00885 m_db_connection->perform(SetCategoryFlag(id, false));
00886 }
00887
00888
00892 void KitListPgsqlDao::set_all_flags() {
00893 m_db_connection->perform(SetAllFlags(true));
00894 }
00895
00896
00900 void KitListPgsqlDao::unset_all_flags() {
00901 m_db_connection->perform(SetAllFlags(false));
00902 }
00903
00904
00912 KitModel* KitListPgsqlDao::get_model() {
00913 KitModel* retval = new KitModel();
00914 m_db_connection->perform(LoadModel(*retval));
00915 return retval;
00916 }
00917
00918
00926 void KitListPgsqlDao::save_model(KitModel* model) {
00927 m_db_connection->perform(SaveModel(model));
00928 }
00929
00930 #endif //HAVE_LIBPQXX