All tables have a drop_field()
method, which drops one or more columns
from the target. It's a wrapper for SQL's
ALTER TABLE
... DROP COLUMN
.
Picking up our story from the previous section, points
is a table with value type point_3d
;
and its target, also named points
, conforms
to it, i.e. the target has columns x
, y
and z
of type REAL
with their
NOT NULL
constraints set. And let's assume that points
is currently closed.
Now we want to remove the y
member.
We can drop the corresponding column from the target, like so:
points.drop_field(points->y);
Here we passed drop_field()
a float
mapper, so it dropped a single REAL
column; but we
can pass a mapper for any mapped type. If it is a multi-column type,
then drop_field()
will drop multiple columns.
That was easy, but there's a catch. Unlike our add_field()
example, which brought the target into
conformance with the table object, drop_field()
destroys conformance. The state of
affairs after drop_field()
is:
points
,
which represents an SQL table with the name points
and three columns x
, y
, z
.
y
column).
The solution is to get another table object. Somewhere out in a namespace-but-not-function scope, we define the new value type:
struct point_xz { float x; float z; }; QUINCE_MAP_CLASS(point_xz, (x)(z))
And then, some time after the construction of db
,
we construct the new table object:
table<point_xz> new_points(db, "points", &point_xz::x);
Notice that new_points
shares the same target as points
.
Furthermore, now that that target has only the columns x
and z
, each of type REAL
and each
with its NOT NULL
constraint set, it conforms to
new_points
. So this will
succeed:
// somewhere after new_points's construction and points's drop_field() call: new_points.open();
and we can get on with querying and data manipulation, using new_points
.