aboutsummaryrefslogtreecommitdiff
path: root/odb/database.txx
blob: abc6ba3f3fea43c284fb09858a6a4588423cedc0 (plain)
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
126
127
128
129
// file      : odb/database.txx
// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC
// license   : GNU GPL v2; see accompanying LICENSE file

#include <odb/exceptions.hxx>
#include <odb/transaction.hxx>
#include <odb/session.hxx>
#include <odb/cache-traits.hxx>
#include <odb/pointer-traits.hxx>

namespace odb
{
  template <typename T>
  typename object_traits<T>::id_type database::
  persist (T& obj)
  {
    // T can be const T while object_type will always be T.
    //
    typedef typename odb::object_traits<T>::object_type object_type;
    typedef odb::object_traits<object_type> object_traits;

    object_traits::persist (*this, obj);

    object_traits::reference_cache_traits::insert (
      *this, reference_cache_type<T>::convert (obj));

    return object_traits::id (obj);
  }

  template <typename T>
  typename object_traits<T>::id_type database::
  persist_ (const typename object_traits<T>::pointer_type& pobj)
  {
    // T can be const T while object_type will always be T.
    //
    typedef typename odb::object_traits<T>::object_type object_type;
    typedef odb::object_traits<object_type> object_traits;

    typedef typename odb::object_traits<T>::pointer_type pointer_type;
    typedef odb::pointer_traits<pointer_type> pointer_traits;

    T& obj (pointer_traits::get_ref (pobj));
    object_traits::persist (*this, obj);

    // Get the canonical object pointer and insert it into object cache.
    //
    object_traits::pointer_cache_traits::insert (
      *this, pointer_cache_type<pointer_type>::convert (pobj));

    return object_traits::id (obj);
  }

  template <typename T>
  typename object_traits<T>::pointer_type database::
  load (const typename object_traits<T>::id_type& id)
  {
    // T is always object_type.
    //
    typedef typename object_traits<T>::pointer_type pointer_type;
    typedef odb::pointer_traits<pointer_type> pointer_traits;

    pointer_type r (find<T> (id));

    if (pointer_traits::null_ptr (r))
      throw object_not_persistent ();

    return r;
  }

  template <typename T>
  void database::
  load (const typename object_traits<T>::id_type& id, T& obj)
  {
    if (!find<T> (id, obj))
      throw object_not_persistent ();
  }

  template <typename T>
  void database::
  reload (T& obj)
  {
    // T should be object_type (cannot be const).
    //
    typedef odb::object_traits<T> object_traits;

    // We don't need to check for transaction here;
    // object_traits::reload () does this.

    if (!object_traits::reload (*this, obj))
      throw object_not_persistent ();
  }

  template <typename T>
  struct database::query_<T, class_object>
  {
    static result<T>
    call (database& db, const odb::query<T>& q)
    {
      return object_traits<T>::query (db, q);
    }
  };

  template <typename T>
  struct database::query_<T, class_view>
  {
    static result<T>
    call (database& db, const odb::query<T>& q)
    {
      return view_traits<T>::query (db, q);
    }
  };

  template <typename T>
  result<T> database::
  query (const odb::query<T>& q, bool cache)
  {
    // T is always object_type.
    //
    if (!transaction::has_current ())
      throw not_in_transaction ();

    result<T> r (query_<T, class_traits<T>::kind>::call (*this, q));

    if (cache)
      r.cache ();

    return r;
  }
}