Workspace 6.21.5
|
An SqlBoundObjectGroup class is bound to a specific SQL table or view, and its instance objects are bound to individual records from this table or view. More...
#include <DataAnalysis/DataStructures/sqlboundobjectgroup.h>
Public Member Functions | |
~SqlBoundObjectGroup () override | |
SqlBoundObjectGroup * | clone () const override=0 |
virtual SqlBoundObjectGroup * | deepCopy () const =0 |
void | detach (bool recursive=false) |
QStringList | getAutoIncrementFieldNames () const |
QString | getBoundTableName () const |
QStringList | getCompositePrimaryKeyFieldNames () const |
QStringList | getCompositePrimaryKeyFieldNamesAliased () const |
QString | getFieldName (const DataExecution::DataObject &object) const |
QStringList | getNonRelationFieldAliases () const |
QStringList | getNonRelationFieldNames () const |
DataExecution::DataObject & | getPrimaryKeyField () |
const DataExecution::DataObject & | getPrimaryKeyField () const |
QString | getPrimaryKeyFieldName () const |
QString | getPrimaryKeyFieldNameAliased () const |
SqlBindingRelationMap | getRelationBindings (const QStringList &relationNames=QStringList(), bool recursive=false) const |
QStringList | getRelationFieldNames (bool recursive) const |
QStringList | getSqlValidCompositePrimaryKeyFieldNames () const |
QStringList | getSqlValidFieldList () const |
bool | hasCompositePrimaryKey () const |
bool | isPersistent () const |
bool | isPrimaryKeyField (const DataExecution::DataObject &obj) const |
bool | isRelationField (const QString &fieldName) const |
void | setPersistent (bool b) |
Public Member Functions inherited from ObjectGroup | |
~ObjectGroup () override | |
bool | add (const QString &name, DataObject &obj) |
bool | canSerialize () const override |
ObjectGroup * | clone () const override=0 |
bool | empty () const |
void | ensureGroupHasData () |
void | erase (int index) |
DataObject * | getChild (const QString &name) |
const DataObject * | getChild (const QString &name) const |
DataObject & | getDataObject (int index) |
const DataObject & | getDataObject (int index) const |
int | getIndex (const QString &name) const |
const QString & | getName (int index) const |
virtual QString | getPreferedWidget (const QString &name) const |
bool | hasData () const |
bool | haveName (const QString &name) const |
bool | insert (const QString &name, DataObject &obj, int index=-1) |
bool | load (const QJsonDocument &doc) |
bool | load (const SerializedItem &item) override |
bool | save (QJsonDocument &doc) const |
bool | save (SerializedItem &item) const override |
unsigned | size () const |
Public Member Functions inherited from Clonable | |
virtual | ~Clonable ()=default |
virtual Clonable * | clone () const =0 |
Public Member Functions inherited from Serialize | |
virtual | ~Serialize ()=default |
virtual bool | canSerialize () const =0 |
virtual bool | load (const SerializedItem &item)=0 |
virtual bool | save (SerializedItem &item) const =0 |
Protected Member Functions | |
SqlBoundObjectGroup (const SqlBoundObjectGroup &other) | |
SqlBoundObjectGroup (SqlBoundObjectGroupData *data) | |
bool | bindCompositePrimaryKey (const QList< const DataExecution::DataObject * > &objects) |
bool | bindField (const QString &fieldName, DataExecution::DataObject &object) |
bool | bindRelation (const SqlBindingRelation &relation) |
virtual const SqlBoundObjectClassData & | getClassData () const =0 |
virtual QSqlQuery | getInsertQuery (const SqlDataModel &model, const QStringList &relations, const QString &foreignKeyName=QString(), const QVariant &foreignKeyValue=QVariant()) const =0 |
virtual QSqlQuery | getUpdateQuery (const SqlDataModel &model, const QStringList &relations, const QString &foreignKeyName=QString(), const QVariant &foreignKeyValue=QVariant()) const =0 |
SqlBoundObjectGroup & | operator= (const SqlBoundObjectGroup &) |
bool | operator== (const SqlBoundObjectGroup &rhs) const |
bool | setPrimaryKeyField (const DataExecution::DataObject &obj, bool autoIncrement) |
Protected Member Functions inherited from ObjectGroup | |
ObjectGroup () | |
void | clear () |
ObjectGroup & | operator= (const ObjectGroup &rhs) |
bool | operator== (const ObjectGroup &rhs) const |
void | swap (ObjectGroup &rhs) |
This SqlBoundObjectGroup is the base class of all ObjectGroup types that are "bound" to a specific database table or view. Bound objects represent a record from the table, and each of their data members is contain a single field of data from the record.
Bound objects represent a statically typed interface to a database record, which can have a number of advantages over using the Qt SQL classes directly (QSqlQuery and QSqlRecord):
- When the database structure changes, the code structure can be easily updated, as all database interaction is via a well-defined, compiled interface, rather than string literals that are assumed to be SQL statements. - Data types are all enforced via the statically typed interface, which saves on validation effort and reduces the risk of bad data being written to the database.
The downside of using this statically typed interface is:
- There is less flexibility that writing a completely custom query and processing the results in a custom fashion. There are some things possible with custom queries and manual data processing that can not be done using this static interface.
To create a specific type of SqlBoundObjectGroup, developers must create a new class deriving from TypedSqlBoundObjectGroup and in its constructor, specify the appropriate data field, primary key and relation bindings. For example, here is an "Author" class, which has a many-to-many relationship with the "Book" class, and a many-to-one relationship with the "Publisher" class:
``` class Author : public DataAnalysis::TypedSqlBoundObjectGroup<Author, int> { public: DataExecution::TypedObject<IdType> id; DataExecution::TypedObject<QString> lastName; DataExecution::TypedObject<QString> firstName; DataExecution::TypedObject<QString> address; DataExecution::TypedObject<QString> city; DataExecution::TypedObject<Publisher> publisher; DataExecution::TypedObject<BookArray> books; Author() : DataAnalysis::TypedSqlBoundObjectGroup<Author, int>() { bindField("Id", id); bindField("LastName", lastName); bindField("FirstName", firstName); bindField("Address", address); bindField("City", city); bindField("Publisher", publisher); bindField("Books", books); bindPrimaryKeyField(id); bindRelation(DataAnalysis::ManyToOneRelation<Testing::Publisher>(publisher, "Publisher_Id")); bindRelation(DataAnalysis::ManyToManyRelation<Testing::Book>(books, "Book_Id", "Author_Id", "Author_Book")); } Author(const Author& other) = delete; Author& operator=(const Author& rhs) { return TypedSqlBoundObjectGroup<Author,int>::operator=(rhs); } };
DECLARE_WORKSPACE_SQL_DATA_FACTORIES(CSIRO::Testing::Author, CSIRO_TESTING_API) DEFINE_WORKSPACE_SQL_DATA_FACTORIES(CSIRO::Testing::Author, CSIRO::Testing::TestSqlDataModelPlugin::getInstance()) ```
Lastly, in order to ensure that the object is bound to the correct view or table, developers must implement a template specialisation of the SqlDataModel::getBoundTableName() function:
``` template<> inline QString SqlDataModel::getBoundTableName<Testing::Author>() { return "Author"; }
```
Once this has been done, SqlBoundObjectGroups can be retrieved from an instance of a SqlDataModel that is attached to a database conforming to the expected schema by using the relevant fetch() or save() function as required.
|
override |
|
protected |
data | The data which this bound object group will refer to. In general, this will be a newly constructed object created by a derived class, as this constructor is protected. |
Creates a new SqlBoundObjectGroup referring to the specified object data. Multiple objects may share the same data, though this is managed through the assignment operator or copy constructor, not this protected constructor.
|
protected |
other | The other object to copy. |
Creates a new SqlBoundObjectGroup which is a shallow copy of other, which is to say that it will share a reference to the same underlying data.
|
protected |
objects | A list of child objects that comprise the composite primary key of this object. |
|
protected |
fieldName | The name of the field in the underlying database (i.e. the column name) |
object | The member object that is going to contain the data associated with this field in the record represented by this object. |
|
protected |
relation | The SqlBindingRelation to bind to this object group. |
Binds a specific relation to this object group. The relation links a specific child member of a type deriving from SqlBoundObjectGroup (or a TypedObjectArray of such derived class objects) to this object. It replaces the need for manually joining the objects to other tables in order to represent relationship data.
|
overridepure virtual |
Implements ObjectGroup.
Implemented in InvalidSqlBoundObjectGroup, and TypedSqlBoundObjectGroup< Derived, PrimaryKeyType >.
|
pure virtual |
Implemented in InvalidSqlBoundObjectGroup, and TypedSqlBoundObjectGroup< Derived, PrimaryKeyType >.
void detach | ( | bool | recursive = false | ) |
recursive | Whether or not to detach child objects, and children of child objects etc. |
Detaches this object from its shared data, creating a local copy of its data. Child objects will still be shared unless specified otherwise via the recursive parameter.
QStringList getAutoIncrementFieldNames | ( | ) | const |
Most database types have support for auto-incrementing certain fields upon insert, usually integer type primary key fields. Some databases support multiple auto-increment fields on the same table. This function returns the list of auto-increment fields associated with this SqlBoundObjectGroup.
QString getBoundTableName | ( | ) | const |
|
protectedpure virtual |
Implemented in InvalidSqlBoundObjectGroup, and TypedSqlBoundObjectGroup< Derived, PrimaryKeyType >.
QStringList getCompositePrimaryKeyFieldNames | ( | ) | const |
QStringList getCompositePrimaryKeyFieldNamesAliased | ( | ) | const |
All object members, when used in an underlying Sql query, must be appropriately aliased so as to avoid naming conflicts. This function returns the aliased versions of the composite primary key field names.
QString getFieldName | ( | const DataExecution::DataObject & | object | ) | const |
object | Reference to the child object for which we wish to retrieve its field name. |
|
protectedpure virtual |
model | The SqlDataModel responsible for the insertion operation. |
relations | A list of relations to follow when generating the insert. |
foreignKeyName | (optional) The name of a foreign key field attached to the table that this object is bound to. Important for inserting objects with bi-directional relations. |
foreignKeyValue | The value to store in the field named foreignKeyName when inserting this object. |
Returns the SQL query required to insert this particular object into a database. Callers should never need to invoke this method directly.
Implemented in TypedSqlBoundObjectGroup< Derived, PrimaryKeyType >, and InvalidSqlBoundObjectGroup.
QStringList getNonRelationFieldAliases | ( | ) | const |
QStringList getNonRelationFieldNames | ( | ) | const |
This method is used to retrieve the list of all member fields that are bound directly to underlying database fields. Relation fields (i.e. fields that reference other SqlBoundObjectGroup types) are not included in the returned list. This allows calling code to differentiate between directly bound members, and members that contain data that is stored in related tables.
DataExecution::DataObject & getPrimaryKeyField | ( | ) |
const DataExecution::DataObject & getPrimaryKeyField | ( | ) | const |
QString getPrimaryKeyFieldName | ( | ) | const |
QString getPrimaryKeyFieldNameAliased | ( | ) | const |
All object fields, when used in a query, must be appropriately aliased so as to avoid naming conflicts with other object types. For example, if two objects were to have the same field, 'Name', it would be impossible to distinguish which field is which. For this reason, we alias each field so that it is unique in any underlying Sql queries.
SqlBindingRelationMap getRelationBindings | ( | const QStringList & | relationNames = QStringList() , |
bool | recursive = false |
||
) | const |
relationNames | The list of relation bindings to retrieve. Each binding has a unique name associated with it. If the name in the list does not match a valid relationship name, it will be ignored. |
recursive | Whether or not to recursively retrieve bindings from child objects to their own child objects. |
QStringList getRelationFieldNames | ( | bool | recursive | ) | const |
QStringList getSqlValidCompositePrimaryKeyFieldNames | ( | ) | const |
SQL-valid field names take the form:
QStringList getSqlValidFieldList | ( | ) | const |
Sql-valid field names take the format: "<tableName>.<fieldName> <fieldAlias>"
|
protectedpure virtual |
model | The SqlDataModel responsible for the update operation. |
relations | A list of relations to follow when generating the update. |
foreignKeyName | (optional) The name of a foreign key field attached to the table that this object is bound to. Important for updating objects with bi-directional relations. |
foreignKeyValue | The value to store in the field named foreignKeyName when updating this object. |
Implemented in TypedSqlBoundObjectGroup< Derived, PrimaryKeyType >, and InvalidSqlBoundObjectGroup.
bool hasCompositePrimaryKey | ( | ) | const |
bool isPersistent | ( | ) | const |
A persistent object is one that exists in the underlying SqlDataModel that this object is associated with. Objects that have been retrieved from an SqlDataModel via the use of the SqlDataModel::fetch() or written to an SqlDataModel via the SqlDataModel::save() functions will be persistent.
Objects that have been created locally but not retrieved via a fetch() call, and that have not yet been saved to the data model will not be marked as persistent.
bool isPrimaryKeyField | ( | const DataExecution::DataObject & | obj | ) | const |
obj | A child data object of this object group. |
bool isRelationField | ( | const QString & | fieldName | ) | const |
fieldName | The name of the field to evaluate whether or not it is a relation field (i.e. a field that is bound to a related object), or a regular field bound directly to a database field. |
|
protected |
rhs | The other SqlBoundObjectGroup to assign to this one. |
Assigns the object rhs to this object, causing the two objects to refer to the same underlying database record. This means that the members of the two objects will refer directly to the same data, and so making changes to the members of one object will also be reflected in the contents of the other object.
To separate the link between the two objects (i.e. to indicate that they refer to two separate, but identical records), use the detach() function.
|
protected |
rhs | The other SqlBoundObjectGroup to compare to. |
void setPersistent | ( | bool | b | ) |
b | Whether or not to mark this object as persistent. |
|
protected |
obj | Reference to a bound object (already registered using bindField) that is going to contain the primary key data of the object. |
autoIncrement | Whether or not the primary key field is auto-incremented or must be manually set by calling code. |