$search
00001 00002 #include <string> 00003 #include <vector> 00004 00005 #include <database_interface/db_class.h> 00006 00007 // all database classes must inherit from database_interface::DBClass 00008 class Student : public database_interface::DBClass 00009 { 00010 00011 //fields are made public in this toy example for easy access, but you 00012 //can treat them as you would any member data of your C++ classes 00013 public: 00014 00015 //key requirement: all fields that are to be stored in the 00016 //database must be wrapped as database_interface::DBField<>, 00017 //templated on the type of data they hold 00018 00019 database_interface::DBField<int> student_id_; 00020 00021 database_interface::DBField<std::string> student_first_name_; 00022 00023 database_interface::DBField<std::string> student_last_name_; 00024 00025 database_interface::DBField< std::vector<std::string> > student_majors_; 00026 00027 database_interface::DBField<double> student_gpa_; 00028 00029 //key requirement: all fields must be initialized in the constructor 00030 //a field constructor takes the following arguments: 00031 // - the type of serialization used (TEXT for all fields in this toy example) 00032 // - the owner of the field ( usually "this", or the instance of the DBClass 00033 // that owns that field) 00034 // - the name of the table column corresponding to that field 00035 // - the name of the table in which the field is stored 00036 // - whether it is allowed to modify en entry in the database using a reference 00037 // to this field 00038 Student() : 00039 student_id_(database_interface::DBFieldBase::TEXT, 00040 this, "student_id", "student", true), 00041 student_first_name_(database_interface::DBFieldBase::TEXT, 00042 this, "student_first_name", "student", true), 00043 student_last_name_(database_interface::DBFieldBase::TEXT, 00044 this, "student_last_name", "student", true), 00045 student_majors_(database_interface::DBFieldBase::TEXT, 00046 this, "student_majors", "student", true), 00047 student_gpa_(database_interface::DBFieldBase::TEXT, 00048 this, "student_gpa", "student", true) 00049 { 00050 //finally, all fields must be registered with the DBClass itself 00051 00052 //one field MUST be a primary key 00053 //all instances of DBClass have a primary_key_field_ pointer, 00054 //which must be set on construction 00055 primary_key_field_ = &student_id_; 00056 00057 //all other fields go into the fields_ array of the DBClass 00058 fields_.push_back(&student_first_name_); 00059 fields_.push_back(&student_last_name_); 00060 fields_.push_back(&student_majors_); 00061 fields_.push_back(&student_gpa_); 00062 00063 //optional: let all fields be read automatically when an instance 00064 //of a student is retrieved from the database 00065 setAllFieldsReadFromDatabase(true); 00066 //optional: let all fields be written automatically when an instance 00067 //of a student is saved the database 00068 setAllFieldsWriteToDatabase(true); 00069 //(these options are usful if you have a very large field (e.g. a 00070 // binary bitmap with the picture of the student) which you do not 00071 //want retrieved automatically whenever you get a student info 00072 //from the database 00073 } 00074 }; 00075 00076 class Grade : public database_interface::DBClass 00077 { 00078 public: 00079 database_interface::DBField<int> grade_id_; 00080 database_interface::DBField<int> student_id_; 00081 database_interface::DBField<std::string> grade_subject_; 00082 database_interface::DBField<double> grade_grade_; 00083 00084 Grade() : 00085 grade_id_(database_interface::DBFieldBase::TEXT, 00086 this, "grade_id", "grade", true), 00087 student_id_(database_interface::DBFieldBase::TEXT, 00088 this, "student_id", "grade", true), 00089 grade_subject_(database_interface::DBFieldBase::TEXT, 00090 this, "grade_subject", "grade", true), 00091 grade_grade_(database_interface::DBFieldBase::TEXT, 00092 this, "grade_grade", "grade", true) 00093 { 00094 primary_key_field_ = &grade_id_; 00095 fields_.push_back(&student_id_); 00096 fields_.push_back(&grade_subject_); 00097 fields_.push_back(&grade_grade_); 00098 00099 setAllFieldsReadFromDatabase(true); 00100 setAllFieldsWriteToDatabase(true); 00101 } 00102 }; 00103 00104 class StudentWithPhoto : public database_interface::DBClass 00105 { 00106 public: 00107 database_interface::DBField<int> student_id_; 00108 database_interface::DBField<std::string> student_first_name_; 00109 database_interface::DBField<std::string> student_last_name_; 00110 database_interface::DBField< std::vector<std::string> > student_majors_; 00111 database_interface::DBField<double> student_gpa_; 00112 database_interface::DBField< std::vector<char> > student_photo_; 00113 00114 StudentWithPhoto() : 00115 student_id_(database_interface::DBFieldBase::TEXT, 00116 this, "student_id", "student", true), 00117 student_first_name_(database_interface::DBFieldBase::TEXT, 00118 this, "student_first_name", "student", true), 00119 student_last_name_(database_interface::DBFieldBase::TEXT, 00120 this, "student_last_name", "student", true), 00121 student_majors_(database_interface::DBFieldBase::TEXT, 00122 this, "student_majors", "student", true), 00123 student_gpa_(database_interface::DBFieldBase::TEXT, 00124 this, "student_gpa", "student", true), 00125 student_photo_(database_interface::DBFieldBase::BINARY, 00126 this, "student_photo", "student", true) 00127 { 00128 primary_key_field_ = &student_id_; 00129 00130 fields_.push_back(&student_first_name_); 00131 fields_.push_back(&student_last_name_); 00132 fields_.push_back(&student_majors_); 00133 fields_.push_back(&student_gpa_); 00134 fields_.push_back(&student_photo_); 00135 00136 setAllFieldsReadFromDatabase(true); 00137 setAllFieldsWriteToDatabase(true); 00138 00139 student_photo_.setReadFromDatabase(false); 00140 student_photo_.setWriteToDatabase(false); 00141 } 00142 }; 00143 00144 00145 class GradeWithSequence : public database_interface::DBClass 00146 { 00147 public: 00148 database_interface::DBField<int> grade_id_; 00149 database_interface::DBField<int> student_id_; 00150 database_interface::DBField<std::string> grade_subject_; 00151 database_interface::DBField<double> grade_grade_; 00152 00153 GradeWithSequence() : 00154 grade_id_(database_interface::DBFieldBase::TEXT, 00155 this, "grade_id", "grade", true), 00156 student_id_(database_interface::DBFieldBase::TEXT, 00157 this, "student_id", "grade", true), 00158 grade_subject_(database_interface::DBFieldBase::TEXT, 00159 this, "grade_subject", "grade", true), 00160 grade_grade_(database_interface::DBFieldBase::TEXT, 00161 this, "grade_grade", "grade", true) 00162 { 00163 primary_key_field_ = &grade_id_; 00164 fields_.push_back(&student_id_); 00165 fields_.push_back(&grade_subject_); 00166 fields_.push_back(&grade_grade_); 00167 00168 setAllFieldsReadFromDatabase(true); 00169 setAllFieldsWriteToDatabase(true); 00170 00171 grade_id_.setSequenceName("grade_id_seq"); 00172 grade_id_.setWriteToDatabase(false); 00173 } 00174 }; 00175 00176 00177 #include <boost/shared_ptr.hpp> 00178 #include <database_interface/postgresql_database.h> 00179 00180 int main(int argc, char **argv) 00181 { 00182 database_interface::PostgresqlDatabase 00183 database("wgs36.willowgarage.com", "5432", 00184 "willow", "willow", "students"); 00185 if (!database.isConnected()) 00186 { 00187 std::cerr << "Database failed to connect \n"; 00188 return -1; 00189 } 00190 std::cerr << "Database connected successfully \n"; 00191 00192 std::vector< boost::shared_ptr<Student> > students; 00193 if (!database.getList(students)) 00194 { 00195 std::cerr << "Failed to get list of students\n"; 00196 return -1; 00197 } 00198 std::cerr << "Retrieved " << students.size() << " student(s) \n"; 00199 00200 std::cerr << "Students: \n"; 00201 for (size_t i=0; i<students.size(); i++) 00202 { 00203 std::cerr << students[i]->student_last_name_.data() 00204 << ", " 00205 << students[i]->student_first_name_.data() 00206 << ": \n"; 00207 std::cerr << " GPA: " << students[i]->student_gpa_.data() << "\n"; 00208 std::cerr << " Major(s): "; 00209 for (size_t j=0; j<students[i]->student_majors_.data().size(); j++) 00210 { 00211 if (j!=0) std::cerr << ", "; 00212 std::cerr << students[i]->student_majors_.data().at(j); 00213 } 00214 std::cerr << "\n"; 00215 } 00216 00217 std::vector< boost::shared_ptr<Grade> > grades; 00218 std::string where_clause("student_id=1"); 00219 database.getList(grades, where_clause); 00220 std::cerr << "Student with id 1 has " << grades.size() << " grade(s) on record\n"; 00221 00222 grades[0]->grade_grade_.data() = 2.5; 00223 if (!database.saveToDatabase( &(grades[0]->grade_grade_) ) ) 00224 std::cerr << "Failed to modify grade\n"; 00225 else 00226 std::cerr << "Grade modified successfully\n"; 00227 00228 //we have forgotten a grade 00229 grades[0]->grade_grade_.data() = 0.0; 00230 //reload it from the database 00231 if (!database.loadFromDatabase( &(grades[0]->grade_grade_) ) ) 00232 std::cerr << "Failed to load grade field from database\n"; 00233 else 00234 std::cerr << "Grade field (re)loaded, its value is " 00235 << grades[0]->grade_grade_.data() 00236 << "\n"; 00237 00238 Grade new_grade; 00239 new_grade.student_id_.data() = 1; 00240 new_grade.grade_subject_.data() = "astrology"; 00241 new_grade.grade_grade_.data() = 4.0; 00242 new_grade.grade_id_.data() = 5; 00243 if (!database.insertIntoDatabase(&new_grade)) 00244 std::cerr << "Grade insertion failed\n"; 00245 else 00246 std::cerr << "Grade insertion succeeded\n"; 00247 00248 //get the students, but photos will not be loaded by default 00249 std::vector< boost::shared_ptr<StudentWithPhoto> > students_with_photos; 00250 database.getList(students_with_photos); 00251 00252 //now get the photo for the first student retrieved 00253 database.loadFromDatabase( &(students_with_photos[0]->student_photo_) ); 00254 std::cerr << "The photo has " 00255 << students_with_photos[0]->student_photo_.data().size() 00256 << " bytes \n"; 00257 00258 //insert a grade with automatic key generation 00259 GradeWithSequence new_grade_seq; 00260 new_grade_seq.student_id_.data() = 2; 00261 new_grade_seq.grade_subject_.data() = "mythology"; 00262 new_grade_seq.grade_grade_.data() = 4.0; 00263 database.insertIntoDatabase(&new_grade_seq); 00264 std::cerr << "The newly inserted grade was assigned grade_id=" 00265 << new_grade_seq.grade_id_.data() 00266 << "\n"; 00267 00268 return 0; 00269 }