C++DB is the database layer that was designed to work with C++CMS. This customized version is used within Ye Ol' Pi Shack.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

106 lines
4.9 KiB

  1. /*! \page backenddev Developing Your Own Backends
  2. Even if your database is not supported directly by one of the backends, take a look on \ref odbc "ODBC" backend,
  3. and see how well your database driver behaves with it. It may solve the problem for you.
  4. Before you begin make sure you are familiar with CppDB library and know how to use it. Take a look to the
  5. source code of existing backends, it is good to take a look on \ref postgresql "PostgreSQL" and \ref sqlite3 "Sqlite3" backends
  6. implementations.
  7. \section backenddev_what_needed What Need to Implement
  8. You need to implement following 3 classes:
  9. -# cppdb::backend::connection - the object that holds connection to the database - similar to cppdb::session.
  10. -# cppdb::backend::statement - the object that holds prepared (or unprepared) statement - similar to cppdb::statement
  11. -# cppdb::backend::result - the object that holds the result of query - similar to cppdb::result
  12. You may safely assume that:
  13. - As long as \ref cppdb::backend::result "result" exists, the \ref cppdb::backend::statement "statement" that created it would exist.
  14. - As long as \ref cppdb::backend::statement "statement" exists, the \ref cppdb::backend::connection "connection" that created it would exist.
  15. The frontend classes make sure that this happens.
  16. \section backend_ref_dynamic Making Loadable Module
  17. You need to implement a single entry point in your library with the \ref cppdb::backend::cppdb_backend_connect_function "following prototype".
  18. It is very important to make the entry point function \c extern \c "C" so it would be resolved using dlsym or GetProcAddress functions
  19. and it should be marked as "__declspec(dllexport)" if it is compiled as Windows DLL.
  20. It should be named it as \c cppdb_xyz_get_connection where \c xyz is the name of your backend.
  21. It should receive as a parameter a const reference to cppdb::connection_info returning newly created \ref cppdb::backend::connection "connection".
  22. For example, in sqlite3 backend this function looks like this:
  23. \code
  24. extern "C" {
  25. CPPDB_DRIVER_API cppdb::backend::connection *cppdb_sqlite3_get_connection(cppdb::connection_info const &cs)
  26. {
  27. return new cppdb::sqlite3_backend::connection(cs);
  28. }
  29. }
  30. \endcode
  31. The shared object or DLL themselves should be named as cppdb_xyz - so under Linux it would be libcppdb_xyz.so and under Windows MSVC it would
  32. be "cppdb_xyz.dll". It is also good idea to give it same soname as the libcppdb.so itself as it would allow keeping several backend
  33. versions for several versions of libcppdb in future as CppDB always tries to load a module as "libcppdb_xyz.so.V" and only
  34. then "libcppdb_xyz.so" where V is the current CppDB library soname.
  35. \section backend_ref_static Making Statically Linked only Module
  36. Of course if you want to link your module statically only, you do not have to create this single entry point
  37. function, you may derive from cppdb::backend::driver class such as its \ref cppdb::backend::driver::open() "open()" function
  38. would return a new connection object and \ref cppdb::backend::driver::in_use() "in_use()" function would always return
  39. true so the module would not be "unloaded".
  40. Such module can be installed using \ref cppdb::driver_manager driver_manager singleton class using its \ref cppdb::driver_manager::install_driver() "install_driver()" member function. For example:
  41. \code
  42. class my_cool_sql_driver {
  43. public:
  44. cppdb::backend::connection *open(cppdb::connection_info const &ci) {
  45. return new my_cool_sql::connection(ci);
  46. }
  47. bool in_use() { return true; }
  48. };
  49. ...
  50. cppdb::driver_manager::instance().install_driver("mycoolsql",new my_cool_sql_driver());
  51. \endcode
  52. Of course if you have the \c extern \c "C" function as shown above you can do the same trick using cppdb::backend::static_driver.
  53. \code
  54. extern "C" {
  55. cppdb::backend::connection *my_cool_sql_open(cppdb::connection_info const &ci) {
  56. return new my_cool_sql::connection(ci);
  57. }
  58. }
  59. ...
  60. cppdb::driver_manager::instance().install_driver("mycoolsql",new cppdb::backend::static_driver(my_cool_sql_open));
  61. \endcode
  62. \section backend_tips Tips
  63. - Use functions from utils.h and numeric_util.h they are very helpful especially in converting data to and from textual representation.
  64. - When converting numbers to strings and backwards make sure you are using std::locale::classic(), otherwise when inserting
  65. 12345.678 you may accidentally get "12.345,678" which is probably not what you want. Do it as following:
  66. \code
  67. std::ostringstream ss;
  68. ss.imbue(std::locale::classic());
  69. ss << number;
  70. std::string text_value = ss.str();
  71. \endcode
  72. And do the same for parsing.
  73. - Try to reduce memory coping as much as possible when handing large texts and objects, remember that when std::string is binded
  74. it remains valid till actual statement execution so it is likely that you can just keep a reference on it rather then
  75. copying the string itself.
  76. - Don't bother too much about statements caching or connection pooling. Front-end classes do this for you.
  77. */