So here is the solution i have made for now (maybe it is ugly, i really want to get feedback from you, and what you think about it):
In DBHelper:
typedef DBHelper
*(*instPtr
)(const QSqlDatabase
&,
const QSqlQuery
&,
QObject*);
static DBHelper* DBHelper::findUnique (const QString& table, const QStringList& fields, const QString& criterion,
const QSqlDatabase
& db, instPtr instanciate,
QObject* parent
=0) { QSqlQuery query
= buildSearch
(table, fields, criterion, db
);
if (!query.next())
return 0;
return (*instanciate)(db, query, parent);
}
typedef DBHelper*(*instPtr)(const QSqlDatabase&, const QSqlQuery&, QObject*);
static DBHelper* DBHelper::findUnique (const QString& table, const QStringList& fields, const QString& criterion,
const QSqlDatabase& db, instPtr instanciate, QObject* parent=0) {
QSqlQuery query = buildSearch(table, fields, criterion, db);
if (!query.next())
return 0;
return (*instanciate)(db, query, parent);
}
To copy to clipboard, switch view to plain text mode
In my derived DBEmployee i have defined TableName and FieldList as two static variables (1st is QString, 2nd is QStringList), and these static methods:
DBHelper
* DBEmployee
::instanciate (const QSqlDatabase
& db,
const QSqlQuery
& query,
QObject* parent
) { DBEmployee* toRet = (DBEmployee*)getCachedObject(TableName+":"+query.value(0).toString());
if (!toRet)
toRet = new DBEmployee(db, query, parent);
return toRet;
}
return (DBEmployee
*)findUnique
(TableName, FieldsList,
"uid="+QString::number(code
), db,
&instanciate, parent
);
}
DBHelper* DBEmployee::instanciate (const QSqlDatabase& db, const QSqlQuery& query, QObject* parent) {
DBEmployee* toRet = (DBEmployee*)getCachedObject(TableName+":"+query.value(0).toString());
if (!toRet)
toRet = new DBEmployee(db, query, parent);
return toRet;
}
DBEmployee* DBEmployee::findByCode (const QSqlDatabase &db, int code, QObject *parent) {
return (DBEmployee*)findUnique(TableName, FieldsList, "uid="+QString::number(code), db, &instanciate, parent);
}
To copy to clipboard, switch view to plain text mode
So... When i want to get an employee from it's code:
DBEmployee* test = DBEmployee::findByExactName (_adminDb, "John Doe", this);
DBEmployee* test = DBEmployee::findByExactName (_adminDb, "John Doe", this);
To copy to clipboard, switch view to plain text mode
Now i have a question:
- Imagine i create a method which returns an instance of QList<DBHelper*>.
- Now if i call this method from another one which HAS to return a QList<DBEmployee*>, is it possible to recast the whole list with some magic, or have i to create a new list, iterate thru the old one, and fill the new one with freshly re-casted objects?
[EDIT] In other words: Do you see a solution to avoid the casting problems? For instance, my function pointer is defined to return a DBHelper*, so in my DBEmployee if i declare the static method "instanciate" with a return of type DBEmployee*, it can't compile...
For now, my search methods to return multiple results looks like this:
In DBHelper:
DBHelperList DBHelper::findMulti (const QString& table, const QStringList& fields, const QString& criterion,
const QSqlDatabase
& db, instPtr instanciate,
QObject* parent
) { QSqlQuery query
= buildSearch
(table, fields, criterion, db
);
DBHelperList listToRet;
while (query.next())
listToRet.append((*instanciate)(db, query, parent));
return listToRet;
}
DBHelperList DBHelper::findMulti (const QString& table, const QStringList& fields, const QString& criterion,
const QSqlDatabase& db, instPtr instanciate, QObject* parent) {
QSqlQuery query = buildSearch(table, fields, criterion, db);
DBHelperList listToRet;
while (query.next())
listToRet.append((*instanciate)(db, query, parent));
return listToRet;
}
To copy to clipboard, switch view to plain text mode
In DBEmployee:
QList<DBEmployee
*> DBEmployee
::findByName (const QSqlDatabase
& db,
const QString
& name,
QObject* parent
) { DBHelperList original = findMulti(TableName, FieldsList, "name like '%"+name+"%'", db, &instanciate, parent);
QList<DBEmployee*> toRet;
while (!original.isEmpty())
toRet.append((DBEmployee*)original.takeFirst());
return toRet;
}
QList<DBEmployee*> DBEmployee::findByName (const QSqlDatabase& db, const QString& name, QObject* parent) {
DBHelperList original = findMulti(TableName, FieldsList, "name like '%"+name+"%'", db, &instanciate, parent);
QList<DBEmployee*> toRet;
while (!original.isEmpty())
toRet.append((DBEmployee*)original.takeFirst());
return toRet;
}
To copy to clipboard, switch view to plain text mode
What i want to avoid is the loop in DBEmployee method, to recast all objects... Which were already all casted in DBHelper findMulti method!
Bookmarks