aboutsummaryrefslogtreecommitdiff
path: root/odb/sqlite/polymorphic-object-statements.txx
blob: 999eb3eb8a2526f0c67d3991a2d7d6c6130e719e (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
130
131
132
133
134
135
136
137
138
139
140
// file      : odb/sqlite/polymorphic-object-statements.txx
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC
// license   : GNU GPL v2; see accompanying LICENSE file

#include <cstring> // std::memset

#include <odb/callback.hxx>
#include <odb/exceptions.hxx>

#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/transaction.hxx>
#include <odb/sqlite/statement-cache.hxx>

namespace odb
{
  namespace sqlite
  {
    //
    // polymorphic_root_object_statements
    //

    template <typename T>
    polymorphic_root_object_statements<T>::
    ~polymorphic_root_object_statements ()
    {
    }

    template <typename T>
    polymorphic_root_object_statements<T>::
    polymorphic_root_object_statements (connection_type& conn)
        : object_statements<T> (conn),
          discriminator_image_binding_ (discriminator_image_bind_,
                                        discriminator_column_count +
                                        managed_optimistic_column_count),
          discriminator_id_image_binding_ (discriminator_id_image_bind_,
                                           id_column_count)
    {
      discriminator_image_.version = 0;
      discriminator_id_image_.version = 0;

      discriminator_image_version_ = 0;
      discriminator_id_image_version_ = 0;

      std::memset (discriminator_image_bind_,
                   0,
                   sizeof (discriminator_image_bind_));
      std::memset (discriminator_id_image_bind_,
                   0,
                   sizeof (discriminator_id_image_bind_));
      std::memset (discriminator_image_truncated_,
                   0,
                   sizeof (discriminator_image_truncated_));

      for (std::size_t i (0);
           i < discriminator_column_count + managed_optimistic_column_count;
           ++i)
      {
        discriminator_image_bind_[i].truncated =
          discriminator_image_truncated_ + i;
      }
    }

    //
    // polymorphic_derived_object_statements
    //

    template <typename T>
    polymorphic_derived_object_statements<T>::
    ~polymorphic_derived_object_statements ()
    {
    }

    template <typename T>
    polymorphic_derived_object_statements<T>::
    polymorphic_derived_object_statements (connection_type& conn)
        : statements_base (conn),
          root_statements_ (conn.statement_cache ().find_object<root_type> ()),
          base_statements_ (conn.statement_cache ().find_object<base_type> ()),
          insert_image_binding_ (insert_image_bind_, insert_column_count),
          update_image_binding_ (update_image_bind_,
                                 update_column_count + id_column_count)
    {
      image_.base = &base_statements_.image ();
      image_.version = 0;

      for (std::size_t i (0); i < object_traits::depth; ++i)
        select_image_versions_[i] = 0;

      for (std::size_t i (0);
           i < (object_traits::abstract ? 1 : object_traits::depth);
           ++i)
      {
        select_image_bindings_[i].bind = select_image_bind_;
        select_image_bindings_[i].count = object_traits::find_column_counts[i];
      }

      insert_image_version_ = 0;
      insert_id_binding_version_ = 0;
      update_image_version_ = 0;
      update_id_binding_version_ = 0;

      std::memset (insert_image_bind_, 0, sizeof (insert_image_bind_));
      std::memset (update_image_bind_, 0, sizeof (update_image_bind_));
      std::memset (select_image_bind_, 0, sizeof (select_image_bind_));
      std::memset (
        select_image_truncated_, 0, sizeof (select_image_truncated_));

      for (std::size_t i (0); i < select_column_count; ++i)
        select_image_bind_[i].truncated = select_image_truncated_ + i;
    }

    template <typename T>
    void polymorphic_derived_object_statements<T>::
    delayed_loader (odb::database& db, const id_type& id, root_type& robj)
    {
      connection_type& conn (transaction::current ().connection ());
      polymorphic_derived_object_statements& sts (
        conn.statement_cache ().find_object<object_type> ());
      root_statements_type& rsts (sts.root_statements ());

      object_type& obj (static_cast<object_type&> (robj));

      // The same code as in object_statements::load_delayed_().
      //
      if (!object_traits::find_ (sts, &id))
        throw object_not_persistent ();

      object_traits::callback (db, obj, callback_event::pre_load);
      object_traits::init (obj, sts.image (), &db);
      object_traits::load_ (sts, obj); // Load containers, etc.

      rsts.load_delayed ();

      {
        typename root_statements_type::auto_unlock u (rsts);
        object_traits::callback (db, obj, callback_event::post_load);
      }
    }
  }
}