8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 01:23:02 +01:00
firebird-mirror/src/jrd/trace/TraceObjects.h
2015-03-21 18:38:48 +00:00

639 lines
15 KiB
C++

/*
* PROGRAM: Firebird Trace Services
* MODULE: TraceObjects.h
* DESCRIPTION: Trace API manager support
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Khorsun Vladyslav
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2009 Khorsun Vladyslav <hvlad@users.sourceforge.net>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
#ifndef JRD_TRACE_OBJECTS_H
#define JRD_TRACE_OBJECTS_H
#include <time.h>
#include "../../common/classes/array.h"
#include "../../common/classes/fb_string.h"
#include "../../dsql/dsql.h"
#include "../../jrd/ntrace.h"
#include "../../common/dsc.h"
#include "../../common/isc_s_proto.h"
#include "../../jrd/req.h"
#include "../../jrd/svc.h"
#include "../../jrd/tra.h"
#include "../../jrd/status.h"
#include "../../jrd/Function.h"
#include "../../jrd/RuntimeStatistics.h"
#include "../../jrd/trace/TraceSession.h"
#include "../../common/classes/ImplementHelper.h"
#include "../../common/prett_proto.h"
//// TODO: DDL triggers, packages and external procedures and functions support
namespace Jrd {
class Database;
class Attachment;
class jrd_tra;
class TraceConnectionImpl :
public Firebird::AutoIface<Firebird::ITraceDatabaseConnectionImpl<TraceConnectionImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceConnectionImpl(const Attachment* att) :
m_att(att)
{}
// TraceConnection implementation
unsigned getKind();
int getProcessID();
const char* getUserName();
const char* getRoleName();
const char* getCharSet();
const char* getRemoteProtocol();
const char* getRemoteAddress();
int getRemoteProcessID();
const char* getRemoteProcessName();
// TraceDatabaseConnection implementation
int getConnectionID();
const char* getDatabaseName();
private:
const Attachment* const m_att;
};
class TraceTransactionImpl :
public Firebird::AutoIface<Firebird::ITraceTransactionImpl<TraceTransactionImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceTransactionImpl(const jrd_tra* tran, PerformanceInfo* perf = NULL) :
m_tran(tran),
m_perf(perf)
{}
// TraceTransaction implementation
unsigned getTransactionID();
FB_BOOLEAN getReadOnly();
int getWait();
unsigned getIsolation();
PerformanceInfo* getPerf() { return m_perf; }
private:
const jrd_tra* const m_tran;
PerformanceInfo* const m_perf;
};
template <class Final>
class BLRPrinter :
public Firebird::AutoIface<Firebird::ITraceBLRStatementImpl<Final, Firebird::CheckStatusWrapper> >
{
public:
BLRPrinter(const unsigned char* blr, unsigned length) :
m_blr(blr),
m_length(length),
m_text(*getDefaultMemoryPool())
{}
// TraceBLRStatement implementation
const unsigned char* getData() { return m_blr; }
unsigned getDataLength() { return m_length; }
const char* getText()
{
if (m_text.empty() && getDataLength())
fb_print_blr(getData(), (ULONG) getDataLength(), print_blr, this, 0);
return m_text.c_str();
}
private:
static void print_blr(void* arg, SSHORT offset, const char* line)
{
BLRPrinter* blr = (BLRPrinter*) arg;
Firebird::string temp;
temp.printf("%4d %s\n", offset, line);
blr->m_text.append(temp);
}
const unsigned char* const m_blr;
const unsigned m_length;
Firebird::string m_text;
};
class TraceBLRStatementImpl : public BLRPrinter<TraceBLRStatementImpl>
{
public:
TraceBLRStatementImpl(const jrd_req* stmt, PerformanceInfo* perf) :
BLRPrinter(stmt->getStatement()->blr.begin(), stmt->getStatement()->blr.getCount()),
m_stmt(stmt),
m_perf(perf)
{}
int getStmtID() { return m_stmt->req_id; }
PerformanceInfo* getPerf() { return m_perf; }
private:
const jrd_req* const m_stmt;
PerformanceInfo* const m_perf;
};
class TraceFailedBLRStatement : public BLRPrinter<TraceFailedBLRStatement>
{
public:
TraceFailedBLRStatement(const unsigned char* blr, unsigned length) :
BLRPrinter(blr, length)
{}
int getStmtID() { return 0; }
PerformanceInfo* getPerf() { return NULL; }
};
class TraceSQLStatementImpl :
public Firebird::AutoIface<Firebird::ITraceSQLStatementImpl<TraceSQLStatementImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceSQLStatementImpl(const dsql_req* stmt, PerformanceInfo* perf) :
m_stmt(stmt),
m_perf(perf),
m_planExplained(false),
m_inputs(*getDefaultMemoryPool(), m_stmt)
{}
// TraceSQLStatement implementation
int getStmtID();
PerformanceInfo* getPerf();
Firebird::ITraceParams* getInputs();
const char* getText();
const char* getPlan();
const char* getTextUTF8();
const char* getExplainedPlan();
private:
class DSQLParamsImpl :
public Firebird::AutoIface<Firebird::ITraceParamsImpl<DSQLParamsImpl, Firebird::CheckStatusWrapper> >
{
public:
DSQLParamsImpl(Firebird::MemoryPool& pool, const dsql_req* const stmt) :
m_stmt(stmt),
m_params(NULL),
m_descs(pool)
{
const dsql_msg* msg = m_stmt->getStatement()->getSendMsg();
if (msg)
m_params = &msg->msg_parameters;
}
FB_SIZE_T getCount();
const dsc* getParam(FB_SIZE_T idx);
private:
void fillParams();
const dsql_req* const m_stmt;
const Firebird::Array<dsql_par*>* m_params;
Firebird::HalfStaticArray<dsc, 16> m_descs;
};
void fillPlan(bool explained);
const dsql_req* const m_stmt;
PerformanceInfo* const m_perf;
Firebird::string m_plan;
bool m_planExplained;
DSQLParamsImpl m_inputs;
Firebird::string m_textUTF8;
};
class TraceFailedSQLStatement :
public Firebird::AutoIface<Firebird::ITraceSQLStatementImpl<TraceFailedSQLStatement, Firebird::CheckStatusWrapper> >
{
public:
TraceFailedSQLStatement(Firebird::string& text) :
m_text(text)
{}
// TraceSQLStatement implementation
int getStmtID() { return 0; }
PerformanceInfo* getPerf() { return NULL; }
Firebird::ITraceParams* getInputs() { return NULL; }
const char* getText() { return m_text.c_str(); }
const char* getPlan() { return ""; }
const char* getTextUTF8();
const char* getExplainedPlan() { return ""; }
private:
Firebird::string& m_text;
Firebird::string m_textUTF8;
};
class TraceContextVarImpl :
public Firebird::AutoIface<Firebird::ITraceContextVariableImpl<TraceContextVarImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceContextVarImpl(const char* ns, const char* name, const char* value) :
m_namespace(ns),
m_name(name),
m_value(value)
{}
// TraceContextVariable implementation
const char* getNameSpace() { return m_namespace; }
const char* getVarName() { return m_name; }
const char* getVarValue() { return m_value; }
private:
const char* const m_namespace;
const char* const m_name;
const char* const m_value;
};
// forward declaration
class TraceDescriptors;
class TraceParamsImpl :
public Firebird::AutoIface<Firebird::ITraceParamsImpl<TraceParamsImpl, Firebird::CheckStatusWrapper> >
{
public:
explicit TraceParamsImpl(TraceDescriptors *descs) :
m_descs(descs)
{}
// TraceParams implementation
FB_SIZE_T getCount();
const dsc* getParam(FB_SIZE_T idx);
private:
TraceDescriptors* m_descs;
};
class TraceDescriptors
{
public:
explicit TraceDescriptors(Firebird::MemoryPool& pool) :
m_descs(pool),
m_traceParams(this)
{
}
FB_SIZE_T getCount()
{
fillParams();
return m_descs.getCount();
}
const dsc* getParam(FB_SIZE_T idx)
{
fillParams();
if (/*idx >= 0 &&*/ idx < m_descs.getCount())
return &m_descs[idx];
return NULL;
}
operator Firebird::ITraceParams* ()
{
return &m_traceParams;
}
protected:
virtual void fillParams() = 0;
Firebird::HalfStaticArray<dsc, 16> m_descs;
private:
TraceParamsImpl m_traceParams;
};
class TraceDscFromValues : public TraceDescriptors
{
public:
TraceDscFromValues(Firebird::MemoryPool& pool, jrd_req* request, const ValueListNode* params) :
TraceDescriptors(pool),
m_request(request),
m_params(params)
{}
protected:
void fillParams();
private:
jrd_req* m_request;
const ValueListNode* m_params;
};
class TraceDscFromMsg : public TraceDescriptors
{
public:
TraceDscFromMsg(Firebird::MemoryPool& pool, const Format* format,
const UCHAR* inMsg, ULONG inMsgLength) :
TraceDescriptors(pool),
m_format(format),
m_inMsg(inMsg),
m_inMsgLength(inMsgLength)
{}
protected:
void fillParams();
private:
const Format* m_format;
const UCHAR* m_inMsg;
ULONG m_inMsgLength;
};
class TraceDscFromDsc : public TraceDescriptors
{
public:
TraceDscFromDsc(Firebird::MemoryPool& pool, const dsc* desc) :
TraceDescriptors(pool)
{
if (desc)
m_descs.add(*desc);
else
{
m_descs.grow(1);
m_descs[0].setNull();
}
}
protected:
void fillParams() {}
};
class TraceProcedureImpl :
public Firebird::AutoIface<Firebird::ITraceProcedureImpl<TraceProcedureImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceProcedureImpl(jrd_req* request, PerformanceInfo* perf) :
m_request(request),
m_perf(perf),
m_inputs(*getDefaultMemoryPool(), request->req_proc_caller, request->req_proc_inputs),
m_name(m_request->getStatement()->procedure->getName().toString())
{}
// TraceProcedure implementation
const char* getProcName()
{
return m_name.c_str();
}
Firebird::ITraceParams* getInputs() { return m_inputs; }
PerformanceInfo* getPerf() { return m_perf; };
private:
jrd_req* const m_request;
PerformanceInfo* const m_perf;
TraceDscFromValues m_inputs;
Firebird::string m_name;
};
class TraceFunctionImpl :
public Firebird::AutoIface<Firebird::ITraceFunctionImpl<TraceFunctionImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceFunctionImpl(jrd_req* request, Firebird::ITraceParams* inputs, PerformanceInfo* perf, const dsc* value) :
m_request(request),
m_perf(perf),
m_inputs(inputs),
m_value(*getDefaultMemoryPool(), value),
m_name(m_request->getStatement()->function->getName().toString())
{}
// TraceFunction implementation
const char* getFuncName()
{
return m_name.c_str();
}
Firebird::ITraceParams* getInputs() { return m_inputs; }
Firebird::ITraceParams* getResult() { return m_value; }
PerformanceInfo* getPerf() { return m_perf; };
private:
jrd_req* const m_request;
PerformanceInfo* const m_perf;
Firebird::ITraceParams* m_inputs;
TraceDscFromDsc m_value;
Firebird::string m_name;
};
class TraceTriggerImpl :
public Firebird::AutoIface<Firebird::ITraceTriggerImpl<TraceTriggerImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceTriggerImpl(const jrd_req* trig, SSHORT which, PerformanceInfo* perf) :
m_trig(trig),
m_which(which),
m_perf(perf)
{}
// TraceTrigger implementation
const char* getTriggerName();
const char* getRelationName();
int getAction() { return m_trig->req_trigger_action; }
int getWhich() { return m_which; }
PerformanceInfo* getPerf() { return m_perf; }
private:
const jrd_req* const m_trig;
const SSHORT m_which;
PerformanceInfo* const m_perf;
};
class TraceServiceImpl :
public Firebird::AutoIface<Firebird::ITraceServiceConnectionImpl<TraceServiceImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceServiceImpl(const Service* svc) :
m_svc(svc)
{}
// TraceConnection implementation
unsigned getKind();
const char* getUserName();
const char* getRoleName();
const char* getCharSet();
int getProcessID();
const char* getRemoteProtocol();
const char* getRemoteAddress();
int getRemoteProcessID();
const char* getRemoteProcessName();
// TraceServiceConnection implementation
void* getServiceID();
const char* getServiceMgr();
const char* getServiceName();
private:
const Service* const m_svc;
};
class TraceRuntimeStats
{
public:
TraceRuntimeStats(Attachment* att, RuntimeStatistics* baseline, RuntimeStatistics* stats,
SINT64 clock, SINT64 records_fetched);
PerformanceInfo* getPerf() { return &m_info; }
private:
PerformanceInfo m_info;
TraceCountsArray m_counts;
static SINT64 m_dummy_counts[RuntimeStatistics::TOTAL_ITEMS]; // Zero-initialized array with zero counts
};
class TraceInitInfoImpl :
public Firebird::AutoIface<Firebird::ITraceInitInfoImpl<TraceInitInfoImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceInitInfoImpl(const Firebird::TraceSession& session, const Attachment* att,
const char* filename) :
m_session(session),
m_trace_conn(att),
m_filename(filename),
m_attachment(att)
{
if (m_attachment && !m_attachment->att_filename.empty()) {
m_filename = m_attachment->att_filename.c_str();
}
}
// TraceInitInfo implementation
const char* getConfigText() { return m_session.ses_config.c_str(); }
int getTraceSessionID() { return m_session.ses_id; }
const char* getTraceSessionName() { return m_session.ses_name.c_str(); }
const char* getFirebirdRootDirectory();
const char* getDatabaseName() { return m_filename; }
Firebird::ITraceDatabaseConnection* getConnection()
{
if (m_attachment)
return &m_trace_conn;
return NULL;
}
Firebird::ITraceLogWriter* getLogWriter();
private:
const Firebird::TraceSession& m_session;
Firebird::RefPtr<Firebird::ITraceLogWriter> m_logWriter;
TraceConnectionImpl m_trace_conn;
const char* m_filename;
const Attachment* const m_attachment;
};
class TraceStatusVectorImpl :
public Firebird::AutoIface<Firebird::ITraceStatusVectorImpl<TraceStatusVectorImpl, Firebird::CheckStatusWrapper> >
{
public:
enum Kind {TS_ERRORS, TS_WARNINGS};
TraceStatusVectorImpl(FbStatusVector* status, Kind k) :
m_status(status), kind(k)
{
}
FB_BOOLEAN hasError()
{
return m_status->getState() & Firebird::IStatus::STATE_ERRORS;
}
FB_BOOLEAN hasWarning()
{
return m_status->getState() & Firebird::IStatus::STATE_WARNINGS;
}
Firebird::IStatus* getStatus()
{
return m_status;
}
const char* getText();
private:
Firebird::string m_error;
FbStatusVector* m_status;
Kind kind;
};
class TraceSweepImpl :
public Firebird::AutoIface<Firebird::ITraceSweepInfoImpl<TraceSweepImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceSweepImpl()
{
m_oit = 0;
m_ost = 0;
m_oat = 0;
m_next = 0;
m_perf = 0;
}
void update(const Ods::header_page* header)
{
m_oit = header->hdr_oldest_transaction;
m_ost = header->hdr_oldest_snapshot;
m_oat = header->hdr_oldest_active;
m_next = header->hdr_next_transaction;
}
void setPerf(PerformanceInfo* perf)
{
m_perf = perf;
}
ISC_UINT64 getOIT() { return m_oit; };
ISC_UINT64 getOST() { return m_ost; };
ISC_UINT64 getOAT() { return m_oat; };
ISC_UINT64 getNext() { return m_next; };
PerformanceInfo* getPerf() { return m_perf; };
private:
TraNumber m_oit;
TraNumber m_ost;
TraNumber m_oat;
TraNumber m_next;
PerformanceInfo* m_perf;
};
} // namespace Jrd
#endif // JRD_TRACE_OBJECTS_H