~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2001, 2003-2004, 2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#include <mysql.h>
17
#include <stdio.h>
18
#include <stdarg.h>
19
#include <stdio.h>
20
#include <string.h>
21
#include <stdlib.h>
22
23
typedef unsigned char uchar;
24
static void die(char* fmt, ...);
25
static void safe_query(MYSQL* mysql, char* query, int read_ok);
26
static void run_query_batch(int* order, int num_queries);
27
static void permute(int *order, int num_queries);
28
static void permute_aux(int *order, int num_queries, int* fixed);
29
static void dump_result(MYSQL* mysql, char* query);
30
31
int count = 0;
32
33
34
struct query
35
{
36
  MYSQL* mysql;
37
  char* query;
38
  int read_ok;
39
  int pri;
40
  int dump_result;
41
};
42
43
MYSQL lock, sel, del_ins;
44
45
struct query queries[] =
46
{
47
  {&del_ins, "insert delayed into foo values(1)", 1, 0, 0},
48
  {&del_ins, "insert delayed into foo values(1)", 1, 0, 0},
49
  {&lock, "lock tables foo write", 1, 1, 0},
50
  {&lock, "unlock tables", 1,2, 0},
51
  {&sel, "select * from foo", 0,0, 0},
52
  {&del_ins, "insert  into foo values(4)", 0,3, 0},
53
  {0,0,0}
54
};
55
56
static void die(char* fmt, ...)
57
{
58
  va_list args;
59
  va_start(args, fmt);
60
  fprintf(stderr, "ERROR: ");
61
  vfprintf(stderr, fmt, args);
62
  fprintf(stderr, "\n");
63
  va_end(args);
64
  exit(1);
65
}
66
67
static void permute(int *order, int num_queries)
68
{
69
  int *fixed;
70
  if(num_queries < 2) return;
71
  if(!(fixed = (int*)malloc(num_queries * sizeof(int))))
72
    die("malloc() failed");
73
74
  memset(fixed, 0, num_queries * sizeof(int));
75
  permute_aux(order, num_queries, fixed);
76
77
  free(fixed);
78
}
79
80
static order_ok(int *order, int num_queries)
81
{
82
  int i,j, pri_i, pri_j;
83
  for(i = 0; i < num_queries; i++)
84
    {
85
      if((pri_i = queries[order[i]].pri))
86
	for(j = i + 1; j < num_queries; j++)
87
	  {
88
	    pri_j = queries[order[j]].pri;
89
	    if(pri_j && pri_i > pri_j)
90
	      return 0;
91
	  }
92
    }
93
94
  return 1;
95
}
96
97
static void permute_aux(int *order, int num_queries, int* fixed)
98
{
99
  int *p,*p1,j,i,tmp, num_free = 0;
100
  p = fixed;
101
  for(i = 0; i < num_queries; i++, p++)
102
    {
103
      if(!*p)
104
	{
105
	  num_free++;
106
	  *p = 1;
107
	  for(j = 0, p1 = fixed ;
108
	      j < num_queries; j++,p1++)
109
	    {
110
	      if(!*p1)
111
		{
112
		  tmp = order[i];
113
		  order[i] = order[j];
114
		  order[j] = tmp;
115
		  *p1 = 1;
116
		  permute_aux(order, num_queries, fixed);
117
		  tmp = order[i];
118
		  order[i] = order[j];
119
		  order[j] = tmp;
120
		  *p1 = 0;
121
		}
122
	    }
123
	  *p = 0;
124
	}
125
    }
126
127
  /*printf("num_free = %d\n", num_free); */
128
129
  if(num_free <= 1)
130
    {
131
      count++;
132
      if(order_ok(order, num_queries))
133
        run_query_batch(order, num_queries);
134
    }
135
}
136
137
static void run_query_batch(int* order, int num_queries)
138
{
139
  int i;
140
  struct query* q;
141
  int *save_order;
142
  safe_query(&lock, "delete from foo", 1);
143
  save_order = order;
144
  for(i = 0; i < num_queries; i++,order++)
145
    {
146
      q = queries + *order;
147
      printf("query='%s'\n", q->query);
148
      safe_query(q->mysql, q->query, q->read_ok);
149
    }
150
  order = save_order;
151
  for(i = 0; i < num_queries; i++,order++)
152
    {
153
      q = queries + *order;
154
      if(q->dump_result)
155
       dump_result(q->mysql, q->query);
156
    }
157
  printf("\n");
158
159
}
160
161
static void safe_net_read(NET* net, char* query)
162
{
163
  int len;
164
  len = my_net_read(net); 
165
  if(len == packet_error || !len)
166
    die("Error running query '%s'", query);
167
  if(net->read_pos[0] == 255)
168
    die("Error running query '%s'", query);
169
}
170
171
172
static void safe_query(MYSQL* mysql, char* query, int read_ok)
173
{
174
  int len;
175
  NET* net = &mysql->net;
176
  net_clear(net);
177
  if(net_write_command(net,(uchar)COM_QUERY, query,strlen(query)))
178
    die("Error running query '%s': %s", query, mysql_error(mysql));
179
  if(read_ok)
180
    {
181
      safe_net_read(net, query);
182
    }
183
}
184
185
static void dump_result(MYSQL* mysql, char* query)
186
{
187
  MYSQL_RES* res;
188
  safe_net_read(&mysql->net, query);
189
  res = mysql_store_result(mysql);
190
  if(res)
191
   mysql_free_result(res);
192
}
193
194
static int* init_order(int* num_queries)
195
{
196
  struct query* q;
197
  int *order, *order_end, *p;
198
  int n,i;
199
200
  for(q = queries; q->mysql; q++)
201
    ;
202
203
  n = q - queries;
204
  if(!(order = (int*) malloc(n * sizeof(int))))
205
    die("malloc() failed");
206
  order_end = order + n;
207
  for(p = order,i = 0; p < order_end; p++,i++)
208
    *p = i;
209
  *num_queries = n;
210
  return order;
211
}
212
213
int main()
214
{
215
  char* user = "root", *pass = "", *host = "localhost", *db = "test";
216
  int *order, num_queries;
217
  order = init_order(&num_queries);
218
  if(!mysql_init(&lock) || !mysql_init(&sel) || !mysql_init(&del_ins))
219
    die("error in mysql_init()");
220
221
  mysql_options(&lock, MYSQL_READ_DEFAULT_GROUP, "mysql");
222
  mysql_options(&sel, MYSQL_READ_DEFAULT_GROUP, "mysql");
223
  mysql_options(&del_ins, MYSQL_READ_DEFAULT_GROUP, "mysql");
224
225
  if(!mysql_real_connect(&lock, host, user, pass, db, 0,0,0 ) ||
226
     !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) ||
227
     !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 ))
228
    die("Error in mysql_real_connect(): %s", mysql_error(&lock));
229
  lock.reconnect= sel.reconnect= del_ins.reconnect= 1;
230
231
  permute(order, num_queries);
232
  printf("count = %d\n", count);
233
234
  mysql_close(&lock);
235
  mysql_close(&sel);
236
  mysql_close(&del_ins);
237
  free(order);
238
}