diff --git a/src/Wt/Dbo/DbAction_impl.h b/src/Wt/Dbo/DbAction_impl.h index de5f415f..ba50d5dc 100644 --- a/src/Wt/Dbo/DbAction_impl.h +++ b/src/Wt/Dbo/DbAction_impl.h @@ -91,9 +91,17 @@ void InitSchema::act(const FieldRef& field) foreignKeyTable_, foreignKeyName_, flags | FieldFlags::ForeignKey, fkConstraints_)); else - // Normal field - mapping_.fields.push_back - (FieldInfo(field.name(), &typeid(V), field.sqlType(session_), flags)); + { + if(field.hasPostFieldString()) + { + mapping_.fields.push_back + (FieldInfo(field.name(), &typeid(V), field.sqlType(session_), flags, field.sqlPostFieldStringValue())); + + }else + // Normal field + mapping_.fields.push_back + (FieldInfo(field.name(), &typeid(V), field.sqlType(session_), flags)); + } } template diff --git a/src/Wt/Dbo/Field.h b/src/Wt/Dbo/Field.h index 8b1b0f94..36b4910a 100644 --- a/src/Wt/Dbo/Field.h +++ b/src/Wt/Dbo/Field.h @@ -182,7 +182,8 @@ public: AuxId = 0x1 }; - FieldRef(V& value, const std::string& name, int size, int flags = 0); + explicit FieldRef(V& value, const std::string& name, int size, int flags = 0); + explicit FieldRef(const std::string& postFieldString, V& value, const std::string& name, int size, int flags = 0); const std::string& name() const; int size() const; @@ -193,6 +194,9 @@ public: const V& value() const { return value_; } void setValue(const V& value) const { value_ = value; } + bool hasPostFieldString() const { return hasPostFieldString_; } + const std::string& sqlPostFieldStringValue() const { return sqlPostFieldStringValue_; } + void bindValue(SqlStatement *statement, int column) const; void setValue(Session& session, SqlStatement *statement, int column) const; @@ -201,6 +205,8 @@ private: std::string name_; int size_; int flags_; + bool hasPostFieldString_ = false; + std::string sqlPostFieldStringValue_ = {}; }; /*! \brief Type of an SQL relation. @@ -368,6 +374,36 @@ void auxId(Action& action, ptr& value, const std::string& name, template void field(Action& action, V& value, const std::string& name, int size = -1); +/** + * @brief Maps a database object field with a postFieldString. + * + * This function binds the field \p value to the database field \p name + * with post string value \p postFieldStringValue + * + * \attention \p postFieldStringValue needs to be escaped as required per backend: + * content of \p postFieldStringValue will be added *as is* after field definition + * + * Primary use was the addition of a default value. + * But recently came across other things that might be interesting to put after the field + * + * \code + * // Adding post field string + * Wt::Dbo::field(" DEFAULT \'escaped String\'", a, stringValue, "name"); // DEFAULT 'escaped String' + * Wt::Dbo::field(" DEFAULT unescaped String", a, stringValue, "name"); // DEFAULT unescaped String // ERROR! + * Wt::Dbo::field(" DEFAULT -1", a, numValue, "number"); // DEFAULT -1 + * \endcode + * + * The optional \p size may be used as a hint for the needed + * storage. It is only useful for std::string or + * Wt::WString fields, and causes the schema to use a + * varchar(size) for storing the + * field instead of an unlimited length string type. + * + * \ingroup dbo + */ +template +void field(const std::string& postFieldStringValue, Action& action, V& value, const std::string& name, int size = -1); + /* * This is synonym for belongsTo(), and used by id(). We should overload * this method also to allow foreign key constraints. diff --git a/src/Wt/Dbo/Field_impl.h b/src/Wt/Dbo/Field_impl.h index 06f509e9..aedb1bb0 100644 --- a/src/Wt/Dbo/Field_impl.h +++ b/src/Wt/Dbo/Field_impl.h @@ -24,6 +24,19 @@ FieldRef::FieldRef(V& value, const std::string& name, int size, int flags) flags_(flags) { } +/// @brief Overload for field with postFieldString Definition +/// @param postFieldString the Value as String that should come after sql field definition +/// Primarily used for DEFAULT Values. Need to include DEFAULT in the string +template +FieldRef::FieldRef(const std::string& postFieldString, V& value, const std::string& name, int size, int flags) + : value_(value), + name_(name), + size_(size), + flags_(flags), + sqlPostFieldStringValue_(postFieldString), + hasPostFieldString_(true) +{ } + template const std::string& FieldRef::name() const { @@ -204,6 +217,12 @@ void field(A& action, V& value, const std::string& name, int size) action.act(FieldRef(value, name, size)); } +template +void field(const std::string& postFieldString, A& action, V& value, const std::string& name, int size) +{ + action.act(FieldRef(postFieldString, value, name, size)); +} + template void field(A& action, ptr& value, const std::string& name, int) { diff --git a/src/Wt/Dbo/Session.C b/src/Wt/Dbo/Session.C index d71bbab4..90692b5d 100644 --- a/src/Wt/Dbo/Session.C +++ b/src/Wt/Dbo/Session.C @@ -794,6 +794,11 @@ void Session::createTable(Impl::MappingInfo *mapping, sql << " \"" << field.name() << "\" " << sqlType; + if(field.hasPostFieldString()) + { + sql << field.sqlPostFieldString(); + } + firstField = false; if (field.isNaturalIdField()) { diff --git a/src/Wt/Dbo/SqlTraits.C b/src/Wt/Dbo/SqlTraits.C index 8ce64afe..655fd11c 100644 --- a/src/Wt/Dbo/SqlTraits.C +++ b/src/Wt/Dbo/SqlTraits.C @@ -29,6 +29,19 @@ FieldInfo::FieldInfo(const std::string& name, flags_(flags) { } +FieldInfo::FieldInfo(const std::string& name, + const std::type_info *type, + const std::string& sqlType, + int flags, + const std::string& postFieldString) + : name_(name), + sqlType_(sqlType), + type_(type), + flags_(flags), + sqlPostFieldString_(postFieldString), + hasPostFieldString_(true) +{ } + FieldInfo::FieldInfo(const std::string& name, const std::type_info *type, const std::string& sqlType, const std::string& foreignKeyTable, diff --git a/src/Wt/Dbo/SqlTraits.h b/src/Wt/Dbo/SqlTraits.h index 8803f314..7abec1f3 100644 --- a/src/Wt/Dbo/SqlTraits.h +++ b/src/Wt/Dbo/SqlTraits.h @@ -196,6 +196,11 @@ public: FieldInfo(const std::string& name, const std::type_info *type, const std::string& sqlType, int flags); + /*! \brief Creates a field description. + */ + FieldInfo(const std::string& name, const std::type_info *type, + const std::string& sqlType, int flags, const std::string& postFieldString); + /*! \brief Creates a field description. */ FieldInfo(const std::string& name, const std::type_info *type, @@ -216,6 +221,14 @@ public: */ const std::string& sqlType() const { return sqlType_; } + /*! \brief Returns the postFieldString that is added after the field. + */ + const std::string& sqlPostFieldString() const { return sqlPostFieldString_; } + + /*! \brief Returns whether there is a postFieldString. + */ + const bool hasPostFieldString() const { return hasPostFieldString_; } + /*! \brief Returns the field qualifier. */ const std::string& qualifier() const { return qualifier_; } @@ -263,11 +276,12 @@ public: std::string sql() const; private: - std::string name_, sqlType_, qualifier_; + std::string name_, sqlType_, qualifier_, sqlPostFieldString_ = ""; std::string foreignKeyName_, foreignKeyTable_; const std::type_info *type_; int flags_; int fkConstraints_; + bool hasPostFieldString_ = false; }; /*! \class query_result_traits Wt/Dbo/SqlTraits.h Wt/Dbo/SqlTraits.h