From 3417fc7c0df3b1b01750874587c4f3bb2ef02f45 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov 14.4.12 readonly
14.4.13 virtual
- 14.4.14 inverse
- 14.4.15 version
- 14.4.16 index
- 14.4.17 unique
- 14.4.18 unordered
- 14.4.19 table
- 14.4.20 load
/update
- 14.4.21 section
- 14.4.22 added
- 14.4.23 deleted
- 14.4.24 index_type
- 14.4.25 key_type
- 14.4.26 value_type
- 14.4.27 value_null
/value_not_null
- 14.4.28 id_options
- 14.4.29 index_options
- 14.4.30 key_options
- 14.4.31 value_options
- 14.4.32 id_column
- 14.4.33 index_column
- 14.4.34 key_column
+ 14.4.35 value_column
+ 14.4.15 on_delete
+ 14.4.16 version
+ 14.4.17 index
+ 14.4.18 unique
+ 14.4.19 unordered
+ 14.4.20 table
+ 14.4.21 load
/update
+ 14.4.22 section
+ 14.4.23 added
+ 14.4.24 deleted
+ 14.4.25 index_type
+ 14.4.26 key_type
+ 14.4.27 value_type
+ 14.4.28 value_null
/value_not_null
+ 14.4.29 id_options
+ 14.4.30 index_options
+ 14.4.31 key_options
+ 14.4.32 value_options
+ 14.4.33 id_column
+ 14.4.34 index_column
+ 14.4.35 key_column
@@ -5783,7 +5784,7 @@ private:
of person's nicknames is probably not important. To instruct the ODB
compiler to ignore the order in ordered containers we can use the
14.4.36 value_column
db unordered
pragma (Section 14.3.9,
- "unordered
", Section 14.4.18,
+ "unordered
", Section 14.4.19,
"unordered
"). For example:
@@ -6089,8 +6090,8 @@ for (;;)@@ -6349,8 +6350,8 @@ class employee use the
odb::vector
incurs 2-bit per element overhead in order to store the change state. It cannot - be stored unordered in the database (Section - 14.4.18 "unordered
") but can be used as an inverse + be stored unordered in the database (Section + 14.4.19 "unordered
") but can be used as an inverse side of a relationship (6.2 "Bidirectional Relationships"). In this case, no change tracking is performed since no state for such a container is stored in the database.not_null
pragma (Section 14.4.6, "null
/not_null
") for single object pointers and thevalue_not_null
pragma - (Section - 14.4.27, "value_null
/value_not_null
") + (Section + 14.4.28, "value_null
/value_not_null
") for containers of object pointers. For example:@@ -6481,7 +6482,12 @@ result r (db.query<employee> (query::employer.is_null ())); or updated. Rather, only a reference to the object (in the form of the object id) is stored for the pointed-to object in the database. The pointed-to object itself is a separate entity and should - be made persistent or updated independently. + be made persistent or updated independently. By default, the + same principle also applies to erasing pointed-to objects. That + is, we have to make sure all the pointing objects are updated + accordingly. However, in the case of erase, we can specify an + alternativeon-delete
semantic as discussed in + Section 14.4.15, "on_delete
".When persisting or updating an object containing a pointer to another object, the pointed-to object must have a valid object id. This, @@ -6808,7 +6814,7 @@ CREATE TABLE employee ( pointer. Also note that an ordered container (Section 5.1, "Ordered Containers") of pointers that is an inverse side of a bidirectional relationship is always treated as unordered - (Section 14.4.18, "
@@ -7895,9 +7901,9 @@ CREATE TABLE person (unordered
") + (Section 14.4.19, "unordered
") because the contents of such a container are implicitly built from the direct side of the relationship which does not contain the element order (index).The same principle applies when a composite value type is used as an element of a container, except that instead of
db column
, either thedb value_column
- (Section 14.4.35, "value_column
") or + (Section 14.4.36, "value_column
") ordb key_column
- (Section 14.4.34, "key_column
") + (Section 14.4.35, "key_column
") pragmas are used to specify the column prefix.When a composite value type contains a container, an extra table @@ -7941,8 +7947,8 @@ CREATE TABLE person (
To customize the container table name we can use the -
+db table
pragma (Section - 14.4.19, "table
"), for example:db table
pragma (Section + 14.4.20, "table
"), for example:#pragma db value @@ -11147,7 +11153,7 @@ p.age (age);-To declare a persistent class with the optimistic concurrency model we use the
@@ -13826,7 +13832,7 @@ class person has the optimistic concurrency model. A class with the optimistic concurrency model must also specify the data member that is used to store the object version using theoptimistic
pragma (Section 14.1.5, "optimistic
"). We also use theversion
- pragma (Section 14.4.15, "version
") + pragma (Section 14.4.16, "version
") to specify which data member will store the object version. For example:version
pragma - (Section 14.4.15, "version
"). + (Section 14.4.16, "version
"). For example:@@ -15004,7 +15010,7 @@ typedef std::vector<std::string> nicknames;-The semantics of the
@@ -15021,7 +15027,7 @@ typedef std::vector<std::string> nicknames;id_options
specifier for a container type are similar to those of theid_options
specifier for - a container data member (Section 14.4.28, + a container data member (Section 14.4.29, "id_options
").The semantics of the
@@ -15038,7 +15044,7 @@ typedef std::map<std::string, std::string> properties;index_options
specifier for a container type are similar to those of theindex_options
specifier for - a container data member (Section 14.4.29, + a container data member (Section 14.4.30, "index_options
").The semantics of the
@@ -15055,7 +15061,7 @@ typedef std::set<std::string> nicknames;key_options
specifier for a container type are similar to those of thekey_options
specifier for - a container data member (Section 14.4.30, + a container data member (Section 14.4.31, "key_options
").The semantics of the
@@ -15218,129 +15224,135 @@ typedef std::map<unsigned short, float> age_weight_map;value_options
specifier for a container type are similar to those of thevalue_options
specifier for - a container data member (Section 14.4.31, + a container data member (Section 14.4.32, "value_options
").+ + ++ on_delete
+ ON DELETE
clause for object pointer member14.4.15 +version
member stores object version -14.4.15 +14.4.16 index
define database index for a member -14.4.16 +14.4.17 unique
define unique database index for a member -14.4.17 +14.4.18 unordered
ordered container should be stored unordered -14.4.18 +14.4.19 table
table name for a container -14.4.19 +14.4.20 load
/update
loading/updating behavior for a section -14.4.20 +14.4.21 section
member belongs to a section -14.4.21 +14.4.22 added
member is soft-added -14.4.22 +14.4.23 deleted
member is soft-deleted -14.4.23 +14.4.24 index_type
database type for a container's index type -14.4.24 +14.4.25 key_type
database type for a container's key type -14.4.25 +14.4.26 value_type
database type for a container's value type -14.4.26 +14.4.27 value_null
/value_not_null
container's value can/cannot be -NULL
14.4.27 +14.4.28 id_options
database options for a container's id column -14.4.28 +14.4.29 index_options
database options for a container's index column -14.4.29 +14.4.30 key_options
database options for a container's key column -14.4.30 +14.4.31 value_options
database options for a container's value column -14.4.31 +14.4.32 id_column
column name for a container's object id -14.4.32 +14.4.33 index_column
column name for a container's index -14.4.33 +14.4.34 key_column
column name for a container's key -14.4.34 +14.4.35 @@ -16341,12 +16353,136 @@ class person relationship information. Only ordered and set containers can be used for inverse members. If an inverse member is of an ordered container type, it is automatically marked as unordered - (Section 14.4.18, " value_column
column name for a container's value -14.4.35 +14.4.36 unordered
"). + (Section 14.4.19, "unordered
").For a more detailed discussion of inverse members, refer to Section 6.2, "Bidirectional Relationships".
-14.4.15
+version
14.4.15
+ +on_delete
The
+ +on_delete
specifier specifies the on-delete semantics + for a data member of an object pointer or a container of object + pointers type. The single required argument to this specifier must + be eithercascade
orset_null
.The
+ +on_delete
specifier is translated directly to the + correspondingON DELETE
SQL clause. That is, if +cascade
is specified, then when a pointed-to object + is erased from the database, the database state of the pointing + object is automatically erased as well. Ifset_null
is + specified, then when a pointed-to object is erased from the database, + the database state of the pointing object is automatically updated + to set the pointer column toNULL
. For example:+#pragma db object +class employer +{ + ... + + #pragma db id auto + unsigned long id_; +}; + +#pragma db object +class person +{ + ... + + #pragma db on_delete(cascade) + employer* employer_; +}; + +unsigned long id; + +{ + employer e; + person p; + p.employer_ = &e; + + transaction t (db.begin ()); + + id = db.persist (e); + db.persist (p); + + t.commit (); +} + +{ + transaction t (db.begin ()); + + // Database state of the person object is erased as well. + // + db.erase<employer> (id); + + t.commit (); +} ++ + +Note that this is a database-level functionality and care must be + taken in order not to end up with inconsistent object states in the + application's memory and database. The following example illustrates + the kind of problems one may encounter:
+ ++#pragma db object +class employer +{ + ... +}; + +#pragma db object +class person +{ + ... + + #pragma db on_delete(set_null) + employer* employer_; +}; + +employer e; +person p; +p.employer_ = &e; + +{ + transaction t (db.begin ()); + db.persist (e); + db.persist (p); + t.commit (); +} + +{ + transaction t (db.begin ()); + + // The employer column is set to NULL in the database but + // not the p.employer_ data member in the application. + // + db.erase (e); + t.commit (); +} + +{ + transaction t (db.begin ()); + + // Override the employer column with an invalid pointer. + // + db.update (p); + + t.commit (); +} ++ +Note that even optimistic concurrency will not resolve such + issues unless you are using database-level support for optimistic + concurrency as well (for example,
+ +ROWVERSION
in SQL + Server).The
+ +on_delete
specifier is only valid for non-inverse + object pointer data members. If theset_null
semantics + is used, then the pointer must allow theNULL
value.14.4.16
version
The
version
specifier specifies that the data member stores the object version used to support optimistic concurrency. If a class @@ -16376,7 +16512,7 @@ class personFor a more detailed discussion of optimistic concurrency, refer to Chapter 12, "Optimistic Concurrency".
-14.4.16
+index
14.4.17
index
The
@@ -16395,7 +16531,7 @@ class personindex
specifier instructs the ODB compiler to define a database index for the data member. For example:For more information on defining database indexes, refer to Section 14.7, "Index Definition Pragmas".
-14.4.17
+unique
14.4.18
unique
The
@@ -16414,7 +16550,7 @@ class personindex
specifier instructs the ODB compiler to define a unique database index for the data member. For example:For more information on defining database indexes, refer to Section 14.7, "Index Definition Pragmas".
-14.4.18
+unordered
14.4.19
unordered
The
-unordered
specifier specifies that the member of an ordered container type should be stored unordered in the database. @@ -16437,7 +16573,7 @@ class person storage in the database, refer to Section 5.1, "Ordered Containers".14.4.19
+table
14.4.20
table
The
@@ -16485,7 +16621,7 @@ class person qualified names, refer to Section 14.1.8, "table
specifier specifies the table name that should be used to store the contents of the container member. For example:schema
". -14.4.20
+load
/update
14.4.21
load
/update
The
-load
andupdate
specifiers specify the loading and updating behavior for an object section, respectively. @@ -16495,7 +16631,7 @@ class personchange
, andmanual
. For more information on object sections, refer to Chapter 9, "Sections".14.4.21
+section
14.4.22
section
The
-section
specifier indicates that a data member of a persistent class belongs to an object section. The single @@ -16504,7 +16640,7 @@ class person members of a persistent class. For more information on object sections, refer to Chapter 9, "Sections".14.4.22
+added
14.4.23
added
The
-added
specifier marks the data member as soft-added. The single required argument to this specifier is @@ -16512,7 +16648,7 @@ class person refer to Section 13.4, "Soft Object Model Changes".14.4.23
+deleted
14.4.24
deleted
The
-deleted
specifier marks the data member as soft-deleted. The single required argument to this specifier is @@ -16520,7 +16656,7 @@ class person refer to Section 13.4, "Soft Object Model Changes".14.4.24
+index_type
14.4.25
index_type
The
index_type
specifier specifies the native database type that should be used for an ordered container's @@ -16540,7 +16676,7 @@ class person };14.4.25
+key_type
14.4.26
key_type
The
key_type
specifier specifies the native database type that should be used for a map container's @@ -16560,7 +16696,7 @@ class person };14.4.26
+value_type
14.4.27
value_type
The
value_type
specifier specifies the native database type that should be used for a container's @@ -16581,12 +16717,12 @@ class person
The value_null
and value_not_null
- (Section 14.4.27,
+ (Section 14.4.28,
"value_null
/value_not_null
") specifiers
can be used to control the NULL
semantics of a value
column.
value_null
/value_not_null
value_null
/value_not_null
The value_null
and value_not_null
specifiers
specify that a container's element value for the data member can or
@@ -16619,7 +16755,7 @@ class account
Multiset Containers") the element value is automatically treated
as not allowing a NULL
value.
id_options
id_options
The id_options
specifier specifies additional
column definition options that should be used for a container's
@@ -16643,7 +16779,7 @@ class person
of the options
specifier (Section
14.4.8, "options
").
index_options
index_options
The index_options
specifier specifies additional
column definition options that should be used for a container's
@@ -16664,7 +16800,7 @@ class person
of the options
specifier (Section
14.4.8, "options
").
key_options
key_options
The key_options
specifier specifies additional
column definition options that should be used for a container's
@@ -16685,7 +16821,7 @@ class person
of the options
specifier (Section
14.4.8, "options
").
value_options
value_options
The value_options
specifier specifies additional
column definition options that should be used for a container's
@@ -16706,7 +16842,7 @@ class person
of the options
specifier (Section
14.4.8, "options
").
id_column
id_column
The id_column
specifier specifies the column
name that should be used to store the object id in a
@@ -16730,7 +16866,7 @@ class person
If the column name is not specified, then object_id
is used by default.
index_column
index_column
The index_column
specifier specifies the column
name that should be used to store the element index in an
@@ -16754,7 +16890,7 @@ class person
If the column name is not specified, then index
is used by default.
key_column
key_column
The key_column
specifier specifies the column
name that should be used to store the key in a map
@@ -16778,7 +16914,7 @@ class person
If the column name is not specified, then key
is used by default.
value_column
value_column
The value_column
specifier specifies the column
name that should be used to store the element value in a
@@ -17138,9 +17274,9 @@ class object
ODB also offers a shortcut for defining an index with the default
method and options for a single data member. Such an index can
- be defined using the index
(Section
- 14.4.16, "index
") or unique
- (Section 14.4.17, "unique
")
+ be defined using the index
(Section
+ 14.4.17, "index
") or unique
+ (Section 14.4.18, "unique
")
member specifier. For example:
@@ -24524,8 +24660,8 @@ class Person-- cgit v1.1
QOdbList
incurs 2-bit per element overhead in order to store the change state. It cannot - be stored unordered in the database (Section - 14.4.18 "unordered
") but can be used as an inverse + be stored unordered in the database (Section + 14.4.19 "unordered
") but can be used as an inverse side of a relationship (6.2 "Bidirectional Relationships"). In this case, no change tracking is performed since no state for such a container is stored in the database.