2006-07-17 19:44:18 +02:00
|
|
|
/*
|
|
|
|
* 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 Dmitry Yemanov
|
|
|
|
* for the Firebird Open Source RDBMS project.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2006 Dmitry Yemanov <dimitr@users.sf.net>
|
|
|
|
* and all contributors signed below.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <process.h>
|
|
|
|
|
|
|
|
#include "firebird.h"
|
|
|
|
#include "ids.h"
|
|
|
|
#include "../jrd/gdsassert.h"
|
|
|
|
#include "../jrd/jrd.h"
|
|
|
|
#include "../jrd/cch.h"
|
|
|
|
#include "../jrd/ini.h"
|
|
|
|
#include "../jrd/os/pio.h"
|
|
|
|
#include "../jrd/req.h"
|
|
|
|
#include "../jrd/tra.h"
|
|
|
|
#include "../jrd/blb_proto.h"
|
|
|
|
#include "../jrd/met_proto.h"
|
|
|
|
#include "../jrd/pag_proto.h"
|
|
|
|
#include "../jrd/os/pio_proto.h"
|
|
|
|
|
|
|
|
#include "../jrd/Relation.h"
|
|
|
|
#include "../jrd/RecordBuffer.h"
|
|
|
|
#include "../jrd/DatabaseSnapshot.h"
|
|
|
|
|
|
|
|
using namespace Jrd;
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
DatabaseSnapshot* DatabaseSnapshot::create(thread_db* tdbb)
|
|
|
|
{
|
2006-07-18 08:00:52 +02:00
|
|
|
SET_TDBB(tdbb);
|
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
jrd_tra* transaction = tdbb->tdbb_transaction;
|
|
|
|
fb_assert(transaction);
|
|
|
|
|
|
|
|
if (!transaction->tra_db_snapshot)
|
|
|
|
{
|
|
|
|
MemoryPool& pool = *transaction->tra_pool;
|
|
|
|
transaction->tra_db_snapshot =
|
2006-07-18 08:00:52 +02:00
|
|
|
FB_NEW(pool) DatabaseSnapshot(tdbb, pool, transaction);
|
2006-07-17 19:44:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return transaction->tra_db_snapshot;
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
RecordBuffer* DatabaseSnapshot::allocBuffer(thread_db* tdbb,
|
|
|
|
MemoryPool& pool,
|
|
|
|
int rel_id)
|
|
|
|
{
|
|
|
|
jrd_rel* relation = MET_lookup_relation_id(tdbb, rel_id, false);
|
2006-07-19 17:22:10 +02:00
|
|
|
fb_assert(relation);
|
2006-07-17 19:44:18 +02:00
|
|
|
MET_scan_relation(tdbb, relation);
|
2006-07-19 17:22:10 +02:00
|
|
|
fb_assert(relation->isVirtual());
|
2006-07-17 19:44:18 +02:00
|
|
|
Format* format = MET_current(tdbb, relation);
|
|
|
|
fb_assert(format);
|
|
|
|
|
|
|
|
RecordBuffer* buffer = FB_NEW(pool) RecordBuffer(pool, format);
|
|
|
|
RelationData data = {relation->rel_id, buffer};
|
|
|
|
snapshot.add(data);
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-18 08:00:52 +02:00
|
|
|
DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool, jrd_tra* tran)
|
2006-07-17 19:44:18 +02:00
|
|
|
: transaction(tran), snapshot(pool)
|
|
|
|
{
|
|
|
|
Database* dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
// Database information
|
|
|
|
|
|
|
|
putDatabase(dbb, allocBuffer(tdbb, pool, rel_mon_database));
|
|
|
|
|
|
|
|
// Attachment information
|
|
|
|
|
|
|
|
RecordBuffer* att_buffer =
|
|
|
|
allocBuffer(tdbb, pool, rel_mon_attachments);
|
|
|
|
RecordBuffer* tra_buffer =
|
|
|
|
allocBuffer(tdbb, pool, rel_mon_transactions);
|
|
|
|
RecordBuffer* req_buffer =
|
|
|
|
allocBuffer(tdbb, pool, rel_mon_statements);
|
|
|
|
|
|
|
|
for (Attachment* attachment = dbb->dbb_attachments;
|
|
|
|
attachment; attachment = attachment->att_next)
|
|
|
|
{
|
|
|
|
putAttachment(attachment, att_buffer);
|
|
|
|
|
|
|
|
// Transaction information
|
|
|
|
|
|
|
|
for (jrd_tra* transaction = attachment->att_transactions;
|
|
|
|
transaction; transaction = transaction->tra_next)
|
|
|
|
{
|
|
|
|
putTransaction(transaction, tra_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Request information
|
|
|
|
|
|
|
|
for (jrd_req* request = attachment->att_requests;
|
|
|
|
request; request = request->req_request)
|
|
|
|
{
|
|
|
|
// Ignore GDML requests
|
2006-07-17 21:26:43 +02:00
|
|
|
if (request->req_sql_text.hasData() || request->req_caller)
|
2006-07-17 19:44:18 +02:00
|
|
|
{
|
|
|
|
putRequest(request, req_buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
DatabaseSnapshot::~DatabaseSnapshot()
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < snapshot.getCount(); i++)
|
|
|
|
{
|
|
|
|
delete snapshot[i].data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
RecordBuffer* DatabaseSnapshot::getData(const jrd_rel* relation) const
|
|
|
|
{
|
|
|
|
fb_assert(relation);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < snapshot.getCount(); i++)
|
|
|
|
{
|
|
|
|
if (snapshot[i].rel_id == relation->rel_id)
|
|
|
|
return snapshot[i].data;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
|
|
|
void DatabaseSnapshot::clearRecord(Record* record)
|
|
|
|
{
|
|
|
|
// Initialize all fields to NULLs
|
|
|
|
memset(record->rec_data, 0, record->rec_length);
|
|
|
|
const size_t null_bytes = (record->rec_format->fmt_count + 7) >> 3;
|
|
|
|
memset(record->rec_data, 0xFF, null_bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
void DatabaseSnapshot::putField(Record* record, int id, const void* source)
|
|
|
|
{
|
|
|
|
fb_assert(record);
|
|
|
|
|
|
|
|
const Format* const format = record->rec_format;
|
|
|
|
fb_assert(format && id < format->fmt_count);
|
|
|
|
|
|
|
|
if (!source) {
|
|
|
|
SET_NULL(record, id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dsc desc = format->fmt_desc[id];
|
|
|
|
UCHAR* const address = record->rec_data + (IPTR) desc.dsc_address;
|
|
|
|
|
|
|
|
switch (desc.dsc_dtype) {
|
|
|
|
case dtype_text:
|
|
|
|
{
|
|
|
|
const char* const string = (char*) source;
|
|
|
|
const size_t max_length = desc.dsc_length;
|
|
|
|
const size_t length = MIN(strlen(string), max_length);
|
|
|
|
memcpy(address, string, length);
|
|
|
|
memcpy(address + length, " ", max_length - length);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case dtype_varying:
|
|
|
|
{
|
|
|
|
const char* const string = (char*) source;
|
|
|
|
const size_t max_length = desc.dsc_length - sizeof(USHORT);
|
|
|
|
const size_t length = MIN(strlen(string), max_length);
|
|
|
|
vary* varying = (vary*) address;
|
|
|
|
varying->vary_length = length;
|
|
|
|
memcpy(varying->vary_string, string, length);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_short:
|
|
|
|
*(SSHORT*) address = *(SSHORT*) source;
|
|
|
|
break;
|
|
|
|
case dtype_long:
|
|
|
|
*(SLONG*) address = *(SLONG*) source;
|
|
|
|
break;
|
|
|
|
case dtype_int64:
|
|
|
|
*(SINT64*) address = *(SINT64*) source;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_real:
|
|
|
|
*(float*) address = *(float*) source;
|
|
|
|
break;
|
|
|
|
case dtype_double:
|
|
|
|
*(double*) address = *(double*) source;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_sql_date:
|
|
|
|
*(ISC_DATE*) address = *(ISC_DATE*) source;
|
|
|
|
break;
|
|
|
|
case dtype_sql_time:
|
|
|
|
*(ISC_TIME*) address = *(ISC_TIME*) source;
|
|
|
|
break;
|
|
|
|
case dtype_timestamp:
|
|
|
|
*(ISC_TIMESTAMP*) address = *(ISC_TIMESTAMP*) source;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_blob:
|
|
|
|
{
|
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
|
|
|
|
|
|
|
bid blob_id;
|
|
|
|
blb* blob = BLB_create2(tdbb, transaction, &blob_id, 0, NULL);
|
|
|
|
|
|
|
|
const char* const string = (char*) source;
|
|
|
|
const size_t length = MIN(strlen(string), MAX_USHORT);
|
|
|
|
|
|
|
|
BLB_put_segment(tdbb, blob, (UCHAR*) string, length);
|
|
|
|
BLB_close(tdbb, blob);
|
|
|
|
|
|
|
|
*(bid*) address = blob_id;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
fb_assert(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
CLEAR_NULL(record, id);
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
void DatabaseSnapshot::putDatabase(Database* dbb, RecordBuffer* buffer)
|
|
|
|
{
|
|
|
|
fb_assert(dbb && buffer);
|
|
|
|
|
|
|
|
// Reload header
|
|
|
|
const PageSpace* const pageSpace =
|
|
|
|
dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
|
|
|
const jrd_file* const file = pageSpace->file;
|
|
|
|
PAG_header(file->fil_string, file->fil_length, true);
|
|
|
|
|
|
|
|
Record* record = buffer->getTempRecord();
|
2006-07-17 21:26:43 +02:00
|
|
|
|
|
|
|
// Initialize all fields to NULLs
|
|
|
|
clearRecord(record);
|
2006-07-17 19:44:18 +02:00
|
|
|
|
|
|
|
SSHORT temp_short;
|
2006-07-17 21:26:43 +02:00
|
|
|
// SLONG temp_long;
|
2006-07-17 19:44:18 +02:00
|
|
|
SINT64 temp_int64;
|
|
|
|
|
|
|
|
// database name or alias
|
|
|
|
putField(record, f_mon_db_name, dbb->dbb_database_name.c_str());
|
|
|
|
// page size
|
|
|
|
putField(record, f_mon_db_page_size, &dbb->dbb_page_size);
|
|
|
|
// major ODS version
|
|
|
|
putField(record, f_mon_db_ods_major, &dbb->dbb_ods_version);
|
|
|
|
// minor ODS version
|
|
|
|
putField(record, f_mon_db_ods_minor, &dbb->dbb_minor_version);
|
|
|
|
// oldest interesting transaction
|
|
|
|
putField(record, f_mon_db_oit, &dbb->dbb_oldest_transaction);
|
|
|
|
// oldest active transaction
|
|
|
|
putField(record, f_mon_db_oat, &dbb->dbb_oldest_active);
|
|
|
|
// oldest snapshot transaction
|
|
|
|
putField(record, f_mon_db_ost, &dbb->dbb_oldest_snapshot);
|
|
|
|
// next transaction
|
|
|
|
putField(record, f_mon_db_nt, &dbb->dbb_next_transaction);
|
|
|
|
// number of page buffers
|
|
|
|
putField(record, f_mon_db_page_bufs, &dbb->dbb_bcb->bcb_count);
|
|
|
|
// SQL dialect
|
|
|
|
temp_short = (dbb->dbb_flags & DBB_DB_SQL_dialect_3) ? 3 : 1;
|
|
|
|
putField(record, f_mon_db_dialect, &temp_short);
|
|
|
|
// shutdown mode
|
|
|
|
if (dbb->dbb_ast_flags & DBB_shutdown_full)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = shut_mode_full;
|
2006-07-17 19:44:18 +02:00
|
|
|
else if (dbb->dbb_ast_flags & DBB_shutdown_single)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = shut_mode_single;
|
2006-07-17 19:44:18 +02:00
|
|
|
else if (dbb->dbb_ast_flags & DBB_shutdown)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = shut_mode_multi;
|
2006-07-17 19:44:18 +02:00
|
|
|
else
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = shut_mode_online;
|
2006-07-17 19:44:18 +02:00
|
|
|
putField(record, f_mon_db_shut_mode, &temp_short);
|
|
|
|
// sweep interval
|
|
|
|
putField(record, f_mon_db_sweep_int, &dbb->dbb_sweep_interval);
|
|
|
|
// read only flag
|
|
|
|
temp_short = (dbb->dbb_flags & DBB_read_only) ? 1 : 0;
|
|
|
|
putField(record, f_mon_db_read_only, &temp_short);
|
|
|
|
// forced writes flag
|
|
|
|
temp_short = (dbb->dbb_flags & DBB_force_write) ? 1 : 0;
|
|
|
|
putField(record, f_mon_db_forced_writes, &temp_short);
|
|
|
|
// reserve space flag
|
|
|
|
temp_short = (dbb->dbb_flags & DBB_no_reserve) ? 0 : 1;
|
|
|
|
putField(record, f_mon_db_res_space, &temp_short);
|
|
|
|
// creation date
|
|
|
|
putField(record, f_mon_db_created, &dbb->dbb_creation_date.value());
|
|
|
|
// database size
|
|
|
|
temp_int64 = PIO_act_alloc(dbb);
|
|
|
|
putField(record, f_mon_db_size, &temp_int64);
|
|
|
|
// current memory usage
|
|
|
|
temp_int64 = dbb->dbb_memory_stats.get_current_usage();
|
|
|
|
putField(record, f_mon_db_cur_mem, &temp_int64);
|
|
|
|
// maximum memory usage
|
|
|
|
temp_int64 = dbb->dbb_memory_stats.get_maximum_usage();
|
|
|
|
putField(record, f_mon_db_max_mem, &temp_int64);
|
|
|
|
// page reads
|
|
|
|
temp_int64 = dbb->dbb_reads;
|
|
|
|
putField(record, f_mon_db_page_reads, &temp_int64);
|
|
|
|
// page writes
|
|
|
|
temp_int64 = dbb->dbb_writes;
|
|
|
|
putField(record, f_mon_db_page_writes, &temp_int64);
|
|
|
|
// page fetches
|
|
|
|
temp_int64 = dbb->dbb_fetches;
|
|
|
|
putField(record, f_mon_db_page_fetches, &temp_int64);
|
|
|
|
// page marks
|
|
|
|
temp_int64 = dbb->dbb_marks;
|
|
|
|
putField(record, f_mon_db_page_marks, &temp_int64);
|
|
|
|
|
|
|
|
buffer->store(record);
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
void DatabaseSnapshot::putAttachment(Attachment* attachment, RecordBuffer* buffer)
|
|
|
|
{
|
|
|
|
fb_assert(attachment && buffer);
|
|
|
|
|
|
|
|
Record* record = buffer->getTempRecord();
|
2006-07-17 21:26:43 +02:00
|
|
|
|
|
|
|
// Initialize all fields to NULLs
|
|
|
|
clearRecord(record);
|
2006-07-17 19:44:18 +02:00
|
|
|
|
|
|
|
SSHORT temp_short;
|
|
|
|
SLONG temp_long;
|
2006-07-17 21:26:43 +02:00
|
|
|
// SINT64 temp_int64;
|
2006-07-17 19:44:18 +02:00
|
|
|
|
2006-07-19 09:07:54 +02:00
|
|
|
SSHORT state = att_s_idle;
|
2006-07-19 07:30:21 +02:00
|
|
|
|
|
|
|
for (jrd_tra* transaction = attachment->att_transactions;
|
|
|
|
transaction; transaction = transaction->tra_next)
|
|
|
|
{
|
|
|
|
if (transaction->tra_requests)
|
2006-07-19 09:07:54 +02:00
|
|
|
state = att_s_active;
|
2006-07-19 07:30:21 +02:00
|
|
|
}
|
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
// attachment id
|
|
|
|
temp_long = PAG_attachment_id(NULL);
|
|
|
|
putField(record, f_mon_att_id, &temp_long);
|
|
|
|
// process id
|
|
|
|
temp_long = getpid();
|
|
|
|
putField(record, f_mon_att_server_pid, &temp_long);
|
2006-07-19 07:30:21 +02:00
|
|
|
// state
|
|
|
|
putField(record, f_mon_att_state, &state);
|
2006-07-17 19:44:18 +02:00
|
|
|
// attachment name
|
|
|
|
putField(record, f_mon_att_name, attachment->att_filename.c_str());
|
|
|
|
// user
|
|
|
|
putField(record, f_mon_att_user, attachment->att_user->usr_user_name);
|
|
|
|
// role
|
|
|
|
putField(record, f_mon_att_role, attachment->att_user->usr_sql_role_name);
|
|
|
|
// remote protocol
|
|
|
|
putField(record, f_mon_att_remote_proto, attachment->att_network_protocol.c_str());
|
|
|
|
// remote address
|
|
|
|
putField(record, f_mon_att_remote_addr, attachment->att_remote_address.c_str());
|
|
|
|
// charset
|
|
|
|
putField(record, f_mon_att_charset_id, &attachment->att_charset);
|
|
|
|
// timestamp
|
|
|
|
putField(record, f_mon_att_timestamp, &attachment->att_timestamp.value());
|
|
|
|
// garbage collection flag
|
|
|
|
temp_short = (attachment->att_flags & ATT_no_cleanup) ? 0 : 1;
|
|
|
|
putField(record, f_mon_att_gc, &temp_short);
|
|
|
|
|
|
|
|
buffer->store(record);
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
void DatabaseSnapshot::putTransaction(jrd_tra* transaction, RecordBuffer* buffer)
|
|
|
|
{
|
|
|
|
fb_assert(transaction && buffer);
|
|
|
|
|
|
|
|
Record* record = buffer->getTempRecord();
|
2006-07-17 21:26:43 +02:00
|
|
|
|
|
|
|
// Initialize all fields to NULLs
|
|
|
|
clearRecord(record);
|
2006-07-17 19:44:18 +02:00
|
|
|
|
|
|
|
SSHORT temp_short;
|
2006-07-17 21:26:43 +02:00
|
|
|
// SLONG temp_long;
|
|
|
|
// SINT64 temp_int64;
|
2006-07-17 19:44:18 +02:00
|
|
|
|
|
|
|
// transaction id
|
|
|
|
putField(record, f_mon_tra_id, &transaction->tra_number);
|
|
|
|
// attachment id
|
|
|
|
putField(record, f_mon_tra_att_id, &transaction->tra_attachment->att_attachment_id);
|
2006-07-19 07:30:21 +02:00
|
|
|
// state
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = transaction->tra_requests ? tra_s_active : tra_s_idle;
|
2006-07-19 07:30:21 +02:00
|
|
|
putField(record, f_mon_tra_state, &temp_short);
|
2006-07-17 19:44:18 +02:00
|
|
|
// timestamp
|
|
|
|
putField(record, f_mon_tra_timestamp, &transaction->tra_timestamp.value());
|
|
|
|
// top transaction
|
|
|
|
putField(record, f_mon_tra_top, &transaction->tra_top);
|
|
|
|
// oldest transaction
|
|
|
|
putField(record, f_mon_tra_oit, &transaction->tra_oldest);
|
|
|
|
// oldest active transaction
|
|
|
|
putField(record, f_mon_tra_oat, &transaction->tra_oldest_active);
|
|
|
|
// isolation mode
|
|
|
|
if (transaction->tra_flags & TRA_degree3)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = iso_mode_consistency;
|
2006-07-17 19:44:18 +02:00
|
|
|
else if (transaction->tra_flags & TRA_read_committed)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = (transaction->tra_flags & TRA_rec_version) ?
|
|
|
|
iso_mode_rc_version : iso_mode_rc_no_version;
|
2006-07-17 19:44:18 +02:00
|
|
|
else
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = iso_mode_concurrency;
|
2006-07-17 19:44:18 +02:00
|
|
|
putField(record, f_mon_tra_iso_mode, &temp_short);
|
|
|
|
// lock timeout
|
|
|
|
putField(record, f_mon_tra_lock_timeout, &transaction->tra_lock_timeout);
|
|
|
|
// read only flag
|
|
|
|
temp_short = (transaction->tra_flags & TRA_readonly) ? 1 : 0;
|
|
|
|
putField(record, f_mon_tra_read_only, &temp_short);
|
|
|
|
// autocommit flag
|
|
|
|
temp_short = (transaction->tra_flags & TRA_autocommit) ? 1 : 0;
|
|
|
|
putField(record, f_mon_tra_auto_commit, &temp_short);
|
|
|
|
// auto undo flag
|
|
|
|
temp_short = (transaction->tra_flags & TRA_no_auto_undo) ? 0 : 1;
|
|
|
|
putField(record, f_mon_tra_auto_undo, &temp_short);
|
|
|
|
|
|
|
|
buffer->store(record);
|
|
|
|
}
|
|
|
|
|
2006-07-17 21:26:43 +02:00
|
|
|
|
2006-07-17 19:44:18 +02:00
|
|
|
void DatabaseSnapshot::putRequest(jrd_req* request, RecordBuffer* buffer)
|
|
|
|
{
|
|
|
|
fb_assert(request && buffer);
|
|
|
|
|
|
|
|
Record* record = buffer->getTempRecord();
|
2006-07-17 21:26:43 +02:00
|
|
|
|
|
|
|
// Initialize all fields to NULLs
|
|
|
|
clearRecord(record);
|
2006-07-17 19:44:18 +02:00
|
|
|
|
|
|
|
SSHORT temp_short;
|
2006-07-17 21:26:43 +02:00
|
|
|
// SLONG temp_long;
|
|
|
|
// SINT64 temp_int64;
|
2006-07-17 19:44:18 +02:00
|
|
|
|
|
|
|
// request id
|
|
|
|
putField(record, f_mon_stmt_id, &request->req_id);
|
|
|
|
// attachment id
|
|
|
|
if (request->req_attachment) {
|
|
|
|
putField(record, f_mon_stmt_att_id,
|
|
|
|
&request->req_attachment->att_attachment_id);
|
|
|
|
}
|
|
|
|
// transaction id
|
|
|
|
if (request->req_transaction) {
|
|
|
|
putField(record, f_mon_stmt_tra_id,
|
|
|
|
&request->req_transaction->tra_number);
|
|
|
|
}
|
|
|
|
// timestamp
|
|
|
|
if (!request->req_timestamp.isEmpty()) {
|
|
|
|
putField(record, f_mon_stmt_timestamp, &request->req_timestamp.value());
|
|
|
|
}
|
|
|
|
// state
|
|
|
|
if (request->req_flags & req_active)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = stmt_s_active;
|
2006-07-17 19:44:18 +02:00
|
|
|
else if (request->req_flags & req_stall)
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = stmt_s_stalled;
|
2006-07-17 19:44:18 +02:00
|
|
|
else
|
2006-07-19 09:07:54 +02:00
|
|
|
temp_short = stmt_s_idle;
|
2006-07-17 19:44:18 +02:00
|
|
|
putField(record, f_mon_stmt_state, &temp_short);
|
|
|
|
// caller
|
|
|
|
if (request->req_caller) {
|
|
|
|
putField(record, f_mon_stmt_caller_id, &request->req_caller->req_id);
|
|
|
|
}
|
|
|
|
// sql text
|
2006-07-17 21:26:43 +02:00
|
|
|
if (request->req_sql_text.hasData()) {
|
2006-07-17 19:44:18 +02:00
|
|
|
putField(record, f_mon_stmt_sql_text, request->req_sql_text.c_str());
|
|
|
|
}
|
|
|
|
// selects
|
|
|
|
putField(record, f_mon_stmt_rec_selects, &request->req_records_selected);
|
|
|
|
// inserts
|
|
|
|
putField(record, f_mon_stmt_rec_inserts, &request->req_records_inserted);
|
|
|
|
// updates
|
|
|
|
putField(record, f_mon_stmt_rec_updates, &request->req_records_updated);
|
|
|
|
// deletes
|
|
|
|
putField(record, f_mon_stmt_rec_deletes, &request->req_records_deleted);
|
|
|
|
|
|
|
|
buffer->store(record);
|
|
|
|
}
|