~drizzle-trunk/drizzle/development

1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2009 Sun Microsystems, Inc.
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
5
 *
6
 *  Authors:
7
 *
8
 *  Jay Pipes <joinfu@sun.com>
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program; if not, write to the Free Software
22
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23
 */
24
25
/**
26
 * @file
27
 *
28
 * Implements the HEXDUMP_TRANSACTION_MESSAGE(filename, offset) UDF.
29
 */
30
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
31
#include <config.h>
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
32
#include <drizzled/plugin/function.h>
33
#include <drizzled/item/func.h>
34
#include <drizzled/function/str/strfunc.h>
35
#include <drizzled/error.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
36
#include <drizzled/internal/my_sys.h>
37
#include <drizzled/charset.h>
2148.7.12 by Brian Aker
Merge in header fixes.
38
#include <drizzled/errmsg_print.h>
39
#include <drizzled/gettext.h>
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
40
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
41
#include <fcntl.h>
1702.3.3 by LinuxJedi
Fix errors in FreeBSD build
42
#include <errno.h>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
43
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
44
#include "transaction_log.h"
45
#include "hexdump_transaction_message.h"
46
47
#include <drizzled/message/transaction.pb.h>
48
#include <drizzled/util/convert.h>
49
#include <google/protobuf/io/zero_copy_stream.h>
50
#include <google/protobuf/io/zero_copy_stream_impl.h>
51
#include <google/protobuf/io/coded_stream.h>
52
#include <google/protobuf/text_format.h>
53
54
using namespace std;
55
using namespace drizzled;
56
using namespace google;
57
58
/** Defined in transaction_log.cc */
59
extern TransactionLog *transaction_log;
60
61
plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory= NULL;
62
63
void HexdumpTransactionMessageFunction::fix_length_and_dec()
64
{
65
  max_length= 2 * 1024 * 1024; /* 2MB size limit seems ok... */
66
  args[0]->collation.set(
67
    get_charset_by_csname(args[0]->collation.collation->csname,
68
                          MY_CS_BINSORT), DERIVATION_COERCIBLE);
69
}
70
71
String *HexdumpTransactionMessageFunction::val_str(String *str)
72
{
73
  assert(fixed == true);
74
75
  String *filename_arg= args[0]->val_str(str);
76
  off_t offset_arg= static_cast<int64_t>(args[1]->val_int());
77
78
  if (filename_arg == NULL || args[1]->null_value == true)
79
  {
80
    my_error(ER_INVALID_NULL_ARGUMENT, MYF(0), func_name());
81
    null_value= true;
82
    return NULL;
83
  }
84
85
  if (transaction_log == NULL)
86
  {
87
    my_error(ER_INVALID_NULL_ARGUMENT, MYF(0), func_name());
88
    null_value= true;
89
    return NULL;
90
  }
91
92
  null_value= false;
93
94
  message::Transaction transaction_message;
95
96
  /**
97
   * @todo Of course, this is not efficient to create a
98
   * new input stream every time we call the UDF.  Create
99
   * a pool of TransactionLogReader objects that can be 
100
   * re-used.
101
   */
102
  const string &filename= transaction_log->getLogFilename();
103
  int log_file= open(filename.c_str(), O_RDONLY);
104
  if (log_file == -1)
105
  {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
106
    drizzled::sql_perror(_("Failed to open transaction log file"), filename);
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
107
    null_value= true;
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
108
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
109
    return NULL;
110
  }
111
112
  (void) lseek(log_file, offset_arg, SEEK_SET);
113
114
  protobuf::io::FileInputStream *file_input= new protobuf::io::FileInputStream(log_file);
115
  file_input->SetCloseOnDelete(true);
116
117
  protobuf::io::CodedInputStream *coded_input= new protobuf::io::CodedInputStream(file_input);
118
119
  /* Grab our message type and length */
120
  uint32_t message_type;
121
  if (! coded_input->ReadLittleEndian32(&message_type))
122
  {
123
    delete file_input;
124
125
    /** @todo Error message for this... */
126
    null_value= true;
127
    return NULL;
128
  }
129
130
  uint32_t message_size;
131
  if (! coded_input->ReadLittleEndian32(&message_size))
132
  {
133
    delete file_input;
134
135
    /** @todo Error message for this... */
136
    null_value= true;
137
    return NULL;
138
  }
139
140
  uint8_t *buffer= (uint8_t *) malloc(message_size);
141
142
  bool result= coded_input->ReadRaw(buffer, message_size);
143
  if (result == false)
144
  {
1702.3.2 by LinuxJedi
Migrate the rest of strerror to strerror_r
145
    char errmsg[STRERROR_MAX];
146
    strerror_r(errno, errmsg, sizeof(errmsg));
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
147
    fprintf(stderr, _("Could not read transaction message.\n"));
1702.3.2 by LinuxJedi
Migrate the rest of strerror to strerror_r
148
    fprintf(stderr, _("GPB ERROR: %s.\n"), errmsg);
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
149
    fprintf(stderr, _("Raw buffer read: %s.\n"), buffer);
150
  }
151
152
  /*
153
   * Convert raw bytes to a hex representation and store back into
154
   * the return String.
155
   */
156
  string hexdump;
157
  hexdump.reserve(message_size * 4);
158
  bytesToHexdumpFormat(hexdump, reinterpret_cast<const unsigned char *>(buffer), message_size);
159
160
  /* 
161
   * Check that the transaction message is actually not corrupt before
162
   * printing out the raw byte representation of the transaction message...
163
   */
164
  result= transaction_message.ParseFromArray(buffer, static_cast<int32_t>(message_size));
165
  if (result == false)
166
  {
167
    fprintf(stderr, _("Unable to parse transaction. Got error: %s.\n"), transaction_message.InitializationErrorString().c_str());
168
    if (buffer != NULL)
169
      fprintf(stderr, _("BUFFER: %s\n"), buffer);
170
  }
171
2275.2.12 by Olaf van der Spek
Return void
172
  str->alloc(message_size * 4); /* Hex representation is ~4 times number of bytes */
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
173
174
  strncpy(str->ptr(), hexdump.c_str(), hexdump.length());
175
  str->length(hexdump.length());
176
177
  free(buffer);
178
179
  delete coded_input;
180
  delete file_input;
181
182
  return str;
183
}