~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/message/binlog_writer.cc

  • Committer: Brian Aker
  • Date: 2009-11-12 16:13:04 UTC
  • mfrom: (1211.1.7 staging)
  • Revision ID: brian@gaz-20091112161304-opamiauv36fg0n6u
Rollup of Brian, Padraig, and Stewart patches.

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 <drizzled/global.h>
 
21
 
 
22
#include <drizzled/message/binlog_encoding.h>
 
23
#include <drizzled/message/binary_log.h>
 
24
 
 
25
#include "drizzled/message/ioutil.h"
 
26
 
 
27
#include <google/protobuf/io/zero_copy_stream_impl.h>
 
28
#include <google/protobuf/io/coded_stream.h>
 
29
 
 
30
#include <iostream>
 
31
#include <fstream>
 
32
#include <sstream>
 
33
#include <string>
 
34
#include <map>
 
35
 
 
36
#include <getopt.h>
 
37
#include <sys/stat.h>
 
38
#include <fcntl.h>
 
39
 
 
40
using namespace drizzled;
 
41
using namespace std;
 
42
using namespace google;
 
43
 
 
44
typedef std::map<std::string,std::string> Assign;
 
45
 
 
46
static void print_usage_and_exit(char *prog) {
 
47
  using std::cerr;
 
48
  const char *name= strrchr(prog, '/');
 
49
 
 
50
  if (name)
 
51
    ++name;
 
52
  else
 
53
    name= "binlog_writer";
 
54
  cerr << "Usage: " << name << " <options> <query>\n"
 
55
       << "    --output name    Append query to file <name> (default: 'log.bin')\n"
 
56
       << "    --set var=val    Set value of user variable for query\n"
 
57
       << "    --trans-id <id>  Set transaction id to <id>\n"
 
58
       << flush;
 
59
  exit(1);
 
60
}
 
61
 
 
62
 
 
63
static void
 
64
write_query(protobuf::io::CodedOutputStream* out,
 
65
            unsigned long trans_id,
 
66
            const string& query,
 
67
            const Assign& assign)
 
68
{
 
69
  BinaryLog::Query *message = new BinaryLog::Query;
 
70
 
 
71
  {
 
72
    BinaryLog::Header *header= message->mutable_header();
 
73
    header->set_seqno(static_cast<google::protobuf::uint32>(time(NULL)));
 
74
    header->set_server_id(1);
 
75
    header->set_trans_id(static_cast<google::protobuf::uint32>(trans_id));
 
76
  }
 
77
 
 
78
  message->set_query(query);
 
79
  for (Assign::const_iterator ii= assign.begin() ;
 
80
       ii != assign.end() ;
 
81
       ++ii )
 
82
  {
 
83
    BinaryLog::Query::Variable *var= message->add_variable();
 
84
    var->set_name(ii->first);
 
85
    var->set_val(ii->second);
 
86
  }
 
87
 
 
88
  BinaryLog::Event event(BinaryLog::Event::QUERY, message);
 
89
  event.write(out);
 
90
}
 
91
 
 
92
 
 
93
int main(int argc, char *argv[])
 
94
{
 
95
  GOOGLE_PROTOBUF_VERIFY_VERSION;
 
96
 
 
97
  static struct option options[] = {
 
98
    { "set",       1 /* has_arg */, NULL, 0 },
 
99
    { "trans-id",  1 /* has_arg */, NULL, 0 },
 
100
    { "output",    1 /* has_arg */, NULL, 0 },
 
101
    { 0, 0, 0, 0 }
 
102
  };
 
103
 
 
104
  Assign assign;
 
105
  unsigned long trans_id= 0;
 
106
  const char* file_name= "log.bin";
 
107
 
 
108
  int ch, option_index;
 
109
  while ((ch= getopt_long(argc, argv, "", options, &option_index)) != -1) {
 
110
    if (ch == '?')
 
111
      print_usage_and_exit(argv[0]);
 
112
 
 
113
    switch (option_index) {
 
114
    case 0:                                     // --set
 
115
    {
 
116
      // Split the supplied string at the first '='
 
117
      char *end= optarg + strlen(optarg);
 
118
      char *pos= strchr(optarg, '=');
 
119
      if (!pos)
 
120
        pos= end;
 
121
      const string key(optarg, pos);
 
122
      const string value(pos == end ? end : pos+1, end);
 
123
      assign[key]= value;
 
124
    }
 
125
 
 
126
    case 1:                                     // --trans-id
 
127
      trans_id= strtoul(optarg, NULL, 0);
 
128
      break;
 
129
 
 
130
    case 2:                                     // --output
 
131
      file_name= optarg;
 
132
      break;
 
133
    }
 
134
  }
 
135
 
 
136
  if (optind >= argc)
 
137
    print_usage_and_exit(argv[0]);
 
138
 
 
139
  filebuf fb;
 
140
 
 
141
  fb.open(file_name, ios::app | ios::out);
 
142
 
 
143
  ostream os(&fb);
 
144
 
 
145
  protobuf::io::ZeroCopyOutputStream* raw_output=
 
146
    new protobuf::io::OstreamOutputStream(&os);
 
147
  protobuf::io::CodedOutputStream* coded_output=
 
148
    new protobuf::io::CodedOutputStream(raw_output);
 
149
 
 
150
  stringstream sout;
 
151
  sout << message::ioutil::join(" ", &argv[optind], &argv[argc]);
 
152
 
 
153
  write_query(coded_output, trans_id, sout.str(), assign);
 
154
 
 
155
  delete coded_output;
 
156
  delete raw_output;
 
157
  fb.close();
 
158
  return 0;
 
159
}