1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
// file : odb/connection.cxx
// copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
#include <odb/database.hxx>
#include <odb/connection.hxx>
#include <odb/result.hxx>
#include <odb/prepared-query.hxx>
#include <odb/exceptions.hxx> // prepared_*
using namespace std;
namespace odb
{
connection::
~connection ()
{
assert (prepared_queries_ == 0);
assert (prepared_map_.empty ());
}
void connection::
clear_prepared_map ()
{
for (prepared_map_type::iterator i (prepared_map_.begin ()),
e (prepared_map_.end ()); i != e; ++i)
{
if (i->second.params != 0)
i->second.params_deleter (i->second.params);
}
prepared_map_.clear ();
}
void connection::
recycle ()
{
while (prepared_queries_ != 0)
{
prepared_queries_->stmt.reset ();
prepared_queries_->list_remove ();
}
}
void connection::
invalidate_results ()
{
while (results_ != 0)
{
results_->invalidate ();
results_->list_remove ();
}
}
void connection::
cache_query_ (prepared_query_impl* pq,
const type_info& ti,
void* params,
const type_info* params_info,
void (*params_deleter) (void*))
{
pair<prepared_map_type::iterator, bool> r (
prepared_map_.insert (
prepared_map_type::value_type (pq->name, prepared_entry_type ())));
if (!r.second)
throw prepared_already_cached (pq->name);
prepared_entry_type& e (r.first->second);
// Mark this prepared query as cached , get its ref count to 1
// (prepared_query instances now reference this impl object),
// and remove it from the invalidation list.
//
pq->cached = true;
while (pq->_ref_count () > 1)
pq->_dec_ref ();
pq->list_remove ();
e.prep_query.reset (pq);
e.type_info = &ti;
e.params = params;
e.params_info = params_info;
e.params_deleter = params_deleter;
}
prepared_query_impl* connection::
lookup_query_ (const char* name,
const type_info& ti,
void** params,
const type_info* params_info) const
{
prepared_map_type::const_iterator i (prepared_map_.find (name));
if (i == prepared_map_.end ())
{
// Use a factory, if there is one.
//
if (database_.call_query_factory (name,
const_cast<connection&> (*this)))
i = prepared_map_.find (name);
}
if (i == prepared_map_.end ())
return 0;
// Make sure the types match.
//
if (*i->second.type_info != ti)
throw prepared_type_mismatch (name);
if (params != 0)
{
if (*i->second.params_info != *params_info)
throw prepared_type_mismatch (name);
*params = i->second.params;
}
return i->second.prep_query.get ();
}
}
|