12 #include "../bscript/bobject.h" 17 #include "../bscript/berror.h" 18 #include "../bscript/impstr.h" 19 #include "../bscript/objmembers.h" 20 #include "../bscript/objmethods.h" 21 #include "../clib/esignal.h" 22 #include "../clib/logfacility.h" 23 #include "../clib/threadhelp.h" 28 #ifndef USE_BOOST_REGEX 31 #define REGEX_NSPACE std 33 #include <boost/regex.hpp> 35 #define REGEX_NSPACE boost 42 using namespace Bscript;
65 unsigned int num_fields = mysql_num_fields(
_result->ptr() );
70 unsigned index = (unsigned)lng.
value();
71 if ( index > num_fields || index <= 0 )
75 else if (
_row[index - 1] == 0 )
81 if (
_fields[index - 1].
type == MYSQL_TYPE_DECIMAL ||
93 for (
unsigned int i = 0; i < num_fields; i++ )
103 if (
_fields[i].type == MYSQL_TYPE_DECIMAL ||
_fields[i].type == MYSQL_TYPE_NEWDECIMAL ||
104 _fields[i].type == MYSQL_TYPE_FLOAT ||
_fields[i].type == MYSQL_TYPE_DOUBLE )
130 if ( result->ptr() != nullptr )
131 _fields = mysql_fetch_fields( result->ptr() );
151 if ( index <= 0 || index > mysql_num_fields(
_result->ptr() ) )
155 return _fields[index - 1].name;
161 return static_cast<int>( mysql_num_rows(
_result->ptr() ) );
174 return mysql_num_fields(
_result->ptr() );
188 return "SQLResultSet";
193 _conn->set(
nullptr );
199 return new BError( _error );
200 RES_WRAPPER result = std::make_shared<ResultWrapper>( mysql_store_result( _conn->ptr() ) );
201 if ( result && result->ptr() != nullptr )
215 if ( mysql_field_count( _conn->ptr() ) == 0 )
217 return new BSQLResultSet( static_cast<int>( mysql_affected_rows( _conn->ptr() ) ) );
220 return new BError(
"Unknown error getting ResultSet" );
225 _conn->set( mysql_init(
nullptr ) );
228 _error =
"Insufficient memory";
241 return "SQLConnection";
247 if ( !mysql_ping(
_conn->ptr() ) )
256 _error =
"No active MYSQL object instance.";
259 if ( !mysql_real_connect(
_conn->ptr(), host, user, passwd,
nullptr, 0,
nullptr, 0 ) )
272 _error =
"No active MYSQL object instance.";
275 else if ( mysql_select_db(
_conn->ptr(), db ) )
289 _error =
"No active MYSQL object instance.";
293 if ( mysql_query(
_conn->ptr(), query.c_str() ) )
309 if ( params ==
nullptr || !params->size() )
310 return this->
query( query );
315 _error =
"No active MYSQL object instance.";
319 std::string replaced =
query;
320 REGEX_NSPACE::regex re(
"^((?:[^']|'[^']*')*?)(\\?)" );
321 for (
auto it = params->begin(); it != params->end(); ++it )
323 if ( !REGEX_NSPACE::regex_search( replaced, re ) )
326 _error =
"Could not replace parameters.";
330 if ( it->size() > ( std::numeric_limits<size_t>::max() - 5 ) / 2 )
333 _error =
"Parameter is too long.";
337 size_t escaped_max_size =
339 std::unique_ptr<char[]> escptr(
340 new char[escaped_max_size] );
342 unsigned long esclen = mysql_real_escape_string(
_conn->ptr(), escptr.get() + 3, it->c_str(),
343 static_cast<unsigned long>( it->size() ) );
349 escptr[esclen - 1] =
'\'';
350 escptr[esclen] =
'\0';
352 replaced = REGEX_NSPACE::regex_replace( replaced, re, escptr.get(),
353 REGEX_NSPACE::regex_constants::format_first_only );
356 return this->
query( replaced );
385 if ( objmember !=
nullptr )
394 if ( objmethod !=
nullptr )
403 return new BLong( 0 );
415 mysql_close(
_conn );
421 mysql_close(
_conn );
455 catch (
const char* msg )
457 POLLOG.Format(
"SQL Thread exits due to exception: {}\n" ) << msg;
460 catch ( std::string& str )
462 POLLOG.Format(
"SQL Thread exits due to exception: {}\n" ) << str;
465 catch ( std::exception& ex )
467 POLLOG.Format(
"SQL Thread exits due to exception: {}\n" ) << ex.what();
480 _msgs.push_move( std::move( msg_ ) );
489 _msgs.pop_wait( &task );
492 catch ( msg_queue::Canceled& )
virtual bool isTrue() const POL_OVERRIDE
std::shared_ptr< ConnectionWrapper > getConnection() const
const char * field_name(unsigned int index) const
virtual Bscript::BObjectImp * copy() const POL_OVERRIDE
virtual Bscript::BObjectRef get_member(const char *membername) POL_OVERRIDE
bool connect(const char *host, const char *user, const char *passwd)
bool isa(BObjectType type) const
virtual std::string getStringRep() const POL_OVERRIDE
void set(MYSQL_RES *result)
ObjMember * getKnownObjMember(const char *token)
virtual Bscript::BObjectRef OperSubscript(const Bscript::BObject &obj) POL_OVERRIDE
void sql_service_thread_stub()
int affected_rows() const
Bscript::BObjectImp * getResultSet() const
void start_thread(void(*entry)(void *), const char *thread_name, void *arg)
std::unique_ptr< SQLService > sql_service
ObjMethod * getKnownObjMethod(const char *token)
BSQLResultSet(RES_WRAPPER result)
virtual Bscript::BObjectImp * copy() const POL_OVERRIDE
virtual Bscript::BObjectRef get_member_id(const int id) POL_OVERRIDE
virtual Bscript::BObjectImp * copy() const POL_OVERRIDE
bool select_db(const char *db)
virtual Bscript::BObjectImp * call_method_id(const int id, Bscript::Executor &ex, bool forcebuiltin=false) POL_OVERRIDE
bool query(const std::string query)
NetworkManager networkManager
std::shared_ptr< QueryParam > QueryParams
static UninitObject * create()
virtual Bscript::BObjectImp * call_method(const char *methodname, Bscript::Executor &ex) POL_OVERRIDE
std::function< void()> msg
std::unordered_map< u64, ScriptDiffData > data
std::shared_ptr< ResultWrapper > RES_WRAPPER
virtual bool isTrue() const POL_OVERRIDE
BSQLRow(RES_WRAPPER resultset)
virtual std::string getStringRep() const POL_OVERRIDE
std::shared_ptr< ConnectionWrapper > _conn
std::atomic< bool > exit_signalled
std::string getLastError() const