mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 02:55:50 +00:00
147 lines
4.7 KiB
HTML
147 lines
4.7 KiB
HTML
<!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' xml:lang='en'>
|
|
<head>
|
|
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type" />
|
|
<link rel="stylesheet" type="text/css" href="style.css" />
|
|
<title>SOCI - queries</title>
|
|
</head>
|
|
|
|
<body>
|
|
<p class="banner">SOCI - The C++ Database Access Library</p>
|
|
|
|
<h2>Queries</h2>
|
|
|
|
<h3>Simple SQL statements</h3>
|
|
|
|
<p>In many cases, the SQL query is intended to be executed only once,
|
|
which means that statement parsing and execution can go together.
|
|
The <code>session</code> class provides a special <code>once</code>
|
|
member, which triggers parsing and execution of such one-time
|
|
statements:</p>
|
|
|
|
<pre class="example">
|
|
sql.once << "drop table persons";
|
|
</pre>
|
|
|
|
<p>For shorter syntax, the following form is also allowed:</p>
|
|
|
|
<pre class="example">
|
|
sql << "drop table persons";
|
|
</pre>
|
|
|
|
<p>The IOStream-like interface is exactly what it looks like, so that
|
|
the
|
|
statement text can be composed of many parts, involving anything that
|
|
is <i>streamable</i> (including custom classes, if they have
|
|
appropriate <code>operator<<</code>):</p>
|
|
|
|
<pre class="example">
|
|
string tableName = "persons";
|
|
sql << "drop table " << tableName;
|
|
|
|
int id = 123;
|
|
sql << "delete from companies where id = " << id;
|
|
</pre>
|
|
|
|
<h3>Query transformation</h3>
|
|
|
|
<p>In SOCI 3.2.0, query transformation mechanism was introduced.</p>
|
|
|
|
<p>Query transformation is specified as user-defined unary function or callable
|
|
function object with input parameter of type <code>std::string</code> which
|
|
returns object of type <code>std::string</code> as well.</p>
|
|
|
|
<p>The query transformation function is registered for current database session
|
|
using dedicated <code>session::set_query_transformation</code> method.
|
|
Then, the transformation function is called with query string as argument
|
|
just before the query is sent to database backend for execution or for
|
|
preparation.</p>
|
|
|
|
<p>For one-time statements, query transformation is performed before
|
|
each execution of statement. For prepared statements, query is transformed
|
|
only once, before preparation, regardless how many times it is executed.</p>
|
|
|
|
<p>A few short examples how to use query transformation:</p>
|
|
|
|
<ul><li>defined as free function:</li></ul>
|
|
|
|
<pre class="example">
|
|
std::string less_than_ten(std::string query)
|
|
{
|
|
return query + " WHERE price < 10";
|
|
}
|
|
|
|
session sql(postgresql, "dbname=mydb");
|
|
sql.set_query_transformation(less_than_ten);
|
|
sql << "DELETE FROM item";
|
|
</pre>
|
|
|
|
<ul><li>defined as function object:</li></ul>
|
|
|
|
<pre class="example">
|
|
struct order : std::unary_function<std::string, std::string>
|
|
{
|
|
order(std::string const& by) : by_(by) {}
|
|
|
|
result_type operator()(argument_type query) const
|
|
{
|
|
return query + " ORDER BY " + by_;
|
|
}
|
|
|
|
std::string by_;
|
|
};
|
|
|
|
char const* query = "SELECT * FROM product";
|
|
sql.set_query_transformation(order("price");
|
|
sql << query;
|
|
sql.set_query_transformation(order("id");
|
|
sql << query;
|
|
</pre>
|
|
|
|
<ul><li>defined as lambda function (since C++11):</li></ul>
|
|
|
|
<pre class="example">
|
|
std::string dep = "sales";
|
|
sql.set_query_transformation(
|
|
[&dep](std::string const& query) {
|
|
return query + " WHERE department = '" + dep + "'";
|
|
});
|
|
sql << "SELECT * FROM employee";
|
|
</pre>
|
|
|
|
<p>Query transformations enable users with simple mechanism to apply extra
|
|
requirements to or interact with SQL statement being executed and that is
|
|
without changing the SQL statement itself which may be passed from different
|
|
parts of application.</p>
|
|
|
|
<p>For example, the query transformation may be used to:</p>
|
|
<ul>
|
|
<li>modify or add clauses of SQL statements (i.e. <code>WHERE</code>
|
|
clause with new condition)</li>
|
|
<li>prefix table names with new schema to allow namespaces switch</li>
|
|
<li>validate SQL statements</li>
|
|
<li>perform sanitization checking for any unverified input</li>
|
|
<li>apply database-specific features like add optimization hints to SQL
|
|
statements (i.e. <code>SELECT /*+RULE*/ A FROM C</code> in Oracle 9)</li>
|
|
</ul>
|
|
|
|
<p>Query transformation mechanism can also be considered for similar uses as
|
|
<code>prefix_with</code> function from
|
|
<a href="http://docs.sqlalchemy.org/en/latest/core/expression_api.html">SQLAlchemy Expressions API</a>.</p>
|
|
|
|
<table class="foot-links" border="0" cellpadding="2" cellspacing="2">
|
|
<tr>
|
|
<td class="foot-link-left">
|
|
<a href="connections.html">Previous (Connections)</a>
|
|
</td>
|
|
<td class="foot-link-right">
|
|
<a href="exchange.html">Next (Exchanging data)</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p class="copyright">Copyright © 2013 Mateusz Loskot</p>
|
|
<p class="copyright">Copyright © 2004-2008 Maciej Sobczak, Stephen Hutton</p>
|
|
</body>
|
|
</html>
|