13 #ifndef __UT_SQLORM_H__
14 #define __UT_SQLORM_H__
70 template <>
struct is_error_code_enum<UT::
SqlOrmError> : true_type
87 bool force_insert =
false,
88 bool force_update =
false)
90 auto&& meta_info = T::metaInfo();
91 return meta_info.save(*
this, ec, force_insert, force_update);
95 auto&& meta_info = T::metaInfo();
96 return meta_info.remove(*
this, ec);
100 auto&& meta_info = T::metaInfo();
101 return meta_info.update(*
this, ec);
104 template <
typename PK>
107 auto&& meta_info = T::metaInfo();
108 return meta_info.template fetch<T>(pk, ec);
113 auto&& meta_info = T::metaInfo();
114 return meta_info.template fetchAll<T>(ec);
148 configureInternals_();
153 template <
typename Cls,
typename FieldT>
159 myColumns.emplace_back(
163 template <
typename Cls,
typename FieldT>
169 myColumns.emplace_back(
171 name, field,
props));
173 template <
typename Cls,
typename ForeignModel>
179 = UT_ORMColumn::OnDelete::DoNothing)
183 myColumns.emplace_back(
184 adapter_t::createColumn(name, field,
props, ondelete_type));
190 for (
auto&& col : myColumns)
192 if (col.isPrimaryKey())
202 template <
typename T>
206 bool force_insert =
false,
207 bool force_update =
false)
const;
208 template <
typename T>
210 template <
typename T>
212 template <
typename T,
typename PK>
214 template <
typename T>
218 virtual void doBuild() = 0;
220 template <
typename T>
223 for (
int i = 0; i < myColumns.size(); i++)
228 adapter->load(&obj, stmt, i, ec);
241 obj.myHasSavedBefore =
true;
246 void configureInternals_();
248 bool myHasBuilt =
false;
249 bool myIsUsingAutoIncPK =
false;
279 ensureConnection_(ec);
288 template <
typename T>
291 auto&& meta_info = T::metaInfo();
292 for (
auto&& m : myRegisteredMetas)
298 myRegisteredMetas.emplace_back(&meta_info);
302 friend class UT_SqlOrmTable;
321 template <
typename T>
327 bool force_update)
const
332 if (obj.hasSavedBefore())
348 sql_query =
"INSERT INTO ";
352 sql_query =
"INSERT OR REPLACE INTO ";
360 if (col.isAutoIncrement())
370 for (
exint i = 0; i < values.
size(); i++)
383 sql_query.
append(
" VALUES (");
384 for (
exint i = 0; i < values.
size(); i++)
396 if (outputs.
size() > 0)
398 sql_query.
append(
" RETURNING ");
418 if (!stmt.prepare(sql_query, ec))
420 for (
int i = 0; i < values.
size(); i++)
426 adapter->bind(&obj, stmt, i+1, ec);
438 int changes = stmt.changes();
441 if (changes > 0 && outputs.
size() > 0)
448 adapter->load(&obj, stmt, i, ec);
456 ec = stmt.getError();
461 template <
typename T>
468 sql_query =
"DELETE FROM ";
470 sql_query.
append(
" WHERE ");
481 if (!stmt.prepare(sql_query, ec))
484 adapter->bind(&obj, stmt, 1, ec);
492 ec = stmt.getError();
501 adapter->
onDelete(&obj, meta_column.onDelete(), ec);
508 template <
typename T>
513 sql_query =
"UPDATE ";
515 sql_query.
append(
" SET ");
527 sql_query.
append(
" WHERE ");
536 sql_query.
append(
" AND ");
553 if (!stmt.prepare(sql_query, ec))
564 adapter->bind(&obj, stmt, index, ec);
579 adapter->bind(&obj, stmt, index, ec);
591 ec = stmt.getError();
593 if (stmt.changes() > 0)
594 obj.myHasSavedBefore =
true;
596 return stmt.changes() > 0;
599 template <
typename T,
typename PK>
604 sql_query =
"SELECT ";
612 sql_query.
append(
" FROM ");
614 sql_query.
append(
" WHERE ");
627 if (!stmt.prepare(sql_query, ec))
636 ec = stmt.getError();
650 template <
typename T>
655 sql_query.
append(
"SELECT");
663 sql_query.
append(
" FROM ");
674 if (!stmt.prepare(sql_query, ec))
677 while (stmt.step() && !stmt.getError())
689 #define UT_DECLARE_MODEL() \
692 friend class UT_ORMModelMeta; \
693 static const Meta& metaInfo();
695 #define UT_DEFINE_MODEL(_model_) \
696 const _model_::Meta& _model_::metaInfo() \
698 static Meta _instance; \
701 #endif // __UT_SQLORM_H__
UT_ORMModel & operator=(const UT_ORMModel &)=default
const UT_StringHolder & name() const
const UT_ErrorCode & getError() const
UT_Array< const UT_ORMModelMeta * > myRegisteredMetas
static UT_Optional< T > fetch(const PK &pk, UT_ErrorCode &ec)
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
SqlOrmError
Error codes to describe ORM errors.
bool hasSavedBefore() const
virtual void onDelete(void *obj, UT_ORMColumn::OnDelete ondelete, UT_ErrorCode &ec)
**But if you need a result
std::error_category UT_ErrorCategory
std::optional< T > UT_Optional
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
size_t appendFormat(const char *fmt, const Args &...args)
UT_IORMFieldAdapter * adapter()
exint emplace_back(S &&...s)
bool isAutoIncrement() const
UT_API const UT_ErrorCategory & GetOrmErrorCategory()
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
GLuint const GLchar * name
UT_ErrorCode make_error_code(UT::OrmMigError e)
void configure(const UT_StringHolder &db_path)
bool update(UT_ErrorCode &ec)
bool save(UT_ErrorCode &ec, bool force_insert=false, bool force_update=false)
std::error_code UT_ErrorCode
auto UTmakeErrorCode(EnumT e) -> decltype(make_error_code(e))
Make a UT_ErrorCode based on the provided namespaced enum class.
UT_SqlStatement cursor() const
GLenum GLsizei GLsizei GLint * values
UT_SqlOrm(const UT_StringHolder &db_path)
SYS_FORCE_INLINE void append(char character)
UT_ThreadSpecificValue< UT_SqlDatabase > myDBLocal
static UT_Array< T > fetchAll(UT_ErrorCode &ec)
SYS_AtomicInt32 myHasConfiguredInternals
GLenum GLenum GLsizei void GLsizei void * column
virtual ~UT_ORMModel()=default
UT_SqlTransaction transaction(UT_ErrorCode *ec=nullptr)
GLenum GLuint GLsizei const GLenum * props