Warning, /sdk/codevis/thirdparty/soci/docs/utilities.md is written in an unsupported language. File is not indexed.

0001 # Utilities
0002 
0003 SOCI provides a portable abstraction for selection of database queries.
0004 
0005 ## DDL
0006 
0007 SOCI supports some basic methods to construct portable DDL queries. That is, instead of writing explicit SQL statement for creating or modifying tables, it is possible to use dedicated SOCI functions, which prepare appropriate DDL statements behind the scenes, thus enabling the user application to create basic database structures in a way that is portable across different database servers. Note that the actual support for these functions depends on the actual backend implementation.
0008 
0009 It is possible to create a new table in a single statement:
0010 
0011 ```cpp
0012 sql.create_table("t1").column("i", soci::dt_integer).column("j", soci::dt_integer);
0013 ```
0014 
0015 Above, table "t1" will be created with two columns ("i", "j") of type integer.
0016 
0017 It is also possible to build similar statements piece by piece, which is useful if the table structure is computed dynamically:
0018 
0019 ```cpp
0020 {
0021     soci::ddl_type ddl = sql.create_table("t2");
0022     ddl.column("i", soci::dt_integer);
0023     ddl.column("j", soci::dt_integer);
0024     ddl.column("k", soci::dt_integer)("not null");
0025     ddl.primary_key("t2_pk", "j");
0026 }
0027 ```
0028 
0029 The actual statement is executed at the end of above block, when the ddl object goes out of scope. The "not null" constraint was added to the definition of column "k" explicitly and in fact any piece of SQL can be inserted this way - with the obvious caveat of having limited portability (the "not null" piece seems to be universaly portable).
0030 
0031 Columns can be added to and dropped from already existing tables as well:
0032 
0033 ```cpp
0034 sql.add_column("t1", "k", soci::dt_integer);
0035 // or with constraint:
0036 //sql.add_column("t1", "k", soci::dt_integer)("not null");
0037 
0038 sql.drop_column("t1", "i");
0039 ```
0040 
0041 If needed, precision and scale can be defined with additional integer arguments to functions that create columns:
0042 
0043 ```cpp
0044 sql.add_column("t1", "s", soci::dt_string, precision);
0045 sql.add_column("t1", "d", soci::dt_double, precision, scale);
0046 ```
0047 
0048 Tables with foreign keys to each other can be also created:
0049 
0050 ```cpp
0051 {
0052     soci::ddl_type ddl = sql.create_table("t3");
0053     ddl.column("x", soci::dt_integer);
0054     ddl.column("y", soci::dt_integer);
0055     ddl.foreign_key("t3_fk", "x", "t2", "j");
0056 }
0057 ```
0058 
0059 Tables can be dropped, too:
0060 
0061 ```cpp
0062 sql.drop_table("t1");
0063 sql.drop_table("t3");
0064 sql.drop_table("t2");
0065 ```
0066 
0067 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.
0068 
0069 In the category of portability utilities, the following functions are also available:
0070 
0071 ```cpp
0072 sql.empty_blob()
0073 ```
0074 
0075 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:
0076 
0077 ```cpp
0078 sql << "insert into my_table (x) values (" + sql.empty_blob() + ")";
0079 ```
0080 
0081 and:
0082 
0083 ```cpp
0084 sql.nvl()
0085 ```
0086 
0087 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:
0088 
0089 ```cpp
0090 sql << "select name, " + sql.nvl() + "(phone, \'UNKNOWN\') from phone_book";
0091 ```
0092 
0093 Note: `empty_blob` and `nvl` are implemented in Oracle, PostgreSQL and SQLite3 backends; for other backends their behaviour is as for PostgreSQL.
0094 
0095 ## DML
0096 
0097 Only two related functions are currently available in this category:
0098 `get_dummy_from_clause()` can be used to construct select statements that don't
0099 operate on any table in a portable way, as while some databases allow simply
0100 omitting the from clause in this case, others -- e.g. Oracle -- still require
0101 providing some syntactically valid from clause even if it is not used. To use
0102 this function, simply append the result of this function to the statement:
0103 
0104 ```cpp
0105 double databasePi;
0106 session << ("select 4*atan(1)" + session.get_dummy_from_clause()),
0107             into(databasePi);
0108 ```
0109 
0110 If just the name of the dummy table is needed, and not the full clause, you can
0111 use `get_dummy_from_table()` to obtain it.
0112 
0113 Notice that both functions require the session to be connected as their result
0114 depends on the database it is connected to.
0115 
0116 ## Database Metadata
0117 
0118 It is possible to portably query the database server to obtain basic metadata information.
0119 
0120 In order to get the list of table names in the current schema:
0121 
0122 ```cpp
0123 std::vector<std::string> names(100);
0124 sql.get_table_names(), into(names);
0125 ```
0126 
0127 alternatively:
0128 
0129 ```cpp
0130 std::string name;
0131 soci::statement st = (sql.prepare_table_names(), into(name));
0132 
0133 st.execute();
0134 while (st.fetch())
0135 {
0136     // ...
0137 }
0138 ```
0139 
0140 Similarly, to get the description of all columns in the given table:
0141 
0142 ```cpp
0143 soci::column_info ci;
0144 soci::statement st = (sql.prepare_column_descriptions(table_name), into(ci));
0145 
0146 st.execute();
0147 while (st.fetch())
0148 {
0149     // ci fields describe each column in turn
0150 }
0151 ```