add Finder::like(...) and ilike(...) methods

This commit is contained in:
Tomasz Sowa 2022-12-05 06:36:13 +01:00
parent dfc631dd06
commit a4a1acebeb
11 changed files with 616 additions and 180 deletions

View File

@ -210,7 +210,7 @@ void BaseExpression::put_field_name(const wchar_t * field_name, const FT & field
else
{
before_field_name();
esc(field_name, *out_stream);
esc(field_name, *out_stream, FT::default_type, nullptr); /* do not use provided field_type here - it would use e.g. binary mode if it was set, similar don't use model_env */
after_field_name();
}
}
@ -277,95 +277,95 @@ void BaseExpression::after_field_name()
}
void BaseExpression::before_field_value(const std::wstring &, const FT & field_type)
void BaseExpression::before_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(const std::string &, const FT & field_type)
void BaseExpression::before_field_value(const std::string &, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const std::wstring &, const FT & field_type)
void BaseExpression::after_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const std::string &, const FT & field_type)
void BaseExpression::after_field_value(const std::string &, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(const wchar_t *, const FT & field_type)
void BaseExpression::before_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const wchar_t *, const FT & field_type)
void BaseExpression::after_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(const char *, const FT & field_type)
void BaseExpression::before_field_value(const char *, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const char *, const FT & field_type)
void BaseExpression::after_field_value(const char *, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(wchar_t, const FT & field_type)
void BaseExpression::before_field_value(wchar_t, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(wchar_t, const FT & field_type)
void BaseExpression::after_field_value(wchar_t, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(char, const FT & field_type)
void BaseExpression::before_field_value(char, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(char, const FT & field_type)
void BaseExpression::after_field_value(char, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(const pt::Date &, const FT & field_type)
void BaseExpression::before_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const pt::Date &, const FT & field_type)
void BaseExpression::after_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(const pt::Space &, const FT & field_type)
void BaseExpression::before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const pt::Space &, const FT & field_type)
void BaseExpression::after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
@ -407,9 +407,9 @@ void BaseExpression::char_to_hex(wchar_t c, pt::TextStream & stream)
* return true if the val character was escaped and put (or ignored) to the stream
*
*/
bool BaseExpression::esc_char(char val, pt::TextStream & stream)
bool BaseExpression::esc_char(char val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
return esc_char((wchar_t)(unsigned char)val, stream);
return esc_char((wchar_t)(unsigned char)val, stream, field_type, model_env);
}
@ -419,13 +419,13 @@ bool BaseExpression::esc_char(char val, pt::TextStream & stream)
* in most caces you have to provide your own esc_char(wchar_t val, pt::TextStream & stream) method
*
*/
bool BaseExpression::esc_char(wchar_t val, pt::TextStream & stream)
bool BaseExpression::esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
return false;
}
void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_binary() || field_type.is_hexadecimal() )
{
@ -433,7 +433,7 @@ void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_typ
}
else
{
if( !esc_char(val, stream) )
if( !esc_char(val, stream, field_type, model_env) )
{
stream << val;
}
@ -441,13 +441,13 @@ void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_typ
}
void BaseExpression::esc(unsigned char val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(unsigned char val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(static_cast<char>(val), stream, field_type);
esc(static_cast<char>(val), stream, field_type, model_env);
}
void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_binary() || field_type.is_hexadecimal() )
{
@ -457,7 +457,7 @@ void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_
{
if( field_type.use_utf8() )
{
if( !esc_char(val, stream) )
if( !esc_char(val, stream, field_type, model_env) )
{
stream << val;
}
@ -466,7 +466,7 @@ void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_
{
char val_char = (char)(unsigned char)val;
if( !esc_char(val_char, stream) )
if( !esc_char(val_char, stream, field_type, model_env) )
{
stream << val_char;
}
@ -475,57 +475,57 @@ void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_
}
void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_numeric() )
{
esc_numeric_string(val, has_known_length, len, stream, field_type);
esc_numeric_string(val, has_known_length, len, stream, field_type, model_env);
}
else
{
esc_normal_string(val, has_known_length, len, stream, field_type);
esc_normal_string(val, has_known_length, len, stream, field_type, model_env);
}
}
void BaseExpression::esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_numeric() )
{
esc_numeric_string(val, has_known_length, len, stream, field_type);
esc_numeric_string(val, has_known_length, len, stream, field_type, model_env);
}
else
{
esc_normal_string(val, has_known_length, len, stream, field_type);
esc_normal_string(val, has_known_length, len, stream, field_type, model_env);
}
}
void BaseExpression::esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val.c_str(), true, val.size(), stream, field_type);
esc(val.c_str(), true, val.size(), stream, field_type, model_env);
}
void BaseExpression::esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val, false, 0, stream, field_type);
esc(val, false, 0, stream, field_type, model_env);
}
void BaseExpression::esc(const std::string & val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const std::string & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val.c_str(), true, val.size(), stream, field_type);
esc(val.c_str(), true, val.size(), stream, field_type, model_env);
}
void BaseExpression::esc(const char * val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const char * val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val, false, 0, stream, field_type);
esc(val, false, 0, stream, field_type, model_env);
}
void BaseExpression::esc(bool val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(bool val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( val )
stream << "true";
@ -534,73 +534,73 @@ void BaseExpression::esc(bool val, pt::TextStream & stream, const FT & field_typ
}
void BaseExpression::esc(short val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(short val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(unsigned short val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(unsigned short val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(int val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(int val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(unsigned int val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(unsigned int val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(long val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(unsigned long val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(unsigned long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(long long val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(long long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(unsigned long long val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(unsigned long long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(float val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(float val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(double val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(double val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(long double val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(long double val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
stream << val;
}
void BaseExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_date_only() )
{
@ -625,29 +625,29 @@ void BaseExpression::esc(const pt::Date & date, pt::TextStream & stream, const F
}
void BaseExpression::esc(const pt::TextStream & val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const pt::TextStream & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
pt::TextStream::const_iterator i = val.begin();
for(; i != val.end() ; ++i)
{
esc(*i, stream, field_type);
esc(*i, stream, field_type, model_env);
}
}
void BaseExpression::esc(const pt::WTextStream & val, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const pt::WTextStream & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
pt::WTextStream::const_iterator i = val.begin();
for(; i != val.end() ; ++i)
{
esc(*i, stream, field_type);
esc(*i, stream, field_type, model_env);
}
}
void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type)
void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
pt::WTextStream tmp_stream;
bool pretty_print = field_type.is_pretty_print();
@ -657,7 +657,7 @@ void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const
else
space.serialize_to_json_stream(tmp_stream, pretty_print);
esc(tmp_stream, stream, field_type);
esc(tmp_stream, stream, field_type, model_env);
}
@ -770,11 +770,11 @@ void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const
//}
void BaseExpression::before_field_value_string(const FT & field_type)
void BaseExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
{
}
void BaseExpression::after_field_value_string(const FT & field_type)
void BaseExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
{
}

View File

@ -157,13 +157,13 @@ public:
if( field_type.is_primary_key() )
{
if( model_env && model_env->has_primary_key_set )
put_field_value(field_value, field_type);
put_field_value(field_value, field_type, model_env);
else
put_null_value();
}
else
{
put_field_value(field_value, field_type);
put_field_value(field_value, field_type, model_env);
}
}
}
@ -290,39 +290,39 @@ public:
template<typename StringType>
void put_string_generic(const StringType * str, const FT & field_type, bool add_quotes)
void put_string_generic(const StringType * str, const FT & field_type, bool add_quotes, ModelEnv * model_env = nullptr)
{
if( out_stream )
{
if( add_quotes )
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
esc(str, *out_stream, field_type);
esc(str, *out_stream, field_type, model_env);
if( add_quotes )
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
}
}
template<typename StringOrStreamType>
void put_string_generic(const StringOrStreamType & str, const FT & field_type, bool add_quotes)
void put_string_generic(const StringOrStreamType & str, const FT & field_type, bool add_quotes, ModelEnv * model_env = nullptr)
{
if( out_stream )
{
if( add_quotes )
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
esc(str, *out_stream, field_type);
esc(str, *out_stream, field_type, model_env);
if( add_quotes )
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
}
}
@ -332,36 +332,36 @@ public:
* esc for: signed char, wchar_t, char16_t, char32_t
*
*/
virtual bool esc_char(char val, pt::TextStream & stream);
virtual bool esc_char(wchar_t val, pt::TextStream & stream);
virtual bool esc_char(char val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(wchar_t val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(char val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned char val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(wchar_t val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const std::string & val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const char * val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const std::string & val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const char * val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(bool val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(float val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(long double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(bool val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(short val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned short val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(int val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned int val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(long long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned long long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(float val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(double val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(long double val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const pt::TextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const pt::WTextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::TextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::WTextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
@ -390,31 +390,31 @@ protected:
virtual void add_additional_columns(Model & model);
template<typename FieldValue>
void put_field_value(const FieldValue & field_value, const FT & field_type)
void put_field_value(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env = nullptr)
{
if( out_stream )
{
before_field_value(field_value, field_type);
esc(field_value, *out_stream, field_type);
after_field_value(field_value, field_type);
before_field_value(field_value, field_type, model_env);
esc(field_value, *out_stream, field_type, model_env);
after_field_value(field_value, field_type, model_env);
}
}
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env = nullptr)
{
if( out_stream && model_env && model_env->model && getter_method )
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
if( scratch_buffer )
{
scratch_buffer->clear();
(model_env->model->*getter_method)(*scratch_buffer);
esc(*scratch_buffer, *out_stream, field_type);
esc(*scratch_buffer, *out_stream, field_type, model_env);
scratch_buffer->clear();
}
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
}
@ -585,7 +585,7 @@ protected:
field_value_list_separator();
}
put_field_value(v, FT::default_type);
put_field_value(v, FT::default_type, model_env);
is_first = false;
}
@ -608,37 +608,37 @@ protected:
virtual void after_field_name();
virtual void before_field_value(const std::wstring &, const FT & field_type);
virtual void after_field_value(const std::wstring &, const FT & field_type);
virtual void before_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(const std::string &, const FT & field_type);
virtual void after_field_value(const std::string &, const FT & field_type);
virtual void before_field_value(const std::string &, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(const std::string &, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(const wchar_t *, const FT & field_type);
virtual void after_field_value(const wchar_t *, const FT & field_type);
virtual void before_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(const char *, const FT & field_type);
virtual void after_field_value(const char *, const FT & field_type);
virtual void before_field_value(const char *, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(const char *, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(wchar_t, const FT & field_type);
virtual void after_field_value(wchar_t, const FT & field_type);
virtual void before_field_value(wchar_t, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(wchar_t, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(char, const FT & field_type);
virtual void after_field_value(char, const FT & field_type);
virtual void before_field_value(char, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(char, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(const pt::Date &, const FT & field_type);
virtual void after_field_value(const pt::Date &, const FT & field_type);
virtual void before_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(const pt::Space &, const FT & field_type);
virtual void after_field_value(const pt::Space &, const FT & field_type);
virtual void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
virtual void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
template<typename FieldValue>
void before_field_value(const FieldValue &, const FT & field_type)
void before_field_value(const FieldValue &, const FT & field_type, ModelEnv * model_env)
{
}
template<typename FieldValue>
void after_field_value(const FieldValue &, const FT & field_type)
void after_field_value(const FieldValue &, const FT & field_type, ModelEnv * model_env)
{
}
@ -690,32 +690,32 @@ protected:
virtual void before_field_value_string(const FT & field_type);
virtual void after_field_value_string(const FT & field_type);
virtual void before_field_value_string(const FT & field_type, ModelEnv * model_env);
virtual void after_field_value_string(const FT & field_type, ModelEnv * model_env);
char char_to_hex_part(char c);
void char_to_hex(char c, pt::TextStream & stream);
void char_to_hex(wchar_t c, pt::TextStream & stream);
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type);
void esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type);
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
void esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
bool is_empty_field(const wchar_t * value);
template<typename CharType>
void esc_normal_string(CharType * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type)
void esc_normal_string(CharType * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
{
esc(val[i], stream, field_type);
esc(val[i], stream, field_type, model_env);
}
}
template<typename CharType>
void esc_numeric_string(CharType * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type)
void esc_numeric_string(CharType * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
bool was_comma = false;
bool was_something_printed = false;
@ -729,7 +729,7 @@ protected:
if( (c=='.' && !was_comma) || (c>='0' && c<='9') )
{
esc(c, stream, field_type);
esc(c, stream, field_type, model_env);
was_something_printed = true;
if( c == '.' )
@ -739,7 +739,7 @@ protected:
if( !was_something_printed )
{
esc(static_cast<CharType>('0'), stream, field_type);
esc(static_cast<CharType>('0'), stream, field_type, model_env);
}
}

View File

@ -120,7 +120,9 @@ void DbExpression::field_before()
output_type == MORM_OUTPUT_TYPE_WHERE_LE ||
output_type == MORM_OUTPUT_TYPE_WHERE_LT ||
output_type == MORM_OUTPUT_TYPE_WHERE_NOT_EQ ||
output_type == MORM_OUTPUT_TYPE_WHERE_IN )
output_type == MORM_OUTPUT_TYPE_WHERE_IN ||
output_type == MORM_OUTPUT_TYPE_WHERE_LIKE ||
output_type == MORM_OUTPUT_TYPE_WHERE_ILIKE )
{
int conjunction = MORM_CONJUNCTION_AND;
@ -180,7 +182,17 @@ void DbExpression::put_name_value_separator()
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_IN )
{
(*out_stream) << " in ";
(*out_stream) << " IN ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_LIKE )
{
(*out_stream) << " LIKE ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_ILIKE )
{
(*out_stream) << " ILIKE ";
}
}
@ -234,14 +246,20 @@ void DbExpression::after_field_name()
void DbExpression::before_field_value_string(const FT & field_type)
void DbExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
{
(*out_stream) << "'";
if( model_env && model_env->use_escaping_for_like && model_env->add_prefix_percent )
(*out_stream) << '%';
}
void DbExpression::after_field_value_string(const FT & field_type)
void DbExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
{
if( model_env && model_env->use_escaping_for_like && model_env->add_postfix_percent )
(*out_stream) << '%';
(*out_stream) << "'";
}
@ -350,4 +368,8 @@ void DbExpression::add_rows_counter_column(Model & model)
}
}

View File

@ -107,8 +107,8 @@ protected:
void add_additional_columns(Model & model);
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
void before_field_value_string(const FT & field_type, ModelEnv * model_env);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
virtual void add_rows_counter_column(Model & model);

View File

@ -711,6 +711,386 @@ public:
}
/*
* like
*/
Finder<ModelClass> & like(const wchar_t * field_name, const char * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, const wchar_t * field_name, const char * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, int table_index, const wchar_t * field_name, const char * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * field_name, const wchar_t * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, const wchar_t * field_name, const wchar_t * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, int table_index, const wchar_t * field_name, const wchar_t * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * field_name, const std::string & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, const wchar_t * field_name, const std::string & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::string & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * field_name, const std::wstring & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, const wchar_t * field_name, const std::wstring & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::wstring & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * field_name, const pt::TextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, const wchar_t * field_name, const pt::TextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, int table_index, const wchar_t * field_name, const pt::TextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * field_name, const pt::WTextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, const wchar_t * field_name, const pt::WTextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & like(const wchar_t * table_name, int table_index, const wchar_t * field_name, const pt::WTextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return like_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
/*
* ilike
*/
Finder<ModelClass> & ilike(const wchar_t * field_name, const char * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, const wchar_t * field_name, const char * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, int table_index, const wchar_t * field_name, const char * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * field_name, const wchar_t * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, const wchar_t * field_name, const wchar_t * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, int table_index, const wchar_t * field_name, const wchar_t * pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * field_name, const std::string & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, const wchar_t * field_name, const std::string & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::string & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * field_name, const std::wstring & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, const wchar_t * field_name, const std::wstring & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::wstring & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * field_name, const pt::TextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, const wchar_t * field_name, const pt::TextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, int table_index, const wchar_t * field_name, const pt::TextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * field_name, const pt::WTextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, const wchar_t * field_name, const pt::WTextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
Finder<ModelClass> & ilike(const wchar_t * table_name, int table_index, const wchar_t * field_name, const pt::WTextStream & pattern,
bool escape_pattern = true, bool add_prefix_percent = true, bool add_postfix_percent = true)
{
return ilike_generic(table_name, table_index, field_name, pattern, escape_pattern, add_prefix_percent, add_postfix_percent);
}
template<typename PatternValue>
Finder<ModelClass> & like_generic(const wchar_t * field_name, const PatternValue & pattern,
bool escape_pattern, bool add_prefix_percent, bool add_postfix_percent)
{
if( db_expression )
{
model_env.use_escaping_for_like = escape_pattern;
model_env.add_prefix_percent = add_prefix_percent;
model_env.add_postfix_percent = add_postfix_percent;
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LIKE);
db_expression->field_to_stream(*out_stream, field_name, pattern, FT::default_type, &model_env);
model_env.use_escaping_for_like = false;
model_env.add_prefix_percent = false;
model_env.add_postfix_percent = false;
}
return *this;
}
template<typename PatternValue>
Finder<ModelClass> & like_generic(const wchar_t * table_name, const wchar_t * field_name, const PatternValue & pattern,
bool escape_pattern, bool add_prefix_percent, bool add_postfix_percent)
{
if( db_expression )
{
model_env.use_escaping_for_like = escape_pattern;
model_env.add_prefix_percent = add_prefix_percent;
model_env.add_postfix_percent = add_postfix_percent;
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LIKE);
field_to_stream(table_name, 1, field_name, pattern);
model_env.use_escaping_for_like = false;
model_env.add_prefix_percent = false;
model_env.add_postfix_percent = false;
}
return *this;
}
template<typename PatternValue>
Finder<ModelClass> & like_generic(const wchar_t * table_name, int table_index, const wchar_t * field_name, const PatternValue & pattern,
bool escape_pattern, bool add_prefix_percent, bool add_postfix_percent)
{
if( db_expression )
{
model_env.use_escaping_for_like = escape_pattern;
model_env.add_prefix_percent = add_prefix_percent;
model_env.add_postfix_percent = add_postfix_percent;
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LIKE);
field_to_stream(table_name, table_index, field_name, pattern);
model_env.use_escaping_for_like = false;
model_env.add_prefix_percent = false;
model_env.add_postfix_percent = false;
}
return *this;
}
template<typename PatternValue>
Finder<ModelClass> & ilike_generic(const wchar_t * field_name, const PatternValue & pattern,
bool escape_pattern, bool add_prefix_percent, bool add_postfix_percent)
{
if( db_expression )
{
model_env.use_escaping_for_like = escape_pattern;
model_env.add_prefix_percent = add_prefix_percent;
model_env.add_postfix_percent = add_postfix_percent;
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_ILIKE);
db_expression->field_to_stream(*out_stream, field_name, pattern, FT::default_type, &model_env);
model_env.use_escaping_for_like = false;
model_env.add_prefix_percent = false;
model_env.add_postfix_percent = false;
}
return *this;
}
template<typename PatternValue>
Finder<ModelClass> & ilike_generic(const wchar_t * table_name, const wchar_t * field_name, const PatternValue & pattern,
bool escape_pattern, bool add_prefix_percent, bool add_postfix_percent)
{
if( db_expression )
{
model_env.use_escaping_for_like = escape_pattern;
model_env.add_prefix_percent = add_prefix_percent;
model_env.add_postfix_percent = add_postfix_percent;
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_ILIKE);
field_to_stream(table_name, 1, field_name, pattern);
model_env.use_escaping_for_like = false;
model_env.add_prefix_percent = false;
model_env.add_postfix_percent = false;
}
return *this;
}
template<typename PatternValue>
Finder<ModelClass> & ilike_generic(const wchar_t * table_name, int table_index, const wchar_t * field_name, const PatternValue & pattern,
bool escape_pattern, bool add_prefix_percent, bool add_postfix_percent)
{
if( db_expression )
{
model_env.use_escaping_for_like = escape_pattern;
model_env.add_prefix_percent = add_prefix_percent;
model_env.add_postfix_percent = add_postfix_percent;
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_ILIKE);
field_to_stream(table_name, table_index, field_name, pattern);
model_env.use_escaping_for_like = false;
model_env.add_prefix_percent = false;
model_env.add_postfix_percent = false;
}
return *this;
}
Cursor<ModelClass> get_cursor()
{
Cursor<ModelClass> cursor;

View File

@ -88,30 +88,30 @@ void JSONExpression::after_field_name()
void JSONExpression::before_field_value_string(const FT & field_type)
void JSONExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
{
(*out_stream) << "\"";
}
void JSONExpression::after_field_value_string(const FT & field_type)
void JSONExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
{
(*out_stream) << "\"";
}
void JSONExpression::before_field_value(const pt::Space &, const FT & field_type)
void JSONExpression::before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_space() )
{
before_field_value_string(field_type);
before_field_value_string(field_type, model_env);
}
}
void JSONExpression::after_field_value(const pt::Space &, const FT & field_type)
void JSONExpression::after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_space() )
{
after_field_value_string(field_type);
after_field_value_string(field_type, model_env);
}
}
@ -135,14 +135,14 @@ void JSONExpression::after_field_value_list()
}
bool JSONExpression::esc_char(wchar_t val, pt::TextStream & stream)
bool JSONExpression::esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
return pt::try_esc_to_json(val, stream);
}
void JSONExpression::esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type)
void JSONExpression::esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
bool pretty_print = field_type.is_pretty_print();
@ -150,7 +150,7 @@ void JSONExpression::esc(const pt::Space & space, pt::TextStream & stream, const
{
pt::WTextStream tmp_stream;
space.serialize_to_space_stream(tmp_stream, pretty_print);
BaseExpression::esc(tmp_stream, stream, field_type);
BaseExpression::esc(tmp_stream, stream, field_type, model_env);
}
else
{

View File

@ -62,21 +62,17 @@ protected:
void before_field_value_list();
void after_field_value_list();
// using FlatExpression::esc to suppress clang warning:
// 'morm::JSONExpression::esc' hides overloaded virtual function [-Woverloaded-virtual]
using FlatExpression::esc;
bool esc_char(wchar_t val, pt::TextStream & stream);
bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
private:
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
void before_field_value(const pt::Space &, const FT & field_type);
void after_field_value(const pt::Space &, const FT & field_type);
void before_field_value_string(const FT & field_type, ModelEnv * model_env);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type);
};

View File

@ -111,6 +111,9 @@ public:
Select select_flags;
size_t rows_counter;
std::wstring rows_counter_column_name;
bool use_escaping_for_like; // escaping % and _ characters for LIKE or ILIKE statements
bool add_prefix_percent; // add a percent sign before a string value (used mainly in LIKE or ILIKE)
bool add_postfix_percent; // add a percent sign after a string value (used mainly in LIKE or ILIKE)
@ -152,6 +155,9 @@ public:
select_flags = e.select_flags;
rows_counter = e.rows_counter;
rows_counter_column_name = e.rows_counter_column_name;
use_escaping_for_like = e.use_escaping_for_like;
add_prefix_percent = e.add_prefix_percent;
add_postfix_percent = e.add_postfix_percent;
#ifdef MORM_HAS_EZC_LIBRARY
ezc_fun_info = e.ezc_fun_info;
@ -208,6 +214,9 @@ public:
select_flags = Select::default_type;
rows_counter = 0;
rows_counter_column_name.clear();
use_escaping_for_like = false;
add_prefix_percent = false;
add_postfix_percent = false;
#ifdef MORM_HAS_EZC_LIBRARY
ezc_fun_info = nullptr;

View File

@ -98,6 +98,8 @@
#define MORM_OUTPUT_TYPE_WHERE_GE 24
#define MORM_OUTPUT_TYPE_WHERE_IN 25
#define MORM_OUTPUT_TYPE_WHERE_NOT_EQ 26
#define MORM_OUTPUT_TYPE_WHERE_LIKE 27
#define MORM_OUTPUT_TYPE_WHERE_ILIKE 28
#define MORM_CONJUNCTION_AND 1

View File

@ -40,7 +40,7 @@ namespace morm
void PostgreSQLExpression::before_field_value_string(const FT & field_type)
void PostgreSQLExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_binary() )
{
@ -59,17 +59,44 @@ void PostgreSQLExpression::before_field_value_string(const FT & field_type)
else
{
(*out_stream) << "E'";
if( model_env && model_env->add_prefix_percent )
(*out_stream) << '%';
}
}
void PostgreSQLExpression::after_field_value_string(const FT & field_type)
void PostgreSQLExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
{
if( model_env && model_env->add_postfix_percent )
(*out_stream) << '%';
(*out_stream) << "'";
}
bool PostgreSQLExpression::esc_char(wchar_t val, pt::TextStream & stream)
bool PostgreSQLExpression::esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( model_env && model_env->use_escaping_for_like )
{
if( val == '%' )
{
stream << "\\\\%"; // gives: "\\%" (we are using a string form with E so we need to double backslashes here)
return true;
}
else
if( val == '_' )
{
stream << "\\\\_"; // gives: "\\_"
return true;
}
else
if( val == '\\' )
{
stream << "\\\\\\\\"; // gives: "\\\\"
return true;
}
}
if( val == '\\' )
{
stream << "\\\\";

View File

@ -55,10 +55,10 @@ protected:
private:
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
void before_field_value_string(const FT & field_type, ModelEnv * model_env);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
bool esc_char(wchar_t val, pt::TextStream & stream);
bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
};