diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-01-11 14:40:02 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-01-11 14:40:02 +0200 |
commit | 5652354aa256426c5ab32c4a1c5687e5509af868 (patch) | |
tree | ac59964abb8696c12ec4ea71c56e9219dd4245e6 | |
parent | 2a7a60a29cc72f07263ec7534732141f8869b5ed (diff) |
Add support for custom table definition options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | doc/manual.xhtml | 45 | ||||
-rw-r--r-- | odb/context.cxx | 84 | ||||
-rw-r--r-- | odb/context.hxx | 8 | ||||
-rw-r--r-- | odb/relational/model.hxx | 8 | ||||
-rw-r--r-- | odb/relational/mysql/model.cxx | 34 |
6 files changed, 175 insertions, 8 deletions
@@ -7,6 +7,10 @@ Version 2.5.0 @@ Ref to the manual. + * Support for custom table definition options in addition to column + definition options. For details, refer to Section 14.1.16, "options" in + the ODB manual. + * Support for nested object ids. Now the 'id' pragma specifier can optionally include the data member path to the id inside a composite value. For example: diff --git a/doc/manual.xhtml b/doc/manual.xhtml index 0b6dc08..fde0a54 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -538,6 +538,7 @@ for consistency. <tr><th>14.1.13</th><td><a href="#14.1.13"><code>sectionable</code></a></td></tr> <tr><th>14.1.14</th><td><a href="#14.1.14"><code>deleted</code></a></td></tr> <tr><th>14.1.15</th><td><a href="#14.1.15"><code>bulk</code></a></td></tr> + <tr><th>14.1.16</th><td><a href="#14.1.16"><code>options</code></a></td></tr> </table> </td> </tr> @@ -14360,6 +14361,12 @@ class person <td><a href="#14.1.15">14.1.15</a></td> </tr> + <tr> + <td><code>options</code></td> + <td>database options for a persistent class</td> + <td><a href="#14.1.16">14.1.16</a></td> + </tr> + </table> <h3><a name="14.1.1">14.1.1 <code>table</code></a></h3> @@ -15002,6 +15009,39 @@ class employer is the batch size. For more information on this functionality, refer to <a href="#15.3">Section 15.3, "Bulk Database Operations"</a>.</p> + <h3><a name="14.1.16">14.1.16 <code>options</code></a></h3> + + <p>The <code>options</code> specifier specifies additional table + definition options that should be used for the persistent class. For + example:</p> + + <pre class="cxx"> +#pragma db object options("PARTITION BY RANGE (age)") +class person +{ + ... + + unsigned short age_; +}; + </pre> + + <p>Table definition options for a container table can be specified with + the <code>options</code> data member specifier + (<a href="#14.4.8">Section 14.4.8, "<code>options</code>"</a>). For + example:</p> + + <pre class="cxx"> +#pragma db object +class person +{ + ... + + #pragma db options("PARTITION BY RANGE (index)") + std::vector<std::string> aliases_; +}; + </pre> + + <h2><a name="14.2">14.2 View Type Pragmas</a></h2> <p>A pragma with the <code>view</code> qualifier declares a C++ class @@ -16578,6 +16618,11 @@ class person }; </pre> + <p>Note that if specified for the container member, then instead of the + column definition options it specifies the table definition options for + the container table (<a href="#14.1.16">Section 14.1.16, + "<code>options</code>"</a>).</p> + <p>Options can also be specified on the per-type basis (<a href="#14.3.5">Section 14.3.5, "<code>options</code>"</a>). By default, options are accumulating. That is, the ODB compiler diff --git a/odb/context.cxx b/odb/context.cxx index e220d0e..dd4019a 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -2130,6 +2130,90 @@ table_name (semantics::data_member& m, table_prefix const& p) const return r; } +string context:: +table_options (semantics::class_& c) +{ + string r; + + // Accumulate options from class. + // + // @@ Should we also get them from bases? + // + // @@ Note for some databases (like SQLite), options are seperated with + // comma, not space. Likely the same issue in the column_options(). + // + if (c.count ("options")) + { + strings const& o (c.get<strings> ("options")); + + for (strings::const_iterator i (o.begin ()); i != o.end (); ++i) + { + if (i->empty ()) + r.clear (); + else + { + if (!r.empty ()) + r += ' '; + + r += *i; + } + } + } + + return r; +} + +string context:: +table_options (semantics::data_member& m, semantics::type& c) +{ + string r; + + // Accumulate options from container and member. + // + // @@ Currently there is no way to assign options to the container type. If + // we use the value specifier, then it ends up being treated as a value + // type. To support this we will probably need to invent the container + // specifier. + // + if (c.count ("options")) + { + strings const& o (c.get<strings> ("options")); + + for (strings::const_iterator i (o.begin ()); i != o.end (); ++i) + { + if (i->empty ()) + r.clear (); + else + { + if (!r.empty ()) + r += ' '; + + r += *i; + } + } + } + + if (m.count ("options")) + { + strings const& o (m.get<strings> ("options")); + + for (strings::const_iterator i (o.begin ()); i != o.end (); ++i) + { + if (i->empty ()) + r.clear (); + else + { + if (!r.empty ()) + r += ' '; + + r += *i; + } + } + } + + return r; +} + // context::column_prefix // context::column_prefix:: diff --git a/odb/context.hxx b/odb/context.hxx index d10d555..ec4505b 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -1342,6 +1342,14 @@ public: qname table_name (semantics::data_member&, table_prefix const&) const; + string + table_options (semantics::class_&); + + // Table options for the container member. + // + string + table_options (semantics::data_member&, semantics::type& ct); + // // struct column_prefix diff --git a/odb/relational/model.hxx b/odb/relational/model.hxx index b7a07ea..fdfa8fd 100644 --- a/odb/relational/model.hxx +++ b/odb/relational/model.hxx @@ -555,9 +555,9 @@ namespace relational } virtual string - table_options (semantics::data_member&, semantics::type&) + table_options (semantics::data_member& m, semantics::type& ct) { - return ""; + return context::table_options (m, ct); } virtual void @@ -784,9 +784,9 @@ namespace relational class_ (sema_rel::model& model): model_ (model) {} virtual string - table_options (type&) + table_options (type& c) { - return ""; + return context::table_options (c); } virtual void diff --git a/odb/relational/mysql/model.cxx b/odb/relational/mysql/model.cxx index 2ec9d8b..17ed4c0 100644 --- a/odb/relational/mysql/model.cxx +++ b/odb/relational/mysql/model.cxx @@ -110,10 +110,23 @@ namespace relational member_create (base const& x): base (x) {} virtual string - table_options (semantics::data_member&, semantics::type&) + table_options (semantics::data_member& m, semantics::type& c) { + string r (relational::member_create::table_options (m, c)); + string const& engine (options.mysql_engine ()); - return engine != "default" ? "ENGINE=" + engine : ""; + if (engine != "default") + { + // Note: MySQL table options can be separated with spaces. + // + if (!r.empty ()) + r += ' '; + + r += "ENGINE="; + r += engine; + } + + return r; } }; entry<member_create> member_create_; @@ -123,10 +136,23 @@ namespace relational class_ (base const& x): base (x) {} virtual string - table_options (type&) + table_options (type& c) { + string r (relational::class_::table_options (c)); + string const& engine (options.mysql_engine ()); - return engine != "default" ? "ENGINE=" + engine : ""; + if (engine != "default") + { + // Note: MySQL table options can be separated with spaces. + // + if (!r.empty ()) + r += ' '; + + r += "ENGINE="; + r += engine; + } + + return r; } }; entry<class_> class__; |