void SQLite::exec(const String &query) { #ifndef HAVE_SQLITE3 throw UnsupportedFeatureException("SQLite"); #else if (!conn) throw NoConnectionException(); String err; double t_start; affectedrows=0; sqlite3_stmt *stmt=NULL; t_start=GetMicrotime(); int ret=sqlite3_prepare_v2((sqlite3*)conn, (const char*)query, query.size(),&stmt,NULL); if (ret!=SQLITE_OK) { throw QueryFailedException("sqlite3_prepare_v2 failed: %s",sqlite3_errmsg((sqlite3*)conn)); } if (stmt==NULL) { throw OutOfMemoryException(); } ret=sqlite3_step(stmt); if (ret!=SQLITE_DONE && ret!=SQLITE_ROW) { err.setf("sqlite3_step: %s, Query: %s",sqlite3_errmsg((sqlite3*)conn),(const char*)query); sqlite3_finalize(stmt); throw QueryFailedException(err); } ret=sqlite3_finalize(stmt); if (ret !=SQLITE_OK) { err.setf("sqlite3_finalize: %s, Query: %s",sqlite3_errmsg((sqlite3*)conn),(const char*)query); throw QueryFailedException(err); } affectedrows=sqlite3_changes((sqlite3*)conn); updateLastUse(); logQuery(query,(float)(GetMicrotime()-t_start)); #endif }
void BeatBoard::SearchApiService::RpcFunc(google::protobuf::RpcController* controller, const searchapi::Request* request, searchapi::Response* response, google::protobuf::Closure* done) { std::cout << __func__ << std::endl; std::string query = request->query(); std::string result = ""; bool ret = false; logQuery( query ); ret = searchDB( query, result ); if (ret) { response->set_result(result); std::cout << "OK: " << response->result() << std::endl; response->set_result_code(SEARCHAPI_RESULT_OK); } else { result = " "; // "" does not work at protobuf serialize response->set_result(result); response->set_result_code(SEARCHAPI_RESULT_ERROR); // response->set_error("message wasn't set"); std::cout << "NG: " << response->result() << std::endl; } done->Run(); }
ResultSet *SQLite::query(const String &query) { #ifndef HAVE_SQLITE3 throw UnsupportedFeatureException("SQLite"); #else if (!conn) throw NoConnectionException(); String err; double t_start; affectedrows=0; sqlite3_stmt *stmt=NULL; t_start=GetMicrotime(); int ret=sqlite3_prepare_v2((sqlite3*)conn, (const char*)query, query.size(),&stmt,NULL); if (ret!=SQLITE_OK) { throw QueryFailedException("sqlite3_prepare_v2 failed: %s",sqlite3_errmsg((sqlite3*)conn)); } if (stmt==NULL) { throw OutOfMemoryException(); } ret=sqlite3_step(stmt); if (ret!=SQLITE_DONE && ret!=SQLITE_ROW) { err.setf("sqlite3_step: %s, Query: %s",sqlite3_errmsg((sqlite3*)conn),(const char*)query); sqlite3_finalize(stmt); throw QueryFailedException(err); } affectedrows=sqlite3_changes((sqlite3*)conn); updateLastUse(); logQuery(query,(float)(GetMicrotime()-t_start)); SQLiteResult *pr=new SQLiteResult; if (!pr) { sqlite3_finalize(stmt); throw OutOfMemoryException(); } pr->stmt=stmt; pr->last_res=ret; pr->sqlite_class=this; pr->conn=(sqlite3 *)conn; pr->affectedrows=affectedrows; pr->num_fields=sqlite3_column_count(stmt); return pr; #endif }
static std::tuple<ASTPtr, BlockIO> executeQueryImpl( IParser::Pos begin, IParser::Pos end, Context & context, bool internal, QueryProcessingStage::Enum stage) { ProfileEvents::increment(ProfileEvents::Query); time_t current_time = time(0); const Settings & settings = context.getSettingsRef(); ParserQuery parser; ASTPtr ast; size_t query_size; size_t max_query_size = settings.max_query_size; try { ast = parseQuery(parser, begin, end, ""); /// Copy query into string. It will be written to log and presented in processlist. If an INSERT query, string will not include data to insertion. query_size = ast->range.second - ast->range.first; if (max_query_size && query_size > max_query_size) throw Exception("Query is too large (" + toString(query_size) + ")." " max_query_size = " + toString(max_query_size), ErrorCodes::QUERY_IS_TOO_LARGE); } catch (...) { /// Anyway log query. if (!internal) { String query = String(begin, begin + std::min(end - begin, static_cast<ptrdiff_t>(max_query_size))); logQuery(query.substr(0, settings.log_queries_cut_to_length), context); onExceptionBeforeStart(query, context, current_time); } throw; } String query(begin, query_size); BlockIO res; try { if (!internal) logQuery(query.substr(0, settings.log_queries_cut_to_length), context); /// Check the limits. checkLimits(*ast, settings.limits); QuotaForIntervals & quota = context.getQuota(); quota.addQuery(current_time); quota.checkExceeded(current_time); /// Put query to process list. But don't put SHOW PROCESSLIST query itself. ProcessList::EntryPtr process_list_entry; if (!internal && nullptr == typeid_cast<const ASTShowProcesslistQuery *>(&*ast)) { process_list_entry = context.getProcessList().insert( query, context.getUser(), context.getCurrentQueryId(), context.getIPAddress(), settings); context.setProcessListElement(&process_list_entry->get()); } auto interpreter = InterpreterFactory::get(ast, context, stage); res = interpreter->execute(); /// Hold element of process list till end of query execution. res.process_list_entry = process_list_entry; if (res.in) { if (IProfilingBlockInputStream * stream = dynamic_cast<IProfilingBlockInputStream *>(res.in.get())) { stream->setProgressCallback(context.getProgressCallback()); stream->setProcessListElement(context.getProcessListElement()); } } /// Everything related to query log. { QueryLogElement elem; elem.type = QueryLogElement::QUERY_START; elem.event_time = current_time; elem.query_start_time = current_time; elem.query = query.substr(0, settings.log_queries_cut_to_length); setClientInfo(elem, context); bool log_queries = settings.log_queries && !internal; /// Log into system table start of query execution, if need. if (log_queries) context.getQueryLog().add(elem); /// Also make possible for caller to log successful query finish and exception during execution. res.finish_callback = [elem, &context, log_queries] (IBlockInputStream * stream) mutable { ProcessListElement * process_list_elem = context.getProcessListElement(); if (!process_list_elem) return; double elapsed_seconds = process_list_elem->watch.elapsedSeconds(); elem.type = QueryLogElement::QUERY_FINISH; elem.event_time = time(0); elem.query_duration_ms = elapsed_seconds * 1000; elem.read_rows = process_list_elem->progress.rows; elem.read_bytes = process_list_elem->progress.bytes; auto memory_usage = process_list_elem->memory_tracker.getPeak(); elem.memory_usage = memory_usage > 0 ? memory_usage : 0; if (stream) { if (IProfilingBlockInputStream * profiling_stream = dynamic_cast<IProfilingBlockInputStream *>(stream)) { const BlockStreamProfileInfo & info = profiling_stream->getProfileInfo(); elem.result_rows = info.rows; elem.result_bytes = info.bytes; } } if (elem.read_rows != 0) { LOG_INFO(&Logger::get("executeQuery"), std::fixed << std::setprecision(3) << "Read " << elem.read_rows << " rows, " << formatReadableSizeWithBinarySuffix(elem.read_bytes) << " in " << elapsed_seconds << " sec., " << static_cast<size_t>(elem.read_rows / elapsed_seconds) << " rows/sec., " << formatReadableSizeWithBinarySuffix(elem.read_bytes / elapsed_seconds) << "/sec."); } if (log_queries) context.getQueryLog().add(elem); }; res.exception_callback = [elem, &context, log_queries, current_time] () mutable { context.getQuota().addError(current_time); elem.type = QueryLogElement::EXCEPTION_WHILE_PROCESSING; elem.event_time = time(0); elem.query_duration_ms = 1000 * (elem.event_time - elem.query_start_time); elem.exception = getCurrentExceptionMessage(false); ProcessListElement * process_list_elem = context.getProcessListElement(); if (process_list_elem) { double elapsed_seconds = process_list_elem->watch.elapsedSeconds(); elem.query_duration_ms = elapsed_seconds * 1000; elem.read_rows = process_list_elem->progress.rows; elem.read_bytes = process_list_elem->progress.bytes; auto memory_usage = process_list_elem->memory_tracker.getPeak(); elem.memory_usage = memory_usage > 0 ? memory_usage : 0; } setExceptionStackTrace(elem); logException(context, elem); if (log_queries) context.getQueryLog().add(elem); }; if (!internal && res.in) { std::stringstream log_str; log_str << "Query pipeline:\n"; res.in->dumpTree(log_str); LOG_DEBUG(&Logger::get("executeQuery"), log_str.str()); } } } catch (...) { if (!internal) onExceptionBeforeStart(query, context, current_time); throw; } return std::make_tuple(ast, res); }