aboutsummaryrefslogtreecommitdiff
path: root/odb/database.txx
blob: d96fd141495cd186b096ee26afd78dd28058b9cf (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/no-op-cache-traits.hxx>
#include <odb/pointer-traits.hxx>

namespace odb
{
  template <typename T>
  result<T> database::
  query (const odb::query<T>& q, bool cache)
  {
    // T is always object_type. We also don't need to check for transaction
    // here; object_traits::query () does this.
    //
    result<T> r (query_<T, id_common>::call (*this, q));

    if (cache)
      r.cache ();

    return r;
  }

  // Implementations (i.e., the *_() functions).
  //
  template <typename T, database_id DB>
  typename object_traits<T>::id_type database::
  persist_ (T& obj)
  {
    // T can be const T while object_type will always be T.
    //
    typedef typename object_traits<T>::object_type object_type;
    typedef object_traits_impl<object_type, DB> object_traits;

    object_traits::persist (*this, obj);

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

    object_traits::reference_cache_traits::persist (p);

    return object_traits::id (obj);
  }

  template <typename T, database_id DB>
  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 object_traits<T>::object_type object_type;
    typedef typename object_traits<T>::pointer_type pointer_type;

    typedef object_traits_impl<object_type, DB> object_traits;

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

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

    object_traits::pointer_cache_traits::persist (p);

    return object_traits::id (obj);
  }

  template <typename T, database_id DB>
  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;

    pointer_type r (find_<T, DB> (id));

    if (pointer_traits<pointer_type>::null_ptr (r))
      throw object_not_persistent ();

    return r;
  }

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

  template <typename T, database_id DB>
  void database::
  reload_ (T& obj)
  {
    // T should be object_type (cannot be const). We also don't need to
    // check for transaction here; object_traits::reload () does this.
    //
    if (!object_traits_impl<T, DB>::reload (*this, obj))
      throw object_not_persistent ();
  }

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

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