~drizzle-trunk/drizzle/development

1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
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.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
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
 *
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
28
 * Implements the PRINT_TRANSACTION_MESSAGE(filename, offset) UDF.
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
29
 */
30
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
31
#include "config.h"
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
32
#include <drizzled/plugin/function.h>
33
#include <drizzled/item/func.h>
34
#include <drizzled/function/str/strfunc.h>
35
#include <drizzled/error.h>
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
36
#include "drizzled/internal/my_sys.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
37
#include "drizzled/charset.h"
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
38
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
39
#include <fcntl.h>
1702.3.3 by LinuxJedi
Fix errors in FreeBSD build
40
#include <errno.h>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
41
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
42
#include "transaction_log.h"
43
#include "print_transaction_message.h"
44
45
#include <drizzled/message/transaction.pb.h>
1764.1.1 by David Shrewsbury
Validate message type and size when reading from transaction log; fix potential memory leaks
46
#include <drizzled/replication_services.h>
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
47
#include <google/protobuf/io/zero_copy_stream.h>
48
#include <google/protobuf/io/zero_copy_stream_impl.h>
49
#include <google/protobuf/io/coded_stream.h>
50
#include <google/protobuf/text_format.h>
51
52
using namespace std;
53
using namespace drizzled;
54
using namespace google;
55
56
/** Defined in transaction_log.cc */
57
extern TransactionLog *transaction_log;
58
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
59
plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory= NULL;
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
60
61
void PrintTransactionMessageFunction::fix_length_and_dec()
62
{
63
  max_length= 2 * 1024 * 1024; /* 2MB size limit seems ok... */
64
  args[0]->collation.set(
65
    get_charset_by_csname(args[0]->collation.collation->csname,
66
                          MY_CS_BINSORT), DERIVATION_COERCIBLE);
67
}
68
69
String *PrintTransactionMessageFunction::val_str(String *str)
70
{
71
  assert(fixed == true);
72
73
  String *filename_arg= args[0]->val_str(str);
74
  off_t offset_arg= static_cast<int64_t>(args[1]->val_int());
75
76
  if (filename_arg == NULL || args[1]->null_value == true)
77
  {
78
    my_error(ER_INVALID_NULL_ARGUMENT, MYF(0), func_name());
79
    null_value= true;
80
    return NULL;
81
  }
82
83
  if (transaction_log == NULL)
84
  {
85
    my_error(ER_INVALID_NULL_ARGUMENT, MYF(0), func_name());
86
    null_value= true;
87
    return NULL;
88
  }
89
90
  null_value= false;
91
92
  message::Transaction transaction_message;
93
94
  /**
95
   * @todo Of course, this is not efficient to create a
96
   * new input stream every time we call the UDF.  Create
97
   * a pool of TransactionLogReader objects that can be 
98
   * re-used.
99
   */
100
  const string &filename= transaction_log->getLogFilename();
101
  int log_file= open(filename.c_str(), O_RDONLY);
102
  if (log_file == -1)
103
  {
1702.3.2 by LinuxJedi
Migrate the rest of strerror to strerror_r
104
    char errmsg[STRERROR_MAX];
105
    strerror_r(errno, errmsg, sizeof(errmsg));
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
106
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to open transaction log file %s.  Got error: %s\n"), 
107
                  filename.c_str(), 
1702.3.2 by LinuxJedi
Migrate the rest of strerror to strerror_r
108
                  errmsg);
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
109
    null_value= true;
110
    return NULL;
111
  }
112
113
  (void) lseek(log_file, offset_arg, SEEK_SET);
114
115
  protobuf::io::FileInputStream *file_input= new protobuf::io::FileInputStream(log_file);
116
  file_input->SetCloseOnDelete(true);
117
118
  protobuf::io::CodedInputStream *coded_input= new protobuf::io::CodedInputStream(file_input);
119
120
  /* Grab our message type and length */
121
  uint32_t message_type;
122
  if (! coded_input->ReadLittleEndian32(&message_type))
123
  {
1764.1.1 by David Shrewsbury
Validate message type and size when reading from transaction log; fix potential memory leaks
124
    delete coded_input;
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
125
    delete file_input;
126
127
    /** @todo Error message for this... */
128
    null_value= true;
129
    return NULL;
130
  }
131
1764.1.1 by David Shrewsbury
Validate message type and size when reading from transaction log; fix potential memory leaks
132
  /* Validate message type */
133
  if (message_type != ReplicationServices::TRANSACTION)
134
  {
135
    fprintf(stderr, _("GPB message is not a valid type.\n"));
136
    delete coded_input;
137
    delete file_input;
138
    null_value= true;
139
    return NULL;
140
  }
141
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
142
  uint32_t message_size;
143
  if (! coded_input->ReadLittleEndian32(&message_size))
144
  {
1764.1.1 by David Shrewsbury
Validate message type and size when reading from transaction log; fix potential memory leaks
145
    delete coded_input;
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
146
    delete file_input;
147
148
    /** @todo Error message for this... */
149
    null_value= true;
150
    return NULL;
151
  }
152
1764.1.1 by David Shrewsbury
Validate message type and size when reading from transaction log; fix potential memory leaks
153
  if (message_size > INT_MAX)
154
  {
155
    fprintf(stderr, _("GPB message is not a valid size.\n"));
156
    delete coded_input;
157
    delete file_input;
158
    null_value= true;
159
    return NULL;
160
  }
161
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
162
  uint8_t *buffer= (uint8_t *) malloc(message_size);
163
164
  bool result= coded_input->ReadRaw(buffer, message_size);
165
  if (result == false)
166
  {
1702.3.2 by LinuxJedi
Migrate the rest of strerror to strerror_r
167
    char errmsg[STRERROR_MAX];
168
    strerror_r(errno, errmsg, sizeof(errmsg));
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
169
    fprintf(stderr, _("Could not read transaction message.\n"));
1702.3.2 by LinuxJedi
Migrate the rest of strerror to strerror_r
170
    fprintf(stderr, _("GPB ERROR: %s.\n"), errmsg);
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
171
    fprintf(stderr, _("Raw buffer read: %s.\n"), buffer);
172
  }
173
174
  result= transaction_message.ParseFromArray(buffer, static_cast<int32_t>(message_size));
175
  if (result == false)
176
  {
177
    fprintf(stderr, _("Unable to parse transaction. Got error: %s.\n"), transaction_message.InitializationErrorString().c_str());
178
    if (buffer != NULL)
179
      fprintf(stderr, _("BUFFER: %s\n"), buffer);
180
  }
181
182
  free(buffer);
183
184
  string transaction_text;
185
  protobuf::TextFormat::PrintToString(transaction_message, &transaction_text);
186
1802.12.1 by Brian Aker
This solves bug lp:654905
187
  std::string::size_type begin_uuid;
188
  while ((begin_uuid= transaction_text.find("uuid")) != string::npos)
189
  {
190
    std::string::size_type end_uuid= transaction_text.find('\n', begin_uuid); 
191
    if (end_uuid != string::npos)
192
    {
193
      transaction_text.erase(begin_uuid, end_uuid - begin_uuid);
194
    }
195
  }
196
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
197
  if (str->alloc(transaction_text.length()))
198
  {
1764.1.1 by David Shrewsbury
Validate message type and size when reading from transaction log; fix potential memory leaks
199
    delete coded_input;
200
    delete file_input;
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
201
    null_value= true;
202
    return NULL;
203
  }
204
205
  str->length(transaction_text.length());
206
207
  strncpy(str->ptr(), transaction_text.c_str(), transaction_text.length());
208
1143.3.9 by Jay Pipes
Fixes information schema tests, adds a hexdump UDF for the transaction message.
209
  delete coded_input;
1143.3.4 by Jay Pipes
Adds INFORMATION_SCHEMA views for the transaction log:
210
  delete file_input;
211
212
  return str;
213
}