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
125
|
// file : odb/connection.cxx
// 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::
~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 (factory_.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 ();
}
}
|