All tables have an add_field()
method, which adds one or more columns
to the target. It's a wrapper for SQL's
ALTER TABLE
... ADD COLUMN
.
Suppose the SQL table points
already exists, with
its columns x
and y
(perhaps as a result of running the
code examples in the previous section), and now we want to add a new
mapped member float z
to each record. We start (at a suitable spot in the code, i.e. in a namespace
but not in a function) by defining the value type that we want the table
to have:
struct point_3d { float x; float y; float z; }; QUINCE_MAP_CLASS(point_3d, (x)(y)(z))
And then, some time after the construction of db
,
we construct the table object:
table<point_3d> points(db, "points", &point_3d::x);
The state of affairs right now is:
points
,
which represents an SQL table with the name points
and three columns x
, y
, z
.
z
column).
Therefore we cannot call points.open()
. If we tried, it would throw a table_mismatch_exception
.
So we do this:
points.add_field(points->z);
This adds a column to the target, with the name (z
),
type (REAL
) and the NOT NULL
setting
(set) that the mapper points->z
expects. (And yes, it really does add the column. Table alteration methods
do things, unlike specify_index()
etc. that leave notes to ask open()
to do things.)
Now the target conforms to the table points
,
so we can go ahead and call points.open()
, and then proceed with querying and
data manipulation.
In this example we passed add_field()
a float
mapper, so it added a single REAL
column; but we can
pass a mapper for any mapped type. If it is a multi-column type, then
add_field()
will add multiple columns.
By default, add_field()
fills the new columns with a default-constructed
value. That is to say, table
.add_field(
mapper
)
makes a default-constructed value of
the mapped type (float
in
this case), and initializes the new columns (just the z
column in this case) with an SQL representation of that default-constructed
value (0.0f
in this case).
Alternatively you can specify the value as a second argument:
points.add_field(points->z, -12.6f);
or use a server-side expression:
points.add_field(points->z, points->x + points->y);
The rules governing the arguments are the same as for update()
:
the first argument must be a mapper for some type T
,
and then the second argument can be T
or
abstract_mapper<
T
>
. The table's value mapper is visible to the second argument.