Patches for any of these thoughtfully considered!  See the HACKERS file
for instructions on sending patches.

The items in the bug fix/maintenance section are the easiest to do
without breaking things, so if you're looking for a project....

Here's a meta-item that doesn't really fit into any of the categories
below: any time you must hand-roll some SQL code in your program,
consider whether it could be reduced to an API feature that would be
widely useful.  Patches or proposals of this sort are always welcome.


v2.2 Plan
---------

	This plan is not set in stone.	These are simply the features
	we want to try and tackle for the v2.2 release.

	Items in this plan may slip to a future release.  This
	typically happens when the proper solution is unclear,
	so the best way to prevent this is to get on the mailing
	list and help discuss it.  Or even better, provide a patch;
	we rarely reject working code outright.

	Items from the following sections may make it in, but if
	you don't help make that happen, this will just be on the
	whim of one of MySQL++'s developers.  Don't forget that it's
	possible to subclass yourself from the "MySQL++'s developers"
	base class.


	o Conditionally allow the Lockable mechanism to the
	  Boost.Threads library.  If MYSQLPP_BOOST_THREADS is defined,
	  #include the proper header and use Boost's mutexes.  Add a
	  configure script option that defines this macro and adds
	  any needed libraries to the <sys-lib> tags.

	  Mechanism must reflect these MySQL C API restrictions:

	  - Only one query executing at once per connection

	  - For "use" queries, Connection (and therefore Query) object must
	    remain locked until last row is consumed

	  - Safest to have one Connection per thread.  Rules for sharing:
	    http://dev.mysql.com/doc/mysql/en/threaded-clients.html

	  Need some way to call mysql_thread_init() and
	  mysql_thread_end() per thread.  Also, work in some way to
	  call mysql_thread_safe() automatically, perhaps the first
	  time through the function that calls mysql_thread_init().
	  If the C API library reports that it is not thread-safe,
	  report this to the caller, perhaps through an exception,
	  or simply by refusing to init more than one thread.

	o Currently, all overloads for Query's execute(), store()
	  and use() methods eventually call the const char*
	  version, which does the actual work of executing the query.
	  This rules out query strings with embedded nulls, as you're
	  likely to get with BLOB columns.  Also, it means MySQL++
	  must scan the string for length in a few places.  The C API
	  isn't limited in this way if you use mysql_real_query(),
	  but you need an accurate length value to call it.  We could
	  get that length with binary data if the end of the call
	  chain were a std::string overload, but we can't do that
	  easily because each of these functions has a version taking
	  a SQLString (a subclass of std:string) for template queries.

	  One way around this is to add a parallel set of functions
	  (e.g. do_execute(), or execute_(), or some such) that take
	  a single std::string, which are the new terminus of the call
	  chain.  Reimplement const char* versions in terms of these.

	  Another way is to add more overloads taking both a const
	  char* and a length parameter. Make these new functions the
	  terminus to each call chain.

	  Yet another way is that we may be able to co-opt the first
	  template query version of each of these functions, as it
	  takes a single SQLString.

	o Viktor Stark reports that a BLOB of binary data containing
	  0's appears to be truncated when stored in an SSQLS with
	  a std::string for the BLOB field.  Investigate, and fix
	  if confirmed.

	o Date and time classes are pretty minimalistic; they could
	  be so much more powerful.  Some ideas:

	  - Add time_t conversion.

	  - Arithmetic features.  (See "Practical Algorithms for
	    Programmers" by Binstock and Rex.)

	  - It may be possible to get some nice syntactic sugar,
	    such as a way to call SQL functions like NOW() when
	    inserting certain Date/Time objects into a Query stream.

	  Don't forget to write an example showing how to use these
	  new mechanisms.

	  It may be possible to find existing date and time classes
	  that can be extended, instead of reinventing the wheel.
	  Boost, perhaps?

	o Build a forward iterator mechanism for ResUse.  Make it
	  general enough that you can use it with STL algorithms
	  like find_if().  Then make an example to demonstrate this
	  augmentation of SELECT.  Also, update usequery example
	  to use the iterator.	Tricky bit: how do we make it not
	  interfere with subclass Result's random-access iterator?

	o Have resetdb create a second table containing a BLOB column
	  that load_file and cgi_image can use.  
	  
	  Rework load_image to take the standard command line
	  parameters, and load a JPEG or something into the BLOB table.
	  Include a suitable JPEG with the distribution.  (A cheesy
	  Photoshopped "MySQL++ Rocks!" thing should suffice.)

	  Rework cgi_image so that you can drop it into a cgi-image
	  directory and immediately use it to query the database and
	  return the image data in CGI format.

	o It may be possible to optimize the use of ColData in
	  the return from Row::operator[].  Currently, that operator
	  returns a temporary ColData object, which contains a
	  std::string buffer which is initialized by a const char*
	  pointer to data within the Row object.  Since the ColData
	  object is temporary, you currently must copy the data a
	  second time to store it when using Row::operator[].  If the
	  end user just wants a const char*, this double copy could
	  be prevented.  See http://lists.mysql.com/plusplus/4451
	  for the proposal.

	o Add Chris Frey's packarray class?


v3.0 Plan
---------

	Version 3.0 is primarily for those changes that will break
	the ABI.  (i.e. removing functions, changing function
	signatures, etc.)  This plan is very tenuous.  Some of this
	could slip to v4.0.

	o Apply Richard Forrest's iterator patch.

	o The quote manipulator (and presumably the others as well) don't
	  work properly with char*.  See this for details:

	      http://lists.mysql.com/plusplus/5617

	o Change the unsigned int overloads for operator[] on
	  const_subscript_iterator and its subclasses from unsigned
	  int to a plain int.  This should fix the ambiguous overload
	  problems, such as with row[0].

	  See the following threads for reference:
	      http://lists.mysql.com/plusplus/4947
	      http://lists.mysql.com/plusplus/4952
	      http://lists.mysql.com/plusplus/4960
	
	o Several MySQL++ functions wrap the MySQL C API too literally:
	  they indicate success by returning 0 instead of true,
	  as most other wrapper functions do.

	o Apply Waba's patch allowing Null<T> fields in SSQLSes:
	  http://lists.mysql.com/plusplus/5433

	o Deprecate sql_create_basic_*  They have less functionality
	  and they're no easier to use than sql_create and friends.

	o Consider whether some of the current boilerplate can be
	  made into a base class that all SSQLSes derive from.	Some
	  template functions like Query::insert<T> might become regular
	  member functions, taking a reference to the SSQLS base class.

	o Abstract all uses of MySQL C API functions into a database
	  driver class with a generic interface.  This is a step
	  towards database-independence, without the parallel class
	  hierarchy required by the MySQL++ 1.7 design.  Also, it
	  will make it easier to make class Connection completely
	  friend-less.	Right now, the main reason it needs friends
	  is because these other classes make C API calls using its
	  private MYSQL data member.  The other reasons for it having
	  friends aren't nearly as compelling, so it wouldn't be
	  hard to justify redesigning Connection to eliminate these
	  final reasons.

	  While it would be easy to have just one global database
	  driver object, it's probably going to be necessary to have
	  one per Connection.  Consider what happens when you have one
	  program connected to two very different MySQL databases,
	  and you indirectly call C API functions that take MYSQL
	  parameters.  It's likely that those calls are supposed
	  to behave different, depending on the data in that MYSQL
	  object; for instance, different character encodings in the
	  selected databases.  So, there must somehow be a way to pass
	  the database driver's instance pointer down to all objects
	  that will need to use the driver.  A side benefit is that
	  a single program could talk to multiple different database
	  server types.  Imagine a program for importing data from
	  PostgreSQL and loading it into a MySQL table, for instance.



Future Features
---------------

	These changes are not assigned to any particular version.
	They could happen at any time.	If you want one to appear at
	some definite date, get coding and provide a patch!

	o Create adaptors for std::bitset, for storing binary data in a
	  MySQL table.	Make two options available, one for storing
	  the return from bitset::to_ulong() in an UNSIGNED INTEGER
	  column, and another for storing a larger set of bits in a
	  more flexible way, perhaps as a BLOB.

	o Row object currently depends on the associated ResUse object
	  to stick around through all calls to .at(), because it needs
	  the list of field types in the result set to construct
	  ColData objects.  This means it's not possible to store
	  the result of several queries before accessing the data.
	  Currently, this is just a documented limitation, but it
	  would be nice if there were a clean way to avoid this.
	  Obviously you could just copy the type list when constructing
	  the Row object, but that seems pointlessly inefficient.

	o Define operator<< for Fields, Row, ResUse, etc.  In other
	  words, there should be a way to get a user-readable version
	  of received data without a lot of code.  Perhaps use a CSV
	  output format, or a mysql(1) one (ASCII grid).

	o manip.cpp uses mysql_escape_string(), which doesn't take the
	  selected database's character set into account.  To do that,
	  you must use mysql_real_escape_string(), which differs
	  by taking a MYSQL instance as an additional parameter.
	  The problem is, Connection owns the relevant MYSQL instance,
	  and the manipulator functionality is implemented in global
	  functions (operator<<() and such) so they have no direct
	  access to the relevant Connection object.

	  The key question for all operator<<'s for manipulators
	  to ask is, "which Query object am I being inserted into?"
	  From there, you can look up the associated Connection object.

	  In some cases, this answer to the question is easy, because
	  the operator takes an ostream parameter, which can be
	  dynamically cast to Query.  From there, it's just a lookup
	  table problem.
	  
	  Other operator<<'s don't take an ostream, but they do take
	  a manipulator.  Right now, manipulators are just enum values,
	  but they could in fact be classes.  Classes can carry data,
	  so there may be a way to "bind" them to the appropriate
	  Connection object.  If not, then perhaps some other method
	  will pop out of the database driver class idea.  The driver
	  object may be able to look up a suitable Connection object
	  for the manipulators.

	o MySQL++ handles automatic quoting and escaping differently
	  for cout and cerr than for Query streams.  This should
	  probably be simplified so that automatic quoting is only
	  done for Query streams.  No other stream type should be
	  treated specially.

	o Some field_list() functions use the do_nothing manipulator,
	  while others use the quote manipulator.  Need to pick one.
	  In the vast majority of cases, quoting won't be necessary,
	  so make that the default.  But, it should be possible to turn
	  it on, if needed.  If all uses of quoting are in template
	  code, this can be a #define, allowing different programs
	  built on the same system to get different quoting rules.
	  Otherwise, it will probably have to be a configure script
	  flag, which will "burn" the choice into the built binary.

	o User-settable floating-point comparison precisions?
	  Something like this: http://lists.mysql.com/plusplus/3984
	  As it currently stands, sql_cmp(double,double) is foolish.
	  One shouldn't do exact equality comparison on floating
	  point values.

	o Consider using MySQL C API enum constants in
	  mysql_type_info::types definition instead of hard-coded
	  values.  This could potentially break a lot of
	  infrastructure, though, so do it only with care.


Bug Fix/Maintenance Items
-------------------------

	These items could happen in any version.


	o 64-bit integer support has been reported to work, but more
	  confirmation is wanted.

	o Template ListInsert in lib/myset.h isn't being used within the
	  library.  It could probably be used in place of SetInsert
	  in the same file, which things like type_info.h do use now,
	  but it isn't clear how one would go about doing that without
	  changing the library code.  Document it or throw it away.

	o Update refman.css to use new Doxygen 1.4 CSS IDs.
