TODO

This file contains a raw bunch of ideas for future releases.
Not all of these ideas will necessarily make sense - they are here to get them together.

---
Source of many concepts
http://lists.boost.org/Archives/boost/2006/12/113961.php

---
RAII for transactions.

---
Query construction utilities (kind of Ultimate++) - can be easily incorporated into SOCI by just making them streamable.

---
CLOB

---
Streaming interface for BLOB

---
Standard names for Session constructor.

---
wstring
Unicode support

---
Handle locales in Session (so that operator<< is immune to strange global locale in the user program). It might even make sense to expose imbue(), so that users set up whatever locale they want.
It might even make sense to expose the whole stream object.
Alternatively, the backend should decide on the locale, because the backend will know best how to format numbers, dates, etc.

---
sql << "select...", into(x, default(7));

Note: default is a reserved word.

---
Provide statement-wide flag for eNoData case (because actually it *is* statement-wide, not field-wide). With this, boost.optional would handle the eNull case and the indicators could be dropped.

---

query backend for supported featureset at runtime
---

Rowset<tuple>
---

Rowset<T>, including Rowset<tuple> - way to indicate nulls?
Additional pair based val/indicator interface?

---
Consolidate iteration methods?
most radical: do we still need Statement::fetch()? into()?
(Rowset<Row> can currently be used for any query, supports indicators,
defaults, and no need to check for eNodata)

---
ColumnProperties() more logically belongs to Rowset than to Row
However Row::ColumnProperties() still needed if we support into(Row)

---
sql.prepare by default when constructing Rowsets and Statements?
Rowset<int> rs = (sql << "select n from t";)

---
row[i].get<string>() instead of row.get<string>(i)
row["col"].get<string>() instead of row.get<string>("col")

---
Make more member functions private

---
Values class should be reference counted

---
CSV backend

Example:
Session s("csv:///etc/protocols");
rowset<string> rs = (s.prepare << "1:*");
copy(rs.begin(), rs.end(), ...);

where "1:*" is taken from the top of my head and would mean "first field
from all rows"

- joins are tricky

---
DBF backend, similar to CSV

Session s("dbf:///table.dbf");
rowset<string> rs = (s.prepare << "1:*") // first field from all rows
rowset<string> rs = (s.prepare << "firstname:*") // 'firstname' field from all rows
rowset<Row> rs = (s.prepare << "firstname='John'") // rows where 'firstname' value is 'John'

Sub-concepts:

- joins are tricky

- boolean operators (<,>,=,<=,=> and <>) and WHERE-like clause support as a query

rowset<Row> rs = (s.prepare << "age > 28") // rows where field 'age' is less than 28
rowset<Row> rs = (s.prepare << "age <> 28") // rows where field 'age' is less or more than 28
rowset<Row> rs = (s.prepare << "firstname='John' AND age > 28") // multi-fields combined queries

- very simple home-made SQL parser or SQL-like queries support (see OGR utils from http://www.gdal.org)

---
