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.