diff options
Diffstat (limited to 'brep/database.cxx')
-rw-r--r-- | brep/database.cxx | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/brep/database.cxx b/brep/database.cxx index 9177b55..17605c5 100644 --- a/brep/database.cxx +++ b/brep/database.cxx @@ -4,40 +4,50 @@ #include <brep/database> +#include <map> + #include <odb/pgsql/database.hxx> namespace brep { + namespace options + { + bool + operator< (const db& x, const db& y) + { + int r; + if ((r = x.db_user ().compare (y.db_user ())) != 0 || + (r = x.db_password ().compare (y.db_password ())) != 0 || + (r = x.db_name ().compare (y.db_name ())) != 0 || + (r = x.db_host ().compare (y.db_host ()))) + return r < 0; + + return x.db_port () < y.db_port (); + } + } + shared_ptr<odb::database> shared_database (const options::db& o) { using odb::pgsql::database; - static weak_ptr<database> db; - // In C++11, function-static variable initialization is guaranteed to be - // thread-safe, thought this doesn't seem to be enough in our case - // (because we are re-initializing the weak pointer). - // - if (shared_ptr<database> d = db.lock ()) - { - if (o.db_user () != d->user () || - o.db_password () != d->password () || - o.db_name () != d->db () || - o.db_host () != d->host () || - o.db_port () != d->port ()) - throw runtime_error ("shared database options mismatch"); - - return d; - } - else + static std::map<options::db, weak_ptr<database>> databases; + + auto i (databases.find (o)); + if (i != databases.end ()) { - d = make_shared<database> (o.db_user (), - o.db_password (), - o.db_name (), - o.db_host (), - o.db_port ()); - db = d; - return d; + if (shared_ptr<database> d = i->second.lock ()) + return d; } + + shared_ptr<database> d ( + make_shared<database> (o.db_user (), + o.db_password (), + o.db_name (), + o.db_host (), + o.db_port ())); + + databases[o] = d; + return d; } } |