aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--NEWS4
-rw-r--r--build/root.build86
-rw-r--r--doc/.gitignore5
-rw-r--r--doc/buildfile185
-rwxr-xr-xdoc/doc.sh78
-rw-r--r--doc/manual.xhtml50
-rw-r--r--doc/pregenerated/odb.1799
-rw-r--r--doc/pregenerated/odb.xhtml978
-rw-r--r--manifest8
-rw-r--r--odb/.gitignore5
-rw-r--r--odb/buildfile112
-rw-r--r--odb/context.cxx109
-rw-r--r--odb/context.hxx8
-rw-r--r--odb/parser.cxx88
-rw-r--r--odb/pregenerated/odb/options.cxx (renamed from odb/options.cxx)50
-rw-r--r--odb/pregenerated/odb/options.hxx (renamed from odb/options.hxx)0
-rw-r--r--odb/pregenerated/odb/options.ixx (renamed from odb/options.ixx)0
-rw-r--r--odb/processor.cxx22
-rw-r--r--odb/relational/model.hxx8
-rw-r--r--odb/relational/mysql/model.cxx34
-rw-r--r--odb/relational/processor.cxx2
-rw-r--r--odb/relational/schema.hxx3
-rw-r--r--odb/relational/source.hxx2
-rw-r--r--odb/relational/sqlite/source.cxx3
-rw-r--r--odb/semantics/derived.hxx2
-rw-r--r--odb/semantics/elements.cxx4
-rw-r--r--odb/version.hxx8
-rw-r--r--repositories.manifest4
-rw-r--r--version2
30 files changed, 2471 insertions, 190 deletions
diff --git a/LICENSE b/LICENSE
index 04f3136..f36493e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2022 Code Synthesis Tools CC.
+Copyright (c) 2009-2024 Code Synthesis Tools CC.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
diff --git a/NEWS b/NEWS
index d6b2844..1bd577e 100644
--- a/NEWS
+++ b/NEWS
@@ -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/build/root.build b/build/root.build
index aea8d03..86a02a0 100644
--- a/build/root.build
+++ b/build/root.build
@@ -1,6 +1,27 @@
# file : build/root.build
# license : GNU GPL v3; see accompanying LICENSE file
+# This configuration variable can be used to specify the GCC plugin directory
+# instead of auto-discovering it with -print-file-name=plugin. Primarily
+# useful when dealing with cross-compilation.
+#
+config [dir_path, config.report.variable=plugin_dir] \
+ config.odb.plugin_dir ?= [null]
+
+# This configuration variable can be used to specify the GCC g++ executable
+# name that will be called by the ODB compiler instead of auto-deriving it
+# from config.cxx. Primarily useful when dealing with cross-compilation.
+#
+config [string, config.report.variable=gxx_name] \
+ config.odb.gxx_name ?= [null]
+
+config [bool] config.odb.develop ?= false
+
+develop = $config.odb.develop
+
+define cli: file
+cli{*}: extension = cli
+
cxx.std = latest
using cxx
@@ -29,28 +50,61 @@ if ($build.mode != 'skeleton')
if ($cxx.id != 'gcc')
fail 'ODB compiler can only be built with GCC'
- # Determine the GCC plugin directory.
- #
- # If plugin support is disabled, then -print-file-name will print the name
- # we have passed (the real plugin directory will always be absolute).
+ # Determine the GCC plugin directory unless specified explicitly.
#
+ if ($config.odb.plugin_dir != [null])
+ plugin_dir = $config.odb.plugin_dir
+ else
+ {
+ # If plugin support is disabled, then -print-file-name will print the name
+ # we have passed (the real plugin directory will always be absolute).
+ #
+ plugin_dir = [dir_path] $process.run($cxx.path -print-file-name=plugin)
+
+ if ("$plugin_dir" == plugin)
+ fail "$recall($cxx.path) does not support plugins"
+ }
+
# It can also include '..' components (e.g., on Windows) so normalize it for
# good measure.
#
- plugin_dir = [dir_path] $process.run($cxx.path -print-file-name=plugin)
-
- if ("$plugin_dir" == plugin)
- fail "$recall($cxx.path) does not support plugins"
-
plugin_dir = $normalize($plugin_dir)
- config [config.report] plugin_dir
+ # Determine the g++ executable name unless specified explicitly.
+ #
+ if ($config.odb.gxx_name != [null])
+ gxx_name = $config.odb.gxx_name
+ else
+ {
+ # Unless cross-compiling, pass the C++ compiler's recall path as the g++
+ # name.
+ #
+ # Note that we used to compare complete target triplets but that prooved
+ # too strict. For example, we may be running on x86_64-apple-darwin17.7.0
+ # while the compiler is targeting x86_64-apple-darwin17.3.0.
+ #
+ if ($cxx.target.cpu == $build.host.cpu && \
+ $cxx.target.system == $build.host.system)
+ {
+ gxx_name = $recall($cxx.path)
+ }
+ else
+ fail "g++ executable name must be specified explicitly with \
+config.odb.gxx_name when cross-compiling"
+ }
- # Load the cli module but only if it's available. This way a distribution
- # that includes pre-generated files can be built without installing cli.
- # This is also the reason why we need to explicitly spell out individual
- # source file prerequisites instead of using the cli.cxx{} group (it won't
- # be there unless the module is configured).
+ # Extract the copyright notice from the LICENSE file.
+ #
+ # Note that cat is a builtin which means this is both portable and fast.
+ #
+ copyright = $process.run_regex(cat $src_root/LICENSE, \
+ 'Copyright \(c\) (.+)\.', \
+ '\1')
+}
+else
+{
+ # Set for report.
#
- using? cli
+ plugin_dir = [null]
+ gxx_name = [null]
}
diff --git a/doc/.gitignore b/doc/.gitignore
index 5accfef..9ee2af2 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -1,4 +1,5 @@
-odb.xhtml
-odb.1
+/odb.1
+/odb.xhtml
+
*.ps
*.pdf
diff --git a/doc/buildfile b/doc/buildfile
index 45b7ac2..88f30fc 100644
--- a/doc/buildfile
+++ b/doc/buildfile
@@ -7,14 +7,185 @@ css{*}: extension = css
define xhtml: doc
xhtml{*}: extension = xhtml
-./: css{default}
+define ps: doc
+ps{*}: extension = ps
-# @@ BUILD2 TMP: auto-generated and not in git (also odb-manual.* below)
+define pdf: doc
+pdf{*}: extension = pdf
+
+define html2ps: file
+html2ps{*}: extension = html2ps
+
+./: css{default} xhtml{manual} doc{*.png} file{*.svg}
+
+# Man pages.
+#
+
+## Consumption build ($develop == false).
+#
+
+# Use pregenerated versions in the consumption build.
+#
+./: pregenerated/{man1 xhtml}{*}: include = (!$develop)
+
+# Distribute pregenerated versions only in the consumption build.
+#
+pregenerated/{man1 xhtml}{*}: dist = (!$develop)
+
+#
+##
+
+## Development build ($develop == true).
+#
+
+./: {man1 xhtml}{odb}: include = $develop
+
+if $develop
+{
+ doc_version = [string] "$version.major.$version.minor.$version.patch"
+ if $version.pre_release
+ doc_version += "-$version.pre_release_string"
+
+ # Let's take the last four-digit number to cover 2000-2021,2022.
+ #
+ doc_year = $regex.replace($copyright, '.+[-, ]([0-9][0-9][0-9][0-9]) .+', '\1')
+
+ man_options = -v project="ODB" -v version="$doc_version" \
+ -v copyright="$copyright" --suppress-undocumented
+
+ import! [metadata] cli = cli%exe{cli}
+}
+
+# In the development build distribute regenerated versions, remapping their
+# locations to the paths of the pregenerated versions (which are only
+# distributed in the consumption build; see above). This way we make sure that
+# the distributed files are always up-to-date.
+#
+{man1 xhtml}{odb}: dist = ($develop ? pregenerated/ : false)
+
+# @@ TMP Note that the project, version, and date variables we are passing to
+# cli are currently unused since the respective values are hard-coded
+# in the odb-prologue.* files.
+#
+man1{odb}: ../odb/cli{options} file{odb-prologue.1 odb-epilogue.1} $cli
+%
+if $develop
+{{
+ # Use the copyright year to approximate the last authoring date.
+ #
+ $cli --generate-man $man_options \
+ -v date="January $doc_year" \
+ --man-prologue-file $path($<[1]) \
+ --man-epilogue-file $path($<[2]) \
+ --stdout $path($<[0]) >$path($>)
+
+ # If the result differs from the pregenerated version, copy it over.
+ #
+ if! diff $src_base/pregenerated/odb.1 $path($>) >-
+ cp $path($>) $src_base/pregenerated/odb.1
+ end
+}}
+
+xhtml{odb}: ../odb/cli{options} file{odb-prologue.xhtml odb-epilogue.xhtml} $cli
+%
+if $develop
+{{
+ $cli --generate-html $man_options \
+ --html-prologue-file $path($<[1]) \
+ --html-epilogue-file $path($<[2]) \
+ --stdout $path($<[0]) >$path($>)
+
+ if! diff $src_base/pregenerated/odb.xhtml $path($>) >-
+ cp $path($>) $src_base/pregenerated/odb.xhtml
+ end
+}}
+
+#
+##
+
+# Manual.
+#
+# This case is slightly more involved because we make the generation of the
+# manual's ps/pdf optional and also don't keep the result in the repository.
+# Specifically:
+#
+# 1. In the consumption build we will install/redistribute ps/pdf if present.
+#
+# 2. In the development build we will generate ps/pdf if we are able to import
+# the needed tools, issuing a warning otherwise.
+
+## Consumption build ($develop == false).
+#
+
+# Use pregenerated versions, if exist, in the consumption build.
+#
+./: pregenerated/{ps pdf}{*}: include = (!$develop)
+
+# Distribute pregenerated versions only in the consumption build.
+#
+pregenerated/{ps pdf}{*}: dist = (!$develop)
+
+#
+##
+
+## Development build ($develop == true).
+#
+
+html2pdf = false
+
+if $develop
+{
+ # Import the html2ps and ps2pdf programs from the system, if available.
+ #
+ import? html2ps = html2ps%exe{html2ps}
+ import? ps2pdf = ps2pdf14%exe{ps2pdf14}
+
+ html2pdf = ($html2ps != [null] && $ps2pdf != [null])
+
+ if! $html2pdf
+ warn "html2ps and/or ps2pdf14 are not available, not generating .ps and .pdf documentation"
+}
+
+./: {ps pdf}{odb-manual}: include = $html2pdf
+
+# In the development build distribute regenerated versions, remapping their
+# locations to the paths of the pregenerated versions (which are only
+# distributed in the consumption build; see above). This way we make sure that
+# the distributed files are always up-to-date.
+#
+{ps pdf}{odb-manual}: dist = ($html2pdf ? pregenerated/ : false)
+
+# Note: the pregenerated file may not exist, thus --no-cleanup option is
+# required for the cp builtin call. Strictly speaking we don't really need to
+# copy them since they are not stored in the repository, but let's do that for
+# consistency with the distributed source tree.
+#
+# @@ TMP Note that manual.{xhtml,html2ps} still have copyright years, ODB
+# version, document revision/date, etc hard-coded.
#
-./: file{odb-*.1} file{odb-*.xhtml}
- # {man1 xhtml}{odb}
+ps{odb-manual}: {xhtml html2ps}{manual} $html2ps
+%
+if $html2pdf
+{{
+ options =
+
+ diag html2ps ($<[0])
+ $html2ps $options -f $path($<[1]) -o $path($>) $path($<[0])
+
+ cp --no-cleanup $path($>) $src_base/pregenerated/odb-manual.ps
+}}
-./: doc{manual.xhtml} doc{*.png} file{*.svg +*.html2ps}
- #doc{odb-manual.ps odb-manual.pdf}
+pdf{odb-manual}: ps{odb-manual} $ps2pdf
+%
+if $html2pdf
+{{
+ options = -dOptimize=true -dEmbedAllFonts=true
-./: file{doc.sh}
+ diag ps2pdf ($<[0])
+ $ps2pdf $options $path($<[0]) $path($>)
+
+ cp --no-cleanup $path($>) $src_base/pregenerated/odb-manual.pdf
+}}
+
+#
+##
diff --git a/doc/doc.sh b/doc/doc.sh
deleted file mode 100755
index 4e96aed..0000000
--- a/doc/doc.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#! /usr/bin/env bash
-
-version=2.5.0-b.6
-
-trap 'exit 1' ERR
-set -o errtrace # Trap in functions.
-
-function info () { echo "$*" 1>&2; }
-function error () { info "$*"; exit 1; }
-
-date="$(date +"%B %Y")"
-copyright="$(sed -n -re 's%^Copyright \(c\) (.+)\.$%\1%p' ../LICENSE)"
-
-while [ $# -gt 0 ]; do
- case $1 in
- --clean)
- rm -f odb.xhtml odb.1
- rm -f odb-manual.ps odb-manual.pdf
- exit 0
- ;;
- *)
- error "unexpected $1"
- ;;
- esac
-done
-
-function compile () # <input-name> <output-name>
-{
- local i=$1; shift
- local o=$1; shift
-
- # Use a bash array to handle empty arguments.
- #
- local ops=()
- while [ $# -gt 0 ]; do
- ops=("${ops[@]}" "$1")
- shift
- done
-
- # --html-suffix .xhtml
- cli -I .. \
--v project="odb" \
--v version="$version" \
--v date="$date" \
--v copyright="$copyright" \
-"${ops[@]}" --generate-html --stdout \
---html-prologue-file odb-prologue.xhtml \
---html-epilogue-file odb-epilogue.xhtml \
-"../odb/$i.cli" >"$o.xhtml"
-
- # --man-suffix .1
- cli -I .. \
--v project="odb" \
--v version="$version" \
--v date="$date" \
--v copyright="$copyright" \
-"${ops[@]}" --generate-man --stdout \
---man-prologue-file odb-prologue.1 \
---man-epilogue-file odb-epilogue.1 \
-"../odb/$i.cli" >"$o.1"
-}
-
-compile options odb --suppress-undocumented
-
-# Manual.
-#
-
-#function compile_doc ()
-#{
-# html2ps -f doc.html2ps:a4.html2ps -o "$n-a4.ps" "$n.xhtml"
-# ps2pdf14 -sPAPERSIZE=a4 -dOptimize=true -dEmbedAllFonts=true "$n-a4.ps" "$n-a4.pdf"
-#
-# html2ps -f doc.html2ps:letter.html2ps -o "$n-letter.ps" "$n.xhtml"
-# ps2pdf14 -sPAPERSIZE=letter -dOptimize=true -dEmbedAllFonts=true "$n-letter.ps" "$n-letter.pdf"
-#}
-
-html2ps -f manual.html2ps -o odb-manual.ps manual.xhtml
-ps2pdf14 -dOptimize=true -dEmbedAllFonts=true odb-manual.ps odb-manual.pdf
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index 0b6dc08..a308758 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>
@@ -5776,6 +5777,11 @@ db.query_factory (
});
</pre>
+ Note that the <code>database::query_factory()</code> function is not
+ thread-safe and should be called before starting any threads that may
+ require this functionality. Normally, all the prepared query factories
+ are registered as part of the database instance creation.
+
<!-- CHAPTER -->
<hr class="page-break"/>
@@ -14360,6 +14366,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 +15014,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&lt;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 +16623,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/doc/pregenerated/odb.1 b/doc/pregenerated/odb.1
new file mode 100644
index 0000000..42d81d0
--- /dev/null
+++ b/doc/pregenerated/odb.1
@@ -0,0 +1,799 @@
+.\" Process this file with
+.\" groff -man -Tascii odb.1
+.\"
+.TH ODB 1 "February 2015" "ODB 2.4.0"
+.SH NAME
+odb \- object-relational mapping (ORM) compiler for C++
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH SYNOPSIS
+.\"--------------------------------------------------------------------
+.B odb
+.B [
+.I options
+.B ]
+.I file
+.B [
+.IR file...
+.B ]
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH DESCRIPTION
+.\"--------------------------------------------------------------------
+Given a set of C++ classes in a header file,
+.B odb
+generates C++ code that allows you to persist, query, and update objects
+of these classes in a relational database (RDBMS). The relational
+database that the generated code should target is specified with the
+required
+.B --database
+option (see below).
+
+
+For an input file in the form
+.B name.hxx
+(other file extensions can be used instead of
+.BR .hxx ),
+in the single-database mode (the default), the generated C++ files by
+default have the following names:
+.B name-odb.hxx
+(header file),
+.B name-odb.ixx
+(inline file), and
+.B name-odb.cxx
+(source file). Additionally, if the
+.B --generate-schema
+option is specified and the
+.B sql
+schema format is requested (see
+.BR --schema-format ),
+the
+.B name.sql
+database schema file is generated. If the
+.B separate
+schema format is requested, the database creation code is generated into
+the separate
+.B name-schema.cxx
+file.
+
+
+In the multi-database mode (see the
+.B --multi-database
+option below), the generated files corresponding to the
+.B common
+database have the same names as in the single-database mode. For other
+databases, the file names include the database name:
+.BR name-odb-\fIdb\fB.hxx ,
+.BR name-odb-\fIdb\fB.ixx ,
+.BR name-odb-\fIdb\fB.cxx ,
+.BR name-\fIdb\fB.sql ,
+and
+.B name-schema-\fIdb\fB.cxx
+(where
+.I db
+is the database name).
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH OPTIONS
+.\"--------------------------------------------------------------------
+.IP "\fB--help\fR"
+Print usage information and exit\.
+.IP "\fB--version\fR"
+Print version and exit\.
+.IP "\fB-I\fR \fIdir\fR"
+Add \fIdir\fR to the beginning of the list of directories to be searched for
+included header files\.
+.IP "\fB-D\fR \fIname\fR[=\fIdef\fR]"
+Define macro \fIname\fR with definition \fIdef\fR\. If definition is omitted,
+define \fIname\fR to be 1\.
+.IP "\fB-U\fR \fIname\fR"
+Cancel any previous definitions of macro \fIname\fR, either built-in or
+provided with the \fB-D\fR option\.
+.IP "\fB--database\fR|\fB-d\fR \fIdb\fR"
+Generate code for the \fIdb\fR database\. Valid values are \fBmssql\fR,
+\fBmysql\fR, \fBoracle\fR, \fBpgsql\fR, \fBsqlite\fR, and \fBcommon\fR
+(multi-database mode only)\.
+.IP "\fB--multi-database\fR|\fB-m\fR \fItype\fR"
+Enable multi-database support and specify its type\. Valid values for this
+option are \fBstatic\fR and \fBdynamic\fR\.
+
+In the multi-database mode, options that determine the kind (for example,
+\fB--schema-format\fR), names (for example, \fB--odb-file-suffix\fR), or
+content (for example, prologue and epilogue options) of the output files can
+be prefixed with the database name followed by a colon, for example,
+\fBmysql:value\fR\. This restricts the value of such an option to only apply
+to generated files corresponding to this database\.
+.IP "\fB--default-database\fR \fIdb\fR"
+When static multi-database support is used, specify the database that should
+be made the default\. When dynamic multi-database support is used,
+\fBcommon\fR is always made the default database\.
+.IP "\fB--generate-query\fR|\fB-q\fR"
+Generate query support code\. Without this support you cannot use views and
+can only load objects via their ids\.
+.IP "\fB--generate-prepared\fR"
+Generate prepared query execution support code\.
+.IP "\fB--omit-unprepared\fR"
+Omit un-prepared (once-off) query execution support code\.
+.IP "\fB--generate-session\fR|\fB-e\fR"
+Generate session support code\. With this option session support will be
+enabled by default for all the persistent classes except those for which it
+was explicitly disabled using the \fBdb session\fR pragma\.
+.IP "\fB--generate-schema\fR|\fB-s\fR"
+Generate the database schema\. The database schema contains SQL statements
+that create database tables necessary to store persistent classes defined in
+the file being compiled\. Note that by applying this schema, all the existing
+information stored in such tables will be lost\.
+
+Depending on the database being used (\fB--database\fR option), the schema is
+generated either as a standalone SQL file or embedded into the generated C++
+code\. By default the SQL file is generated for the MySQL, PostgreSQL, Oracle,
+and Microsoft SQL Server databases and the schema is embedded into the C++
+code for the SQLite database\. Use the \fB--schema-format\fR option to alter
+the default schema format\.
+
+If database schema evolution support is enabled (that is, the object model
+version is specified), then this option also triggers the generation of
+database schema migration statements, again either as standalong SQL files or
+embedded into the generated C++ code\. You can suppress the generation of
+schema migration statements by specifying the \fB--suppress-migration\fR
+option\.
+.IP "\fB--generate-schema-only\fR"
+Generate only the database schema\. Note that this option is only valid when
+generating schema as a standalone SQL file (see \fB--schema-format\fR for
+details)\.
+.IP "\fB--suppress-migration\fR"
+Suppress the generation of database schema migration statements\.
+.IP "\fB--suppress-schema-version\fR"
+Suppress the generation of schema version table\. If you specify this option
+then you are also expected to manually specify the database schema version and
+migration state at runtime using the \fBodb::database::schema_version()\fR
+function\.
+.IP "\fB--schema-version-table\fR \fIname\fR"
+Specify the alternative schema version table name instead of the default
+\fBschema_version\fR\. If you specify this option then you are also expected
+to manually specify the schema version table name at runtime using the
+\fBodb::database::schema_version_table()\fR function\. The table name can be
+qualified\.
+.IP "\fB--schema-format\fR \fIformat\fR"
+Generate the database schema in the specified format\. Pass \fBsql\fR as
+\fIformat\fR to generate the database schema as a standalone SQL file or pass
+\fBembedded\fR to embed the schema into the generated C++ code\. The
+\fBseparate\fR value is similar to \fBembedded\fR except the schema creation
+code is generated into a separate C++ file (\fBname-schema\.cxx\fR by
+default)\. This value is primarily useful if you want to place the schema
+creation functionality into a separate program or library\. Repeat this option
+to generate the same database schema in multiple formats\.
+.IP "\fB--omit-drop\fR"
+Omit \fBDROP\fR statements from the generated database schema\.
+.IP "\fB--omit-create\fR"
+Omit \fBCREATE\fR statements from the generated database schema\.
+.IP "\fB--schema-name\fR \fIname\fR"
+Use \fIname\fR as the database schema name\. Schema names are primarily used
+to distinguish between multiple embedded schemas in the schema catalog\. They
+are not to be confused with database schemas (database namespaces) which are
+specified with the \fB--schema\fR option\. If this option is not specified,
+the empty name, which is the default schema name, is used\.
+.IP "\fB--fkeys-deferrable-mode\fR \fIm\fR"
+Use constraint checking mode \fIm\fR in foreign keys generated for object
+relationships\. Valid values for this option are \fBnot_deferrable\fR,
+\fBimmediate\fR, and \fBdeferred\fR (default)\. MySQL and SQL Server do not
+support deferrable foreign keys and for these databases such keys are
+generated commented out\. Other foreign keys generated by the ODB compiler
+(such as the ones used to support containers and polymorphic hierarchies) are
+always generated as not deferrable\.
+
+Note also that if you use either \fBnot_deferrable\fR or \fBimmediate\fR mode,
+then the order in which you persist, update, and erase objects within a
+transaction becomes important\.
+.IP "\fB--default-pointer\fR \fIptr\fR"
+Use \fIptr\fR as the default pointer for persistent objects and views\.
+Objects and views that do not have a pointer assigned with the \fBdb
+pointer\fR pragma will use this pointer by default\. The value of this option
+can be '\fB*\fR' which denotes the raw pointer and is the default, or
+qualified name of a smart pointer class template, for example,
+\fBstd::shared_ptr\fR\. In the latter case, the ODB compiler constructs the
+object or view pointer by adding a single template argument of the object or
+view type to the qualified name, for example \fBstd::shared_ptr<object>\fR\.
+The ODB runtime uses object and view pointers to return, and, in case of
+objects, pass and cache dynamically allocated instances of object and view
+types\.
+
+Except for the raw pointer and the standard smart pointers defined in the
+\fB<memory>\fR header file, you are expected to include the definition of the
+default pointer at the beginning of the generated header file\. There are two
+common ways to achieve this: you can either include the necessary header in
+the file being compiled or you can use the \fB--hxx-prologue\fR option to add
+the necessary \fB#include\fR directive to the generated code\.
+.IP "\fB--session-type\fR \fItype\fR"
+Use \fItype\fR as the alternative session type instead of the default
+\fBodb::session\fR\. This option can be used to specify a custom session
+implementation to be use by the persistent classes\. Note that you will also
+need to include the definition of the custom session type into the generated
+header file\. This is normally achieved with the \fB--hxx-prologue*\fR
+options\.
+.IP "\fB--profile\fR|\fB-p\fR \fIname\fR"
+Specify a profile that should be used during compilation\. A profile is an
+options file\. The ODB compiler first looks for a database-specific version
+with the name constructed by appending the
+\fB-\fR\fIdatabase\fR\fB\.options\fR suffix to \fIname\fR, where
+\fIdatabase\fR is the database name as specified with the \fB--database\fR
+option\. If this file is not found, then the ODB compiler looks for a
+database-independant version with the name constructed by appending just the
+\fB\.options\fR suffix\.
+
+The profile options files are searched for in the same set of directories as
+C++ headers included with the \fB#include <\.\.\.>\fR directive (built-in
+paths plus those specified with the \fB-I\fR options)\. The options file is
+first searched for in the directory itself and then in its \fBodb/\fR
+subdirectory\.
+
+For the format of the options file refer to the \fB--options-file\fR option
+below\. You can repeat this option to specify more than one profile\.
+.IP "\fB--at-once\fR"
+Generate code for all the input files as well as for all the files that they
+include at once\. The result is a single set of source/schema files that
+contain all the generated code\. If more than one input file is specified
+together with this option, then the \fB--input-name\fR option must also be
+specified in order to provide the base name for the output files\. In this
+case, the directory part of such a base name is used as the location of the
+combined file\. This can be important for the \fB#include\fR directive
+resolution\.
+.IP "\fB--schema\fR \fIschema\fR"
+Specify a database schema (database namespace) that should be assigned to the
+persistent classes in the file being compiled\. Database schemas are not to be
+confused with database schema names (schema catalog names) which are specified
+with the \fB--schema-name\fR option\.
+.IP "\fB--export-symbol\fR \fIsymbol\fR"
+Insert \fIsymbol\fR in places where DLL export/import control statements
+(\fB__declspec(dllexport/dllimport)\fR) are necessary\. See also the
+\fB--extern-symbol\fR option below\.
+.IP "\fB--extern-symbol\fR \fIsymbol\fR"
+If \fIsymbol\fR is defined, insert it in places where a template instantiation
+must be declared \fBextern\fR\. This option is normally used together with
+\fB--export-symbol\fR when both multi-database support and queries are
+enabled\.
+.IP "\fB--std\fR \fIversion\fR"
+Specify the C++ standard that should be used during compilation\. Valid values
+are \fBc++98\fR (default), \fBc++11\fR, \fBc++14\fR, \fBc++17\fR, and
+\fBc++20\fR\.
+.IP "\fB--warn-hard-add\fR"
+Warn about hard-added data members\.
+.IP "\fB--warn-hard-delete\fR"
+Warn about hard-deleted data members and persistent classes\.
+.IP "\fB--warn-hard\fR"
+Warn about both hard-added and hard-deleted data members and persistent
+classes\.
+.IP "\fB--output-dir\fR|\fB-o\fR \fIdir\fR"
+Write the generated files to \fIdir\fR instead of the current directory\.
+.IP "\fB--input-name\fR \fIname\fR"
+Use \fIname\fR instead of the input file to derive the names of the generated
+files\. If the \fB--at-once\fR option is specified, then the directory part of
+\fIname\fR is used as the location of the combined file\. Refer to the
+\fB--at-once\fR option for details\.
+.IP "\fB--changelog\fR \fIfile\fR"
+Read/write changelog from/to \fIfile\fR instead of the default changelog
+file\. The default changelog file name is derived from the input file name and
+it is placed into the same directory as the input file\. Note that the
+\fB--output-dir\fR option does not affect the changelog file location\. In
+other words, by default, the changelog file is treated as another input rather
+than output even though the ODB compiler may modify it\. Use the
+\fB--changelog-in\fR and \fB--changelog-out\fR options to specify different
+input and output chaneglog files\.
+.IP "\fB--changelog-in\fR \fIfile\fR"
+Read changelog from \fIfile\fR instead of the default changelog file\. If this
+option is specified, then you must also specify the output chanegelog file
+with \fB--changelog-out\fR\.
+.IP "\fB--changelog-out\fR \fIfile\fR"
+Write changelog to \fIfile\fR instead of the default changelog file\. If this
+option is specified, then you must also specify the input chanegelog file with
+\fB--changelog-in\fR\.
+.IP "\fB--changelog-dir\fR \fIdir\fR"
+Use \fIdir\fR instead of the input file directory as the changelog file
+directory\. This directory is also added to changelog files specified with the
+\fB--changelog\fR, \fB--changelog-in\fR, and \fB--changelog-in\fR options
+unless they are absolute paths\.
+.IP "\fB--init-changelog\fR"
+Force re-initialization of the changelog even if one exists (all the existing
+change history will be lost)\. This option is primarily useful for automated
+testing\.
+.IP "\fB--odb-file-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR to construct the names of the generated C++ files\. In the
+single-database mode the default value for this option is \fB-odb\fR\. In the
+multi-database mode it is \fB-odb\fR for the files corresponding to the
+\fBcommon\fR database and \fB-odb-\fR\fIdb\fR\fR (where \fIdb\fR is the
+database name) for other databases\.
+.IP "\fB--sql-file-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR to construct the name of the generated schema SQL file\. In
+the single-database mode by default no suffix is used\. In the multi-database
+mode the default value for this option is \fB-\fR\fIdb\fR\fR (where \fIdb\fR
+is the database name)\.
+.IP "\fB--schema-file-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR to construct the name of the generated schema C++ source
+file\. In the single-database mode the default value for this option is
+\fB-schema\fR\. In the multi-database mode it is \fB-schema-\fR\fIdb\fR\fR
+(where \fIdb\fR is the database name)\. See the \fB--schema-format\fR option
+for details\.
+.IP "\fB--changelog-file-suffix\fR \fIsfx\fR"
+Use \fIsfx\fR to construct the name of the changelog file\. In the
+single-database mode by default no suffix is used\. In the multi-database mode
+the default value for this option is \fB-\fR\fIdb\fR\fR (where \fIdb\fR is the
+database name)\.
+.IP "\fB--hxx-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.hxx\fR to construct the name of
+the generated C++ header file\.
+.IP "\fB--ixx-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.ixx\fR to construct the name of
+the generated C++ inline file\.
+.IP "\fB--cxx-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.cxx\fR to construct the name of
+the generated C++ source file\.
+.IP "\fB--sql-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.sql\fR to construct the name of
+the generated database schema file\.
+.IP "\fB--changelog-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.xml\fR to construct the name of
+the changelog file\.
+.IP "\fB--hxx-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated C++ header file\.
+.IP "\fB--ixx-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated C++ inline file\.
+.IP "\fB--cxx-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated C++ source file\.
+.IP "\fB--schema-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated schema C++ source file\.
+.IP "\fB--sql-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated database schema file\.
+.IP "\fB--migration-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated database migration file\.
+.IP "\fB--sql-interlude\fR \fItext\fR"
+Insert \fItext\fR after all the \fBDROP\fR and before any \fBCREATE\fR
+statements in the generated database schema file\.
+.IP "\fB--hxx-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated C++ header file\.
+.IP "\fB--ixx-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated C++ inline file\.
+.IP "\fB--cxx-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated C++ source file\.
+.IP "\fB--schema-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated schema C++ source file\.
+.IP "\fB--sql-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated database schema file\.
+.IP "\fB--migration-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated database migration file\.
+.IP "\fB--hxx-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated C++ header
+file\.
+.IP "\fB--ixx-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated C++ inline
+file\.
+.IP "\fB--cxx-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated C++ source
+file\.
+.IP "\fB--schema-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated schema C++
+source file\.
+.IP "\fB--sql-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated database
+schema file\.
+.IP "\fB--migration-prologue-file\fR \fIf\fR"
+Insert the content of file \fIf\fR at the beginning of the generated database
+migration file\.
+.IP "\fB--sql-interlude-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR after all the \fBDROP\fR and before any
+\fBCREATE\fR statements in the generated database schema file\.
+.IP "\fB--hxx-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated C++ header file\.
+.IP "\fB--ixx-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated C++ inline file\.
+.IP "\fB--cxx-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated C++ source file\.
+.IP "\fB--schema-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated schema C++ source
+file\.
+.IP "\fB--sql-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated database schema
+file\.
+.IP "\fB--migration-epilogue-file\fR \fIf\fR"
+Insert the content of file \fIf\fR at the end of the generated database
+migration file\.
+.IP "\fB--odb-prologue\fR \fItext\fR"
+Compile \fItext\fR before the input header file\. This option allows you to
+add additional declarations, such as custom traits specializations, to the ODB
+compilation process\.
+.IP "\fB--odb-prologue-file\fR \fIfile\fR"
+Compile \fIfile\fR contents before the input header file\. Prologue files are
+compiled after all the prologue text fragments (\fB--odb-prologue\fR option)\.
+.IP "\fB--odb-epilogue\fR \fItext\fR"
+Compile \fItext\fR after the input header file\. This option allows you to add
+additional declarations, such as custom traits specializations, to the ODB
+compilation process\.
+.IP "\fB--odb-epilogue-file\fR \fIfile\fR"
+Compile \fIfile\fR contents after the input header file\. Epilogue files are
+compiled after all the epilogue text fragments (\fB--odb-epilogue\fR option)\.
+.IP "\fB--table-prefix\fR \fIprefix\fR"
+Add \fIprefix\fR to table names and, for databases that have global index
+and/or foreign key names, to those names as well\. The prefix is added to both
+names that were specified with the \fBdb table\fR and \fBdb index\fR pragmas
+and those that were automatically derived from class and data member names\.
+If you require a separator, such as an underscore, between the prefix and the
+name, then you should include it into the prefix value\.
+.IP "\fB--index-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB_i\fR to construct index names\.
+The suffix is only added to names that were automatically derived from data
+member names\. If you require a separator, such as an underscore, between the
+name and the suffix, then you should include it into the suffix value\.
+.IP "\fB--fkey-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB_fk\fR to construct foreign key
+names\. If you require a separator, such as an underscore, between the name
+and the suffix, then you should include it into the suffix value\.
+.IP "\fB--sequence-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB_seq\fR to construct sequence
+names\. If you require a separator, such as an underscore, between the name
+and the suffix, then you should include it into the suffix value\.
+.IP "\fB--sql-name-case\fR \fIcase\fR"
+Convert all automatically-derived SQL names to upper or lower case\. Valid
+values for this option are \fBupper\fR and \fBlower\fR\.
+.IP "\fB--table-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+automatically-derived table names\. See the SQL NAME TRANSFORMATIONS section
+below for details\.
+.IP "\fB--column-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+automatically-derived column names\. See the SQL NAME TRANSFORMATIONS section
+below for details\.
+.IP "\fB--index-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+automatically-derived index names\. See the SQL NAME TRANSFORMATIONS section
+below for details\.
+.IP "\fB--fkey-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+automatically-derived foreign key names\. See the SQL NAME TRANSFORMATIONS
+section below for details\.
+.IP "\fB--sequence-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+automatically-derived sequence names\. See the SQL NAME TRANSFORMATIONS
+section below for details\.
+.IP "\fB--statement-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+automatically-derived prepared statement names\. See the SQL NAME
+TRANSFORMATIONS section below for details\.
+.IP "\fB--sql-name-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions that is used to transform
+all automatically-derived SQL names\. See the SQL NAME TRANSFORMATIONS section
+below for details\.
+.IP "\fB--sql-name-regex-trace\fR"
+Trace the process of applying regular expressions specified with the SQL name
+\fB--*-regex\fR options\. Use this option to find out why your regular
+expressions don't do what you expected them to do\.
+.IP "\fB--accessor-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions used to transform data
+member names to function names when searching for a suitable accessor
+function\. The argument to this option is a Perl-like regular expression in
+the form \fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any
+character can be used as a delimiter instead of '\fB/\fR' and the delimiter
+can be escaped inside \fIpattern\fR and \fIreplacement\fR with a backslash
+(\fB\e\fR)\. You can specify multiple regular expressions by repeating this
+option\.
+
+All the regular expressions are tried in the order specified and the first
+expression that produces a suitable accessor function is used\. Each
+expression is tried twice: first with the actual member name and then with the
+member's \fIpublic name\fR which is obtained by removing the common member
+name decorations, such as leading and trailing underscores, the \fBm_\fR
+prefix, etc\. The ODB compiler also includes a number of built-in expressions
+for commonly used accessor names, such as \fBget_foo\fR, \fBgetFoo\fR,
+\fBgetfoo\fR, and just \fBfoo\fR\. The built-in expressions are tried last\.
+
+As an example, the following expression transforms data members with public
+names in the form \fBfoo\fR to accessor names in the form \fBGetFoo\fR:
+
+\fB/(\.+)/Get\eu$1/\fR
+
+See also the REGEX AND SHELL QUOTING section below\.
+.IP "\fB--accessor-regex-trace\fR"
+Trace the process of applying regular expressions specified with the
+\fB--accessor-regex\fR option\. Use this option to find out why your regular
+expressions don't do what you expected them to do\.
+.IP "\fB--modifier-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions used to transform data
+member names to function names when searching for a suitable modifier
+function\. The argument to this option is a Perl-like regular expression in
+the form \fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any
+character can be used as a delimiter instead of '\fB/\fR' and the delimiter
+can be escaped inside \fIpattern\fR and \fIreplacement\fR with a backslash
+(\fB\e\fR)\. You can specify multiple regular expressions by repeating this
+option\.
+
+All the regular expressions are tried in the order specified and the first
+expression that produces a suitable modifier function is used\. Each
+expression is tried twice: first with the actual member name and then with the
+member's \fIpublic name\fR which is obtained by removing the common member
+name decorations, such as leading and trailing underscores, the \fBm_\fR
+prefix, etc\. The ODB compiler also includes a number of built-in expressions
+for commonly used modifier names, such as \fBset_foo\fR, \fBsetFoo\fR,
+\fBsetfoo\fR, and just \fBfoo\fR\. The built-in expressions are tried last\.
+
+As an example, the following expression transforms data members with public
+names in the form \fBfoo\fR to modifier names in the form \fBSetFoo\fR:
+
+\fB/(\.+)/Set\eu$1/\fR
+
+See also the REGEX AND SHELL QUOTING section below\.
+.IP "\fB--modifier-regex-trace\fR"
+Trace the process of applying regular expressions specified with the
+\fB--modifier-regex\fR option\. Use this option to find out why your regular
+expressions don't do what you expected them to do\.
+.IP "\fB--include-with-brackets\fR"
+Use angle brackets (<>) instead of quotes ("") in the generated \fB#include\fR
+directives\.
+.IP "\fB--include-prefix\fR \fIprefix\fR"
+Add \fIprefix\fR to the generated \fB#include\fR directive paths\.
+.IP "\fB--include-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions used to transform generated
+\fB#include\fR directive paths\. The argument to this option is a Perl-like
+regular expression in the form
+\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be
+used as a delimiter instead of '\fB/\fR' and the delimiter can be escaped
+inside \fIpattern\fR and \fIreplacement\fR with a backslash (\fB\e\fR)\. You
+can specify multiple regular expressions by repeating this option\. All the
+regular expressions are tried in the order specified and the first expression
+that matches is used\.
+
+As an example, the following expression transforms include paths in the form
+\fBfoo/bar-odb\.h\fR to paths in the form \fBfoo/generated/bar-odb\.h\fR:
+
+\fB%foo/(\.+)-odb\.h%foo/generated/$1-odb\.h%\fR
+
+See also the REGEX AND SHELL QUOTING section below\.
+.IP "\fB--include-regex-trace\fR"
+Trace the process of applying regular expressions specified with the
+\fB--include-regex\fR option\. Use this option to find out why your regular
+expressions don't do what you expected them to do\.
+.IP "\fB--guard-prefix\fR \fIprefix\fR"
+Add \fIprefix\fR to the generated header inclusion guards\. The prefix is
+transformed to upper case and characters that are illegal in a preprocessor
+macro name are replaced with underscores\.
+.IP "\fB--show-sloc\fR"
+Print the number of generated physical source lines of code (SLOC)\.
+.IP "\fB--sloc-limit\fR \fInum\fR"
+Check that the number of generated physical source lines of code (SLOC) does
+not exceed \fInum\fR\.
+.IP "\fB--options-file\fR \fIfile\fR"
+Read additional options from \fIfile\fR\. Each option should appear on a
+separate line optionally followed by space or equal sign (\fB=\fR) and an
+option value\. Empty lines and lines starting with \fB#\fR are ignored\.
+Option values can be enclosed in double (\fB"\fR) or single (\fB'\fR) quotes
+to preserve leading and trailing whitespaces as well as to specify empty
+values\. If the value itself contains trailing or leading quotes, enclose it
+with an extra pair of quotes, for example \fB'"x"'\fR\. Non-leading and
+non-trailing quotes are interpreted as being part of the option value\.
+
+The semantics of providing options in a file is equivalent to providing the
+same set of options in the same order on the command line at the point where
+the \fB--options-file\fR option is specified except that the shell escaping
+and quoting is not required\. Repeat this option to specify more than one
+options file\.
+.IP "\fB-x\fR \fIoption\fR"
+Pass \fIoption\fR to the underlying C++ compiler (\fBg++\fR)\. The
+\fIoption\fR value that doesn't start with '\fB-\fR' is considered the
+\fBg++\fR executable name\.
+.IP "\fB-v\fR"
+Print the commands executed to run the stages of compilation\.
+.IP "\fB--trace\fR"
+Trace the compilation process\.
+.IP "\fB--mysql-engine\fR \fIengine\fR"
+Use \fIengine\fR instead of the default \fBInnoDB\fR in the generated database
+schema file\. For more information on the storage engine options see the MySQL
+documentation\. If you would like to use the database-default engine, pass
+\fBdefault\fR as the value for this option\.
+.IP "\fB--sqlite-override-null\fR"
+Make all columns in the generated database schema allow \fBNULL\fR values\.
+This is primarily useful in schema migration since SQLite does not support
+dropping of columns\. By making all columns \fBNULL\fR we can later "delete"
+them by setting their values to \fBNULL\fR\. Note that this option overrides
+even the \fBnot_null\fR pragma\.
+.IP "\fB--sqlite-lax-auto-id\fR"
+Do not force monotonically increasing automatically-assigned object ids\. In
+this mode the generated database schema omits the \fBAUTOINCREMENT\fR keyword
+which results in faster object persistence but may lead to
+automatically-assigned ids not being in a strictly ascending order\. Refer to
+the SQLite documentation for details\.
+.IP "\fB--pgsql-server-version\fR \fIver\fR"
+Specify the minimum PostgreSQL server version with which the generated C++
+code and schema will be used\. This information is used to enable
+version-specific optimizations and workarounds in the generated C++ code and
+schema\. The version must be in the \fImajor\fR\fB\.\fR\fIminor\fR\fR form,
+for example, \fB9\.1\fR\. If this option is not specified, then \fB7\.4\fR or
+later is assumed\.
+.IP "\fB--oracle-client-version\fR \fIver\fR"
+Specify the minimum Oracle client library (OCI) version with which the
+generated C++ code will be linked\. This information is used to enable
+version-specific optimizations and workarounds in the generated C++ code\. The
+version must be in the \fImajor\fR\fB\.\fR\fIminor\fR\fR form, for example,
+\fB11\.2\fR\. If this option is not specified, then \fB10\.1\fR or later is
+assumed\.
+.IP "\fB--oracle-warn-truncation\fR"
+Warn about SQL names that are longer than 30 characters and are therefore
+truncated\. Note that during database schema generation
+(\fB--generate-schema\fR) ODB detects when such truncations lead to name
+conflicts and issues diagnostics even without this option specified\.
+.IP "\fB--mssql-server-version\fR \fIver\fR"
+Specify the minimum SQL Server server version with which the generated C++
+code and schema will be used\. This information is used to enable
+version-specific optimizations and workarounds in the generated C++ code and
+schema\. The version must be in the \fImajor\fR\fB\.\fR\fIminor\fR\fR form,
+for example, \fB9\.0\fR (SQL Server 2005), \fB10\.5\fR (2008R2), or
+\fB11\.0\fR (2012)\. If this option is not specified, then \fB10\.0\fR (SQL
+Server 2008) or later is assumed\.
+.IP "\fB--mssql-short-limit\fR \fIsize\fR"
+Specify the short data size limit\. If a character, national character, or
+binary data type has a maximum length (in bytes) less than or equal to this
+limit, then it is treated as \fIshort data\fR, otherwise it is \fIlong
+data\fR\. For short data ODB pre-allocates an intermediate buffer of the
+maximum size and binds it directly to a parameter or result column\. This way
+the underlying API (ODBC) can read/write directly from/to this buffer\. In the
+case of long data, the data is read/written in chunks using the
+\fBSQLGetData()\fR/\fBSQLPutData()\fR ODBC functions\. While the long data
+approach reduces the amount of memory used by the application, it may require
+greater CPU resources\. The default short data limit is 1024 bytes\. When
+setting a custom short data limit, make sure that it is sufficiently large so
+that no object id in the application is treated as long data\.
+.\"
+.\" SQL NAME TRANSFORMATIONS
+.\"
+.SH SQL NAME TRANSFORMATIONS
+The ODB compiler provides a number of mechanisms for transforming
+automatically-derived SQL names, such as tables, columns, etc.,
+to match a specific naming convention. At the higher level, we can
+add a prefix to global names (tables and, for some databases,
+indexes and/or foreign keys) with the
+.B --table-prefix
+option. Similarly, we can specify custom suffixes for automatically-derived
+index
+.RB ( --index-suffix ;
+default is
+.BR _i ),
+foreign key
+.RB ( --fkey-suffix ;
+default is
+.BR _fk ),
+and sequence
+.RB ( --sequence-suffix ;
+default is
+.BR _seq )
+names. Finally, we can also convert all the names to upper or lower
+case with the
+.B --sql-name-case
+option (valid values are
+.B upper
+and
+.BR lower ).
+
+At the lower level we can specify a set of regular expressions to
+implement arbitrary transformations of the automatically-derived SQL
+names. If we want a particular regular expression only to apply to
+a specific name, for example, table or column, then we use one of the
+.B --\fIkind\fB-regex
+options, where
+.I kind
+can be
+.BR table ,
+.BR column ,
+.BR index ,
+.BR fkey ,
+.BR sequence ,
+or
+.BR statement .
+On the other hand, if we want our regular expressions to apply to all SQL
+names, then we use the
+.B --sql-name-regex
+option.
+
+The interaction between the higher and lower level transformations
+is as follows. Prefixes and suffixes are added first. Then the
+regular expression transformations are applied. Finally, if requested,
+the name is converted to upper or lower case. Note also that all of
+these transformations except for
+.B --table-prefix
+only apply to automatically-derived names. In other words, if a table,
+column, etc., name was explicitly specified with a pragma, then it
+is used as is, without applying any (except for the table prefix)
+transformations.
+
+The value for the
+.B --*-regex
+options is a Perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.B /
+and the delimiter can be escaped inside
+.I pattern
+and
+.I replacement
+with a backslash
+.RB ( \e ).
+You can also specify multiple regular expressions by repeating these
+options.
+
+All the regular expressions are tried in the order specified with the
+name-specific expressions (for example,
+.BR --table-regex)
+tried first followed by the generic expressions
+.RB ( --sql-name-regex ).
+The first expression that matches is used.
+
+As an example, consider a regular expression that transforms a class
+name in the form
+.B CFoo
+to a table name in the form
+.BR FOO:
+
+.B --table-regex '/C(.+)/\eU$1/'
+
+As a more interesting example, consider the transformation of class
+names that follow the upper camel case convention (for example,
+.BR FooBar )
+to table names that follow the underscore-separated, all upper case
+convention (for example,
+.BR FOO_BAR ).
+For this case we have to use separate expressions to handle one-word,
+two-word, etc., names:
+
+.B --table-regex '/([A-z][a-z]+)/\eU$1/'
+
+.B --table-regex '/([A-z][a-z]+)([A-z][a-z]+)/\eU$1_$2/'
+
+See also the REGEX AND SHELL QUOTING section below.
+.\"
+.\" REGEX AND SHELL QUOTING
+.\"
+.SH REGEX AND SHELL QUOTING
+When entering a regular expression argument in the shell command line
+it is often necessary to use quoting (enclosing the argument in " "
+or ' ') in order to prevent the shell from interpreting certain
+characters, for example, spaces as argument separators and $ as
+variable expansions.
+
+Unfortunately it is hard to achieve this in a manner that is portable
+across POSIX shells, such as those found on GNU/Linux and UNIX, and
+Windows shell. For example, if you use " " for quoting you will get
+a wrong result with POSIX shells if your expression contains $. The
+standard way of dealing with this on POSIX systems is to use ' '
+instead. Unfortunately, Windows shell does not remove ' ' from
+arguments when they are passed to applications. As a result you may
+have to use ' ' for POSIX and " " for Windows ($ is not treated as
+a special character on Windows).
+
+Alternatively, you can save regular expression options into a file,
+one option per line, and use this file with the
+.B --options-file
+option. With this approach you don't need to worry about shell quoting.
+.\"
+.\" DIAGNOSTICS
+.\"
+.SH DIAGNOSTICS
+If the input file is not valid C++,
+.B odb
+will issue diagnostic messages to STDERR and exit with non-zero exit code.
+.\"
+.\" BUGS
+.\"
+.SH BUGS
+Send bug reports to the odb-users@codesynthesis.com mailing list.
+.\"
+.\" COPYRIGHT
+.\"
+.SH COPYRIGHT
+Copyright (c) 2009-2023 Code Synthesis Tools CC.
+
+Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License,
+version 1.2; with no Invariant Sections, no Front-Cover Texts and
+no Back-Cover Texts. Copy of the license can be obtained from
+http://www.codesynthesis.com/licenses/fdl-1.3.txt
diff --git a/doc/pregenerated/odb.xhtml b/doc/pregenerated/odb.xhtml
new file mode 100644
index 0000000..0a9785c
--- /dev/null
+++ b/doc/pregenerated/odb.xhtml
@@ -0,0 +1,978 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>ODB 2.4.0 Compiler Command Line Manual</title>
+
+ <meta name="copyright" content="&#169; 2009-2023 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="odb,object,relational,mapping,compiler,c++"/>
+ <meta name="description" content="ODB Compiler Command Line Manual"/>
+
+ <link rel="stylesheet" type="text/css" href="default.css" />
+
+<style type="text/css">
+
+ #synopsis {
+ list-style-type: none;
+ }
+
+ #synopsis li {
+ padding-top : 0.0em;
+ padding-bottom : 0.0em;
+ }
+
+ .options {
+ margin: 1em 0 1em 0;
+ }
+
+ .options dt {
+ margin: 1em 0 0 0;
+ }
+
+ .options dd {
+ margin: .1em 0 0 4.5em;
+ }
+
+</style>
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <h1>NAME</h1>
+
+ <p>odb - object-relational mapping (ORM) compiler for C++</p>
+
+ <h1>SYNOPSIS</h1>
+
+ <dl id="synopsis">
+ <dt><code><b>odb</b> [<i>options</i>] <i>file</i> [<i>file</i>...]</code></dt>
+ </dl>
+
+ <h1>DESCRIPTION</h1>
+
+ <p>Given a set of C++ classes in a header file, <code><b>odb</b></code>
+ generates C++ code that allows you to persist, query, and update objects
+ of these classes in a relational database (RDBMS). The relational
+ database that the generated code should target is specified with the
+ required <code><b>--database</b></code> option (see below).</p>
+
+ <p>For an input file in the form <code><b>name.hxx</b></code> (other
+ file extensions can be used instead of <code><b>.hxx</b></code>),
+ in the single-database mode (the default), the generated C++ files
+ by default have the following names:
+ <code><b>name-odb.hxx</b></code> (header file),
+ <code><b>name-odb.ixx</b></code> (inline file), and
+ <code><b>name-odb.cxx</b></code> (source file).
+
+ Additionally, if the <code><b>--generate-schema</b></code> option is
+ specified and the <code><b>sql</b></code> schema format is requested (see
+ <code><b>--schema-format</b></code>), the <code><b>name.sql</b></code>
+ database schema file is generated. If the <code><b>separate</b></code>
+ schema format is requested, the database creation code is generated
+ into the separate <code><b>name-schema.cxx</b></code> file.</p>
+
+ <p>In the multi-database mode (see the <code><b>--multi-database</b></code>
+ option below), the generated files corresponding to the
+ <code><b>common</b></code> database have the same names as in the
+ single-database mode. For other databases, the file names include
+ the database name:
+ <code><b>name-odb-</b><i>db</i><b>.hxx</b></code>,
+ <code><b>name-odb-</b><i>db</i><b>.ixx</b></code>,
+ <code><b>name-odb-</b><i>db</i><b>.cxx</b></code>,
+ <code><b>name-</b><i>db</i><b>.sql</b></code>, and
+ <code><b>name-schema-</b><i>db</i><b>.cxx</b></code>
+ (where <code><i>db</i></code> is the database name).</p>
+
+ <h1>OPTIONS</h1>
+ <dl class="options">
+ <dt><code><b>--help</b></code></dt>
+ <dd>Print usage information and exit.</dd>
+
+ <dt><code><b>--version</b></code></dt>
+ <dd>Print version and exit.</dd>
+
+ <dt><code><b>-I</b></code> <code><i>dir</i></code></dt>
+ <dd>Add <code><i>dir</i></code> to the beginning of the list of
+ directories to be searched for included header files.</dd>
+
+ <dt><code><b>-D</b></code> <code><i>name</i></code>[=<code><i>def</i></code>]</dt>
+ <dd>Define macro <code><i>name</i></code> with definition
+ <code><i>def</i></code>. If definition is omitted, define
+ <code><i>name</i></code> to be 1.</dd>
+
+ <dt><code><b>-U</b></code> <code><i>name</i></code></dt>
+ <dd>Cancel any previous definitions of macro <code><i>name</i></code>,
+ either built-in or provided with the <code><b>-D</b></code> option.</dd>
+
+ <dt><code><b>--database</b></code>|<code><b>-d</b></code> <code><i>db</i></code></dt>
+ <dd>Generate code for the <code><i>db</i></code> database. Valid values
+ are <code><b>mssql</b></code>, <code><b>mysql</b></code>,
+ <code><b>oracle</b></code>, <code><b>pgsql</b></code>,
+ <code><b>sqlite</b></code>, and <code><b>common</b></code> (multi-database
+ mode only).</dd>
+
+ <dt><code><b>--multi-database</b></code>|<code><b>-m</b></code> <code><i>type</i></code></dt>
+ <dd>Enable multi-database support and specify its type. Valid values for
+ this option are <code><b>static</b></code> and
+ <code><b>dynamic</b></code>.
+
+ <p>In the multi-database mode, options that determine the kind (for
+ example, <code><b>--schema-format</b></code>), names (for example,
+ <code><b>--odb-file-suffix</b></code>), or content (for example, prologue
+ and epilogue options) of the output files can be prefixed with the
+ database name followed by a colon, for example,
+ <code><b>mysql:value</b></code>. This restricts the value of such an
+ option to only apply to generated files corresponding to this
+ database.</p></dd>
+
+ <dt><code><b>--default-database</b></code> <code><i>db</i></code></dt>
+ <dd>When static multi-database support is used, specify the database that
+ should be made the default. When dynamic multi-database support is used,
+ <code><b>common</b></code> is always made the default database.</dd>
+
+ <dt><code><b>--generate-query</b></code>|<code><b>-q</b></code></dt>
+ <dd>Generate query support code. Without this support you cannot use views
+ and can only load objects via their ids.</dd>
+
+ <dt><code><b>--generate-prepared</b></code></dt>
+ <dd>Generate prepared query execution support code.</dd>
+
+ <dt><code><b>--omit-unprepared</b></code></dt>
+ <dd>Omit un-prepared (once-off) query execution support code.</dd>
+
+ <dt><code><b>--generate-session</b></code>|<code><b>-e</b></code></dt>
+ <dd>Generate session support code. With this option session support will
+ be enabled by default for all the persistent classes except those for
+ which it was explicitly disabled using the <code><b>db session</b></code>
+ pragma.</dd>
+
+ <dt><code><b>--generate-schema</b></code>|<code><b>-s</b></code></dt>
+ <dd>Generate the database schema. The database schema contains SQL
+ statements that create database tables necessary to store persistent
+ classes defined in the file being compiled. Note that by applying this
+ schema, all the existing information stored in such tables will be lost.
+
+ <p>Depending on the database being used (<code><b>--database</b></code>
+ option), the schema is generated either as a standalone SQL file or
+ embedded into the generated C++ code. By default the SQL file is generated
+ for the MySQL, PostgreSQL, Oracle, and Microsoft SQL Server databases and
+ the schema is embedded into the C++ code for the SQLite database. Use the
+ <code><b>--schema-format</b></code> option to alter the default schema
+ format.</p>
+
+ <p>If database schema evolution support is enabled (that is, the object
+ model version is specified), then this option also triggers the generation
+ of database schema migration statements, again either as standalong SQL
+ files or embedded into the generated C++ code. You can suppress the
+ generation of schema migration statements by specifying the
+ <code><b>--suppress-migration</b></code> option.</p></dd>
+
+ <dt><code><b>--generate-schema-only</b></code></dt>
+ <dd>Generate only the database schema. Note that this option is only valid
+ when generating schema as a standalone SQL file (see
+ <code><b>--schema-format</b></code> for details).</dd>
+
+ <dt><code><b>--suppress-migration</b></code></dt>
+ <dd>Suppress the generation of database schema migration statements.</dd>
+
+ <dt><code><b>--suppress-schema-version</b></code></dt>
+ <dd>Suppress the generation of schema version table. If you specify this
+ option then you are also expected to manually specify the database schema
+ version and migration state at runtime using the
+ <code><b>odb::database::schema_version()</b></code> function.</dd>
+
+ <dt><code><b>--schema-version-table</b></code> <code><i>name</i></code></dt>
+ <dd>Specify the alternative schema version table name instead of the
+ default <code><b>schema_version</b></code>. If you specify this option
+ then you are also expected to manually specify the schema version table
+ name at runtime using the
+ <code><b>odb::database::schema_version_table()</b></code> function. The
+ table name can be qualified.</dd>
+
+ <dt><code><b>--schema-format</b></code> <code><i>format</i></code></dt>
+ <dd>Generate the database schema in the specified format. Pass
+ <code><b>sql</b></code> as <code><i>format</i></code> to generate the
+ database schema as a standalone SQL file or pass
+ <code><b>embedded</b></code> to embed the schema into the generated C++
+ code. The <code><b>separate</b></code> value is similar to
+ <code><b>embedded</b></code> except the schema creation code is generated
+ into a separate C++ file (<code><b>name-schema.cxx</b></code> by default).
+ This value is primarily useful if you want to place the schema creation
+ functionality into a separate program or library. Repeat this option to
+ generate the same database schema in multiple formats.</dd>
+
+ <dt><code><b>--omit-drop</b></code></dt>
+ <dd>Omit <code><b>DROP</b></code> statements from the generated database
+ schema.</dd>
+
+ <dt><code><b>--omit-create</b></code></dt>
+ <dd>Omit <code><b>CREATE</b></code> statements from the generated database
+ schema.</dd>
+
+ <dt><code><b>--schema-name</b></code> <code><i>name</i></code></dt>
+ <dd>Use <code><i>name</i></code> as the database schema name. Schema names
+ are primarily used to distinguish between multiple embedded schemas in the
+ schema catalog. They are not to be confused with database schemas
+ (database namespaces) which are specified with the
+ <code><b>--schema</b></code> option. If this option is not specified, the
+ empty name, which is the default schema name, is used.</dd>
+
+ <dt><code><b>--fkeys-deferrable-mode</b></code> <code><i>m</i></code></dt>
+ <dd>Use constraint checking mode <code><i>m</i></code> in foreign keys
+ generated for object relationships. Valid values for this option are
+ <code><b>not_deferrable</b></code>, <code><b>immediate</b></code>, and
+ <code><b>deferred</b></code> (default). MySQL and SQL Server do not
+ support deferrable foreign keys and for these databases such keys are
+ generated commented out. Other foreign keys generated by the ODB compiler
+ (such as the ones used to support containers and polymorphic hierarchies)
+ are always generated as not deferrable.
+
+ <p>Note also that if you use either <code><b>not_deferrable</b></code> or
+ <code><b>immediate</b></code> mode, then the order in which you persist,
+ update, and erase objects within a transaction becomes important.</p></dd>
+
+ <dt><code><b>--default-pointer</b></code> <code><i>ptr</i></code></dt>
+ <dd>Use <code><i>ptr</i></code> as the default pointer for persistent
+ objects and views. Objects and views that do not have a pointer assigned
+ with the <code><b>db pointer</b></code> pragma will use this pointer by
+ default. The value of this option can be '<code><b>*</b></code>' which
+ denotes the raw pointer and is the default, or qualified name of a smart
+ pointer class template, for example, <code><b>std::shared_ptr</b></code>.
+ In the latter case, the ODB compiler constructs the object or view pointer
+ by adding a single template argument of the object or view type to the
+ qualified name, for example
+ <code><b>std::shared_ptr&lt;object></b></code>. The ODB runtime uses
+ object and view pointers to return, and, in case of objects, pass and
+ cache dynamically allocated instances of object and view types.
+
+ <p>Except for the raw pointer and the standard smart pointers defined in
+ the <code><b>&lt;memory></b></code> header file, you are expected to
+ include the definition of the default pointer at the beginning of the
+ generated header file. There are two common ways to achieve this: you can
+ either include the necessary header in the file being compiled or you can
+ use the <code><b>--hxx-prologue</b></code> option to add the necessary
+ <code><b>#include</b></code> directive to the generated code.</p></dd>
+
+ <dt><code><b>--session-type</b></code> <code><i>type</i></code></dt>
+ <dd>Use <code><i>type</i></code> as the alternative session type instead
+ of the default <code><b>odb::session</b></code>. This option can be used
+ to specify a custom session implementation to be use by the persistent
+ classes. Note that you will also need to include the definition of the
+ custom session type into the generated header file. This is normally
+ achieved with the <code><b>--hxx-prologue*</b></code> options.</dd>
+
+ <dt><code><b>--profile</b></code>|<code><b>-p</b></code> <code><i>name</i></code></dt>
+ <dd>Specify a profile that should be used during compilation. A profile is
+ an options file. The ODB compiler first looks for a database-specific
+ version with the name constructed by appending the
+ <code><b>-</b></code><code><i>database</i></code><code><b>.options</b></code>
+ suffix to <code><i>name</i></code>, where <code><i>database</i></code> is
+ the database name as specified with the <code><b>--database</b></code>
+ option. If this file is not found, then the ODB compiler looks for a
+ database-independant version with the name constructed by appending just
+ the <code><b>.options</b></code> suffix.
+
+ <p>The profile options files are searched for in the same set of
+ directories as C++ headers included with the <code><b>#include
+ &lt;...></b></code> directive (built-in paths plus those specified with
+ the <code><b>-I</b></code> options). The options file is first searched
+ for in the directory itself and then in its <code><b>odb/</b></code>
+ subdirectory.</p>
+
+ <p>For the format of the options file refer to the
+ <code><b>--options-file</b></code> option below. You can repeat this
+ option to specify more than one profile.</p></dd>
+
+ <dt><code><b>--at-once</b></code></dt>
+ <dd>Generate code for all the input files as well as for all the files
+ that they include at once. The result is a single set of source/schema
+ files that contain all the generated code. If more than one input file is
+ specified together with this option, then the
+ <code><b>--input-name</b></code> option must also be specified in order to
+ provide the base name for the output files. In this case, the directory
+ part of such a base name is used as the location of the combined file.
+ This can be important for the <code><b>#include</b></code> directive
+ resolution.</dd>
+
+ <dt><code><b>--schema</b></code> <code><i>schema</i></code></dt>
+ <dd>Specify a database schema (database namespace) that should be assigned
+ to the persistent classes in the file being compiled. Database schemas are
+ not to be confused with database schema names (schema catalog names) which
+ are specified with the <code><b>--schema-name</b></code> option.</dd>
+
+ <dt><code><b>--export-symbol</b></code> <code><i>symbol</i></code></dt>
+ <dd>Insert <code><i>symbol</i></code> in places where DLL export/import
+ control statements (<code><b>__declspec(dllexport/dllimport)</b></code>)
+ are necessary. See also the <code><b>--extern-symbol</b></code> option
+ below.</dd>
+
+ <dt><code><b>--extern-symbol</b></code> <code><i>symbol</i></code></dt>
+ <dd>If <code><i>symbol</i></code> is defined, insert it in places where a
+ template instantiation must be declared <code><b>extern</b></code>. This
+ option is normally used together with <code><b>--export-symbol</b></code>
+ when both multi-database support and queries are enabled.</dd>
+
+ <dt><code><b>--std</b></code> <code><i>version</i></code></dt>
+ <dd>Specify the C++ standard that should be used during compilation. Valid
+ values are <code><b>c++98</b></code> (default), <code><b>c++11</b></code>,
+ <code><b>c++14</b></code>, <code><b>c++17</b></code>, and
+ <code><b>c++20</b></code>.</dd>
+
+ <dt><code><b>--warn-hard-add</b></code></dt>
+ <dd>Warn about hard-added data members.</dd>
+
+ <dt><code><b>--warn-hard-delete</b></code></dt>
+ <dd>Warn about hard-deleted data members and persistent classes.</dd>
+
+ <dt><code><b>--warn-hard</b></code></dt>
+ <dd>Warn about both hard-added and hard-deleted data members and
+ persistent classes.</dd>
+
+ <dt><code><b>--output-dir</b></code>|<code><b>-o</b></code> <code><i>dir</i></code></dt>
+ <dd>Write the generated files to <code><i>dir</i></code> instead of the
+ current directory.</dd>
+
+ <dt><code><b>--input-name</b></code> <code><i>name</i></code></dt>
+ <dd>Use <code><i>name</i></code> instead of the input file to derive the
+ names of the generated files. If the <code><b>--at-once</b></code> option
+ is specified, then the directory part of <code><i>name</i></code> is used
+ as the location of the combined file. Refer to the
+ <code><b>--at-once</b></code> option for details.</dd>
+
+ <dt><code><b>--changelog</b></code> <code><i>file</i></code></dt>
+ <dd>Read/write changelog from/to <code><i>file</i></code> instead of the
+ default changelog file. The default changelog file name is derived from
+ the input file name and it is placed into the same directory as the input
+ file. Note that the <code><b>--output-dir</b></code> option does not
+ affect the changelog file location. In other words, by default, the
+ changelog file is treated as another input rather than output even though
+ the ODB compiler may modify it. Use the <code><b>--changelog-in</b></code>
+ and <code><b>--changelog-out</b></code> options to specify different input
+ and output chaneglog files.</dd>
+
+ <dt><code><b>--changelog-in</b></code> <code><i>file</i></code></dt>
+ <dd>Read changelog from <code><i>file</i></code> instead of the default
+ changelog file. If this option is specified, then you must also specify
+ the output chanegelog file with <code><b>--changelog-out</b></code>.</dd>
+
+ <dt><code><b>--changelog-out</b></code> <code><i>file</i></code></dt>
+ <dd>Write changelog to <code><i>file</i></code> instead of the default
+ changelog file. If this option is specified, then you must also specify
+ the input chanegelog file with <code><b>--changelog-in</b></code>.</dd>
+
+ <dt><code><b>--changelog-dir</b></code> <code><i>dir</i></code></dt>
+ <dd>Use <code><i>dir</i></code> instead of the input file directory as the
+ changelog file directory. This directory is also added to changelog files
+ specified with the <code><b>--changelog</b></code>,
+ <code><b>--changelog-in</b></code>, and <code><b>--changelog-in</b></code>
+ options unless they are absolute paths.</dd>
+
+ <dt><code><b>--init-changelog</b></code></dt>
+ <dd>Force re-initialization of the changelog even if one exists (all the
+ existing change history will be lost). This option is primarily useful for
+ automated testing.</dd>
+
+ <dt><code><b>--odb-file-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> to construct the names of the generated
+ C++ files. In the single-database mode the default value for this option
+ is <code><b>-odb</b></code>. In the multi-database mode it is
+ <code><b>-odb</b></code> for the files corresponding to the
+ <code><b>common</b></code> database and <code><b>-odb-</b><i>db</i></code>
+ (where <code><i>db</i></code> is the database name) for other
+ databases.</dd>
+
+ <dt><code><b>--sql-file-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> to construct the name of the generated
+ schema SQL file. In the single-database mode by default no suffix is used.
+ In the multi-database mode the default value for this option is
+ <code><b>-</b><i>db</i></code> (where <code><i>db</i></code> is the
+ database name).</dd>
+
+ <dt><code><b>--schema-file-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> to construct the name of the generated
+ schema C++ source file. In the single-database mode the default value for
+ this option is <code><b>-schema</b></code>. In the multi-database mode it
+ is <code><b>-schema-</b><i>db</i></code> (where <code><i>db</i></code> is
+ the database name). See the <code><b>--schema-format</b></code> option for
+ details.</dd>
+
+ <dt><code><b>--changelog-file-suffix</b></code> <code><i>sfx</i></code></dt>
+ <dd>Use <code><i>sfx</i></code> to construct the name of the changelog
+ file. In the single-database mode by default no suffix is used. In the
+ multi-database mode the default value for this option is
+ <code><b>-</b><i>db</i></code> (where <code><i>db</i></code> is the
+ database name).</dd>
+
+ <dt><code><b>--hxx-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.hxx</b></code> to construct the name of the generated C++ header
+ file.</dd>
+
+ <dt><code><b>--ixx-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.ixx</b></code> to construct the name of the generated C++ inline
+ file.</dd>
+
+ <dt><code><b>--cxx-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.cxx</b></code> to construct the name of the generated C++ source
+ file.</dd>
+
+ <dt><code><b>--sql-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.sql</b></code> to construct the name of the generated database
+ schema file.</dd>
+
+ <dt><code><b>--changelog-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.xml</b></code> to construct the name of the changelog file.</dd>
+
+ <dt><code><b>--hxx-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated C++
+ header file.</dd>
+
+ <dt><code><b>--ixx-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated C++
+ inline file.</dd>
+
+ <dt><code><b>--cxx-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated C++
+ source file.</dd>
+
+ <dt><code><b>--schema-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated
+ schema C++ source file.</dd>
+
+ <dt><code><b>--sql-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated
+ database schema file.</dd>
+
+ <dt><code><b>--migration-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated
+ database migration file.</dd>
+
+ <dt><code><b>--sql-interlude</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> after all the <code><b>DROP</b></code>
+ and before any <code><b>CREATE</b></code> statements in the generated
+ database schema file.</dd>
+
+ <dt><code><b>--hxx-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated C++ header
+ file.</dd>
+
+ <dt><code><b>--ixx-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated C++ inline
+ file.</dd>
+
+ <dt><code><b>--cxx-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated C++ source
+ file.</dd>
+
+ <dt><code><b>--schema-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated schema C++
+ source file.</dd>
+
+ <dt><code><b>--sql-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated database
+ schema file.</dd>
+
+ <dt><code><b>--migration-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated database
+ migration file.</dd>
+
+ <dt><code><b>--hxx-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated C++ header file.</dd>
+
+ <dt><code><b>--ixx-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated C++ inline file.</dd>
+
+ <dt><code><b>--cxx-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated C++ source file.</dd>
+
+ <dt><code><b>--schema-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated schema C++ source file.</dd>
+
+ <dt><code><b>--sql-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated database schema file.</dd>
+
+ <dt><code><b>--migration-prologue-file</b></code> <code><i>f</i></code></dt>
+ <dd>Insert the content of file <code><i>f</i></code> at the beginning of
+ the generated database migration file.</dd>
+
+ <dt><code><b>--sql-interlude-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> after all the
+ <code><b>DROP</b></code> and before any <code><b>CREATE</b></code>
+ statements in the generated database schema file.</dd>
+
+ <dt><code><b>--hxx-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated C++ header file.</dd>
+
+ <dt><code><b>--ixx-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated C++ inline file.</dd>
+
+ <dt><code><b>--cxx-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated C++ source file.</dd>
+
+ <dt><code><b>--schema-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated schema C++ source file.</dd>
+
+ <dt><code><b>--sql-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated database schema file.</dd>
+
+ <dt><code><b>--migration-epilogue-file</b></code> <code><i>f</i></code></dt>
+ <dd>Insert the content of file <code><i>f</i></code> at the end of the
+ generated database migration file.</dd>
+
+ <dt><code><b>--odb-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Compile <code><i>text</i></code> before the input header file. This
+ option allows you to add additional declarations, such as custom traits
+ specializations, to the ODB compilation process.</dd>
+
+ <dt><code><b>--odb-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Compile <code><i>file</i></code> contents before the input header
+ file. Prologue files are compiled after all the prologue text fragments
+ (<code><b>--odb-prologue</b></code> option).</dd>
+
+ <dt><code><b>--odb-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Compile <code><i>text</i></code> after the input header file. This
+ option allows you to add additional declarations, such as custom traits
+ specializations, to the ODB compilation process.</dd>
+
+ <dt><code><b>--odb-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Compile <code><i>file</i></code> contents after the input header file.
+ Epilogue files are compiled after all the epilogue text fragments
+ (<code><b>--odb-epilogue</b></code> option).</dd>
+
+ <dt><code><b>--table-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> to table names and, for databases that
+ have global index and/or foreign key names, to those names as well. The
+ prefix is added to both names that were specified with the <code><b>db
+ table</b></code> and <code><b>db index</b></code> pragmas and those that
+ were automatically derived from class and data member names. If you
+ require a separator, such as an underscore, between the prefix and the
+ name, then you should include it into the prefix value.</dd>
+
+ <dt><code><b>--index-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>_i</b></code> to construct index names. The suffix is only added
+ to names that were automatically derived from data member names. If you
+ require a separator, such as an underscore, between the name and the
+ suffix, then you should include it into the suffix value.</dd>
+
+ <dt><code><b>--fkey-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>_fk</b></code> to construct foreign key names. If you require a
+ separator, such as an underscore, between the name and the suffix, then
+ you should include it into the suffix value.</dd>
+
+ <dt><code><b>--sequence-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>_seq</b></code> to construct sequence names. If you require a
+ separator, such as an underscore, between the name and the suffix, then
+ you should include it into the suffix value.</dd>
+
+ <dt><code><b>--sql-name-case</b></code> <code><i>case</i></code></dt>
+ <dd>Convert all automatically-derived SQL names to upper or lower case.
+ Valid values for this option are <code><b>upper</b></code> and
+ <code><b>lower</b></code>.</dd>
+
+ <dt><code><b>--table-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform automatically-derived table names. See the SQL NAME
+ TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--column-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform automatically-derived column names. See the SQL NAME
+ TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--index-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform automatically-derived index names. See the SQL NAME
+ TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--fkey-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform automatically-derived foreign key names. See the SQL
+ NAME TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--sequence-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform automatically-derived sequence names. See the SQL
+ NAME TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--statement-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform automatically-derived prepared statement names. See
+ the SQL NAME TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--sql-name-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions that
+ is used to transform all automatically-derived SQL names. See the SQL NAME
+ TRANSFORMATIONS section below for details.</dd>
+
+ <dt><code><b>--sql-name-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with the
+ SQL name <code><b>--*-regex</b></code> options. Use this option to find
+ out why your regular expressions don't do what you expected them to
+ do.</dd>
+
+ <dt><code><b>--accessor-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions used
+ to transform data member names to function names when searching for a
+ suitable accessor function. The argument to this option is a Perl-like
+ regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any
+ character can be used as a delimiter instead of '<code><b>/</b></code>'
+ and the delimiter can be escaped inside <code><i>pattern</i></code> and
+ <code><i>replacement</i></code> with a backslash (<code><b>\</b></code>).
+ You can specify multiple regular expressions by repeating this option.
+
+ <p>All the regular expressions are tried in the order specified and the
+ first expression that produces a suitable accessor function is used. Each
+ expression is tried twice: first with the actual member name and then with
+ the member's <i>public name</i> which is obtained by removing the common
+ member name decorations, such as leading and trailing underscores, the
+ <code><b>m_</b></code> prefix, etc. The ODB compiler also includes a
+ number of built-in expressions for commonly used accessor names, such as
+ <code><b>get_foo</b></code>, <code><b>getFoo</b></code>,
+ <code><b>getfoo</b></code>, and just <code><b>foo</b></code>. The built-in
+ expressions are tried last.</p>
+
+ <p>As an example, the following expression transforms data members with
+ public names in the form <code><b>foo</b></code> to accessor names in the
+ form <code><b>GetFoo</b></code>:</p>
+
+ <p class="code"><code><b>/(.+)/Get\u$1/</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p></dd>
+
+ <dt><code><b>--accessor-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with the
+ <code><b>--accessor-regex</b></code> option. Use this option to find out
+ why your regular expressions don't do what you expected them to do.</dd>
+
+ <dt><code><b>--modifier-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions used
+ to transform data member names to function names when searching for a
+ suitable modifier function. The argument to this option is a Perl-like
+ regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any
+ character can be used as a delimiter instead of '<code><b>/</b></code>'
+ and the delimiter can be escaped inside <code><i>pattern</i></code> and
+ <code><i>replacement</i></code> with a backslash (<code><b>\</b></code>).
+ You can specify multiple regular expressions by repeating this option.
+
+ <p>All the regular expressions are tried in the order specified and the
+ first expression that produces a suitable modifier function is used. Each
+ expression is tried twice: first with the actual member name and then with
+ the member's <i>public name</i> which is obtained by removing the common
+ member name decorations, such as leading and trailing underscores, the
+ <code><b>m_</b></code> prefix, etc. The ODB compiler also includes a
+ number of built-in expressions for commonly used modifier names, such as
+ <code><b>set_foo</b></code>, <code><b>setFoo</b></code>,
+ <code><b>setfoo</b></code>, and just <code><b>foo</b></code>. The built-in
+ expressions are tried last.</p>
+
+ <p>As an example, the following expression transforms data members with
+ public names in the form <code><b>foo</b></code> to modifier names in the
+ form <code><b>SetFoo</b></code>:</p>
+
+ <p class="code"><code><b>/(.+)/Set\u$1/</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p></dd>
+
+ <dt><code><b>--modifier-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with the
+ <code><b>--modifier-regex</b></code> option. Use this option to find out
+ why your regular expressions don't do what you expected them to do.</dd>
+
+ <dt><code><b>--include-with-brackets</b></code></dt>
+ <dd>Use angle brackets (&lt;>) instead of quotes ("") in the generated
+ <code><b>#include</b></code> directives.</dd>
+
+ <dt><code><b>--include-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> to the generated
+ <code><b>#include</b></code> directive paths.</dd>
+
+ <dt><code><b>--include-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions used
+ to transform generated <code><b>#include</b></code> directive paths. The
+ argument to this option is a Perl-like regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any
+ character can be used as a delimiter instead of '<code><b>/</b></code>'
+ and the delimiter can be escaped inside <code><i>pattern</i></code> and
+ <code><i>replacement</i></code> with a backslash (<code><b>\</b></code>).
+ You can specify multiple regular expressions by repeating this option. All
+ the regular expressions are tried in the order specified and the first
+ expression that matches is used.
+
+ <p>As an example, the following expression transforms include paths in the
+ form <code><b>foo/bar-odb.h</b></code> to paths in the form
+ <code><b>foo/generated/bar-odb.h</b></code>:</p>
+
+ <p
+ class="code"><code><b>%foo/(.+)-odb.h%foo/generated/$1-odb.h%</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p></dd>
+
+ <dt><code><b>--include-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with the
+ <code><b>--include-regex</b></code> option. Use this option to find out
+ why your regular expressions don't do what you expected them to do.</dd>
+
+ <dt><code><b>--guard-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> to the generated header inclusion
+ guards. The prefix is transformed to upper case and characters that are
+ illegal in a preprocessor macro name are replaced with underscores.</dd>
+
+ <dt><code><b>--show-sloc</b></code></dt>
+ <dd>Print the number of generated physical source lines of code
+ (SLOC).</dd>
+
+ <dt><code><b>--sloc-limit</b></code> <code><i>num</i></code></dt>
+ <dd>Check that the number of generated physical source lines of code
+ (SLOC) does not exceed <code><i>num</i></code>.</dd>
+
+ <dt><code><b>--options-file</b></code> <code><i>file</i></code></dt>
+ <dd>Read additional options from <code><i>file</i></code>. Each option
+ should appear on a separate line optionally followed by space or equal
+ sign (<code><b>=</b></code>) and an option value. Empty lines and lines
+ starting with <code><b>#</b></code> are ignored. Option values can be
+ enclosed in double (<code><b>"</b></code>) or single
+ (<code><b>'</b></code>) quotes to preserve leading and trailing
+ whitespaces as well as to specify empty values. If the value itself
+ contains trailing or leading quotes, enclose it with an extra pair of
+ quotes, for example <code><b>'"x"'</b></code>. Non-leading and
+ non-trailing quotes are interpreted as being part of the option value.
+
+ <p>The semantics of providing options in a file is equivalent to providing
+ the same set of options in the same order on the command line at the point
+ where the <code><b>--options-file</b></code> option is specified except
+ that the shell escaping and quoting is not required. Repeat this option to
+ specify more than one options file.</p></dd>
+
+ <dt><code><b>-x</b></code> <code><i>option</i></code></dt>
+ <dd>Pass <code><i>option</i></code> to the underlying C++ compiler
+ (<code><b>g++</b></code>). The <code><i>option</i></code> value that
+ doesn't start with '<code><b>-</b></code>' is considered the
+ <code><b>g++</b></code> executable name.</dd>
+
+ <dt><code><b>-v</b></code></dt>
+ <dd>Print the commands executed to run the stages of compilation.</dd>
+
+ <dt><code><b>--trace</b></code></dt>
+ <dd>Trace the compilation process.</dd>
+
+ <dt><code><b>--mysql-engine</b></code> <code><i>engine</i></code></dt>
+ <dd>Use <code><i>engine</i></code> instead of the default
+ <code><b>InnoDB</b></code> in the generated database schema file. For more
+ information on the storage engine options see the MySQL documentation. If
+ you would like to use the database-default engine, pass
+ <code><b>default</b></code> as the value for this option.</dd>
+
+ <dt><code><b>--sqlite-override-null</b></code></dt>
+ <dd>Make all columns in the generated database schema allow
+ <code><b>NULL</b></code> values. This is primarily useful in schema
+ migration since SQLite does not support dropping of columns. By making all
+ columns <code><b>NULL</b></code> we can later "delete" them by setting
+ their values to <code><b>NULL</b></code>. Note that this option overrides
+ even the <code><b>not_null</b></code> pragma.</dd>
+
+ <dt><code><b>--sqlite-lax-auto-id</b></code></dt>
+ <dd>Do not force monotonically increasing automatically-assigned object
+ ids. In this mode the generated database schema omits the
+ <code><b>AUTOINCREMENT</b></code> keyword which results in faster object
+ persistence but may lead to automatically-assigned ids not being in a
+ strictly ascending order. Refer to the SQLite documentation for
+ details.</dd>
+
+ <dt><code><b>--pgsql-server-version</b></code> <code><i>ver</i></code></dt>
+ <dd>Specify the minimum PostgreSQL server version with which the generated
+ C++ code and schema will be used. This information is used to enable
+ version-specific optimizations and workarounds in the generated C++ code
+ and schema. The version must be in the
+ <code><i>major</i><b>.</b><i>minor</i></code> form, for example,
+ <code><b>9.1</b></code>. If this option is not specified, then
+ <code><b>7.4</b></code> or later is assumed.</dd>
+
+ <dt><code><b>--oracle-client-version</b></code> <code><i>ver</i></code></dt>
+ <dd>Specify the minimum Oracle client library (OCI) version with which the
+ generated C++ code will be linked. This information is used to enable
+ version-specific optimizations and workarounds in the generated C++ code.
+ The version must be in the <code><i>major</i><b>.</b><i>minor</i></code>
+ form, for example, <code><b>11.2</b></code>. If this option is not
+ specified, then <code><b>10.1</b></code> or later is assumed.</dd>
+
+ <dt><code><b>--oracle-warn-truncation</b></code></dt>
+ <dd>Warn about SQL names that are longer than 30 characters and are
+ therefore truncated. Note that during database schema generation
+ (<code><b>--generate-schema</b></code>) ODB detects when such truncations
+ lead to name conflicts and issues diagnostics even without this option
+ specified.</dd>
+
+ <dt><code><b>--mssql-server-version</b></code> <code><i>ver</i></code></dt>
+ <dd>Specify the minimum SQL Server server version with which the generated
+ C++ code and schema will be used. This information is used to enable
+ version-specific optimizations and workarounds in the generated C++ code
+ and schema. The version must be in the
+ <code><i>major</i><b>.</b><i>minor</i></code> form, for example,
+ <code><b>9.0</b></code> (SQL Server 2005), <code><b>10.5</b></code>
+ (2008R2), or <code><b>11.0</b></code> (2012). If this option is not
+ specified, then <code><b>10.0</b></code> (SQL Server 2008) or later is
+ assumed.</dd>
+
+ <dt><code><b>--mssql-short-limit</b></code> <code><i>size</i></code></dt>
+ <dd>Specify the short data size limit. If a character, national character,
+ or binary data type has a maximum length (in bytes) less than or equal to
+ this limit, then it is treated as <i>short data</i>, otherwise it is
+ <i>long data</i>. For short data ODB pre-allocates an intermediate buffer
+ of the maximum size and binds it directly to a parameter or result column.
+ This way the underlying API (ODBC) can read/write directly from/to this
+ buffer. In the case of long data, the data is read/written in chunks using
+ the <code><b>SQLGetData()</b></code>/<code><b>SQLPutData()</b></code> ODBC
+ functions. While the long data approach reduces the amount of memory used
+ by the application, it may require greater CPU resources. The default
+ short data limit is 1024 bytes. When setting a custom short data limit,
+ make sure that it is sufficiently large so that no object id in the
+ application is treated as long data.</dd>
+ </dl>
+
+ <h1>SQL NAME TRANSFORMATIONS</h1>
+
+ <p>The ODB compiler provides a number of mechanisms for transforming
+ automatically-derived SQL names, such as tables, columns, etc.,
+ to match a specific naming convention. At the higher level, we can
+ add a prefix to global names (tables and, for some databases,
+ indexes and/or foreign keys) with the <code><b>--table-prefix</b></code>
+ option. Similarly, we can specify custom suffixes for
+ automatically-derived
+ index (<code><b>--index-suffix</b></code>; default is <code><b>_i</b></code>),
+ foreign key (<code><b>--fkey-suffix</b></code>; default is <code><b>_fk</b></code>), and
+ sequence (<code><b>--sequence-suffix</b></code>; default is <code><b>_seq</b></code>)
+ names. Finally, we can also convert all the names to upper or lower
+ case with the <code><b>--sql-name-case</b></code> option (valid values
+ are <code><b>upper</b></code> and <code><b>lower</b></code>).</p>
+
+ <p>At the lower level we can specify a set of regular expressions to
+ implement arbitrary transformations of the automatically-derived SQL
+ names. If we want a particular regular expression only to apply to
+ a specific name, for example, table or column, then we use one of the
+ <code><b>--</b><i>kind</i><b>-regex</b></code> options, where
+ <code><i>kind</i></code> can be <code><b>table</b></code>,
+ <code><b>column</b></code>, <code><b>index</b></code>,
+ <code><b>fkey</b></code>, <code><b>sequence</b></code>, or
+ <code><b>statement</b></code>. On the other hand, if we want our
+ regular expressions to apply to all SQL names, then we use the
+ <code><b>--sql-name-regex</b></code> option.</p>
+
+ <p>The interaction between the higher and lower level transformations
+ is as follows. Prefixes and suffixes are added first. Then the
+ regular expression transformations are applied. Finally, if requested,
+ the name is converted to upper or lower case. Note also that all of
+ these transformations except for <code><b>--table-prefix</b></code>
+ only apply to automatically-derived names. In other words, if a table,
+ column, etc., name was explicitly specified with a pragma, then it
+ is used as is, without applying any (except for the table prefix)
+ transformations.</p>
+
+ <p>The value for the <code><b>--*-regex</b></code> options is a Perl-like
+ regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>
+ and the delimiter can be escaped inside <code><i>pattern</i></code> and
+ <code><i>replacement</i></code> with a backslash (<code><b>\</b></code>).
+ You can also specify multiple regular expressions by repeating these
+ options.</p>
+
+ <p>All the regular expressions are tried in the order specified with the
+ name-specific expressions (for example, <code><b>--table-regex</b></code>)
+ tried first followed by the generic expressions
+ (<code><b>--sql-name-regex</b></code>). The first expression that
+ matches is used.</p>
+
+ <p>As an example, consider a regular expression that transforms a class
+ name in the form <code><b>CFoo</b></code> to a table name in the
+ form <code><b>FOO</b></code>:</p>
+
+ <p><code><b>--table-regex '/C(.+)/\U$1/'</b></code></p>
+
+ <p>As a more interesting example, consider the transformation of class
+ names that follow the upper camel case convention (for example,
+ <code><b>FooBar</b></code>) to table names that follow the
+ underscore-separated, all upper case convention (for example,
+ <code><b>FOO_BAR</b></code>). For this case we have to use
+ separate expressions to handle one-word, two-word, etc.,
+ names:</p>
+
+ <p><code><b>--table-regex '/([A-z][a-z]+)/\U$1/'</b></code></p>
+ <p><code><b>--table-regex '/([A-z][a-z]+)([A-z][a-z]+)/\U$1_$2/'</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+
+ <h1>REGEX AND SHELL QUOTING</h1>
+
+ <p>When entering a regular expression argument in the shell
+ command line it is often necessary to use quoting (enclosing
+ the argument in <code><b>"&nbsp;"</b></code> or
+ <code><b>'&nbsp;'</b></code>) in order to prevent the shell
+ from interpreting certain characters, for example, spaces as
+ argument separators and <code><b>$</b></code> as variable
+ expansions.</p>
+
+ <p>Unfortunately it is hard to achieve this in a manner that is
+ portable across POSIX shells, such as those found on
+ GNU/Linux and UNIX, and Windows shell. For example, if you
+ use <code><b>"&nbsp;"</b></code> for quoting you will get a
+ wrong result with POSIX shells if your expression contains
+ <code><b>$</b></code>. The standard way of dealing with this
+ on POSIX systems is to use <code><b>'&nbsp;'</b></code> instead.
+ Unfortunately, Windows shell does not remove <code><b>'&nbsp;'</b></code>
+ from arguments when they are passed to applications. As a result you
+ may have to use <code><b>'&nbsp;'</b></code> for POSIX and
+ <code><b>"&nbsp;"</b></code> for Windows (<code><b>$</b></code> is
+ not treated as a special character on Windows).</p>
+
+ <p>Alternatively, you can save regular expression options into
+ a file, one option per line, and use this file with the
+ <code><b>--options-file</b></code> option. With this approach
+ you don't need to worry about shell quoting.</p>
+
+ <h1>DIAGNOSTICS</h1>
+
+ <p>If the input file is not valid C++, <code><b>odb</b></code>
+ will issue diagnostic messages to STDERR and exit with non-zero exit
+ code.</p>
+
+ <h1>BUGS</h1>
+
+ <p>Send bug reports to the
+ <a href="mailto:odb-users@codesynthesis.com">odb-users@codesynthesis.com</a> mailing list.</p>
+
+ </div>
+ <div id="footer">
+ Copyright &#169; 2009-2023 Code Synthesis Tools CC.
+
+ <div id="terms">
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://codesynthesis.com/licenses/fdl-1.3.txt">GNU Free
+ Documentation License, version 1.3</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/manifest b/manifest
index 6e00bf3..adef20c 100644
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
: 1
name: odb
-version: 2.5.0-b.24.z
+version: 2.5.0-b.26.z
summary: ODB compiler
license: GPL-3.0-only
topics: C++, ORM, source code generation, object persistence, \
@@ -19,11 +19,13 @@ builds: &gcc-5+ ; Requires GCC 5 or later.
builds: -static ; Implementation uses plugins and requires -fPIC.
requires: host
requires: c++11
-depends: * build2 >= 0.15.0-
-depends: * bpkg >= 0.15.0-
+depends: * build2 >= 0.16.0-
+depends: * bpkg >= 0.16.0-
depends: libstudxml ^1.1.0-
depends: libcutl ^1.11.0-
#depends: libstudxml == 1.1.0-b.10
#depends: libcutl == 1.11.0-b.9
+
+depends: * cli ^1.2.0- ? ($config.odb.develop)
diff --git a/odb/.gitignore b/odb/.gitignore
index 7e97b78..4fd410e 100644
--- a/odb/.gitignore
+++ b/odb/.gitignore
@@ -1,3 +1,2 @@
-odb
-odb.so
-#options.?xx
+/odb
+/options.?xx
diff --git a/odb/buildfile b/odb/buildfile
index 2625e0d..34a6329 100644
--- a/odb/buildfile
+++ b/odb/buildfile
@@ -32,22 +32,6 @@ if ($cxx.target.class != 'windows')
#
plugin{*}: install = bin/
-# Unless cross-compiling, pass the C++ compiler's recall path as the g++
-# name. At some point we should also make it configurable.
-#
-# Note that we used to compare complete target triplets but that prooved too
-# strict. For example, we may be running on x86_64-apple-darwin17.7.0 while
-# the compiler is targeting x86_64-apple-darwin17.3.0.
-#
-if ($cxx.target.cpu == $build.host.cpu && \
- $cxx.target.system == $build.host.system)
-{
- gxx_name = $recall($cxx.path)
- gxx_name = $regex.replace($gxx_name, '\\', '\\\\') # Escape back slashes.
-}
-else
- gxx_name = g++
-
import libs = libcutl%lib{cutl}
import libs += libstudxml%lib{studxml}
@@ -94,49 +78,83 @@ switch $cxx.target.system
plugin{odb}: cxx.loptions += -undefined dynamic_lookup
}
-libus{odb}: {hxx ixx txx cxx}{** -odb -options} {hxx ixx cxx}{options} $libs
+libus{odb}: {hxx ixx txx cxx}{** -odb -options -pregenerated/**} $libs
# Build options.
#
-cxx.poptions += "-I$plugin_dir/include" "-DODB_GXX_NAME=\"$gxx_name\""
+# Note: escape backslashes in gxx_name.
+#
+cxx.poptions += "-I$plugin_dir/include"
+cxx.poptions += "-DODB_GXX_NAME=\"$regex.replace($gxx_name, '\\', '\\\\')\""
cxx.poptions += -DODB_BUILD2 # @@ TMP while supporting other build systems.
-# Pass the copyright notice extracted from the LICENSE file.
+## Consumption build ($develop == false).
#
-copyright = $process.run_regex(cat $src_root/LICENSE, \
- 'Copyright \(c\) (.+)\.', \
- '\1')
-obj{odb}: cxx.poptions += -DODB_COPYRIGHT=\"$copyright\"
+# Use pregenerated versions in the consumption build.
+#
+libus{odb}: pregenerated/{hxx ixx cxx}{**}: include = (!$develop)
+
+if! $develop
+ cxx.poptions =+ "-I($src_base/pregenerated)" # Note: must come first.
-# Generated options parser.
+# Distribute pregenerated versions only in the consumption build.
#
-# @@ TMP: currently generated code is committed to allow building from git.
+pregenerated/{hxx ixx cxx}{*}: dist = (!$develop)
+
#
-if $cli.configured
+##
+
+## Development build ($develop == true).
+#
+
+libus{odb}: {hxx ixx cxx}{options}: include = $develop
+
+if $develop
+ import! [metadata] cli = cli%exe{cli}
+
+# In the development build distribute regenerated {hxx ixx cxx}{options},
+# remapping their locations to the paths of the pregenerated versions (which
+# are only distributed in the consumption build; see above). This way we make
+# sure that the distributed files are always up-to-date.
+#
+<{hxx ixx cxx}{options}>: cli{options} $cli
{
- cli.cxx{options}: cli{options}
-
- cli.options += --include-with-brackets --include-prefix odb \
---guard-prefix ODB --generate-file-scanner --generate-specifier \
---generate-modifier --generate-description --suppress-undocumented \
---cxx-prologue '#include <odb/option-parsers.hxx>'
-
- cli.cxx{*}:
- {
- # Include the generated cli files into the distribution and don't remove
- # them when cleaning in src (so that clean results in a state identical to
- # distributed).
- #
- dist = true
- clean = ($src_root != $out_root)
-
- # We keep the generated code in the repository so copy it back to src in
- # case of a forwarded configuration.
- #
- backlink = overwrite
- }
+ dist = ($develop ? pregenerated/odb/ : false)
+
+ # Symlink the generated code in src for convenience of development.
+ #
+ backlink = true
}
+%
+if $develop
+{{
+ options = --include-with-brackets --include-prefix odb --guard-prefix ODB \
+ --generate-file-scanner --generate-specifier --generate-modifier \
+ --generate-description --suppress-undocumented \
+ --cxx-prologue '#include <odb/option-parsers.hxx>'
+
+ $cli $options -o $out_base $path($<[0])
+
+ # If the result differs from the pregenerated version, copy it over.
+ #
+ if diff $src_base/pregenerated/odb/options.hxx $path($>[0]) >- && \
+ diff $src_base/pregenerated/odb/options.ixx $path($>[1]) >- && \
+ diff $src_base/pregenerated/odb/options.cxx $path($>[2]) >-
+ exit
+ end
+
+ cp $path($>[0]) $src_base/pregenerated/odb/options.hxx
+ cp $path($>[1]) $src_base/pregenerated/odb/options.ixx
+ cp $path($>[2]) $src_base/pregenerated/odb/options.cxx
+}}
+
+#
+##
+
+# Pass the copyright notice extracted from the LICENSE file.
+#
+obj{odb}: cxx.poptions += -DODB_COPYRIGHT=\"$copyright\"
# Don't install any of the plugin's headers.
#
diff --git a/odb/context.cxx b/odb/context.cxx
index e220d0e..13fc1b3 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -1472,7 +1472,7 @@ utype (semantics::data_member& m,
}
}
- if (s->global_scope ())
+ if (!s->named_p () || s->global_scope ())
break;
}
@@ -1882,8 +1882,13 @@ schema (semantics::scope& s) const
namespace_* ns (dynamic_cast<namespace_*> (ps));
- if (ns == 0)
- continue; // Some other scope.
+ if (ns == 0) // Some other scope.
+ {
+ if (!ps->named_p ())
+ break;
+
+ continue;
+ }
if (ns->extension ())
ns = &ns->original ();
@@ -1920,7 +1925,8 @@ schema (semantics::scope& s) const
n.swap (r);
}
- if (r.fully_qualified () || ns->global_scope ())
+ if (r.fully_qualified () ||
+ ns->global_scope ()) // Note: namespaces always named.
break;
}
@@ -1952,8 +1958,13 @@ table_name_prefix (semantics::scope& s) const
namespace_* ns (dynamic_cast<namespace_*> (ps));
- if (ns == 0)
- continue; // Some other scope.
+ if (ns == 0) // Some other scope.
+ {
+ if (!ps->named_p ())
+ break;
+
+ continue;
+ }
if (ns->extension ())
ns = &ns->original ();
@@ -1964,7 +1975,7 @@ table_name_prefix (semantics::scope& s) const
r = n.uname () + r;
}
- if (ns->global_scope ())
+ if (ns->global_scope ()) // Note: namespaces always named.
break;
}
@@ -2130,6 +2141,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/parser.cxx b/odb/parser.cxx
index 58388c9..c026808 100644
--- a/odb/parser.cxx
+++ b/odb/parser.cxx
@@ -176,6 +176,7 @@ private:
unit* unit_;
scope* scope_;
+ vector<scope*> class_scopes_; // Current hierarchy of class-like scopes.
size_t error_;
decl_set decls_;
@@ -263,6 +264,11 @@ emit_class (tree c, path const& file, size_t line, size_t clmn, bool stub)
if (stub || !COMPLETE_TYPE_P (c))
return *c_node;
+ // Note: "include" the base classes into the class scope (see comment for
+ // self-typedefs in emit_type_decl()).
+ //
+ class_scopes_.push_back (c_node);
+
// Traverse base information.
//
tree bis (TYPE_BINFO (c));
@@ -557,6 +563,8 @@ emit_class (tree c, path const& file, size_t line, size_t clmn, bool stub)
diagnose_unassoc_pragmas (decls);
scope_ = prev_scope;
+ class_scopes_.pop_back ();
+
return *c_node;
}
@@ -583,6 +591,8 @@ emit_union (tree u, path const& file, size_t line, size_t clmn, bool stub)
if (stub || !COMPLETE_TYPE_P (u))
return *u_node;
+ class_scopes_.push_back (u_node);
+
// Collect member declarations so that we can traverse them in
// the source code order.
//
@@ -728,6 +738,7 @@ emit_union (tree u, path const& file, size_t line, size_t clmn, bool stub)
diagnose_unassoc_pragmas (decls);
scope_ = prev_scope;
+ class_scopes_.pop_back ();
return *u_node;
}
@@ -942,9 +953,10 @@ collect (tree ns)
if (!DECL_IS_BUILTIN (decl) || DECL_NAMESPACE_STD_P (decl))
{
+ tree dn (DECL_NAME (decl));
+
if (trace)
{
- tree dn (DECL_NAME (decl));
char const* name (dn ? IDENTIFIER_POINTER (dn) : "<anonymous>");
ts << "namespace " << name << " at "
@@ -952,7 +964,12 @@ collect (tree ns)
<< DECL_SOURCE_LINE (decl) << endl;
}
- collect (decl);
+ // Skip anonymous namespaces (there could be nothing of interest to us
+ // inside but they wreck havoc with our attempts to sort declarations
+ // into namespaces).
+ //
+ if (dn != 0)
+ collect (decl);
}
}
}
@@ -1079,6 +1096,8 @@ emit ()
break;
}
}
+
+ assert (class_scopes_.empty ());
}
// Diagnose any position pragmas that haven't been associated.
@@ -1201,6 +1220,58 @@ emit_type_decl (tree decl)
size_t c (DECL_SOURCE_COLUMN (decl));
type& node (emit_type (t, decl_access (decl), f, l, c));
+
+ // Omit inner self-typedefs (e.g., a class typedefs itself in its own
+ // scope). Such aliases don't buy us anything (in particular, they cannot
+ // be used to form an fq-name) but they do cause scoping cycles if this
+ // name happens to be used to find outer scope (see scope::scope_()).
+ // Note that this means we can now have class template instantiations that
+ // are not named and therefore don't belong to any scope.
+ //
+ // Note that emit_type() might still enter this decl as a hint. It's fuzzy
+ // whether this is harmless or not.
+ //
+ // Note also that using the normal scope hierarchy does not work in more
+ // complex cases where templates cross-self-typedef. So instead we now use
+ // a special-purpose mechanism (class_scopes_). Note for this to work
+ // correctly (hopefully), the class should be "in scope" for its bases.
+ // Here is a representative examples (inspired by code in Eigen):
+ //
+ // template <typename M>
+ // struct PlainObjectBase
+ // {
+ // typedef M Self;
+ // };
+ //
+ // template <typename T, int X, int Y>
+ // struct Matrix: PlainObjectBase<Matrix<T, X, Y>>
+ // {
+ // typedef PlainObjectBase<Matrix> Base;
+ // typedef Matrix Self;
+ // };
+ //
+ // typedef Matrix<double, 3, 1> Vector3d;
+ //
+ // Here we want both Self's (but not Base) to be skipped.
+ //
+ if (scope* s = dynamic_cast<scope*> (&node))
+ {
+ for (auto i (class_scopes_.rbegin ()); i != class_scopes_.rend (); ++i)
+ {
+ if (s == *i)
+ {
+ if (trace)
+ {
+ string s (emit_type_name (t, false));
+
+ ts << "omitting inner self-typedef " << s << " (" << &node
+ << ") -> " << name << " at " << f << ":" << l << endl;
+ }
+ return 0;
+ }
+ }
+ }
+
typedefs& edge (unit_->new_edge<typedefs> (*scope_, node, name));
// Find our hint.
@@ -1327,6 +1398,8 @@ emit_class_template (tree t, bool stub)
if (stub || !COMPLETE_TYPE_P (c))
return *ct_node;
+ class_scopes_.push_back (ct_node);
+
// Collect member declarations so that we can traverse them in
// the source code order. For now we are only interested in
// nested class template declarations.
@@ -1382,6 +1455,7 @@ emit_class_template (tree t, bool stub)
diagnose_unassoc_pragmas (decls);
scope_ = prev_scope;
+ class_scopes_.pop_back ();
return *ct_node;
}
@@ -1410,6 +1484,8 @@ emit_union_template (tree t, bool stub)
if (stub || !COMPLETE_TYPE_P (u))
return *ut_node;
+ class_scopes_.push_back (ut_node);
+
// Collect member declarations so that we can traverse them in
// the source code order. For now we are only interested in
// nested class template declarations.
@@ -1465,6 +1541,7 @@ emit_union_template (tree t, bool stub)
diagnose_unassoc_pragmas (decls);
scope_ = prev_scope;
+ class_scopes_.pop_back ();
return *ut_node;
}
@@ -2053,9 +2130,12 @@ emit_type_name (tree type, bool direct)
if (i != 0)
id += ", ";
- // Assume type-only arguments.
+ // Assume integer and type-only arguments.
//
- id += emit_type_name (a);
+ if (TREE_CODE (a) == INTEGER_CST)
+ id += to_string (integer_value (a));
+ else
+ id += emit_type_name (a);
}
id += '>';
diff --git a/odb/options.cxx b/odb/pregenerated/odb/options.cxx
index 93335d2..da22570 100644
--- a/odb/options.cxx
+++ b/odb/pregenerated/odb/options.cxx
@@ -689,6 +689,56 @@ namespace cli
}
};
+ template <typename K, typename V, typename C>
+ struct parser<std::multimap<K, V, C> >
+ {
+ static void
+ parse (std::multimap<K, V, C>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m.insert (typename std::multimap<K, V, C>::value_type (k, v));
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
template <typename X, typename T, T X::*M>
void
thunk (X& x, scanner& s)
diff --git a/odb/options.hxx b/odb/pregenerated/odb/options.hxx
index 74406a0..74406a0 100644
--- a/odb/options.hxx
+++ b/odb/pregenerated/odb/options.hxx
diff --git a/odb/options.ixx b/odb/pregenerated/odb/options.ixx
index 9a78a2e..9a78a2e 100644
--- a/odb/options.ixx
+++ b/odb/pregenerated/odb/options.ixx
diff --git a/odb/processor.cxx b/odb/processor.cxx
index 9cda5e6..d48baa7 100644
--- a/odb/processor.cxx
+++ b/odb/processor.cxx
@@ -2194,8 +2194,13 @@ namespace
namespace_* ns (dynamic_cast<namespace_*> (s));
- if (ns == 0)
- continue; // Some other scope.
+ if (ns == 0) // Some other scope.
+ {
+ if (!s->named_p ())
+ break;
+
+ continue;
+ }
if (ns->extension ())
ns = &ns->original ();
@@ -2207,7 +2212,7 @@ namespace
break;
}
- if (ns->global_scope ())
+ if (ns->global_scope ()) // Note: namespaces always named.
break;
}
@@ -2702,15 +2707,20 @@ namespace
namespace_* ns (dynamic_cast<namespace_*> (s));
- if (ns == 0)
- continue; // Some other scope.
+ if (ns == 0) // Some other scope.
+ {
+ if (!s->named_p ())
+ break;
+
+ continue;
+ }
if (ns->extension ())
ns = &ns->original ();
if (!ns->count ("pointer"))
{
- if (ns->global_scope ())
+ if (ns->global_scope ()) // Note: namespace always named.
break;
else
continue;
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__;
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index aac8d79..0f60359 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -1456,6 +1456,8 @@ namespace relational
object_members_base::traverse (*pointer.obj);
}
+ using object_members_base::traverse; // Unhide.
+
virtual void
traverse_pointer (semantics::data_member& m, semantics::class_& c)
{
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index c5e16c6..cd975b7 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -442,6 +442,9 @@ namespace relational
traverse (*t, true);
}
+ using add_table::traverse; // Unhide.
+ using alter_table::traverse; // Unhide.
+
using table::names;
void
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index 026f48d..3c6f5da 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -6481,6 +6481,8 @@ namespace relational
rs->base = 0;
}
+ using class_::traverse; // Unhide.
+
protected:
semantics::class_& c_;
string scope_;
diff --git a/odb/relational/sqlite/source.cxx b/odb/relational/sqlite/source.cxx
index 2624af2..5a4b9d3 100644
--- a/odb/relational/sqlite/source.cxx
+++ b/odb/relational/sqlite/source.cxx
@@ -399,7 +399,8 @@ namespace relational
virtual void
process_statement_columns (relational::statement_columns& cols,
- statement_kind sk)
+ statement_kind sk,
+ bool)
{
statement_columns_common::process (cols, sk);
}
diff --git a/odb/semantics/derived.hxx b/odb/semantics/derived.hxx
index 60c4896..e58ec9f 100644
--- a/odb/semantics/derived.hxx
+++ b/odb/semantics/derived.hxx
@@ -416,6 +416,8 @@ namespace semantics
string
fq_name (names*, string& trailer) const;
+ using derived_type::fq_name; // Unhide.
+
public:
array (path const&,
size_t line,
diff --git a/odb/semantics/elements.cxx b/odb/semantics/elements.cxx
index fba9b9b..b5793d0 100644
--- a/odb/semantics/elements.cxx
+++ b/odb/semantics/elements.cxx
@@ -56,7 +56,7 @@ namespace semantics
if (p == &s)
return true;
- if (p->global_scope ())
+ if (!p->named_p () || p->global_scope ())
break;
}
@@ -476,7 +476,7 @@ namespace semantics
// Look in the outer scope unless requested not to or if this is
// the global scope.
//
- if ((flags & exclude_outer) == 0 && !global_scope ())
+ if ((flags & exclude_outer) == 0 && named_p () && !global_scope ())
return scope ().lookup (name, ti, flags, hidden);
return 0;
diff --git a/odb/version.hxx b/odb/version.hxx
index 464e9d2..4ad389a 100644
--- a/odb/version.hxx
+++ b/odb/version.hxx
@@ -23,15 +23,15 @@
// ODB interface version: minor, major, and alpha/beta versions.
//
-#define ODB_VERSION 20474
-#define ODB_VERSION_STR "2.5-b.24"
+#define ODB_VERSION 20476
+#define ODB_VERSION_STR "2.5-b.26"
// ODB compiler version: interface version plus the bugfix version.
//
// NOTE: remember to update metadata to full version when switching to
// version.hxx.in.
//
-#define ODB_COMPILER_VERSION 2049974
-#define ODB_COMPILER_VERSION_STR "2.5.0-b.24"
+#define ODB_COMPILER_VERSION 2049976
+#define ODB_COMPILER_VERSION_STR "2.5.0-b.26"
#endif // ODB_VERSION_HXX
diff --git a/repositories.manifest b/repositories.manifest
index b5047b5..e0c2961 100644
--- a/repositories.manifest
+++ b/repositories.manifest
@@ -8,3 +8,7 @@ location: https://git.codesynthesis.com/libcutl/libcutl.git##HEAD
:
role: prerequisite
location: https://git.codesynthesis.com/libstudxml/libstudxml.git##HEAD
+
+:
+role: prerequisite
+location: https://git.codesynthesis.com/cli/cli.git##HEAD
diff --git a/version b/version
index cd2d927..6bc2f39 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.5.0-b.24
+2.5.0-b.26