Oracle ODB Runtime Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
simple-object-statements.hxx
Go to the documentation of this file.
1 // file : odb/oracle/simple-object-statements.hxx
2 // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC
3 // license : ODB NCUEL; see accompanying LICENSE file
4 
5 #ifndef ODB_ORACLE_SIMPLE_OBJECT_STATEMENTS_HXX
6 #define ODB_ORACLE_SIMPLE_OBJECT_STATEMENTS_HXX
7 
8 #include <odb/pre.hxx>
9 
10 #include <vector>
11 #include <cassert>
12 #include <cstddef> // std::size_t
13 
14 #include <odb/forward.hxx>
15 #include <odb/traits.hxx>
16 
17 #include <odb/details/shared-ptr.hxx>
18 
19 #include <odb/oracle/version.hxx>
20 #include <odb/oracle/forward.hxx>
22 #include <odb/oracle/binding.hxx>
23 #include <odb/oracle/statement.hxx>
25 
26 #include <odb/oracle/details/export.hxx>
27 
28 namespace odb
29 {
30  namespace oracle
31  {
32  // The extra_statement_cache class is only defined (and used) in
33  // the generated source file. However, object_statements may be
34  // referenced from another source file in the case of a polymorphic
35  // hierarchy (though in this case the extra statement cache is
36  // not used). As a result, we cannot have a by-value member and
37  // instead will store a pointer and lazily allocate the cache if
38  // and when needed. We will also need to store a pointer to the
39  // deleter function which will be initialized during allocation
40  // (at that point we know that the cache class is defined).
41  //
42  template <typename T, typename I>
44  {
45  typedef I image_type;
47 
50  {
51  if (p_ != 0)
52  (this->*deleter_) (0, 0, 0, 0);
53  }
54 
55  T&
56  get (connection_type& c, image_type& im, binding& id, binding* idv)
57  {
58  if (p_ == 0)
59  allocate (&c, &im, &id, (idv != 0 ? idv : &id));
60 
61  return *p_;
62  }
63 
64  private:
65  void
66  allocate (connection_type*, image_type*, binding*, binding*);
67 
68  private:
69  T* p_;
70  void (extra_statement_cache_ptr::*deleter_) (
72  };
73 
74  template <typename T, typename I>
75  void extra_statement_cache_ptr<T, I>::
76  allocate (connection_type* c, image_type* im, binding* id, binding* idv)
77  {
78  // To reduce object code size, this function acts as both allocator
79  // and deleter.
80  //
81  if (p_ == 0)
82  {
83  p_ = new T (*c, *im, *id, *idv);
84  deleter_ = &extra_statement_cache_ptr<T, I>::allocate;
85  }
86  else
87  delete p_;
88  }
89 
90  //
91  // Implementation for objects with object id.
92  //
93 
94  class LIBODB_ORACLE_EXPORT object_statements_base: public statements_base
95  {
96  // Locking.
97  //
98  public:
99  void
100  lock ()
101  {
102  assert (!locked_);
103  locked_ = true;
104  }
105 
106  void
108  {
109  assert (locked_);
110  locked_ = false;
111  }
112 
113  bool
114  locked () const
115  {
116  return locked_;
117  }
118 
119  struct auto_unlock
120  {
121  // Unlocks the statement on construction and re-locks it on
122  // destruction.
123  //
125  ~auto_unlock ();
126 
127  private:
128  auto_unlock (const auto_unlock&);
129  auto_unlock& operator= (const auto_unlock&);
130 
131  private:
133  };
134 
135  public:
136  virtual
138 
139  protected:
141  : statements_base (conn), locked_ (false)
142  {
143  }
144 
145  protected:
146  bool locked_;
147  };
148 
149  template <typename T, bool optimistic>
151 
152  template <typename T>
153  struct optimistic_data<T, true>
154  {
155  typedef T object_type;
157 
159 
160  binding*
161  id_image_binding () {return &id_image_binding_;}
162 
163  // The id + optimistic column binding.
164  //
166 
167  details::shared_ptr<delete_statement> erase_;
168  };
169 
170  template <typename T>
171  struct optimistic_data<T, false>
172  {
174 
175  binding*
176  id_image_binding () {return 0;}
177  };
178 
179  template <typename T>
180  class object_statements: public object_statements_base
181  {
182  public:
183  typedef T object_type;
185  typedef typename object_traits::id_type id_type;
187  typedef typename object_traits::image_type image_type;
188  typedef typename object_traits::id_image_type id_image_type;
189 
190  typedef
191  typename object_traits::pointer_cache_traits
193 
194  typedef
195  typename object_traits::extra_statement_cache_type
197 
202 
203  // Automatic lock.
204  //
205  struct auto_lock
206  {
207  // Lock the statements unless they are already locked in which
208  // case subsequent calls to locked() will return false.
209  //
211 
212  // Unlock the statements if we are holding the lock and clear
213  // the delayed loads. This should only happen in case an
214  // exception is thrown. In normal circumstances, the user
215  // should call unlock() explicitly.
216  //
217  ~auto_lock ();
218 
219  // Return true if this auto_lock instance holds the lock.
220  //
221  bool
222  locked () const;
223 
224  // Unlock the statements.
225  //
226  void
227  unlock ();
228 
229  private:
230  auto_lock (const auto_lock&);
231  auto_lock& operator= (const auto_lock&);
232 
233  private:
234  object_statements& s_;
235  bool locked_;
236  };
237 
238  public:
240 
241  virtual
243 
244  // Delayed loading.
245  //
246  typedef void (*loader_function) (odb::database&,
247  const id_type&,
248  object_type&,
249  const schema_version_migration*);
250 
251  void
252  delay_load (const id_type& id,
253  object_type& obj,
254  const typename pointer_cache_traits::position_type& p,
255  loader_function l = 0)
256  {
257  delayed_.push_back (delayed_load (id, obj, p, l));
258  }
259 
260  void
262  {
263  assert (locked ());
264 
265  if (!delayed_.empty ())
266  load_delayed_<object_statements> (svm);
267  }
268 
269  void
271  {
272  if (!delayed_.empty ())
273  clear_delayed_ ();
274  }
275 
276  // Object image.
277  //
278  image_type&
279  image ()
280  {
281  return image_;
282  }
283 
284  // Insert binding.
285  //
286  std::size_t
288 
289  void
291 
292  binding&
294 
295  // Update binding.
296  //
297  std::size_t
299 
300  void
302 
303  std::size_t
305 
306  void
308 
309  binding&
311 
312  // Select binding.
313  //
314  std::size_t
316 
317  void
319 
320  binding&
322 
323  // Object id image and binding.
324  //
326  id_image () {return id_image_;}
327 
328  std::size_t
330 
331  void
332  id_image_version (std::size_t v) {id_image_version_ = v;}
333 
334  binding&
336 
337  // Optimistic id + managed column image binding. It points to
338  // the same suffix as id binding and they are always updated
339  // at the same time.
340  //
341  binding&
342  optimistic_id_image_binding () {return od_.id_image_binding_;}
343 
344  // Statements.
345  //
348  {
349  if (persist_ == 0)
350  persist_.reset (
351  new (details::shared) insert_statement_type (
352  conn_,
353  object_traits::persist_statement,
354  object_traits::versioned, // Process if versioned.
356  object_traits::auto_id));
357 
358  return *persist_;
359  }
360 
363  {
364  if (find_ == 0)
365  find_.reset (
366  new (details::shared) select_statement_type (
367  conn_,
368  object_traits::find_statement,
369  object_traits::versioned, // Process if versioned.
370  false, // Don't optimize.
373  4096)); // Hardcode a 4kB LOB prefetch size.
374 
375  return *find_;
376  }
377 
380  {
381  if (update_ == 0)
382  update_.reset (
383  new (details::shared) update_statement_type (
384  conn_,
385  object_traits::update_statement,
386  object_traits::versioned, // Process if versioned.
388 
389  return *update_;
390  }
391 
394  {
395  if (erase_ == 0)
396  erase_.reset (
397  new (details::shared) delete_statement_type (
398  conn_,
399  object_traits::erase_statement,
401 
402  return *erase_;
403  }
404 
407  {
408  if (od_.erase_ == 0)
409  {
410  od_.erase_.reset (
411  new (details::shared) delete_statement_type (
412  conn_,
413  object_traits::optimistic_erase_statement,
414  od_.id_image_binding_));
415  }
416 
417  return *od_.erase_;
418  }
419 
420  // Extra (container, section) statement cache.
421  //
424  {
425  return extra_statement_cache_.get (
426  conn_, image_, id_image_binding_, od_.id_image_binding ());
427  }
428 
429  public:
430  // select = total - separate_load
431  // insert = total - inverse - managed_optimistic - auto_id
432  // update = total - inverse - managed_optimistic - id - readonly
433  // - separate_update
434  //
435  static const std::size_t id_column_count =
436  object_traits::id_column_count;
437 
438  static const std::size_t managed_optimistic_column_count =
439  object_traits::managed_optimistic_column_count;
440 
441  static const std::size_t select_column_count =
442  object_traits::column_count -
443  object_traits::separate_load_column_count;
444 
445  static const std::size_t insert_column_count =
446  object_traits::column_count -
447  object_traits::inverse_column_count -
448  object_traits::managed_optimistic_column_count -
449  (object_traits::auto_id ? id_column_count : 0);
450 
451  static const std::size_t update_column_count =
453  (object_traits::auto_id ? 0 : id_column_count) -
454  object_traits::readonly_column_count -
455  object_traits::separate_update_column_count;
456 
457  private:
459  object_statements& operator= (const object_statements&);
460 
461  protected:
462  template <typename STS>
463  void
465 
466  void
467  clear_delayed_ ();
468 
469  protected:
470  template <typename T1>
472 
475 
477 
478  // Select binding.
479  //
483 
484  // Insert binding.
485  //
490 
491  // Update binding. Note that the id suffix is bound to id_image_
492  // below instead of image_ which makes this binding effectively
493  // bound to two images. As a result, we have to track versions
494  // for both of them. If this object uses optimistic concurrency,
495  // then the binding for the managed column (version, timestamp,
496  // etc) comes after the id and the image for such a column is
497  // stored as part of the id image.
498  //
504 
505  // Id image binding (only used as a parameter). Uses the suffix in
506  // the update bind.
507  //
509  std::size_t id_image_version_;
511 
512  // Extra data for objects with optimistic concurrency support.
513  //
515 
516  details::shared_ptr<insert_statement_type> persist_;
517  details::shared_ptr<select_statement_type> find_;
518  details::shared_ptr<update_statement_type> update_;
519  details::shared_ptr<delete_statement_type> erase_;
520 
521  // Delayed loading.
522  //
524  {
526 
529  object_type& o,
530  const position_type& p,
531  loader_function l)
532  : id (i), obj (&o), pos (p), loader (l)
533  {
534  }
535 
540  };
541 
542  typedef std::vector<delayed_load> delayed_loads;
544 
545  // Delayed vectors swap guard. See the load_delayed_() function for
546  // details.
547  //
548  struct swap_guard
549  {
551  : os_ (os), dl_ (dl)
552  {
553  dl_.swap (os_.delayed_);
554  }
555 
557  {
558  os_.clear_delayed ();
559  dl_.swap (os_.delayed_);
560  }
561 
562  private:
563  object_statements& os_;
564  delayed_loads& dl_;
565  };
566  };
567  }
568 }
569 
570 #include <odb/oracle/simple-object-statements.ixx>
571 #include <odb/oracle/simple-object-statements.txx>
572 
573 #include <odb/post.hxx>
574 
575 #endif // ODB_ORACLE_SIMPLE_OBJECT_STATEMENTS_HXX
void update_image_version(std::size_t v)
Definition: simple-object-statements.hxx:301
object_traits_impl< object_type, id_oracle > object_traits
Definition: simple-object-statements.hxx:156
Definition: simple-object-statements.hxx:150
oracle::delete_statement delete_statement_type
Definition: simple-object-statements.hxx:201
delayed_load(const id_type &i, object_type &o, const position_type &p, loader_function l)
Definition: simple-object-statements.hxx:528
std::size_t select_image_version() const
Definition: simple-object-statements.hxx:315
Definition: connection.hxx:35
void lock()
Definition: simple-object-statements.hxx:100
~extra_statement_cache_ptr()
Definition: simple-object-statements.hxx:49
void load_delayed_(const schema_version_migration *)
binding id_image_binding_
Definition: simple-object-statements.hxx:510
std::size_t update_image_version_
Definition: simple-object-statements.hxx:499
object_traits::pointer_type pointer_type
Definition: simple-object-statements.hxx:186
object_statements_base(connection_type &conn)
Definition: simple-object-statements.hxx:140
details::shared_ptr< update_statement_type > update_
Definition: simple-object-statements.hxx:518
binding & insert_image_binding()
Definition: simple-object-statements.hxx:293
void load_delayed(const schema_version_migration *svm)
Definition: simple-object-statements.hxx:261
binding update_image_binding_
Definition: simple-object-statements.hxx:501
Definition: simple-object-statements.hxx:523
std::size_t update_image_version() const
Definition: simple-object-statements.hxx:298
Definition: simple-object-statements.hxx:548
object_traits::id_type id_type
Definition: simple-object-statements.hxx:185
void delay_load(const id_type &id, object_type &obj, const typename pointer_cache_traits::position_type &p, loader_function l=0)
Definition: simple-object-statements.hxx:252
details::shared_ptr< select_statement_type > find_
Definition: simple-object-statements.hxx:517
binding id_image_binding_
Definition: simple-object-statements.hxx:165
binding select_image_binding_
Definition: simple-object-statements.hxx:481
void insert_image_version(std::size_t v)
Definition: simple-object-statements.hxx:290
details::shared_ptr< insert_statement_type > persist_
Definition: simple-object-statements.hxx:516
delete_statement_type & optimistic_erase_statement()
Definition: simple-object-statements.hxx:406
loader_function loader
Definition: simple-object-statements.hxx:539
std::size_t select_image_version_
Definition: simple-object-statements.hxx:480
Definition: statement.hxx:340
T object_type
Definition: simple-object-statements.hxx:183
oracle::connection connection_type
Definition: simple-object-statements.hxx:46
binding * id_image_binding()
Definition: simple-object-statements.hxx:176
Definition: simple-object-statements.hxx:94
std::size_t id_image_version_
Definition: simple-object-statements.hxx:509
details::shared_ptr< delete_statement > erase_
Definition: simple-object-statements.hxx:167
binding insert_image_binding_
Definition: simple-object-statements.hxx:487
bind select_image_bind_[select_column_count]
Definition: simple-object-statements.hxx:482
image_type image_
Definition: simple-object-statements.hxx:476
static const std::size_t managed_optimistic_column_count
Definition: simple-object-statements.hxx:438
bool locked() const
Definition: simple-object-statements.hxx:114
oracle::select_statement select_statement_type
Definition: simple-object-statements.hxx:199
bool locked_
Definition: simple-object-statements.hxx:146
id_image_type id_image_
Definition: simple-object-statements.hxx:508
delete_statement_type & erase_statement()
Definition: simple-object-statements.hxx:393
object_traits::image_type image_type
Definition: simple-object-statements.hxx:187
swap_guard(object_statements &os, delayed_loads &dl)
Definition: simple-object-statements.hxx:550
void select_image_version(std::size_t v)
Definition: simple-object-statements.hxx:318
oracle::update_statement update_statement_type
Definition: simple-object-statements.hxx:200
T object_type
Definition: simple-object-statements.hxx:155
access::object_traits< T >::pointer_type pointer_type
extra_statement_cache_ptr< extra_statement_cache_type, image_type > extra_statement_cache_
Definition: simple-object-statements.hxx:474
extra_statement_cache_type & extra_statement_cache()
Definition: simple-object-statements.hxx:423
Definition: statement.hxx:316
binding & update_image_binding()
Definition: simple-object-statements.hxx:310
I image_type
Definition: simple-object-statements.hxx:45
id_type id
Definition: simple-object-statements.hxx:536
pointer_cache_traits::position_type position_type
Definition: simple-object-statements.hxx:525
Definition: statement.hxx:169
void unlock()
Definition: simple-object-statements.hxx:107
static const std::size_t select_column_count
Definition: simple-object-statements.hxx:441
insert_statement_type & persist_statement()
Definition: simple-object-statements.hxx:347
static const std::size_t insert_column_count
Definition: simple-object-statements.hxx:445
select_statement_type & find_statement()
Definition: simple-object-statements.hxx:362
connection_type & conn_
Definition: statements-base.hxx:56
Definition: binding.hxx:21
bind insert_image_bind_[insert_column_count!=0?insert_column_count:1]
Definition: simple-object-statements.hxx:489
std::size_t insert_image_version() const
Definition: simple-object-statements.hxx:287
void id_image_version(std::size_t v)
Definition: simple-object-statements.hxx:332
binding & id_image_binding()
Definition: simple-object-statements.hxx:335
object_traits::extra_statement_cache_type extra_statement_cache_type
Definition: simple-object-statements.hxx:196
std::size_t update_id_image_version_
Definition: simple-object-statements.hxx:500
object_statements(connection_type &)
Definition: oracle-types.hxx:78
extra_statement_cache_ptr()
Definition: simple-object-statements.hxx:48
Definition: simple-object-statements.hxx:119
binding * id_image_binding()
Definition: simple-object-statements.hxx:161
position_type pos
Definition: simple-object-statements.hxx:538
optimistic_data(bind *)
Definition: simple-object-statements.hxx:173
static const std::size_t id_column_count
Definition: simple-object-statements.hxx:435
optimistic_data< T, managed_optimistic_column_count!=0 > od_
Definition: simple-object-statements.hxx:514
void(* loader_function)(odb::database &, const id_type &, object_type &, const schema_version_migration *)
Definition: simple-object-statements.hxx:246
Definition: simple-object-statements.hxx:43
void clear_delayed()
Definition: simple-object-statements.hxx:270
object_traits_impl< object_type, id_oracle > object_traits
Definition: simple-object-statements.hxx:184
object_type * obj
Definition: simple-object-statements.hxx:537
delayed_loads delayed_
Definition: simple-object-statements.hxx:543
static const std::size_t update_column_count
Definition: simple-object-statements.hxx:451
Definition: statement.hxx:254
std::size_t update_id_image_version() const
Definition: simple-object-statements.hxx:304
~swap_guard()
Definition: simple-object-statements.hxx:556
std::vector< delayed_load > delayed_loads
Definition: simple-object-statements.hxx:542
std::size_t id_image_version() const
Definition: simple-object-statements.hxx:329
details::shared_ptr< delete_statement_type > erase_
Definition: simple-object-statements.hxx:519
id_image_type & id_image()
Definition: simple-object-statements.hxx:326
void update_id_image_version(std::size_t v)
Definition: simple-object-statements.hxx:307
object_traits::pointer_cache_traits pointer_cache_traits
Definition: simple-object-statements.hxx:192
T & get(connection_type &c, image_type &im, binding &id, binding *idv)
Definition: simple-object-statements.hxx:56
Definition: simple-object-statements.hxx:205
session_type::template cache_position< object_type > position_type
oracle::insert_statement insert_statement_type
Definition: simple-object-statements.hxx:198
image_type & image()
Definition: simple-object-statements.hxx:279
bind update_image_bind_[update_column_count+id_column_count+managed_optimistic_column_count]
Definition: simple-object-statements.hxx:503
delayed_load()
Definition: simple-object-statements.hxx:527
object_traits::id_image_type id_image_type
Definition: simple-object-statements.hxx:188
Definition: statements-base.hxx:23
binding & optimistic_id_image_binding()
Definition: simple-object-statements.hxx:342
Definition: forward.hxx:55
std::size_t insert_image_version_
Definition: simple-object-statements.hxx:486
update_statement_type & update_statement()
Definition: simple-object-statements.hxx:379
binding & select_image_binding()
Definition: simple-object-statements.hxx:321