Wexus2 0.20
|
00001 00002 /* 00003 * Copyright (c) 2011 Aleksander B. Demko 00004 * This source code is distributed under the MIT license. 00005 * See the accompanying file LICENSE.MIT.txt for details. 00006 */ 00007 00008 #ifndef __INCLUDED_WEXUS_ACTIVERECORD_H__ 00009 #define __INCLUDED_WEXUS_ACTIVERECORD_H__ 00010 00011 #include <wexus/TR1.h> 00012 00013 #include <wexus/ActiveExpr.h> 00014 #include <wexus/ActiveClass.h> 00015 #include <wexus/ValidationExpr.h> 00016 #include <wexus/Context.h> 00017 #include <wexus/IDAble.h> 00018 00019 namespace wexus 00020 { 00021 class ActiveRecord; 00022 } 00023 00024 /** 00025 * The base class for all Wexus-generated 00026 * user records. This is a type of ORM. 00027 * 00028 * @author Aleksander Demko 00029 */ 00030 class wexus::ActiveRecord : public wexus::IDAble 00031 { 00032 public: 00033 // helper functions 00034 // retutrns the DB, throwing an exception on failure 00035 static QSqlDatabase & database(void); 00036 // throws an exception is qy.lastError().isValid() 00037 static void check(const QSqlQuery &qy); 00038 // throws an exception on false 00039 static void check(bool b, const QString &exceptionMsg = "ActiveRecord::check(bool) failed"); 00040 00041 public: 00042 /// implementation 00043 virtual QVariant getIDAsVariant(void); 00044 00045 /** 00046 * Returns the active class for this 00047 * record. 00048 * Should never be null. 00049 * 00050 * @author Aleksander Demko 00051 */ 00052 ActiveClass * activeClass(void) const { return dm_class; } 00053 00054 /** 00055 * Resets the fields to default values... usually -1 for ints 00056 * and empty strings. 00057 * 00058 * Skips the filter column, if set. 00059 * 00060 * @author Aleksander Demko 00061 */ 00062 void clear(void); 00063 00064 /** 00065 * Validates the fields in the current record 00066 * against any defined validation checks. 00067 * 00068 * outerrors should be Context::errors. 00069 * 00070 * @author Aleksander Demko 00071 */ 00072 void test(Context::Errors *outerrors = 0) const; 00073 00074 /** 00075 * Calls clear() first. 00076 * 00077 * Extracts the fields from the given form map and calls 00078 * test(). 00079 * 00080 * If is v is invalid (the default), then 00081 * params[activeClass()->table()] will be assumed 00082 * (this works with the Form(ActiveRecord&) class. 00083 * 00084 * Returns true if atleast one field was extracted 00085 * and errors is empty (after calling test()) 00086 * 00087 * @author Aleksander Demko 00088 */ 00089 bool fromForm(const QVariant &v = QVariant()); 00090 00091 /** 00092 * Returns a printable string reprensentation 00093 * of the fields in this record. 00094 * 00095 * @author Aleksander Demko 00096 */ 00097 QString toString(void) const; 00098 00099 /** 00100 * Sets the filter column to use in all where clauses. 00101 * By default this is -1, for none. 00102 * 00103 * @author Aleksander Demko 00104 */ 00105 void setFilterColumn(int colindex); 00106 00107 public: 00108 /** 00109 * Sets the default ordering. 00110 * If not called, the default is no ordering 00111 * at all. 00112 * 00113 * @author Aleksander Demko 00114 */ 00115 void order(const ActiveExpr & orderByExpr); 00116 00117 /** 00118 * Returns all the records. 00119 * 00120 * @author Aleksander Demko 00121 */ 00122 void all(void); 00123 00124 /** 00125 * Returns all the records that match the given whereExpr 00126 * expression. 00127 * 00128 * @author Aleksander Demko 00129 */ 00130 void where(const ActiveExpr & whereExpr); 00131 00132 /** 00133 * Finds the record that that has the given 00134 * value as its primary key. 00135 * Throws an exception on not-found. 00136 * 00137 * @author Aleksander Demko 00138 */ 00139 void find(const QVariant &keyVal); 00140 00141 /** 00142 * Same as find(), except returns false on failure. 00143 * find() raises an exception. 00144 * 00145 * @author Aleksander Demko 00146 */ 00147 bool exists(const QVariant &keyVal); 00148 00149 /** 00150 * Finds the loads the first record that matches the 00151 * given whereExpr expression. 00152 * This calls next() for, and returns true if that 00153 * succeeded. 00154 * 00155 * @author Aleksander Demko 00156 */ 00157 bool first(const ActiveExpr & whereExpr = ActiveExpr()); 00158 00159 /** 00160 * Finds the loads the last record matches the 00161 * given whereExpr expression. 00162 * This calls next() for, and returns true if that 00163 * succeeded. 00164 * 00165 * @author Aleksander Demko 00166 */ 00167 bool last(const ActiveExpr & whereExpr = ActiveExpr()); 00168 00169 /** 00170 * Inserts the current values into the database. 00171 * If a specific id is desired, it must be passed here. 00172 * Otherwise, one will be auto generated. 00173 * 00174 * @author Aleksander Demko 00175 */ 00176 void create(const QVariant &v = QVariant()); 00177 00178 /** 00179 * Saves the current values back into the database. 00180 * You must not have changed the primary key value :) 00181 * 00182 * The current query is unaffected, so you can continue 00183 * iteration (with next()), for example. 00184 * 00185 * @author Aleksander Demko 00186 */ 00187 void save(void); 00188 00189 /** 00190 * Removes the current record from the DB. 00191 * Does nothing on failure. 00192 * 00193 * @author Aleksander Demko 00194 */ 00195 void destroy(void); 00196 00197 /** 00198 * Removes the record with the given primary key from the DB. 00199 * Does nothing on failure. 00200 * 00201 * @author Aleksander Demko 00202 */ 00203 void destroy(const QVariant &keyVal); 00204 00205 /** 00206 * Deletes all the records that match the given query. 00207 * A null query (the default), deletes all the rows. 00208 * Does nothing on failure. 00209 * 00210 * @author Aleksander Demko 00211 */ 00212 void destroyAll(const ActiveExpr & whereExpr = ActiveExpr()); 00213 00214 /** 00215 * Returns the number of rows that match the given where query, 00216 * or all the rows if no query is upplied. 00217 * 00218 * @author Aleksander Demko 00219 */ 00220 int count(const ActiveExpr & whereExpr = ActiveExpr()); 00221 00222 /** 00223 * After running a query function, this will move the current row 00224 * to the first row in the result set. Subsequent calls will move 00225 * the current row to the next one. true is returns if the current 00226 * row is valid. 00227 * 00228 * @author Aleksander Demko 00229 */ 00230 bool next(void); 00231 00232 protected: 00233 /// ctor, protected. this class is meanted to be inherited from. 00234 ActiveRecord(ActiveClass *klass); 00235 // virtual dtor required 00236 virtual ~ActiveRecord(); 00237 00238 /** 00239 * Appends the column filter criteria (if any) 00240 * to the given filter and returns that. 00241 * 00242 * @author Aleksander Demko 00243 */ 00244 ActiveExpr filterExpr(const ActiveExpr &e); 00245 00246 void resetQuery(void); 00247 void setQuery(std::shared_ptr<QSqlQuery> qry); 00248 00249 // core query function 00250 void internalWhere(const ActiveExpr & whereExpr, int limit); 00251 00252 private: 00253 ActiveClass *dm_class; 00254 int dm_filtercol; // the filter column, or -1 if none is set 00255 ActiveExpr dm_orderByExpr; 00256 std::shared_ptr<QSqlQuery> dm_query; 00257 }; 00258 00259 #endif 00260