~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/message/binary_log.cc

  • Committer: Monty Taylor
  • Date: 2010-02-05 08:11:15 UTC
  • mfrom: (1283 build)
  • mto: (1273.13.43 fix_is)
  • mto: This revision was merged to the branch mainline in revision 1300.
  • Revision ID: mordred@inaugust.com-20100205081115-dr82nvrwv4lvw7sd
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#include "config.h"
21
 
#include <drizzled/message/binary_log.h>
22
 
 
23
 
#include <google/protobuf/io/coded_stream.h>
24
 
 
25
 
using namespace google;
26
 
 
27
 
bool
28
 
BinaryLog::Event::write(protobuf::io::CodedOutputStream* out) const
29
 
{
30
 
  // We frame each event in a length encoded in a special manner, and
31
 
  // end it with a CRC-32 checksum.
32
 
 
33
 
  // Write length and type
34
 
  unsigned char buf[LENGTH_ENCODE_MAX_BYTES + 1];
35
 
  unsigned char *end= length_encode(m_message->ByteSize(), buf);
36
 
  *end++= m_type;
37
 
 
38
 
  char cs[4] = { 0 };                           // !!! No checksum yet
39
 
#if GOOGLE_PROTOBUF_VERSION >= 2001000
40
 
  out->WriteRaw(buf, static_cast<int>(end - buf)); // Length + Type
41
 
  if (out->HadError()
42
 
    || !m_message->SerializeToCodedStream(out)) // Event body
43
 
    return false;
44
 
  out->WriteRaw(cs, sizeof(cs)); // Checksum
45
 
  if (out->HadError())
46
 
    return false;
47
 
#else
48
 
  if (!out->WriteRaw(buf, end - buf) ||         // Length + Type
49
 
      !m_message->SerializeToCodedStream(out) || // Event body
50
 
      !out->WriteRaw(cs, sizeof(cs)))           // Checksum
51
 
    return false;
52
 
#endif
53
 
 
54
 
  return true;
55
 
}
56
 
 
57
 
 
58
 
bool
59
 
BinaryLog::Event::read(protobuf::io::CodedInputStream *in)
60
 
{
61
 
  unsigned char buf[LENGTH_ENCODE_MAX_BYTES + 1];
62
 
 
63
 
  // Read length peek byte to figure out length
64
 
  if (!in->ReadRaw(buf, 1))
65
 
    return false;
66
 
 
67
 
  // Read in the rest of the length bytes plus the type
68
 
  size_t bytes= length_decode_bytes(*buf);
69
 
  if (! in->ReadRaw(buf + 1, static_cast<int>(bytes)))
70
 
    return false;
71
 
 
72
 
  size_t length;
73
 
  (void) length_decode(buf, &length);
74
 
 
75
 
  // Fetch type from read buffer
76
 
  m_type= static_cast<EventType>(buf[bytes]);
77
 
 
78
 
  // Create the right event based on the type code (is there something
79
 
  // better in the protobuf library?)
80
 
  protobuf::Message *message= NULL;
81
 
  switch (m_type) {
82
 
  case QUERY:
83
 
    message= new BinaryLog::Query;
84
 
    break;
85
 
 
86
 
  case COMMIT:
87
 
    message= new BinaryLog::Commit;
88
 
    break;
89
 
 
90
 
  case ROLLBACK:
91
 
    message= new BinaryLog::Rollback;
92
 
    break;
93
 
 
94
 
  case START:
95
 
    message= new BinaryLog::Start;
96
 
    break;
97
 
 
98
 
  case CHAIN:
99
 
    message= new BinaryLog::Chain;
100
 
    break;
101
 
 
102
 
  case COUNT:
103
 
  case UNDEF:
104
 
    break;
105
 
  }
106
 
 
107
 
  if (!message)
108
 
    return false;
109
 
 
110
 
  // Read the event body as length bytes. It is necessary to limit the
111
 
  // stream since otherwise ParseFromCodedStream reads all bytes of
112
 
  // the stream.
113
 
  protobuf::io::CodedInputStream::Limit limit= in->PushLimit(static_cast<int>(length));
114
 
  if (!message->ParseFromCodedStream(in))
115
 
    return false;
116
 
  in->PopLimit(limit);
117
 
  delete m_message;
118
 
  m_message= message;
119
 
 
120
 
  // Read checksum (none here yet)
121
 
  char checksum[4];
122
 
  if (!in->ReadRaw(checksum, sizeof(checksum)))
123
 
    return false;
124
 
  return true;
125
 
}
126
 
 
127
 
template <class EventClass>
128
 
void print_common(std::ostream& out, EventClass* event)
129
 
{
130
 
  out << "# Global Id: (" << event->header().server_id() << "," << event->header().trans_id() << ")\n";
131
 
}
132
 
 
133
 
 
134
 
void
135
 
BinaryLog::Event::print(std::ostream& out) const
136
 
{
137
 
  switch (m_type) {
138
 
  case QUERY:
139
 
  {
140
 
    Query *event= static_cast<Query*>(m_message);
141
 
    print_common(out, event);
142
 
    for (protobuf::RepeatedPtrField<Query::Variable>::const_iterator ii=
143
 
           event->variable().begin() ;
144
 
         ii != event->variable().end() ;
145
 
         ++ii)
146
 
    {
147
 
      out << "set @" << ii->name() << " = '" << ii->val() << "'\n";
148
 
    }
149
 
    out << event->query() << std::endl;
150
 
    break;
151
 
  }
152
 
 
153
 
  case COMMIT:
154
 
  {
155
 
    Commit *event= static_cast<Commit*>(m_message);
156
 
    print_common(out, event);
157
 
    // NYI !!!
158
 
    break;
159
 
  }
160
 
 
161
 
  case ROLLBACK:
162
 
  {
163
 
    Rollback *event= static_cast<Rollback*>(m_message);
164
 
    print_common(out, event);
165
 
    // NYI !!!
166
 
    break;
167
 
  }
168
 
 
169
 
  case START:
170
 
  {
171
 
    Start *event= static_cast<Start*>(m_message);
172
 
    print_common(out, event);
173
 
    // NYI !!!
174
 
    break;
175
 
  }
176
 
 
177
 
  case CHAIN:
178
 
  {
179
 
    Chain *event= static_cast<Chain*>(m_message);
180
 
    print_common(out, event);
181
 
    // NYI !!!
182
 
    break;
183
 
  }
184
 
 
185
 
  default:
186
 
    break;                                      /* Nothing */
187
 
  }
188
 
}
189