- Schema file:
<schema> <table name="accounts"> <column name="account_id" datatype="int64_t" primarykey="1" /> <column name="name" /> <column name="balance" datatype="double" /> </table> </schema>- Code:
accounts all_accounts=accounts::create(conn); for (accounts::base::iterator b=all_accounts->begin(), e=all_accounts->end(); b != e; ++b) { accounts::base::row row=*b; std::cout << row->account_id.value() << std::endl; if (!row->name.isnull()) std::cout << row->name.value() << std::endl; std::cout << row->balance.value() << std::endl; }
The C++ code created by buildschema.xsl
defines a
reference-counted object whose name
is the same as each table's name.
In this example accounts
is a resultset for the
accounts
table.
The resultsets are subclasses of
x::sql::dbi::resultset
s.
The reference-counted objects have a begin
()
and an end
() method
that return a
that define an input sequence over the table's rows.
Other methods, described later, add constraints that translate to
SQL class
::base::iteratorWHERE
and other clauses. But without them,
iterating over the input sequence becomes an equivalent to a simple
“SELECT * FROM table
”.
The iterators iterate over
s,
each one is a single row in the table.
Each class
::base::rowcolumn
is a member of the
,
whose class
::base::rowvalue
() returns the value of the
column in that row.
The above example schema file defines a table with three columns,
“account_id”, “name”, and
“balance”; consequently
account_id.value()
,
name.value()
,
balance.value()
return the values of the corresponding
columns, in each row.
By default, each column value is a std::string
.
An optional datatype
attribute specifies
a different datatype to use for the column's value.
An optional primarykey
attribute specifies
the table's primary key column(s). All tables must have primary keys.
Primary keys are used when
updating and
inserting new rows.
All fields also have an
()
method, that returns an indication if the value is
field
.isnullNULL
or not.
It's possible that a field could be NULL
even if it's “NOT NULL” in the schema:
prefetching a row from
an outer-joined table produces a row with all NULL
fields if the outer joined table did not have a row that matched the
join!
The begin
()
and end
() methods are suitable for
range iteration:
accounts all_accounts=accounts::create(conn); for (const auto &row: *all_accounts) { // ... }
Do not use a temporary with range iteration:
for (const auto &row: *accounts:create())
This is because range iteration uses
rvalue references,
and create
() goes out of scope in the body,
resulting in the iterators getting invoked via a dangling rvalue
reference.