HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_ORMField.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_ORMField.h
7  *
8  * COMMENTS:
9  *
10  * The UT_ORMField is the C++ object that defines the relationship between the
11  * c++ object member and the database column. The adapter is added to every
12  * field which defines how to bind/load the C++ member to a database value.
13  *
14  * In the case of UT_ORMForeignKeyField we can lazy load the underlying model
15  * that the column relates to. This allows us to load the foreign key value
16  * and optionally fetch the related object value at a later time or not at all
17  * depending on our needs at the time.
18  *
19  * See UT_SQLORM for more information on the entire system.
20  */
21 
22 #ifndef __UT_ORMFIELD_H__
23 #define __UT_ORMFIELD_H__
24 
25 #include "UT_API.h"
26 
27 #include "UT_StringHolder.h"
28 #include "UT_ErrorCode.h"
29 #include "UT_DateTimeField.h"
30 #include "UT_WorkBuffer.h"
31 #include "UT_SQL.h"
32 #include "UT_Array.h"
33 #include "UT_Optional.h"
34 #include "UT_SGuid.h"
35 #include "UT_ORMColumn.h"
36 #include "UT_IntrusivePtr.h"
37 
38 #include <variant>
39 
40 class UT_JSONValue;
41 class UT_SqlStatement;
42 class UT_SqlOrm;
43 class UT_ORMColumn;
44 class UT_ORMModelMeta;
45 
47 {
48 public:
49  virtual ~UT_IORMFieldAdapter() = default;
50  UT_IORMFieldAdapter(const UT_IORMFieldAdapter&) = default;
52 
53  virtual UT_ORMColumn::Type sqlType() const = 0;
54  virtual void bind(
55  const void* obj,
56  UT_SqlStatement& cursor,
57  int bind_index,
58  UT_ErrorCode& ec)
59  = 0;
60  virtual void load(
61  void* obj,
62  UT_SqlStatement& cursor,
63  int index,
64  UT_ErrorCode& ec)
65  = 0;
66  virtual void onDelete(
67  void* obj,
68  UT_ORMColumn::OnDelete ondelete,
69  UT_ErrorCode& ec)
70  {
71  }
72  virtual bool isSame(
73  const void* obj_left,
74  const void* obj_right,
75  UT_ErrorCode& ec) const
76  = 0;
77 
78  template <typename Cls, typename MemberT>
79  void setValue(Cls& obj, const MemberT& member_value, UT_ErrorCode& ec)
80  {
81  mySetter(this, &obj, &member_value, ec);
82  }
83 
84  template <typename Cls, typename MemberT>
85  void getValue(const Cls& obj, MemberT& member_value, UT_ErrorCode& ec)
86  {
87  myGetter(this, &obj, &member_value, ec);
88  }
89 
90 protected:
91  typedef void (*setter_func_t)(
92  UT_IORMFieldAdapter* adapter,
93  void* obj,
94  const void* value,
95  UT_ErrorCode& ec);
96  typedef void (*getter_func_t)(
97  UT_IORMFieldAdapter* adapter,
98  const void* obj,
99  void* value,
100  UT_ErrorCode& ec);
101 
102  UT_IORMFieldAdapter(setter_func_t setter, getter_func_t getter)
103  : mySetter(setter), myGetter(getter)
104  {
105  }
106  setter_func_t mySetter;
107  getter_func_t myGetter;
108 };
109 
111 {
112 public:
114  const UT_StringHolder& name,
116  unsigned props = UT_ORMColumn::Properties::Empty,
117  UT_ORMColumn::OnDelete ondelete = UT_ORMColumn::OnDelete::DoNothing,
118  const UT_StringHolder& related_name = UT_StringHolder::theEmptyString)
119  : UT_ORMColumn(name, adapter->sqlType(), props, ondelete)
120  , myFieldPtr(std::move(adapter))
121  {
122  }
123  /// This should almost never be called. Its mainly used with dynamic objects
124  /// that arent attached to a model but we still want to generate meta
125  /// information for migrations and migration validation.
127  const UT_StringHolder& name,
129  unsigned props = UT_ORMColumn::Empty,
130  UT_ORMColumn::OnDelete ondelete = UT_ORMColumn::OnDelete::DoNothing)
131  : UT_ORMColumn(name, type, props, ondelete), myFieldPtr(nullptr)
132  {
133  }
135  {
136  return myFieldPtr.get();
137  }
139  {
140  return SYSconst_cast(this)->myFieldPtr.get();
141  }
142 
143  void setAsManyToMany(
144  const UT_ORMModelMeta& through_meta,
145  const UT_ORMModelMeta& meta,
146  const UT_StringHolder& m2m_field_name,
147  const UT_ORMModelMeta& foreign_meta,
148  const UT_StringHolder& m2m_reverse_field_name,
149  const UT_StringHolder& related_name
151 
152  bool verify(UT_SqlOrm* orm, UT_Error& ec, UT_StringHolder& err_msg);
153 
154  void connectLinks(const UT_SharedPtr<UT_ORMModelMeta>& meta);
155 
157  {
158  return myForeignModel.lock();
159  }
160 
162  {
163  return myM2MFieldName;
164  }
166  {
167  return myM2MReverseFieldName;
168  }
169 
170 protected:
176 };
177 
178 template <typename Cls, typename MemberT>
180 {
181 private:
182  static void memberSetter(
184  void* obj,
185  const void* member_value,
186  UT_ErrorCode& ec)
187  {
188  auto value = static_cast<const MemberT*>(member_value);
189  static_cast<UT_ORMBasicFieldAdapter<Cls, MemberT>*>(me)->field(obj)
190  = *value;
191  }
192  static void memberGetter(
194  const void* obj,
195  void* member_value,
196  UT_ErrorCode& ec)
197  {
198  auto value = static_cast<MemberT*>(member_value);
199  *value = static_cast<UT_ORMBasicFieldAdapter<Cls, MemberT>*>(me)->field(
200  obj);
201  }
202 
203 public:
204  using model_t = Cls;
205  using field_t = MemberT;
206 
207  UT_ORMBasicFieldAdapter(MemberT Cls::*member_ptr) :
208  UT_IORMFieldAdapter(&memberSetter, &memberGetter),
209  myMemberPtr(member_ptr)
210  {
211  }
212 
214  const UT_StringHolder& name,
215  MemberT Cls::*member_ptr,
216  unsigned props)
217  {
218  auto adapter = UTmakeUnique<UT_ORMBasicFieldAdapter<Cls, MemberT>>(
219  member_ptr);
220  UT_ORMFieldColumn col(name, std::move(adapter), props);
221  return col;
222  }
223 
224  UT_ORMColumn::Type sqlType() const override
225  {
226  return UTsqlOrmColumnType<MemberT>();
227  }
228  void bind(
229  const void* obj,
230  UT_SqlStatement& stmt,
231  int index,
232  UT_ErrorCode& ec) override
233  {
234  const MemberT& v = this->field(obj);
235  stmt.bind(index, v);
236  ec = stmt.getError();
237  }
238  void load(void* obj, UT_SqlStatement& stmt, int index, UT_ErrorCode& ec)
239  override
240  {
241  MemberT& v = this->field(obj);
242  v = stmt.get<MemberT>(index);
243  ec = stmt.getError();
244  }
245  void setValue(void* obj, const MemberT& t)
246  {
247  field(obj) = t;
248  }
249  MemberT& getValue(void* obj) { return field(obj); }
250  bool isSame(const void* obj_left, const void* obj_right, UT_ErrorCode& ec)
251  const final override
252  {
253  const MemberT& left_value = field(obj_left);
254  const MemberT& right_value = field(obj_right);
255  return left_value == right_value;
256  }
257 
258 protected:
259  MemberT& field(void* obj)
260  {
261  Cls* cls = static_cast<Cls*>(obj);
262  return (cls->*myMemberPtr);
263  }
264  const MemberT& field(const void* obj) const
265  {
266  const Cls* cls = static_cast<const Cls*>(obj);
267  return (cls->*myMemberPtr);
268  }
269 
270 private:
271  MemberT Cls::*myMemberPtr;
272 
273 };
274 template <typename Cls>
276 template <typename Cls>
278 template <typename Cls>
280 template <typename Cls>
282 
283 template <typename ModelT>
285 {
286 private:
287  struct PointerHolder : public UT_IntrusiveRefCounter<
288  PointerHolder,
289  std::default_delete<PointerHolder>,
290  UT_IntrusiveNonThreadSafeCounterPolicy>
291  {
292  PointerHolder(const ModelT& m) :
293  myModel(m)
294  {}
295  PointerHolder(ModelT&& m) :
296  myModel(std::move(m))
297  {}
298 
299  ModelT& operator*() { return myModel; }
300  ModelT myModel;
301  };
302 
303 public:
305  using model_t = ModelT;
306  using foreign_key_t = typename ModelT::Meta::primary_key_t;
307 
308  UT_ORMForeignKeyField() = default;
310  myID(pk)
311  {}
312 
313  bool operator==(const UT_ORMForeignKeyField& rhs) const
314  {
315  return myID == rhs.myID;
316  }
317  bool operator!=(const UT_ORMForeignKeyField& rhs) const
318  {
319  return !(*this == rhs);
320  }
321 
322  ModelT* get()
323  {
324  if (!myValue)
325  {
326  UT_ErrorCode ec;
327  load_(ec);
328  }
329  UT_ASSERT(myValue);
330  return &(myValue->myModel);
331  }
332  const ModelT* get() const
333  {
334  return SYSconst_cast(this)->get();
335  }
336 
338  {
339  return myID;
340  }
341  void setId(const foreign_key_t& id)
342  {
343  myID = id;
344  myValue.reset();
345  }
346  void setValue(const ModelT& value)
347  {
348  using foreign_field_t = UT_ORMBasicFieldAdapter<ModelT, foreign_key_t>;
349 
350  UT_ErrorCode ec;
351  UT_IORMFieldAdapter* adapter = value.meta().primaryKey()->adapter();
352  if (auto fadp = dynamic_cast<foreign_field_t*>(adapter); fadp)
353  {
354  myID = fadp->getValue(SYSconst_cast(&value));
355  myValue = UTmakeIntrusive<PointerHolder>(value);
356  }
357  }
358 
359  void clear()
360  {
361  myID = foreign_key_t();
362  myValue.reset();
363  }
364 
365 private:
366  void load_(UT_ErrorCode &ec)
367  {
368  if (auto&& opt = ModelT::fetch(myID, ec); opt)
369  {
370  myValue = UTmakeIntrusive<PointerHolder>(opt.value());
371  }
372  }
373 
374  foreign_key_t myID;
375  model_pointer_t myValue;
376 };
377 
378 template <typename Cls, typename ForeignKey>
380 {
381 public:
382  using model_t = typename ForeignKey::model_t;
383  using field_t = ForeignKey;
384  using id_t = typename ForeignKey::foreign_key_t;
385 
386  UT_ORMForeignKeyFieldAdapter(ForeignKey Cls::*member_ptr)
388  , myMemberPtr(member_ptr)
389  {
390  }
391 
393  const UT_ORMModelMeta& meta,
394  const UT_StringHolder& name,
395  ForeignKey Cls::*member_ptr,
396  unsigned props,
397  UT_ORMColumn::OnDelete ondelete,
398  const UT_StringHolder& related_name
400  {
401  auto adapter
402  = UTmakeUnique<UT_ORMForeignKeyFieldAdapter<Cls, ForeignKey>>(
403  member_ptr);
404  UT_ORMFieldColumn col(name, std::move(adapter), props);
405  col.setAsForeignKey(meta, related_name);
406  col.setOnDelete(ondelete);
407 
408  return col;
409  }
410 
411  static void memberSetter(
413  void* obj,
414  const void* value,
415  UT_ErrorCode& ec)
416  {
417  auto member_value = static_cast<const id_t*>(value);
419  ->field(obj)
420  .setId(*member_value);
421  }
422  static void memberGetter(
424  const void* obj,
425  void* value,
426  UT_ErrorCode& ec)
427  {
428  auto member_value = static_cast<id_t*>(value);
429  *member_value
431  me)
432  ->field(obj)
433  .id();
434  }
435 
436  UT_ORMColumn::Type sqlType() const override
437  {
438  return UTsqlOrmColumnType<id_t>();
439  }
440  void bind(
441  const void* obj,
442  UT_SqlStatement& stmt,
443  int bind_index,
444  UT_ErrorCode& ec) override
445  {
446  stmt.bind(bind_index, field(obj).id());
447  ec = stmt.getError();
448  }
449  void load(void* obj, UT_SqlStatement& stmt, int index, UT_ErrorCode& ec)
450  override
451  {
452  field(obj).setId(stmt.get<id_t>(index));
453  ec = stmt.getError();
454  }
455  void onDelete(void* obj, UT_ORMColumn::OnDelete ondelete, UT_ErrorCode& ec)
456  override
457  {
458  if (ondelete != UT_ORMColumn::OnDelete::DoNothing)
459  {
460  ForeignKey& f = field(obj);
461  f.clear();
462  }
463  }
464  bool isSame(const void* obj_left, const void* obj_right, UT_ErrorCode& ec)
465  const final override
466  {
467  const ForeignKey& left = field(obj_left);
468  const ForeignKey& right = field(obj_right);
469  return left.id() == right.id();
470  }
471 
472 protected:
473  ForeignKey& field(void* obj)
474  {
475  Cls* cls = static_cast<Cls*>(obj);
476  return (cls->*myMemberPtr);
477  }
478  const ForeignKey& field(const void* obj) const
479  {
480  const Cls* cls = static_cast<const Cls*>(obj);
481  return (cls->*myMemberPtr);
482  }
483 
484 private:
485  ForeignKey Cls::*myMemberPtr;
486 };
487 
488 #endif // __UT_ORMFIELD_H__
489 
ForeignKey & field(void *obj)
Definition: UT_ORMField.h:473
void getValue(const Cls &obj, MemberT &member_value, UT_ErrorCode &ec)
Definition: UT_ORMField.h:85
UT_IORMFieldAdapter * adapter() const
Definition: UT_ORMField.h:138
UT_WeakPtr< UT_ORMModelMeta > myForeignModel
Definition: UT_ORMField.h:173
const UT_ErrorCode & getError() const
Definition: UT_SQL.h:701
setter_func_t mySetter
Definition: UT_ORMField.h:106
UT_ORMColumn::Type sqlType() const override
Definition: UT_ORMField.h:224
UT_ORMFieldColumn(const UT_StringHolder &name, UT_ORMColumn::Type type, unsigned props=UT_ORMColumn::Empty, UT_ORMColumn::OnDelete ondelete=UT_ORMColumn::OnDelete::DoNothing)
Definition: UT_ORMField.h:126
void bind(const void *obj, UT_SqlStatement &stmt, int bind_index, UT_ErrorCode &ec) override
Definition: UT_ORMField.h:440
void
Definition: png.h:1083
GLint left
Definition: glcorearb.h:2005
const GLdouble * v
Definition: glcorearb.h:837
UT_StringHolder myM2MReverseFieldName
Definition: UT_ORMField.h:175
typename ModelT::Meta::primary_key_t foreign_key_t
Definition: UT_ORMField.h:306
GLsizei const GLfloat * value
Definition: glcorearb.h:824
bool bind(int idx, null_tag_t)
Definition: UT_SQL.h:556
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
UT_ORMColumnType
GLdouble right
Definition: glad.h:2817
UT_IORMFieldAdapter(setter_func_t setter, getter_func_t getter)
Definition: UT_ORMField.h:102
virtual void onDelete(void *obj, UT_ORMColumn::OnDelete ondelete, UT_ErrorCode &ec)
Definition: UT_ORMField.h:66
UT_ORMFieldColumn(const UT_StringHolder &name, UT_UniquePtr< UT_IORMFieldAdapter > adapter, unsigned props=UT_ORMColumn::Properties::Empty, UT_ORMColumn::OnDelete ondelete=UT_ORMColumn::OnDelete::DoNothing, const UT_StringHolder &related_name=UT_StringHolder::theEmptyString)
Definition: UT_ORMField.h:113
#define UT_API
Definition: UT_API.h:14
UT_ORMForeignKeyField()=default
static UT_ORMFieldColumn createColumn(const UT_ORMModelMeta &meta, const UT_StringHolder &name, ForeignKey Cls::*member_ptr, unsigned props, UT_ORMColumn::OnDelete ondelete, const UT_StringHolder &related_name=UT_StringHolder::theEmptyString)
Definition: UT_ORMField.h:392
bool isSame(const void *obj_left, const void *obj_right, UT_ErrorCode &ec) const finaloverride
Definition: UT_ORMField.h:464
typename ForeignKey::foreign_key_t id_t
Definition: UT_ORMField.h:384
A reference counter base class for use with UT_IntrusivePtr.
const UT_StringHolder & m2mReverseFieldName() const
Definition: UT_ORMField.h:165
void setValue(const ModelT &value)
Definition: UT_ORMField.h:346
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
bool operator==(const UT_ORMForeignKeyField &rhs) const
Definition: UT_ORMField.h:313
UT_ORMColumn::Type sqlType() const override
Definition: UT_ORMField.h:436
void load(void *obj, UT_SqlStatement &stmt, int index, UT_ErrorCode &ec) override
Definition: UT_ORMField.h:449
UT_ORMForeignKeyField(foreign_key_t pk)
Definition: UT_ORMField.h:309
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
typename ForeignKey::model_t model_t
Definition: UT_ORMField.h:382
UT_IORMFieldAdapter * adapter()
Definition: UT_ORMField.h:134
UT_StringHolder myM2MFieldName
Definition: UT_ORMField.h:174
const UT_StringHolder & m2mFieldName() const
Definition: UT_ORMField.h:161
getter_func_t myGetter
Definition: UT_ORMField.h:107
MemberT & field(void *obj)
Definition: UT_ORMField.h:259
static void memberSetter(UT_IORMFieldAdapter *me, void *obj, const void *value, UT_ErrorCode &ec)
Definition: UT_ORMField.h:411
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
bool isSame(const void *obj_left, const void *obj_right, UT_ErrorCode &ec) const finaloverride
Definition: UT_ORMField.h:250
static const UT_StringHolder theEmptyString
UT_SharedPtr< UT_ORMModelMeta > foreignModel() const
Definition: UT_ORMField.h:156
IMATH_HOSTDEVICE constexpr Color4< T > operator*(S a, const Color4< T > &v) IMATH_NOEXCEPT
Reverse multiplication: S * Color4.
Definition: ImathColor.h:732
MemberT & getValue(void *obj)
Definition: UT_ORMField.h:249
GLuint const GLchar * name
Definition: glcorearb.h:786
static UT_ORMFieldColumn createColumn(const UT_StringHolder &name, MemberT Cls::*member_ptr, unsigned props)
Definition: UT_ORMField.h:213
GLdouble t
Definition: glad.h:2397
void bind(const void *obj, UT_SqlStatement &stmt, int index, UT_ErrorCode &ec) override
Definition: UT_ORMField.h:228
static void memberGetter(UT_IORMFieldAdapter *me, const void *obj, void *value, UT_ErrorCode &ec)
Definition: UT_ORMField.h:422
std::error_code UT_ErrorCode
Definition: UT_ErrorCode.h:20
const ForeignKey & field(const void *obj) const
Definition: UT_ORMField.h:478
void setValue(Cls &obj, const MemberT &member_value, UT_ErrorCode &ec)
Definition: UT_ORMField.h:79
UT_ORMBasicFieldAdapter(MemberT Cls::*member_ptr)
Definition: UT_ORMField.h:207
foreign_key_t id() const
Definition: UT_ORMField.h:337
LeafData & operator=(const LeafData &)=delete
GLuint index
Definition: glcorearb.h:786
UT_UniquePtr< UT_IORMFieldAdapter > myFieldPtr
Definition: UT_ORMField.h:171
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
void setValue(void *obj, const MemberT &t)
Definition: UT_ORMField.h:245
bool operator!=(const UT_ORMForeignKeyField &rhs) const
Definition: UT_ORMField.h:317
void onDelete(void *obj, UT_ORMColumn::OnDelete ondelete, UT_ErrorCode &ec) override
Definition: UT_ORMField.h:455
UT_StringHolder myThroughModelName
Definition: UT_ORMField.h:172
T get(int idx) const
Definition: UT_SQL.h:653
UT_ORMForeignKeyFieldAdapter(ForeignKey Cls::*member_ptr)
Definition: UT_ORMField.h:386
void setId(const foreign_key_t &id)
Definition: UT_ORMField.h:341
const MemberT & field(const void *obj) const
Definition: UT_ORMField.h:264
std::weak_ptr< T > UT_WeakPtr
Definition: UT_SharedPtr.h:49
UT_IntrusivePtr< PointerHolder > model_pointer_t
Definition: UT_ORMField.h:304
void load(void *obj, UT_SqlStatement &stmt, int index, UT_ErrorCode &ec) override
Definition: UT_ORMField.h:238
GLenum GLuint GLsizei const GLenum * props
Definition: glcorearb.h:2525