Commit e7194837 authored by Maciej Sobczak's avatar Maciej Sobczak

Added empty_blob() and nvl() to portable utilities.

parent adae5ade
......@@ -343,6 +343,24 @@ Tables can be dropped, too:
Note that due to the differences in the set of types that are actually supported on the target database server, the type mappings, as well as precision and scales, might be different, even in the way that makes them impossible to portably recover with metadata queries.
In the category of portability utilities, the following functions are also available:
sql.empty_blob()
the above call returns the string containing expression that represents an empty BLOB value in the given target backend. This expression can be used as part of a bigger SQL statement, for example:
sql << "insert into my_table (x) values (" + sql.empty_blob() + ")";
and:
sql.nvl()
the above call returns the string containing the name of the SQL function that implements the NVL or COALESCE operation in the given target backend, for example:
sql << "select name, " + sql.nvl() + "(phone, \'UNKNOWN\') from phone_book";
Note: `empty_blob` and `nvl` are implemented in Oracle, PostgreSQL and SQLite3 backends; for other backends their behaviour is as for PostgreSQL.
### <a name="metadata"></a> Metadata queries
It is possible to portably query the database server to obtain basic metadata information.
......
......@@ -419,6 +419,14 @@ struct oracle_session_backend : details::session_backend
return "alter table " + tableName + " modify " +
columnName + " " + create_column_type(dt, precision, scale);
}
virtual std::string empty_blob()
{
return "empty_blob()";
}
virtual std::string nvl()
{
return "nvl";
}
virtual std::string get_backend_name() const { return "oracle"; }
......
......@@ -147,6 +147,8 @@ public:
int precision = 0, int scale = 0);
ddl_type drop_column(const std::string & tableName,
const std::string & columnName);
std::string empty_blob();
std::string nvl();
// Sets the failover callback object.
void set_failover_callback(failover_callback & callback)
......
......@@ -428,6 +428,14 @@ public:
" foreign key (" + columnNames + ")" +
" references " + refTableName + " (" + refColumnNames + ")";
}
virtual std::string empty_blob()
{
return "lo_creat(-1)";
}
virtual std::string nvl()
{
return "coalesce";
}
void set_failover_callback(failover_callback & callback, session & sql)
{
......
......@@ -291,6 +291,11 @@ struct sqlite3_session_backend : details::session_backend
virtual bool get_last_insert_id(session&, std::string const&, long&);
virtual std::string empty_blob()
{
return "x\'\'";
}
virtual std::string get_backend_name() const { return "sqlite3"; }
void clean_up();
......
......@@ -426,6 +426,16 @@ ddl_type session::drop_column(const std::string & tableName,
return ddl;
}
std::string session::empty_blob()
{
return backEnd_->empty_blob();
}
std::string session::nvl()
{
return backEnd_->nvl();
}
std::string session::get_backend_name() const
{
ensureConnected(backEnd_);
......
......@@ -1329,6 +1329,14 @@ TEST_CASE("Oracle DDL with metadata", "[oracle][ddl]")
CHECK(ddl_t1_found == false);
CHECK(ddl_t2_found == false);
CHECK(ddl_t3_found == false);
int i = -1;
sql << "select length(" + sql.empty_blob() + ") from dual", into(i);
CHECK(i == 0);
sql << "select " + sql.nvl() + "(1, 2) from dual", into(i);
CHECK(i == 1);
sql << "select " + sql.nvl() + "(NULL, 2) from dual", into(i);
CHECK(i == 2);
}
// Test the bulk iterators functionality
......
......@@ -946,6 +946,14 @@ TEST_CASE("PostgreSQL DDL with metadata", "[postgresql][ddl]")
CHECK(ddl_t1_found == false);
CHECK(ddl_t2_found == false);
CHECK(ddl_t3_found == false);
int i = -1;
sql << "select lo_unlink(" + sql.empty_blob() + ")", into(i);
CHECK(i == 1);
sql << "select " + sql.nvl() + "(1, 2)", into(i);
CHECK(i == 1);
sql << "select " + sql.nvl() + "(NULL, 2)", into(i);
CHECK(i == 2);
}
// Test the bulk iterators functionality
......
......@@ -237,6 +237,19 @@ TEST_CASE("SQLite vector long long", "[sqlite][vector][longlong]")
CHECK(v2[4] == 1000000000000LL);
}
TEST_CASE("SQLite DDL wrappers", "[sqlite][ddl]")
{
soci::session sql(backEnd, connectString);
int i = -1;
sql << "select length(" + sql.empty_blob() + ")", into(i);
CHECK(i == 0);
sql << "select " + sql.nvl() + "(1, 2)", into(i);
CHECK(i == 1);
sql << "select " + sql.nvl() + "(NULL, 2)", into(i);
CHECK(i == 2);
}
struct table_creator_for_get_last_insert_id : table_creator_base
{
table_creator_for_get_last_insert_id(soci::session & sql)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment