From e98e9d357c64c905fe123bdd619f2a8f55912d1a Mon Sep 17 00:00:00 2001 From: Santanu Sinha Date: Fri, 22 May 2009 02:26:48 +0530 Subject: [PATCH] Proper handling of multiple types of queries - A type was added to denote the type of clubbing - Convenience functions were added to query-criteria interface - Automatic ID generation for all query types have been aded - ID and Clubbing types are now used by the database to create queries --- src/attribute/basic-exif-view.cpp | 28 +++++++++++------ src/attribute/exif-data-key.cpp | 26 ++++++++++++++++ src/attribute/exif-data-key.h | 24 +++++++++++++-- src/attribute/modification-date.cpp | 31 ++++++++++++++++++- src/attribute/modification-date.h | 12 +++++++ src/attribute/tag.cpp | 24 ++++++++++++++- src/attribute/tag.h | 14 +++++++++ src/common/Makefile.am | 3 ++ src/common/id-base.h | 56 +++++++++++++++++++++++++++++++++++ src/common/id-repo.cpp | 29 ++++++++++++++++++ src/common/id-repo.h | 44 +++++++++++++++++++++++++++ src/common/photo-search-criteria.h | 34 +++++++++++++++++---- src/database/database.cpp | 55 ++++++++++++++++++++++++++++++---- 13 files changed, 352 insertions(+), 28 deletions(-) create mode 100644 src/common/id-base.h create mode 100644 src/common/id-repo.cpp create mode 100644 src/common/id-repo.h diff --git a/src/attribute/basic-exif-view.cpp b/src/attribute/basic-exif-view.cpp index d169106..00c7533 100644 --- a/src/attribute/basic-exif-view.cpp +++ b/src/attribute/basic-exif-view.cpp @@ -79,7 +79,8 @@ BasicExifView::populate(const ExifData& data) throw() Gtk::TreeModel::iterator model_iter = listStore_->append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("aperture", data.get_aperture())); + new ExifDataKey("Aperture", + "aperture", data.get_aperture())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; @@ -91,8 +92,9 @@ BasicExifView::populate(const ExifData& data) throw() Gtk::TreeModel::iterator model_iter = listStore_->append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("shutter_speed", - data.get_shutter_speed())); + new ExifDataKey("Shutter Speed", + "shutter_speed", + data.get_shutter_speed())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; row[modelColumnRecord_.get_column_description()] = "Shutter Speed"; @@ -103,8 +105,9 @@ BasicExifView::populate(const ExifData& data) throw() Gtk::TreeModel::iterator model_iter = listStore_->append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("exposure_program" , - data.get_exposure_program())); + new ExifDataKey("Exposure Program", + "exposure_program" , + data.get_exposure_program())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; row[modelColumnRecord_.get_column_description()] = "Exposure Program"; @@ -117,7 +120,8 @@ BasicExifView::populate(const ExifData& data) throw() std::ostringstream sout; sout<append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("metering_mode" , + new ExifDataKey("Exposure Metering Mode", + "metering_mode" , data.get_exposure_metering_mode())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; @@ -142,7 +147,8 @@ BasicExifView::populate(const ExifData& data) throw() Gtk::TreeModel::iterator model_iter = listStore_->append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("focal_length" , + new ExifDataKey("Actual Focal Length", + "focal_length" , data.get_focal_length())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; @@ -156,7 +162,8 @@ BasicExifView::populate(const ExifData& data) throw() Gtk::TreeModel::iterator model_iter = listStore_->append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("white_balance" , + new ExifDataKey("White Balance", + "white_balance" , data.get_white_balance())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; @@ -170,7 +177,8 @@ BasicExifView::populate(const ExifData& data) throw() Gtk::TreeModel::iterator model_iter = listStore_->append(); Gtk::TreeModel::Row row = *model_iter; const ExifDataKeyPtr key( - new ExifDataKey("focal_length_in_film" , + new ExifDataKey("35mm Camera Focal Length", + "focal_length_in_film" , data.get_focal_length_film())); row[modelColumnRecord_.get_column_key()] = key; row[modelColumnRecord_.get_column_selected()] = false; diff --git a/src/attribute/exif-data-key.cpp b/src/attribute/exif-data-key.cpp index e277901..21665d9 100644 --- a/src/attribute/exif-data-key.cpp +++ b/src/attribute/exif-data-key.cpp @@ -1,4 +1,5 @@ #include "exif-data-key.h" +#include "id-base.h" namespace Solang { @@ -11,4 +12,29 @@ ExifDataKey::get_query_criteria() const throw() return sout.str(); } +PhotoSearchCriteria::ClubbingOperationType +ExifDataKey::get_clubbing_type() const throw() +{ + return PhotoSearchCriteria::CLUB_AND; +} + +gint32 +ExifDataKey::get_id() const throw() +{ + return IDBase::get_id(); +} + +Glib::ustring +ExifDataKey::get_criteria_description() const throw() +{ + return title_ + ": " + value_; +} + +Glib::ustring +ExifDataKey::get_criteria_icon_path() const throw() +{ + //TBD::CORRECT + return PACKAGE_DATA_DIR"/"PACKAGE_NAME"/pixmaps/tag-16.png"; +} + } diff --git a/src/attribute/exif-data-key.h b/src/attribute/exif-data-key.h index fdd44cc..b97c536 100644 --- a/src/attribute/exif-data-key.h +++ b/src/attribute/exif-data-key.h @@ -19,6 +19,8 @@ #ifndef SOLANG_EXIF_DATA_KEY_H #define SOLANG_EXIF_DATA_KEY_H +#include "config.h" + #include "photo-search-criteria.h" namespace Solang @@ -28,13 +30,16 @@ class ExifDataKey : public PhotoSearchCriteria { private: + Glib::ustring title_; Glib::ustring key_; Glib::ustring value_; public: - ExifDataKey( const Glib::ustring & key, - const Glib::ustring & value ) - :key_( key ), + ExifDataKey( const Glib::ustring &title, + const Glib::ustring & key, + const Glib::ustring & value ) + :title_( title ), + key_( key ), value_( value ) { } @@ -45,6 +50,19 @@ class ExifDataKey : Glib::ustring get_query_criteria() const throw(); + + virtual ClubbingOperationType + get_clubbing_type() const throw(); + + virtual gint32 + get_id() const throw(); + + virtual Glib::ustring + get_criteria_description() const throw(); + + virtual Glib::ustring + get_criteria_icon_path() const throw(); + }; } // namespace Solang diff --git a/src/attribute/modification-date.cpp b/src/attribute/modification-date.cpp index 4819858..d085483 100644 --- a/src/attribute/modification-date.cpp +++ b/src/attribute/modification-date.cpp @@ -1,11 +1,11 @@ #include +#include "id-base.h" #include "modification-date.h" namespace Solang { - const gint32 ModificationDate::MOD_DAY_COL = 2; const gint32 ModificationDate::MOD_MONTH_COL = 3; const gint32 ModificationDate::MOD_YEAR_COL = 4; @@ -21,6 +21,35 @@ ModificationDate::get_query_criteria() const throw() return sout.str(); } +PhotoSearchCriteria::ClubbingOperationType +ModificationDate::get_clubbing_type() const throw() +{ + return PhotoSearchCriteria::CLUB_OR; +} + +gint32 +ModificationDate::get_id() const throw() +{ + return IDBase::get_id(); +} + +Glib::ustring +ModificationDate::get_criteria_description() const throw() +{ + std::ostringstream sout; + sout< &values) { diff --git a/src/attribute/modification-date.h b/src/attribute/modification-date.h index afc01cc..0ddd663 100644 --- a/src/attribute/modification-date.h +++ b/src/attribute/modification-date.h @@ -149,6 +149,18 @@ class ModificationDate virtual Glib::ustring get_query_criteria() const throw(); + virtual ClubbingOperationType + get_clubbing_type() const throw(); + + virtual gint32 + get_id() const throw(); + + virtual Glib::ustring + get_criteria_description() const throw(); + + virtual Glib::ustring + get_criteria_icon_path() const throw(); + void insert(std::list &values); diff --git a/src/attribute/tag.cpp b/src/attribute/tag.cpp index b6b60b9..114abd3 100644 --- a/src/attribute/tag.cpp +++ b/src/attribute/tag.cpp @@ -22,11 +22,11 @@ #include #include +#include "id-base.h" #include "tag.h" namespace Solang { - const gint32 Tag::TAGID_COL = 0; const gint32 Tag::NAME_COL = 1; const gint32 Tag::DESCRIPTION_COL = 2; @@ -160,6 +160,28 @@ Tag::set_icon_path(Glib::ustring const & value) iconPath_ = value; } +PhotoSearchCriteria::ClubbingOperationType +Tag::get_clubbing_type() const throw() +{ + return PhotoSearchCriteria::CLUB_OR; +} +gint32 +Tag::get_id() const throw() +{ + return IDBase::get_id(); +} + +Glib::ustring +Tag::get_criteria_description() const throw() +{ + return "Tag: " + get_name(); +} + +Glib::ustring +Tag::get_criteria_icon_path() const throw() +{ + return PACKAGE_DATA_DIR"/"PACKAGE_NAME"/pixmaps/tag-16.png"; +} } //namespace Solang diff --git a/src/attribute/tag.h b/src/attribute/tag.h index 3948aee..30d6ba8 100644 --- a/src/attribute/tag.h +++ b/src/attribute/tag.h @@ -93,6 +93,20 @@ class Tag : virtual Glib::ustring get_query_criteria() const throw(); + + virtual ClubbingOperationType + get_clubbing_type() const throw(); + + virtual gint32 + get_id() const throw(); + + virtual Glib::ustring + get_criteria_description() const throw(); + + virtual Glib::ustring + get_criteria_icon_path() const throw(); + + }; inline gint diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 037e168..69b4bdd 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -3,6 +3,9 @@ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = \ error.cpp \ error.h \ + id-counted-base.h \ + id-repo.cpp \ + id-repo.h \ i-photo-destination.cpp \ i-photo-destination.h \ i-photo-source.cpp \ diff --git a/src/common/id-base.h b/src/common/id-base.h new file mode 100644 index 0000000..d9abf13 --- /dev/null +++ b/src/common/id-base.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * Copyright (C) Santanu Sinha 2009 + * + * Solang is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Solang is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SOLANG_ID_BASE_H +#define SOLANG_ID_BASE_H + +#include "config.h" + +#include + +#include "id-repo.h" + +namespace Solang +{ + +template +class IDBase +{ + private: + static const gint32 id_; + + public: + static inline gint32 + get_id(); + +}; + + +template +inline gint32 +IDBase::get_id() +{ + return IDBase::id_; +} + +template +const gint32 IDBase::id_ = IdRepo::getValue(); + +} // namespace Solang + +#endif //SOLANG_ID_BASE_H diff --git a/src/common/id-repo.cpp b/src/common/id-repo.cpp new file mode 100644 index 0000000..2f728cb --- /dev/null +++ b/src/common/id-repo.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * Copyright (C) Santanu Sinha 2009 + * + * Solang is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Solang is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "id-repo.h" + +namespace Solang +{ + +gint32 IdRepo::id_ = 0; + +} + +//namespace Solang + diff --git a/src/common/id-repo.h b/src/common/id-repo.h new file mode 100644 index 0000000..288ea4e --- /dev/null +++ b/src/common/id-repo.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * Copyright (C) Santanu Sinha 2009 + * + * Solang is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Solang is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SOLANG_ID_GEN_H +#define SOLANG_ID_GEN_H + +#include "config.h" + +#include + +namespace Solang +{ + +class IdRepo +{ + private: + static gint32 id_; + + public: + static int getValue() + { + return id_++; + } + +}; + +} //namespace Solang + +#endif //SOLANG_ID_GEN_H diff --git a/src/common/photo-search-criteria.h b/src/common/photo-search-criteria.h index 810da7e..20fd8e5 100644 --- a/src/common/photo-search-criteria.h +++ b/src/common/photo-search-criteria.h @@ -34,17 +34,39 @@ namespace Solang class PhotoSearchCriteria : public NonCopyable { + public: + enum ClubbingOperationType + { + CLUB_AND, // All criterions of this type will be + //clubbed using "AND" + CLUB_OR // All criterions of this type will be + //clubbed using "OR" + }; protected: - PhotoSearchCriteria(); + PhotoSearchCriteria(); public: - virtual + virtual ~PhotoSearchCriteria() throw(); - - //Returns SQL formatted string that can be appended - //in the where clause - virtual Glib::ustring + + //Returns SQL formatted string that can be appended + //in the where clause + virtual Glib::ustring get_query_criteria() const throw() = 0; + + virtual ClubbingOperationType + get_clubbing_type() const throw() = 0; + + virtual gint32 + get_id() const throw() = 0; //Each class should keep a static + //constant and return the + //value here + virtual Glib::ustring + get_criteria_description() const throw() = 0; + + virtual Glib::ustring + get_criteria_icon_path() const throw() = 0; + }; } // namespace Solang diff --git a/src/database/database.cpp b/src/database/database.cpp index 27d5f41..fa60287 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -21,6 +21,7 @@ #include #include +#include #include "database.h" #include "db-table-factory.h" @@ -31,6 +32,16 @@ namespace Solang { +class Comparator +{ + public: + bool operator() ( const PhotoSearchCriteriaPtr &lhs, + const PhotoSearchCriteriaPtr &rhs ) + { + return lhs->get_id() < rhs->get_id(); + } +}; + const Glib::ustring Database::DB_NAME="solang.db"; Database::Database( const Glib::ustring &path) @@ -158,6 +169,8 @@ PhotoList Database::search( //Selection from views not supported? WTF?!! //Glib::ustring sql = "select * from photo_data "; + std::vector tmpList( criterion.begin(), criterion.end() ); + std::sort( tmpList.begin(), tmpList.end(), Comparator() ); Glib::ustring sql = "select distinct photos.* \ from photos, photo_tags \ @@ -166,16 +179,44 @@ PhotoList Database::search( if( ! criterion.empty() ) { - //sql += " where "; bool first = true; - for( PhotoSearchCriteriaList::const_iterator it - = criterion.begin(); - it != criterion.end(); it++ ) + gint32 lastId = -1; + PhotoSearchCriteria::ClubbingOperationType lastOp; + for( std::vector::const_iterator it + = tmpList.begin(); + it != tmpList.end(); it++ ) { - //sql += ( first ) ? " and ( ": " or "; - sql += ( first ) ? " and ( ": " and "; + if( !first ) + { + if( lastId == (*it)->get_id() ) + { + switch( (*it)->get_clubbing_type() ) + { + case PhotoSearchCriteria::CLUB_AND: + { + sql += " and "; + break; + } + case PhotoSearchCriteria::CLUB_OR: + { + sql += " or "; + break; + } + } + } + else + { + sql += " ) and ( "; + //first = true; + } + } + else + { + sql += " and ( "; + first = false; + } sql += (*it)->get_query_criteria(); - first = false; + lastId = (*it)->get_id(); } sql += " )"; } -- 1.6.2.1